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 androidx.test.core.app.ApplicationProvider.getApplicationContext;
19 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
20 
21 import static com.android.launcher3.WorkspaceLayoutManager.FIRST_SCREEN_ID;
22 
23 import android.appwidget.AppWidgetHost;
24 import android.appwidget.AppWidgetManager;
25 import android.appwidget.AppWidgetProviderInfo;
26 import android.content.ComponentName;
27 import android.content.ContentResolver;
28 import android.content.Context;
29 import android.os.Bundle;
30 import android.os.Process;
31 
32 import com.android.launcher3.LauncherSettings;
33 import com.android.launcher3.model.data.ItemInfo;
34 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
35 import com.android.launcher3.widget.LauncherAppWidgetHost;
36 import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
37 import com.android.launcher3.widget.PendingAddWidgetInfo;
38 import com.android.launcher3.widget.WidgetManagerHelper;
39 
40 /**
41  * Common method for widget binding
42  */
43 public class WidgetUtils {
44 
45     /**
46      * Creates a LauncherAppWidgetInfo corresponding to {@param info}
47      *
48      * @param bindWidget if true the info is bound and a valid widgetId is assigned to
49      *                   the LauncherAppWidgetInfo
50      */
createWidgetInfo( LauncherAppWidgetProviderInfo info, Context targetContext, boolean bindWidget)51     public static LauncherAppWidgetInfo createWidgetInfo(
52             LauncherAppWidgetProviderInfo info, Context targetContext, boolean bindWidget) {
53         LauncherAppWidgetInfo item = new LauncherAppWidgetInfo(
54                 LauncherAppWidgetInfo.NO_ID, info.provider);
55         item.spanX = info.minSpanX;
56         item.spanY = info.minSpanY;
57         item.minSpanX = info.minSpanX;
58         item.minSpanY = info.minSpanY;
59         item.user = info.getProfile();
60         item.cellX = 0;
61         item.cellY = 1;
62         item.container = LauncherSettings.Favorites.CONTAINER_DESKTOP;
63 
64         if (bindWidget) {
65             PendingAddWidgetInfo pendingInfo =
66                     new PendingAddWidgetInfo(
67                             info, LauncherSettings.Favorites.CONTAINER_WIDGETS_TRAY);
68             pendingInfo.spanX = item.spanX;
69             pendingInfo.spanY = item.spanY;
70             pendingInfo.minSpanX = item.minSpanX;
71             pendingInfo.minSpanY = item.minSpanY;
72             Bundle options = pendingInfo.getDefaultSizeOptions(targetContext);
73 
74             AppWidgetHost host = new LauncherAppWidgetHost(targetContext);
75             int widgetId = host.allocateAppWidgetId();
76             if (!new WidgetManagerHelper(targetContext)
77                     .bindAppWidgetIdIfAllowed(widgetId, info, options)) {
78                 host.deleteAppWidgetId(widgetId);
79                 throw new IllegalArgumentException("Unable to bind widget id");
80             }
81             item.appWidgetId = widgetId;
82         }
83         return item;
84     }
85 
86     /**
87      * Adds {@param item} on the homescreen on the 0th screen
88      */
addItemToScreen(ItemInfo item, Context targetContext)89     public static void addItemToScreen(ItemInfo item, Context targetContext) {
90         ContentResolver resolver = targetContext.getContentResolver();
91         int screenId = FIRST_SCREEN_ID;
92         // Update the screen id counter for the provider.
93         LauncherSettings.Settings.call(resolver,
94                 LauncherSettings.Settings.METHOD_NEW_SCREEN_ID);
95 
96         if (screenId > FIRST_SCREEN_ID) {
97             screenId = FIRST_SCREEN_ID;
98         }
99 
100         // Insert the item
101         ContentWriter writer = new ContentWriter(targetContext);
102         item.id = LauncherSettings.Settings.call(
103                 resolver, LauncherSettings.Settings.METHOD_NEW_ITEM_ID)
104                 .getInt(LauncherSettings.Settings.EXTRA_VALUE);
105         item.screenId = screenId;
106         item.onAddToDatabase(writer);
107         writer.put(LauncherSettings.Favorites._ID, item.id);
108         resolver.insert(LauncherSettings.Favorites.CONTENT_URI,
109                 writer.getValues(targetContext));
110     }
111 
112 
113     /**
114      * Creates a {@link AppWidgetProviderInfo} for the provided component name
115      */
createAppWidgetProviderInfo(ComponentName cn)116     public static AppWidgetProviderInfo createAppWidgetProviderInfo(ComponentName cn) {
117         AppWidgetProviderInfo info = AppWidgetManager.getInstance(getApplicationContext())
118                 .getInstalledProvidersForPackage(
119                         getInstrumentation().getContext().getPackageName(), Process.myUserHandle())
120                 .get(0);
121         info.provider = cn;
122         return info;
123     }
124 }
125