Android11.0-rgo版添加微件小部件功能

74 篇文章 1 订阅
49 篇文章 1 订阅

最近遇到几个客户要求长按桌面要有添加微件这个功能按钮,我们知道项目是按照go版过的GMS,go版系统是不带这个功能的,微件小部件是normal版的功能,也就是ddr必须是3G及以上容量才能带这个功能的,但是客户就是要求有这个功能,所以还是老老实实的加上,没办法,谁叫客户就是上帝呢,具体方法如下:

1. frameworks/base

diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
old mode 100644
new mode 100755
index fc27da1..38f31f7
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3363,7 +3363,7 @@
 
     <!-- True if the device requires AppWidgetService even if it does not have
          the PackageManager.FEATURE_APP_WIDGETS feature -->
-    <bool name="config_enableAppWidgetService">false</bool>
+    <bool name="config_enableAppWidgetService">true</bool>
 
     <!-- True if the device supports Sustained Performance Mode-->
     <bool name="config_sustainedPerformanceModeSupported">false</bool>

2. frameworks/native

diff --git a/data/etc/go_handheld_core_hardware.xml b/data/etc/go_handheld_core_hardware.xml
old mode 100644
new mode 100755
index ec73a60..dba7fcd
--- a/data/etc/go_handheld_core_hardware.xml
+++ b/data/etc/go_handheld_core_hardware.xml
@@ -34,6 +34,7 @@
     <feature name="android.hardware.screen.landscape" />
 
     <!-- basic system services -->
+    <feature name="android.software.app_widgets" />
     <feature name="android.software.connectionservice" />
     <feature name="android.software.backup" />
     <feature name="android.software.home_screen" />

3. packages/apps/Launcher3     这个目录下改动比较大,请仔细核对

diff --git a/go/src/com/android/launcher3/model/LoaderResults.java b/go/src/com/android/launcher3/model/LoaderResults.java
old mode 100644
new mode 100755
index 7130531..aa2f679
--- a/go/src/com/android/launcher3/model/LoaderResults.java
+++ b/go/src/com/android/launcher3/model/LoaderResults.java
@@ -20,7 +20,12 @@ import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.model.BgDataModel.Callbacks;
+import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.LooperExecutor;
+import com.android.launcher3.widget.WidgetListRowEntry;
+
+import java.util.ArrayList;
+import java.util.HashMap;
 
 /**
  * Helper class to handle results of {@link com.android.launcher3.model.LoaderTask}.
@@ -39,9 +44,17 @@ public class LoaderResults extends BaseLoaderResults {
 
     @Override
     public void bindDeepShortcuts() {
+        final HashMap<ComponentKey, Integer> shortcutMapCopy;
+        synchronized (mBgDataModel) {
+            shortcutMapCopy = new HashMap<>(mBgDataModel.deepShortcutMap);
+        }
+        executeCallbacksTask(c -> c.bindDeepShortcutMap(shortcutMapCopy), mUiExecutor);
     }
 
     @Override
     public void bindWidgets() {
+        final ArrayList<WidgetListRowEntry> widgets =
+                mBgDataModel.widgetsModel.getWidgetsList(mApp.getContext());
+        executeCallbacksTask(c -> c.bindAllWidgets(widgets), mUiExecutor);
     }
 }
diff --git a/go/src/com/android/launcher3/model/WidgetsModel.java b/go/src/com/android/launcher3/model/WidgetsModel.java
old mode 100644
new mode 100755
index 3b3dc01..9d87788
--- a/go/src/com/android/launcher3/model/WidgetsModel.java
+++ b/go/src/com/android/launcher3/model/WidgetsModel.java
@@ -1,35 +1,45 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
 
 package com.android.launcher3.model;
 
+import static android.appwidget.AppWidgetProviderInfo.WIDGET_FEATURE_HIDE_FROM_PICKER;
+
+import static com.android.launcher3.pm.ShortcutConfigActivityInfo.queryList;
+
+import android.appwidget.AppWidgetProviderInfo;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Process;
 import android.os.UserHandle;
+import android.util.Log;
 
 import androidx.annotation.Nullable;
 
+import com.android.launcher3.AppFilter;
+import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherAppWidgetProviderInfo;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.compat.AlphabeticIndexCompat;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.icons.ComponentWithLabelAndIcon;
+import com.android.launcher3.icons.IconCache;
+import com.android.launcher3.model.data.PackageItemInfo;
+import com.android.launcher3.pm.ShortcutConfigActivityInfo;
+import com.android.launcher3.util.MultiHashMap;
 import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.util.Preconditions;
+import com.android.launcher3.widget.WidgetItemComparator;
 import com.android.launcher3.widget.WidgetListRowEntry;
+import com.android.launcher3.widget.WidgetManagerHelper;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 
 /**
@@ -40,9 +50,15 @@ import java.util.Set;
 public class WidgetsModel {
 
     // True is the widget support is disabled.
-    public static final boolean GO_DISABLE_WIDGETS = true;
+    public static final boolean GO_DISABLE_WIDGETS = false;
+
+    private static final String TAG = "WidgetsModel";
+    private static final boolean DEBUG = false;
 
-    private static final ArrayList<WidgetListRowEntry> EMPTY_WIDGET_LIST = new ArrayList<>();
+    /* Map of widgets and shortcuts that are tracked per package. */
+    private final MultiHashMap<PackageItemInfo, WidgetItem> mWidgetsList = new MultiHashMap<>();
+
+    private AppFilter mAppFilter;
 
     /**
      * Returns a list of {@link WidgetListRowEntry}. All {@link WidgetItem} in a single row
@@ -53,25 +69,196 @@ public class WidgetsModel {
      * @see com.android.launcher3.widget.WidgetsListAdapter#setWidgets(ArrayList)
      */
     public synchronized ArrayList<WidgetListRowEntry> getWidgetsList(Context context) {
-        return EMPTY_WIDGET_LIST;
+        ArrayList<WidgetListRowEntry> result = new ArrayList<>();
+        AlphabeticIndexCompat indexer = new AlphabeticIndexCompat(context);
+
+        WidgetItemComparator widgetComparator = new WidgetItemComparator();
+        for (Map.Entry<PackageItemInfo, ArrayList<WidgetItem>> entry : mWidgetsList.entrySet()) {
+            WidgetListRowEntry row = new WidgetListRowEntry(entry.getKey(), entry.getValue());
+            row.titleSectionName = (row.pkgItem.title == null) ? "" :
+                    indexer.computeSectionName(row.pkgItem.title);
+            Collections.sort(row.widgets, widgetComparator);
+            result.add(row);
+        }
+        return result;
     }
 
     /**
      * @param packageUser If null, all widgets and shortcuts are updated and returned, otherwise
      *                    only widgets and shortcuts associated with the package/user are.
      */
-    public List<ComponentWithLabelAndIcon> update(LauncherAppState app,
-            @Nullable PackageUserKey packageUser) {
-        return Collections.emptyList();
+    public List<ComponentWithLabelAndIcon> update(
+            LauncherAppState app, @Nullable PackageUserKey packageUser) {
+        Preconditions.assertWorkerThread();
+
+        Context context = app.getContext();
+        final ArrayList<WidgetItem> widgetsAndShortcuts = new ArrayList<>();
+        List<ComponentWithLabelAndIcon> updatedItems = new ArrayList<>();
+        try {
+            InvariantDeviceProfile idp = app.getInvariantDeviceProfile();
+            PackageManager pm = app.getContext().getPackageManager();
+
+            // Widgets
+            WidgetManagerHelper widgetManager = new WidgetManagerHelper(context);
+            for (AppWidgetProviderInfo widgetInfo : widgetManager.getAllProviders(packageUser)) {
+                LauncherAppWidgetProviderInfo launcherWidgetInfo =
+                        LauncherAppWidgetProviderInfo.fromProviderInfo(context, widgetInfo);
+
+                widgetsAndShortcuts.add(new WidgetItem(
+                        launcherWidgetInfo, idp, app.getIconCache()));
+                updatedItems.add(launcherWidgetInfo);
+            }
+
+            // Shortcuts
+            for (ShortcutConfigActivityInfo info :
+                    queryList(context, packageUser)) {
+                widgetsAndShortcuts.add(new WidgetItem(info, app.getIconCache(), pm));
+                updatedItems.add(info);
+            }
+            setWidgetsAndShortcuts(widgetsAndShortcuts, app, packageUser);
+        } catch (Exception e) {
+            if (!FeatureFlags.IS_STUDIO_BUILD && Utilities.isBinderSizeError(e)) {
+                // the returned value may be incomplete and will not be refreshed until the next
+                // time Launcher starts.
+                // TODO: after figuring out a repro step, introduce a dirty bit to check when
+                // onResume is called to refresh the widget provider list.
+            } else {
+                throw e;
+            }
+        }
+
+        app.getWidgetCache().removeObsoletePreviews(widgetsAndShortcuts, packageUser);
+        return updatedItems;
     }
 
+    private synchronized void setWidgetsAndShortcuts(ArrayList<WidgetItem> rawWidgetsShortcuts,
+            LauncherAppState app, @Nullable PackageUserKey packageUser) {
+        if (DEBUG) {
+            Log.d(TAG, "addWidgetsAndShortcuts, widgetsShortcuts#=" + rawWidgetsShortcuts.size());
+        }
+
+        // Temporary list for {@link PackageItemInfos} to avoid having to go through
+        // {@link mPackageItemInfos} to locate the key to be used for {@link #mWidgetsList}
+        HashMap<String, PackageItemInfo> tmpPackageItemInfos = new HashMap<>();
+
+        // clear the lists.
+        if (packageUser == null) {
+            mWidgetsList.clear();
+        } else {
+            // Only clear the widgets for the given package/user.
+            PackageItemInfo packageItem = null;
+            for (PackageItemInfo item : mWidgetsList.keySet()) {
+                if (item.packageName.equals(packageUser.mPackageName)) {
+                    packageItem = item;
+                    break;
+                }
+            }
+            if (packageItem != null) {
+                // We want to preserve the user that was on the packageItem previously,
+                // so add it to tmpPackageItemInfos here to avoid creating a new entry.
+                tmpPackageItemInfos.put(packageItem.packageName, packageItem);
+
+                Iterator<WidgetItem> widgetItemIterator = mWidgetsList.get(packageItem).iterator();
+                while (widgetItemIterator.hasNext()) {
+                    WidgetItem nextWidget = widgetItemIterator.next();
+                    if (nextWidget.componentName.getPackageName().equals(packageUser.mPackageName)
+                            && nextWidget.user.equals(packageUser.mUser)) {
+                        widgetItemIterator.remove();
+                    }
+                }
+            }
+        }
+
+        InvariantDeviceProfile idp = app.getInvariantDeviceProfile();
+        UserHandle myUser = Process.myUserHandle();
+
+        // add and update.
+        for (WidgetItem item : rawWidgetsShortcuts) {
+            if (item.widgetInfo != null) {
+                if ((item.widgetInfo.getWidgetFeatures() & WIDGET_FEATURE_HIDE_FROM_PICKER) != 0) {
+                    // Widget is hidden from picker
+                    continue;
+                }
+
+                // Ensure that all widgets we show can be added on a workspace of this size
+                int minSpanX = Math.min(item.widgetInfo.spanX, item.widgetInfo.minSpanX);
+                int minSpanY = Math.min(item.widgetInfo.spanY, item.widgetInfo.minSpanY);
+                if (minSpanX > idp.numColumns || minSpanY > idp.numRows) {
+                    if (DEBUG) {
+                        Log.d(TAG, String.format(
+                                "Widget %s : (%d X %d) can't fit on this device",
+                                item.componentName, minSpanX, minSpanY));
+                    }
+                    continue;
+                }
+            }
+
+            if (mAppFilter == null) {
+                mAppFilter = AppFilter.newInstance(app.getContext());
+            }
+            if (!mAppFilter.shouldShowApp(item.componentName)) {
+                if (DEBUG) {
+                    Log.d(TAG, String.format("%s is filtered and not added to the widget tray.",
+                            item.componentName));
+                }
+                continue;
+            }
+
+            String packageName = item.componentName.getPackageName();
+            PackageItemInfo pInfo = tmpPackageItemInfos.get(packageName);
+            if (pInfo == null) {
+                pInfo = new PackageItemInfo(packageName);
+                pInfo.user = item.user;
+                tmpPackageItemInfos.put(packageName,  pInfo);
+            } else if (!myUser.equals(pInfo.user)) {
+                // Keep updating the user, until we get the primary user.
+                pInfo.user = item.user;
+            }
+            mWidgetsList.addToList(pInfo, item);
+        }
+
+        // Update each package entry
+        IconCache iconCache = app.getIconCache();
+        for (PackageItemInfo p : tmpPackageItemInfos.values()) {
+            iconCache.getTitleAndIconForApp(p, true /* userLowResIcon */);
+        }
+    }
 
     public void onPackageIconsUpdated(Set<String> packageNames, UserHandle user,
             LauncherAppState app) {
+        for (Entry<PackageItemInfo, ArrayList<WidgetItem>> entry : mWidgetsList.entrySet()) {
+            if (packageNames.contains(entry.getKey().packageName)) {
+                ArrayList<WidgetItem> items = entry.getValue();
+                int count = items.size();
+                for (int i = 0; i < count; i++) {
+                    WidgetItem item = items.get(i);
+                    if (item.user.equals(user)) {
+                        if (item.activityInfo != null) {
+                            items.set(i, new WidgetItem(item.activityInfo, app.getIconCache(),
+                                    app.getContext().getPackageManager()));
+                        } else {
+                            items.set(i, new WidgetItem(item.widgetInfo,
+                                    app.getInvariantDeviceProfile(), app.getIconCache()));
+                        }
+                    }
+                }
+            }
+        }
     }
 
     public WidgetItem getWidgetProviderInfoByProviderName(
             ComponentName providerName) {
+        ArrayList<WidgetItem> widgetsList = mWidgetsList.get(
+                new PackageItemInfo(providerName.getPackageName()));
+        if (widgetsList == null) {
+            return null;
+        }
+
+        for (WidgetItem item : widgetsList) {
+            if (item.componentName.equals(providerName)) {
+                return item;
+            }
+        }
         return null;
     }
 }
\ No newline at end of file

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值