From f5523921c3aeebe723a7bae96d93abaefde291a4 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Mon, 28 Aug 2017 15:29:18 -0700 Subject: Adding support for badging instant app icons. Change-Id: Idc43a1a83e0a93f70879730a0acefbc124f9c0e2 --- res/drawable/ic_instant_app_badge.xml | 43 +++++++++++++++++++++ res/values/config.xml | 3 ++ src/com/android/launcher3/IconCache.java | 17 ++++---- .../launcher3/model/CacheDataUpdatedTask.java | 2 +- .../model/PackageInstallStateChangedTask.java | 15 ++++++++ .../launcher3/model/PackageUpdatedTask.java | 26 ++++++------- .../android/launcher3/util/InstantAppResolver.java | 45 ++++++++++++++++++++++ 7 files changed, 130 insertions(+), 21 deletions(-) create mode 100644 res/drawable/ic_instant_app_badge.xml create mode 100644 src/com/android/launcher3/util/InstantAppResolver.java diff --git a/res/drawable/ic_instant_app_badge.xml b/res/drawable/ic_instant_app_badge.xml new file mode 100644 index 000000000..cc532309c --- /dev/null +++ b/res/drawable/ic_instant_app_badge.xml @@ -0,0 +1,43 @@ + + + + + + + + + \ No newline at end of file diff --git a/res/values/config.xml b/res/values/config.xml index b41172bb1..01772f186 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -116,6 +116,9 @@ + + + diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java index ecadb18ef..6f86954dc 100644 --- a/src/com/android/launcher3/IconCache.java +++ b/src/com/android/launcher3/IconCache.java @@ -47,6 +47,7 @@ import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.graphics.LauncherIcons; import com.android.launcher3.model.PackageItemInfo; import com.android.launcher3.util.ComponentKey; +import com.android.launcher3.util.InstantAppResolver; import com.android.launcher3.util.Preconditions; import com.android.launcher3.util.Provider; import com.android.launcher3.util.SQLiteCacheHelper; @@ -94,6 +95,7 @@ public class IconCache { private final LauncherAppsCompat mLauncherApps; private final HashMap mCache = new HashMap<>(INITIAL_ICON_CACHE_CAPACITY); + private final InstantAppResolver mInstantAppResolver; private final int mIconDpi; @Thunk final IconDB mIconDb; @@ -106,6 +108,7 @@ public class IconCache { mPackageManager = context.getPackageManager(); mUserManager = UserManagerCompat.getInstance(mContext); mLauncherApps = LauncherAppsCompat.getInstance(mContext); + mInstantAppResolver = InstantAppResolver.newInstance(mContext); mIconDpi = inv.fillResIconDpi; mIconDb = new IconDB(context, inv.iconBitmapSize); @@ -478,12 +481,6 @@ public class IconCache { } private void applyCacheEntry(CacheEntry entry, ItemInfoWithIcon info) { - if (info instanceof ShortcutInfo - && ((ShortcutInfo) info).hasStatusFlag(ShortcutInfo.FLAG_SUPPORTS_WEB_UI) - && (entry.icon == null || isDefaultIcon(entry.icon, info.user))) { - // skip updating shortcut info if no icon and supports web ui - return; - } info.title = Utilities.trim(entry.title); info.contentDescription = entry.contentDescription; info.iconBitmap = entry.icon == null ? getDefaultIcon(info.user) : entry.icon; @@ -581,7 +578,6 @@ public class IconCache { // For icon caching, do not go through DB. Just update the in-memory entry. if (entry == null) { entry = new CacheEntry(); - mCache.put(cacheKey, entry); } if (!TextUtils.isEmpty(title)) { entry.title = title; @@ -589,6 +585,9 @@ public class IconCache { if (icon != null) { entry.icon = LauncherIcons.createIconBitmap(icon, mContext); } + if (!TextUtils.isEmpty(title) && entry.icon != null) { + mCache.put(cacheKey, entry); + } } private static ComponentKey getPackageKey(String packageName, UserHandle user) { @@ -625,6 +624,10 @@ public class IconCache { // only keep the low resolution icon instead of the larger full-sized icon Bitmap icon = LauncherIcons.createBadgedIconBitmap( appInfo.loadIcon(mPackageManager), user, mContext, appInfo.targetSdkVersion); + if (mInstantAppResolver.isInstantApp(appInfo)) { + icon = LauncherIcons.badgeWithDrawable(icon, + mContext.getDrawable(R.drawable.ic_instant_app_badge), mContext); + } Bitmap lowResIcon = generateLowResIcon(icon); entry.title = appInfo.loadLabel(mPackageManager); entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user); diff --git a/src/com/android/launcher3/model/CacheDataUpdatedTask.java b/src/com/android/launcher3/model/CacheDataUpdatedTask.java index 7a27741c3..0139bd902 100644 --- a/src/com/android/launcher3/model/CacheDataUpdatedTask.java +++ b/src/com/android/launcher3/model/CacheDataUpdatedTask.java @@ -88,7 +88,7 @@ public class CacheDataUpdatedTask extends BaseModelUpdateTask { case OP_CACHE_UPDATE: return true; case OP_SESSION_UPDATE: - return si.isPromise(); + return si.hasPromiseIconUi(); default: return false; } diff --git a/src/com/android/launcher3/model/PackageInstallStateChangedTask.java b/src/com/android/launcher3/model/PackageInstallStateChangedTask.java index ebc6f2379..32dfe2537 100644 --- a/src/com/android/launcher3/model/PackageInstallStateChangedTask.java +++ b/src/com/android/launcher3/model/PackageInstallStateChangedTask.java @@ -16,6 +16,9 @@ package com.android.launcher3.model; import android.content.ComponentName; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.os.Process; import com.android.launcher3.AllAppsList; import com.android.launcher3.AppInfo; @@ -28,6 +31,7 @@ import com.android.launcher3.PromiseAppInfo; import com.android.launcher3.ShortcutInfo; import com.android.launcher3.compat.PackageInstallerCompat; import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo; +import com.android.launcher3.util.InstantAppResolver; import java.util.ArrayList; import java.util.HashSet; @@ -46,6 +50,17 @@ public class PackageInstallStateChangedTask extends BaseModelUpdateTask { @Override public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) { if (mInstallInfo.state == PackageInstallerCompat.STATUS_INSTALLED) { + try { + // For instant apps we do not get package-add. Use setting events to update + // any pinned icons. + ApplicationInfo ai = app.getContext() + .getPackageManager().getApplicationInfo(mInstallInfo.packageName, 0); + if (InstantAppResolver.newInstance(app.getContext()).isInstantApp(ai)) { + app.getModel().onPackageAdded(ai.packageName, Process.myUserHandle()); + } + } catch (PackageManager.NameNotFoundException e) { + // Ignore + } // Ignore install success events as they are handled by Package add events. return; } diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java index 98bffe1fb..13962a259 100644 --- a/src/com/android/launcher3/model/PackageUpdatedTask.java +++ b/src/com/android/launcher3/model/PackageUpdatedTask.java @@ -23,6 +23,7 @@ import android.os.Process; import android.os.UserHandle; import android.util.ArrayMap; import android.util.Log; + import com.android.launcher3.AllAppsList; import com.android.launcher3.AppInfo; import com.android.launcher3.IconCache; @@ -32,7 +33,6 @@ import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.LauncherModel.CallbackTask; import com.android.launcher3.LauncherModel.Callbacks; -import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.SessionCommitReceiver; import com.android.launcher3.ShortcutInfo; @@ -46,6 +46,7 @@ import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.LongArrayMap; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.PackageUserKey; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -198,10 +199,11 @@ public class PackageUpdatedTask extends BaseModelUpdateTask { if (cn != null && matcher.matches(si, cn)) { AppInfo appInfo = addedOrUpdatedApps.get(cn); - if (mOp == OP_REMOVE - && si.hasStatusFlag(ShortcutInfo.FLAG_SUPPORTS_WEB_UI)) { + if (si.hasStatusFlag(ShortcutInfo.FLAG_SUPPORTS_WEB_UI)) { removedShortcuts.put(si.id, false); - continue; + if (mOp == OP_REMOVE) { + continue; + } } // For system apps, package manager send OP_UPDATE when an @@ -220,22 +222,20 @@ public class PackageUpdatedTask extends BaseModelUpdateTask { appInfo = addedOrUpdatedApps.get(cn); } - if ((intent == null) || (appInfo == null)) { + if (intent != null && appInfo != null) { + si.intent = intent; + si.status = ShortcutInfo.DEFAULT; + infoUpdated = true; + } else if (si.hasPromiseIconUi()) { removedShortcuts.put(si.id, true); continue; } - si.intent = intent; } } - si.status = ShortcutInfo.DEFAULT; - infoUpdated = true; - if (si.itemType == Favorites.ITEM_TYPE_APPLICATION) { - iconCache.getTitleAndIcon(si, si.usingLowResIcon); - } } - if (appInfo != null && Intent.ACTION_MAIN.equals(si.intent.getAction()) - && si.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { + if ((mOp == OP_ADD || mOp == OP_UPDATE) && + si.itemType == Favorites.ITEM_TYPE_APPLICATION) { iconCache.getTitleAndIcon(si, si.usingLowResIcon); infoUpdated = true; } diff --git a/src/com/android/launcher3/util/InstantAppResolver.java b/src/com/android/launcher3/util/InstantAppResolver.java new file mode 100644 index 000000000..e60d76808 --- /dev/null +++ b/src/com/android/launcher3/util/InstantAppResolver.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2015 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.util; + +import android.content.Context; +import android.content.pm.ApplicationInfo; + +import com.android.launcher3.R; +import com.android.launcher3.Utilities; + +import java.util.Collections; +import java.util.List; + +/** + * A wrapper class to access instant app related APIs. + */ +public class InstantAppResolver { + + public static InstantAppResolver newInstance(Context context) { + return Utilities.getOverrideObject( + InstantAppResolver.class, context, R.string.instant_app_resolver_class); + } + + public boolean isInstantApp(ApplicationInfo info) { + return false; + } + + public List getInstantApps() { + return Collections.emptyList(); + } +} -- cgit v1.2.3