1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.launcher3.util; 17 18 import static android.appwidget.AppWidgetProviderInfo.WIDGET_FEATURE_HIDE_FROM_PICKER; 19 20 import android.appwidget.AppWidgetProviderInfo; 21 import android.content.ComponentName; 22 import android.content.Context; 23 import android.content.pm.ActivityInfo; 24 import android.content.pm.ApplicationInfo; 25 import android.os.Bundle; 26 import android.os.Process; 27 28 import com.android.launcher3.LauncherSettings; 29 import com.android.launcher3.model.data.LauncherAppWidgetInfo; 30 import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; 31 import com.android.launcher3.widget.LauncherWidgetHolder; 32 import com.android.launcher3.widget.PendingAddWidgetInfo; 33 import com.android.launcher3.widget.WidgetManagerHelper; 34 35 /** 36 * Common method for widget binding 37 */ 38 public class WidgetUtils { 39 40 /** 41 * Creates a LauncherAppWidgetInfo corresponding to {@param info} 42 * 43 * @param bindWidget if true the info is bound and a valid widgetId is assigned to 44 * the LauncherAppWidgetInfo 45 */ createWidgetInfo( LauncherAppWidgetProviderInfo info, Context targetContext, boolean bindWidget)46 public static LauncherAppWidgetInfo createWidgetInfo( 47 LauncherAppWidgetProviderInfo info, Context targetContext, boolean bindWidget) { 48 LauncherAppWidgetInfo item = new LauncherAppWidgetInfo( 49 LauncherAppWidgetInfo.NO_ID, info.provider); 50 item.spanX = info.minSpanX; 51 item.spanY = info.minSpanY; 52 item.minSpanX = info.minSpanX; 53 item.minSpanY = info.minSpanY; 54 item.user = info.getProfile(); 55 item.cellX = 0; 56 item.cellY = 1; 57 item.container = LauncherSettings.Favorites.CONTAINER_DESKTOP; 58 59 if (bindWidget) { 60 PendingAddWidgetInfo pendingInfo = 61 new PendingAddWidgetInfo( 62 info, LauncherSettings.Favorites.CONTAINER_WIDGETS_TRAY); 63 pendingInfo.spanX = item.spanX; 64 pendingInfo.spanY = item.spanY; 65 pendingInfo.minSpanX = item.minSpanX; 66 pendingInfo.minSpanY = item.minSpanY; 67 Bundle options = pendingInfo.getDefaultSizeOptions(targetContext); 68 69 LauncherWidgetHolder holder = LauncherWidgetHolder.newInstance(targetContext); 70 try { 71 int widgetId = holder.allocateAppWidgetId(); 72 if (!new WidgetManagerHelper(targetContext) 73 .bindAppWidgetIdIfAllowed(widgetId, info, options)) { 74 holder.deleteAppWidgetId(widgetId); 75 throw new IllegalArgumentException("Unable to bind widget id"); 76 } 77 item.appWidgetId = widgetId; 78 } finally { 79 // Necessary to destroy the holder to free up possible activity context 80 holder.destroy(); 81 } 82 } 83 return item; 84 } 85 86 /** 87 * Creates a {@link AppWidgetProviderInfo} for the provided component name 88 * 89 * @param cn component name of the appwidget provider 90 * @param hideFromPicker indicates if the widget should appear in widget picker 91 */ createAppWidgetProviderInfo(ComponentName cn, boolean hideFromPicker)92 public static AppWidgetProviderInfo createAppWidgetProviderInfo(ComponentName cn, 93 boolean hideFromPicker) { 94 ActivityInfo activityInfo = new ActivityInfo(); 95 activityInfo.applicationInfo = new ApplicationInfo(); 96 activityInfo.applicationInfo.uid = Process.myUid(); 97 AppWidgetProviderInfo info = new AppWidgetProviderInfo(); 98 if (hideFromPicker) { 99 info.widgetFeatures = WIDGET_FEATURE_HIDE_FROM_PICKER; 100 } 101 info.providerInfo = activityInfo; 102 info.provider = cn; 103 return info; 104 } 105 106 /** 107 * Creates a {@link AppWidgetProviderInfo} for the provided component name 108 * 109 * @param cn component name of the appwidget provider 110 */ createAppWidgetProviderInfo(ComponentName cn)111 public static AppWidgetProviderInfo createAppWidgetProviderInfo(ComponentName cn) { 112 return createAppWidgetProviderInfo(cn, /*hideFromPicker=*/ false); 113 } 114 } 115