当前位置:   article > 正文

Android14系统go版添加微件功能

Android14系统go版添加微件功能

一般normal版软件自带微件功能,但是go版没有这个功能,但是客户有时会要求也要加上这个微件功能,实现的方法修改如下:

1. frameworks/base

  1. diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
  2. index 24b3fdf64b0f..d805ff07871a 100644
  3. --- a/core/res/res/values/config.xml
  4. +++ b/core/res/res/values/config.xml
  5. @@ -4191,7 +4191,7 @@
  6. <!-- True if the device requires AppWidgetService even if it does not have
  7. the PackageManager.FEATURE_APP_WIDGETS feature -->
  8. - <bool name="config_enableAppWidgetService">false</bool>
  9. + <bool name="config_enableAppWidgetService">true</bool>
  10. <!-- True if the device supports Sustained Performance Mode-->
  11. <bool name="config_sustainedPerformanceModeSupported">false</bool>

2. frameworks/native

  1. diff --git a/data/etc/go_handheld_core_hardware.xml b/data/etc/go_handheld_core_hardware.xml
  2. index ee829728c8..23077cbc82 100644
  3. --- a/data/etc/go_handheld_core_hardware.xml
  4. +++ b/data/etc/go_handheld_core_hardware.xml
  5. @@ -36,6 +36,7 @@
  6. <feature name="android.hardware.security.model.compatible" />
  7. <!-- basic system services -->
  8. + <feature name="android.software.app_widgets" />
  9. <feature name="android.software.telecom" />
  10. <feature name="android.software.backup" />
  11. <feature name="android.software.home_screen" />

3. packages/apps/Launcher3

  1. diff --git a/go/src/com/android/launcher3/model/LauncherBinder.java b/go/src/com/android/launcher3/model/LauncherBinder.java
  2. index 437d8caf94..66d9db0c67 100644
  3. --- a/go/src/com/android/launcher3/model/LauncherBinder.java
  4. +++ b/go/src/com/android/launcher3/model/LauncherBinder.java
  5. @@ -20,6 +20,11 @@ import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
  6. import com.android.launcher3.LauncherAppState;
  7. import com.android.launcher3.model.BgDataModel.Callbacks;
  8. +import com.android.launcher3.util.ComponentKey;
  9. +import com.android.launcher3.widget.model.WidgetsListBaseEntry;
  10. +
  11. +import java.util.HashMap;
  12. +import java.util.List;
  13. /**
  14. * Binds the results of {@link com.android.launcher3.model.LoaderTask} to the Callbacks objects.
  15. @@ -33,9 +38,17 @@ public class LauncherBinder extends BaseLauncherBinder {
  16. @Override
  17. public void bindDeepShortcuts() {
  18. + final HashMap<ComponentKey, Integer> shortcutMapCopy;
  19. + synchronized (mBgDataModel) {
  20. + shortcutMapCopy = new HashMap<>(mBgDataModel.deepShortcutMap);
  21. + }
  22. + executeCallbacksTask(c -> c.bindDeepShortcutMap(shortcutMapCopy), mUiExecutor);
  23. }
  24. @Override
  25. public void bindWidgets() {
  26. + final List<WidgetsListBaseEntry> widgets =
  27. + mBgDataModel.widgetsModel.getWidgetsListForPicker(mApp.getContext());
  28. + executeCallbacksTask(c -> c.bindAllWidgets(widgets), mUiExecutor);
  29. }
  30. }
  31. diff --git a/go/src/com/android/launcher3/model/WidgetsModel.java b/go/src/com/android/launcher3/model/WidgetsModel.java
  32. index 1aa5d03f6d..75df5e5787 100644
  33. --- a/go/src/com/android/launcher3/model/WidgetsModel.java
  34. +++ b/go/src/com/android/launcher3/model/WidgetsModel.java
  35. @@ -16,23 +16,57 @@
  36. package com.android.launcher3.model;
  37. +import static android.appwidget.AppWidgetProviderInfo.WIDGET_FEATURE_HIDE_FROM_PICKER;
  38. +
  39. +import static com.android.launcher3.pm.ShortcutConfigActivityInfo.queryList;
  40. +import static com.android.launcher3.widget.WidgetSections.NO_CATEGORY;
  41. +
  42. +import static java.util.stream.Collectors.groupingBy;
  43. +import static java.util.stream.Collectors.mapping;
  44. +import static java.util.stream.Collectors.toList;
  45. +
  46. +import android.appwidget.AppWidgetProviderInfo;
  47. import android.content.ComponentName;
  48. import android.content.Context;
  49. +import android.content.pm.PackageManager;
  50. import android.os.UserHandle;
  51. +import android.util.Log;
  52. +import android.util.Pair;
  53. import androidx.annotation.Nullable;
  54. +import androidx.collection.ArrayMap;
  55. +import com.android.launcher3.AppFilter;
  56. +import com.android.launcher3.InvariantDeviceProfile;
  57. import com.android.launcher3.LauncherAppState;
  58. +import com.android.launcher3.Utilities;
  59. +import com.android.launcher3.compat.AlphabeticIndexCompat;
  60. +import com.android.launcher3.config.FeatureFlags;
  61. import com.android.launcher3.icons.ComponentWithLabelAndIcon;
  62. +import com.android.launcher3.icons.IconCache;
  63. import com.android.launcher3.model.data.PackageItemInfo;
  64. +import com.android.launcher3.pm.ShortcutConfigActivityInfo;
  65. +import com.android.launcher3.util.IntSet;
  66. import com.android.launcher3.util.PackageUserKey;
  67. +import com.android.launcher3.util.Preconditions;
  68. +import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
  69. +import com.android.launcher3.widget.WidgetManagerHelper;
  70. +import com.android.launcher3.widget.WidgetSections;
  71. import com.android.launcher3.widget.model.WidgetsListBaseEntry;
  72. +import com.android.launcher3.widget.model.WidgetsListContentEntry;
  73. +import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
  74. import java.util.ArrayList;
  75. +import java.util.Arrays;
  76. +import java.util.Collection;
  77. import java.util.Collections;
  78. +import java.util.HashMap;
  79. +import java.util.Iterator;
  80. import java.util.List;
  81. import java.util.Map;
  82. +import java.util.Map.Entry;
  83. import java.util.Set;
  84. +import java.util.function.Predicate;
  85. /**
  86. * Widgets data model that is used by the adapters of the widget views and controllers.
  87. @@ -42,10 +76,14 @@ import java.util.Set;
  88. public class WidgetsModel {
  89. // True is the widget support is disabled.
  90. - public static final boolean GO_DISABLE_WIDGETS = true;
  91. - public static final boolean GO_DISABLE_NOTIFICATION_DOTS = true;
  92. + public static final boolean GO_DISABLE_WIDGETS = false;
  93. + public static final boolean GO_DISABLE_NOTIFICATION_DOTS = false;
  94. +
  95. + private static final String TAG = "WidgetsModel";
  96. + private static final boolean DEBUG = false;
  97. - private static final ArrayList<WidgetsListBaseEntry> EMPTY_WIDGET_LIST = new ArrayList<>();
  98. + /* Map of widgets and shortcuts that are tracked per package. */
  99. + private final Map<PackageItemInfo, List<WidgetItem>> mWidgetsList = new HashMap<>();
  100. /**
  101. * Returns a list of {@link WidgetsListBaseEntry}. All {@link WidgetItem} in a single row are
  102. @@ -56,36 +94,246 @@ public class WidgetsModel {
  103. * @see com.android.launcher3.widget.picker.WidgetsListAdapter#setWidgets(List)
  104. */
  105. public synchronized ArrayList<WidgetsListBaseEntry> getWidgetsListForPicker(Context context) {
  106. - return EMPTY_WIDGET_LIST;
  107. + ArrayList<WidgetsListBaseEntry> result = new ArrayList<>();
  108. + AlphabeticIndexCompat indexer = new AlphabeticIndexCompat(context);
  109. +
  110. + for (Map.Entry<PackageItemInfo, List<WidgetItem>> entry : mWidgetsList.entrySet()) {
  111. + PackageItemInfo pkgItem = entry.getKey();
  112. + List<WidgetItem> widgetItems = entry.getValue();
  113. + String sectionName = (pkgItem.title == null) ? "" :
  114. + indexer.computeSectionName(pkgItem.title);
  115. + result.add(WidgetsListHeaderEntry.create(pkgItem, sectionName, widgetItems));
  116. + result.add(new WidgetsListContentEntry(pkgItem, sectionName, widgetItems));
  117. + }
  118. + return result;
  119. }
  120. /** Returns a mapping of packages to their widgets without static shortcuts. */
  121. public synchronized Map<PackageUserKey, List<WidgetItem>> getAllWidgetsWithoutShortcuts() {
  122. - return Map.of();
  123. + Map<PackageUserKey, List<WidgetItem>> packagesToWidgets = new HashMap<>();
  124. + mWidgetsList.forEach((packageItemInfo, widgetsAndShortcuts) -> {
  125. + List<WidgetItem> widgets = widgetsAndShortcuts.stream()
  126. + .filter(item -> item.widgetInfo != null)
  127. + .collect(toList());
  128. + if (widgets.size() > 0) {
  129. + packagesToWidgets.put(
  130. + new PackageUserKey(packageItemInfo.packageName, packageItemInfo.user),
  131. + widgets);
  132. + }
  133. + });
  134. + return packagesToWidgets;
  135. }
  136. /**
  137. * @param packageUser If null, all widgets and shortcuts are updated and returned, otherwise
  138. * only widgets and shortcuts associated with the package/user are.
  139. */
  140. - public List<ComponentWithLabelAndIcon> update(LauncherAppState app,
  141. - @Nullable PackageUserKey packageUser) {
  142. - return Collections.emptyList();
  143. + public List<ComponentWithLabelAndIcon> update(
  144. + LauncherAppState app, @Nullable PackageUserKey packageUser) {
  145. + Preconditions.assertWorkerThread();
  146. +
  147. + Context context = app.getContext();
  148. + final ArrayList<WidgetItem> widgetsAndShortcuts = new ArrayList<>();
  149. + List<ComponentWithLabelAndIcon> updatedItems = new ArrayList<>();
  150. + try {
  151. + InvariantDeviceProfile idp = app.getInvariantDeviceProfile();
  152. + PackageManager pm = app.getContext().getPackageManager();
  153. +
  154. + // Widgets
  155. + WidgetManagerHelper widgetManager = new WidgetManagerHelper(context);
  156. + for (AppWidgetProviderInfo widgetInfo : widgetManager.getAllProviders(packageUser)) {
  157. + LauncherAppWidgetProviderInfo launcherWidgetInfo =
  158. + LauncherAppWidgetProviderInfo.fromProviderInfo(context, widgetInfo);
  159. +
  160. + widgetsAndShortcuts.add(new WidgetItem(
  161. + launcherWidgetInfo, idp, app.getIconCache(), app.getContext()));
  162. + updatedItems.add(launcherWidgetInfo);
  163. + }
  164. +
  165. + // Shortcuts
  166. + for (ShortcutConfigActivityInfo info :
  167. + queryList(context, packageUser)) {
  168. + widgetsAndShortcuts.add(new WidgetItem(info, app.getIconCache(), pm));
  169. + updatedItems.add(info);
  170. + }
  171. + setWidgetsAndShortcuts(widgetsAndShortcuts, app, packageUser);
  172. + } catch (Exception e) {
  173. + if (!FeatureFlags.IS_STUDIO_BUILD && Utilities.isBinderSizeError(e)) {
  174. + // the returned value may be incomplete and will not be refreshed until the next
  175. + // time Launcher starts.
  176. + // TODO: after figuring out a repro step, introduce a dirty bit to check when
  177. + // onResume is called to refresh the widget provider list.
  178. + } else {
  179. + throw e;
  180. + }
  181. + }
  182. +
  183. + return updatedItems;
  184. }
  185. + private synchronized void setWidgetsAndShortcuts(ArrayList<WidgetItem> rawWidgetsShortcuts,
  186. + LauncherAppState app, @Nullable PackageUserKey packageUser) {
  187. + if (DEBUG) {
  188. + Log.d(TAG, "addWidgetsAndShortcuts, widgetsShortcuts#=" + rawWidgetsShortcuts.size());
  189. + }
  190. +
  191. + // Temporary cache for {@link PackageItemInfos} to avoid having to go through
  192. + // {@link mPackageItemInfos} to locate the key to be used for {@link #mWidgetsList}
  193. + PackageItemInfoCache packageItemInfoCache = new PackageItemInfoCache();
  194. +
  195. + if (packageUser == null) {
  196. + // Clear the list if this is an update on all widgets and shortcuts.
  197. + mWidgetsList.clear();
  198. + } else {
  199. + // Otherwise, only clear the widgets and shortcuts for the changed package.
  200. + mWidgetsList.remove(packageItemInfoCache.getOrCreate(packageUser));
  201. + }
  202. +
  203. + // add and update.
  204. + mWidgetsList.putAll(rawWidgetsShortcuts.stream()
  205. + .filter(new WidgetValidityCheck(app))
  206. + .flatMap(widgetItem -> getPackageUserKeys(app.getContext(), widgetItem).stream()
  207. + .map(key -> new Pair<>(packageItemInfoCache.getOrCreate(key), widgetItem)))
  208. + .collect(groupingBy(pair -> pair.first, mapping(pair -> pair.second, toList()))));
  209. +
  210. + // Update each package entry
  211. + IconCache iconCache = app.getIconCache();
  212. + for (PackageItemInfo p : packageItemInfoCache.values()) {
  213. + iconCache.getTitleAndIconForApp(p, true /* userLowResIcon */);
  214. + }
  215. + }
  216. public void onPackageIconsUpdated(Set<String> packageNames, UserHandle user,
  217. LauncherAppState app) {
  218. + for (Entry<PackageItemInfo, List<WidgetItem>> entry : mWidgetsList.entrySet()) {
  219. + if (packageNames.contains(entry.getKey().packageName)) {
  220. + List<WidgetItem> items = entry.getValue();
  221. + int count = items.size();
  222. + for (int i = 0; i < count; i++) {
  223. + WidgetItem item = items.get(i);
  224. + if (item.user.equals(user)) {
  225. + if (item.activityInfo != null) {
  226. + items.set(i, new WidgetItem(item.activityInfo, app.getIconCache(),
  227. + app.getContext().getPackageManager()));
  228. + } else {
  229. + items.set(i, new WidgetItem(item.widgetInfo,
  230. + app.getInvariantDeviceProfile(), app.getIconCache(),
  231. + app.getContext()));
  232. + }
  233. + }
  234. + }
  235. + }
  236. + }
  237. }
  238. public WidgetItem getWidgetProviderInfoByProviderName(
  239. ComponentName providerName, UserHandle user) {
  240. + List<WidgetItem> widgetsList = mWidgetsList.get(
  241. + new PackageItemInfo(providerName.getPackageName(), user));
  242. + if (widgetsList == null) {
  243. + return null;
  244. + }
  245. +
  246. + for (WidgetItem item : widgetsList) {
  247. + if (item.componentName.equals(providerName)) {
  248. + return item;
  249. + }
  250. + }
  251. return null;
  252. }
  253. /** Returns {@link PackageItemInfo} of a pending widget. */
  254. - public static PackageItemInfo newPendingItemInfo(
  255. - Context context, ComponentName provider, UserHandle userHandle) {
  256. - return new PackageItemInfo(provider.getPackageName(), userHandle);
  257. + public static PackageItemInfo newPendingItemInfo(Context context, ComponentName provider,
  258. + UserHandle user) {
  259. + Map<ComponentName, IntSet> widgetsToCategories =
  260. + WidgetSections.getWidgetsToCategory(context);
  261. + if (widgetsToCategories.containsKey(provider)) {
  262. + Iterator<Integer> categoriesIterator = widgetsToCategories.get(provider).iterator();
  263. + int firstCategory = NO_CATEGORY;
  264. + while (categoriesIterator.hasNext() && firstCategory == NO_CATEGORY) {
  265. + firstCategory = categoriesIterator.next();
  266. + }
  267. + return new PackageItemInfo(provider.getPackageName(), firstCategory, user);
  268. + }
  269. + return new PackageItemInfo(provider.getPackageName(), user);
  270. + }
  271. +
  272. + private List<PackageUserKey> getPackageUserKeys(Context context, WidgetItem item) {
  273. + Map<ComponentName, IntSet> widgetsToCategories =
  274. + WidgetSections.getWidgetsToCategory(context);
  275. + IntSet categories = widgetsToCategories.get(item.componentName);
  276. + if (categories == null || categories.isEmpty()) {
  277. + return Arrays.asList(
  278. + new PackageUserKey(item.componentName.getPackageName(), item.user));
  279. + }
  280. + List<PackageUserKey> packageUserKeys = new ArrayList<>();
  281. + categories.forEach(category -> {
  282. + if (category == NO_CATEGORY) {
  283. + packageUserKeys.add(
  284. + new PackageUserKey(item.componentName.getPackageName(),
  285. + item.user));
  286. + } else {
  287. + packageUserKeys.add(new PackageUserKey(category, item.user));
  288. + }
  289. + });
  290. + return packageUserKeys;
  291. + }
  292. +
  293. + private static class WidgetValidityCheck implements Predicate<WidgetItem> {
  294. +
  295. + private final InvariantDeviceProfile mIdp;
  296. + private final AppFilter mAppFilter;
  297. +
  298. + WidgetValidityCheck(LauncherAppState app) {
  299. + mIdp = app.getInvariantDeviceProfile();
  300. + mAppFilter = new AppFilter(app.getContext());
  301. + }
  302. +
  303. + @Override
  304. + public boolean test(WidgetItem item) {
  305. + if (item.widgetInfo != null) {
  306. + if ((item.widgetInfo.getWidgetFeatures() & WIDGET_FEATURE_HIDE_FROM_PICKER) != 0) {
  307. + // Widget is hidden from picker
  308. + return false;
  309. + }
  310. +
  311. + // Ensure that all widgets we show can be added on a workspace of this size
  312. + if (!item.widgetInfo.isMinSizeFulfilled()) {
  313. + if (DEBUG) {
  314. + Log.d(TAG, String.format(
  315. + "Widget %s : can't fit on this device with a grid size: %dx%d",
  316. + item.componentName, mIdp.numColumns, mIdp.numRows));
  317. + }
  318. + return false;
  319. + }
  320. + }
  321. + if (!mAppFilter.shouldShowApp(item.componentName)) {
  322. + if (DEBUG) {
  323. + Log.d(TAG, String.format("%s is filtered and not added to the widget tray.",
  324. + item.componentName));
  325. + }
  326. + return false;
  327. + }
  328. +
  329. + return true;
  330. + }
  331. + }
  332. +
  333. + private static final class PackageItemInfoCache {
  334. + private final Map<PackageUserKey, PackageItemInfo> mMap = new ArrayMap<>();
  335. +
  336. + PackageItemInfo getOrCreate(PackageUserKey key) {
  337. + PackageItemInfo pInfo = mMap.get(key);
  338. + if (pInfo == null) {
  339. + pInfo = new PackageItemInfo(key.mPackageName, key.mWidgetCategory, key.mUser);
  340. + pInfo.user = key.mUser;
  341. + mMap.put(key, pInfo);
  342. + }
  343. + return pInfo;
  344. + }
  345. +
  346. + Collection<PackageItemInfo> values() {
  347. + return mMap.values();
  348. + }
  349. }
  350. }
  351. \ No newline at end of file

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/414198
推荐阅读
相关标签
  

闽ICP备14008679号