diff options
14 files changed, 369 insertions, 80 deletions
diff --git a/api/current.txt b/api/current.txt index 05f1027f3130..07243eb6421b 100644 --- a/api/current.txt +++ b/api/current.txt @@ -11718,7 +11718,10 @@ package android.content.pm { method public android.graphics.drawable.Drawable getIcon(int); method public CharSequence getLabel(); method public String getName(); + method public float getProgress(); method public android.os.UserHandle getUser(); + method public boolean isLoading(); + method public boolean isStartable(); } public class LauncherApps { @@ -11758,6 +11761,7 @@ package android.content.pm { ctor public LauncherApps.Callback(); method public abstract void onPackageAdded(String, android.os.UserHandle); method public abstract void onPackageChanged(String, android.os.UserHandle); + method public void onPackageProgressChanged(@NonNull String, @NonNull android.os.UserHandle, float); method public abstract void onPackageRemoved(String, android.os.UserHandle); method public abstract void onPackagesAvailable(String[], android.os.UserHandle, boolean); method public void onPackagesSuspended(String[], android.os.UserHandle); diff --git a/core/java/android/content/pm/ILauncherApps.aidl b/core/java/android/content/pm/ILauncherApps.aidl index 389458b64fc1..d9ecf46069cd 100644 --- a/core/java/android/content/pm/ILauncherApps.aidl +++ b/core/java/android/content/pm/ILauncherApps.aidl @@ -21,9 +21,9 @@ import android.content.ComponentName; import android.content.Intent; import android.content.IntentSender; import android.content.LocusId; -import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.IOnAppsChangedListener; +import android.content.pm.LauncherActivityInfoInternal; import android.content.pm.LauncherApps; import android.content.pm.ShortcutQueryWrapper; import android.content.pm.IPackageInstallerCallback; @@ -47,7 +47,7 @@ interface ILauncherApps { void removeOnAppsChangedListener(in IOnAppsChangedListener listener); ParceledListSlice getLauncherActivities( String callingPackage, String packageName, in UserHandle user); - ActivityInfo resolveActivity( + LauncherActivityInfoInternal resolveLauncherActivityInternal( String callingPackage, in ComponentName component, in UserHandle user); void startSessionDetailsActivityAsUser(in IApplicationThread caller, String callingPackage, String callingFeatureId, in PackageInstaller.SessionInfo sessionInfo, diff --git a/core/java/android/content/pm/IOnAppsChangedListener.aidl b/core/java/android/content/pm/IOnAppsChangedListener.aidl index fcb1de016078..f24ed80983f8 100644 --- a/core/java/android/content/pm/IOnAppsChangedListener.aidl +++ b/core/java/android/content/pm/IOnAppsChangedListener.aidl @@ -33,4 +33,5 @@ oneway interface IOnAppsChangedListener { in Bundle launcherExtras); void onPackagesUnsuspended(in UserHandle user, in String[] packageNames); void onShortcutChanged(in UserHandle user, String packageName, in ParceledListSlice shortcuts); + void onPackageProgressChanged(in UserHandle user, String packageName, float progress); } diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 30f3325cc11c..c32d34457889 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -31,7 +31,6 @@ import android.content.pm.IPackageInstaller; import android.content.pm.IPackageDeleteObserver; import android.content.pm.IPackageDeleteObserver2; import android.content.pm.IPackageDataObserver; -import android.content.pm.IPackageLoadingProgressCallback; import android.content.pm.IPackageMoveObserver; import android.content.pm.IPackageStatsObserver; import android.content.pm.IntentFilterVerificationInfo; diff --git a/core/java/android/content/pm/LauncherActivityInfo.java b/core/java/android/content/pm/LauncherActivityInfo.java index 67deb82f1fbb..ead80d022542 100644 --- a/core/java/android/content/pm/LauncherActivityInfo.java +++ b/core/java/android/content/pm/LauncherActivityInfo.java @@ -16,7 +16,6 @@ package android.content.pm; -import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager.NameNotFoundException; @@ -35,28 +34,19 @@ public class LauncherActivityInfo { private static final String TAG = "LauncherActivityInfo"; private final PackageManager mPm; - - @UnsupportedAppUsage - private ActivityInfo mActivityInfo; - private ComponentName mComponentName; private UserHandle mUser; + private final LauncherActivityInfoInternal mInternal; /** * Create a launchable activity object for a given ResolveInfo and user. * * @param context The context for fetching resources. - * @param info ResolveInfo from which to create the LauncherActivityInfo. - * @param user The UserHandle of the profile to which this activity belongs. - */ - LauncherActivityInfo(Context context, ActivityInfo info, UserHandle user) { - this(context); - mActivityInfo = info; - mComponentName = new ComponentName(info.packageName, info.name); - mUser = user; - } - LauncherActivityInfo(Context context) { + */ + LauncherActivityInfo(Context context, UserHandle user, LauncherActivityInfoInternal internal) { mPm = context.getPackageManager(); + mUser = user; + mInternal = internal; } /** @@ -65,7 +55,7 @@ public class LauncherActivityInfo { * @return ComponentName of the activity */ public ComponentName getComponentName() { - return mComponentName; + return mInternal.getComponentName(); } /** @@ -90,7 +80,28 @@ public class LauncherActivityInfo { */ public CharSequence getLabel() { // TODO: Go through LauncherAppsService - return mActivityInfo.loadLabel(mPm); + return mInternal.getActivityInfo().loadLabel(mPm); + } + + /** + * @return whether the package is startable. + */ + public boolean isStartable() { + return mInternal.getIncrementalStatesInfo().isStartable(); + } + + /** + * @return whether the package is still loading. + */ + public boolean isLoading() { + return mInternal.getIncrementalStatesInfo().isLoading(); + } + + /** + * @return Package loading progress + */ + public float getProgress() { + return mInternal.getIncrementalStatesInfo().getProgress(); } /** @@ -103,20 +114,20 @@ public class LauncherActivityInfo { */ public Drawable getIcon(int density) { // TODO: Go through LauncherAppsService - final int iconRes = mActivityInfo.getIconResource(); + final int iconRes = mInternal.getActivityInfo().getIconResource(); Drawable icon = null; // Get the preferred density icon from the app's resources if (density != 0 && iconRes != 0) { try { - final Resources resources - = mPm.getResourcesForApplication(mActivityInfo.applicationInfo); + final Resources resources = mPm.getResourcesForApplication( + mInternal.getActivityInfo().applicationInfo); icon = resources.getDrawableForDensity(iconRes, density); } catch (NameNotFoundException | Resources.NotFoundException exc) { } } // Get the default density icon if (icon == null) { - icon = mActivityInfo.loadIcon(mPm); + icon = mInternal.getActivityInfo().loadIcon(mPm); } return icon; } @@ -128,7 +139,7 @@ public class LauncherActivityInfo { * @hide remove before shipping */ public int getApplicationFlags() { - return mActivityInfo.applicationInfo.flags; + return mInternal.getActivityInfo().flags; } /** @@ -136,7 +147,7 @@ public class LauncherActivityInfo { * @return */ public ApplicationInfo getApplicationInfo() { - return mActivityInfo.applicationInfo; + return mInternal.getActivityInfo().applicationInfo; } /** @@ -147,7 +158,7 @@ public class LauncherActivityInfo { public long getFirstInstallTime() { try { // TODO: Go through LauncherAppsService - return mPm.getPackageInfo(mActivityInfo.packageName, + return mPm.getPackageInfo(mInternal.getActivityInfo().packageName, PackageManager.MATCH_UNINSTALLED_PACKAGES).firstInstallTime; } catch (NameNotFoundException nnfe) { // Sorry, can't find package @@ -160,7 +171,7 @@ public class LauncherActivityInfo { * @return the name from android:name for the acitivity. */ public String getName() { - return mActivityInfo.name; + return mInternal.getActivityInfo().name; } /** diff --git a/core/java/android/content/pm/LauncherActivityInfoInternal.aidl b/core/java/android/content/pm/LauncherActivityInfoInternal.aidl new file mode 100644 index 000000000000..5d98d54a27a0 --- /dev/null +++ b/core/java/android/content/pm/LauncherActivityInfoInternal.aidl @@ -0,0 +1,20 @@ +/* +** +** Copyright 2020, 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 android.content.pm; + +parcelable LauncherActivityInfoInternal;
\ No newline at end of file diff --git a/core/java/android/content/pm/LauncherActivityInfoInternal.java b/core/java/android/content/pm/LauncherActivityInfoInternal.java new file mode 100644 index 000000000000..417f168940b6 --- /dev/null +++ b/core/java/android/content/pm/LauncherActivityInfoInternal.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2020 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 android.content.pm; + +import android.annotation.NonNull; +import android.compat.annotation.UnsupportedAppUsage; +import android.content.ComponentName; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * @hide + */ +public class LauncherActivityInfoInternal implements Parcelable { + @UnsupportedAppUsage + @NonNull private ActivityInfo mActivityInfo; + @NonNull private ComponentName mComponentName; + @NonNull private IncrementalStatesInfo mIncrementalStatesInfo; + + /** + * @param info ActivityInfo from which to create the LauncherActivityInfo. + * @param incrementalStatesInfo The package's states. + */ + public LauncherActivityInfoInternal(@NonNull ActivityInfo info, + @NonNull IncrementalStatesInfo incrementalStatesInfo) { + mActivityInfo = info; + mComponentName = new ComponentName(info.packageName, info.name); + mIncrementalStatesInfo = incrementalStatesInfo; + } + + public LauncherActivityInfoInternal(Parcel source) { + mActivityInfo = source.readParcelable(ActivityInfo.class.getClassLoader()); + mComponentName = new ComponentName(mActivityInfo.packageName, mActivityInfo.name); + mIncrementalStatesInfo = source.readParcelable( + IncrementalStatesInfo.class.getClassLoader()); + } + + public ComponentName getComponentName() { + return mComponentName; + } + + public ActivityInfo getActivityInfo() { + return mActivityInfo; + } + + public IncrementalStatesInfo getIncrementalStatesInfo() { + return mIncrementalStatesInfo; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelable(mActivityInfo, 0); + dest.writeParcelable(mIncrementalStatesInfo, 0); + } + + public static final @android.annotation.NonNull Creator<LauncherActivityInfoInternal> CREATOR = + new Creator<LauncherActivityInfoInternal>() { + public LauncherActivityInfoInternal createFromParcel(Parcel source) { + return new LauncherActivityInfoInternal(source); + } + public LauncherActivityInfoInternal[] newArray(int size) { + return new LauncherActivityInfoInternal[size]; + } + }; +} diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java index 1a694b34474a..b7af397cd36a 100644 --- a/core/java/android/content/pm/LauncherApps.java +++ b/core/java/android/content/pm/LauncherApps.java @@ -218,6 +218,7 @@ public class LauncherApps { * Indicates that a package was modified in the specified profile. * This can happen, for example, when the package is updated or when * one or more components are enabled or disabled. + * It can also happen if package state has changed, i.e., package becomes unstartable. * * @param packageName The name of the package that has changed. * @param user The UserHandle of the profile that generated the change. @@ -323,6 +324,16 @@ public class LauncherApps { public void onShortcutsChanged(@NonNull String packageName, @NonNull List<ShortcutInfo> shortcuts, @NonNull UserHandle user) { } + + /** + * Indicates that the loading progress of an installed package has changed. + * + * @param packageName The name of the package that has changed. + * @param user The UserHandle of the profile that generated the change. + * @param progress The new progress value, between [0, 1]. + */ + public void onPackageProgressChanged(@NonNull String packageName, + @NonNull UserHandle user, float progress) {} } /** @@ -715,16 +726,15 @@ public class LauncherApps { public LauncherActivityInfo resolveActivity(Intent intent, UserHandle user) { logErrorForInvalidProfileAccess(user); try { - ActivityInfo ai = mService.resolveActivity(mContext.getPackageName(), - intent.getComponent(), user); - if (ai != null) { - LauncherActivityInfo info = new LauncherActivityInfo(mContext, ai, user); - return info; + LauncherActivityInfoInternal ai = mService.resolveLauncherActivityInternal( + mContext.getPackageName(), intent.getComponent(), user); + if (ai == null) { + return null; } + return new LauncherActivityInfo(mContext, user, ai); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } - return null; } /** @@ -813,13 +823,13 @@ public class LauncherApps { } private List<LauncherActivityInfo> convertToActivityList( - @Nullable ParceledListSlice<ResolveInfo> activities, UserHandle user) { - if (activities == null) { + @Nullable ParceledListSlice<LauncherActivityInfoInternal> internals, UserHandle user) { + if (internals == null || internals.getList().isEmpty()) { return Collections.EMPTY_LIST; } ArrayList<LauncherActivityInfo> lais = new ArrayList<>(); - for (ResolveInfo ri : activities.getList()) { - LauncherActivityInfo lai = new LauncherActivityInfo(mContext, ri.activityInfo, user); + for (LauncherActivityInfoInternal internal : internals.getList()) { + LauncherActivityInfo lai = new LauncherActivityInfo(mContext, user, internal); if (DEBUG) { Log.v(TAG, "Returning activity for profile " + user + " : " + lai.getComponentName()); @@ -1667,6 +1677,19 @@ public class LauncherApps { } } } + + public void onPackageProgressChanged(UserHandle user, String packageName, + float progress) { + if (DEBUG) { + Log.d(TAG, "onPackageProgressChanged " + user.getIdentifier() + "," + + packageName + "," + progress); + } + synchronized (LauncherApps.this) { + for (CallbackMessageHandler callback : mCallbacks) { + callback.postOnPackageProgressChanged(user, packageName, progress); + } + } + } }; private static class CallbackMessageHandler extends Handler { @@ -1678,6 +1701,7 @@ public class LauncherApps { private static final int MSG_SUSPENDED = 6; private static final int MSG_UNSUSPENDED = 7; private static final int MSG_SHORTCUT_CHANGED = 8; + private static final int MSG_LOADING_PROGRESS_CHANGED = 9; private LauncherApps.Callback mCallback; @@ -1688,6 +1712,7 @@ public class LauncherApps { boolean replacing; UserHandle user; List<ShortcutInfo> shortcuts; + float mLoadingProgress; } public CallbackMessageHandler(Looper looper, LauncherApps.Callback callback) { @@ -1727,6 +1752,10 @@ public class LauncherApps { case MSG_SHORTCUT_CHANGED: mCallback.onShortcutsChanged(info.packageName, info.shortcuts, info.user); break; + case MSG_LOADING_PROGRESS_CHANGED: + mCallback.onPackageProgressChanged(info.packageName, info.user, + info.mLoadingProgress); + break; } } @@ -1793,6 +1822,15 @@ public class LauncherApps { info.shortcuts = shortcuts; obtainMessage(MSG_SHORTCUT_CHANGED, info).sendToTarget(); } + + public void postOnPackageProgressChanged(UserHandle user, String packageName, + float progress) { + CallbackInfo info = new CallbackInfo(); + info.packageName = packageName; + info.user = user; + info.mLoadingProgress = progress; + obtainMessage(MSG_LOADING_PROGRESS_CHANGED, info).sendToTarget(); + } } /** diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java index 3682b7bcd891..af666d87d6f1 100644 --- a/core/java/com/android/internal/content/PackageMonitor.java +++ b/core/java/com/android/internal/content/PackageMonitor.java @@ -37,6 +37,7 @@ import java.util.Objects; * updating, and disappearing and reappearing on the SD card. */ public abstract class PackageMonitor extends android.content.BroadcastReceiver { + static final String TAG = "PackageMonitor"; static final IntentFilter sPackageFilt = new IntentFilter(); static final IntentFilter sNonDataFilt = new IntentFilter(); static final IntentFilter sExternalFilt = new IntentFilter(); @@ -48,6 +49,9 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver { sPackageFilt.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); sPackageFilt.addAction(Intent.ACTION_PACKAGE_RESTARTED); sPackageFilt.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED); + sPackageFilt.addAction(Intent.ACTION_PACKAGE_STARTABLE); + sPackageFilt.addAction(Intent.ACTION_PACKAGE_UNSTARTABLE); + sPackageFilt.addAction(Intent.ACTION_PACKAGE_FULLY_LOADED); sPackageFilt.addDataScheme("package"); sNonDataFilt.addAction(Intent.ACTION_UID_REMOVED); sNonDataFilt.addAction(Intent.ACTION_USER_STOPPED); @@ -305,6 +309,13 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver { public void onPackageDataCleared(String packageName, int uid) { } + /** + * Callback to indicate the package's state has changed. + * @param packageName Name of an installed package + * @param uid The UID the package runs under. + */ + public void onPackageStateChanged(String packageName, int uid) {} + public int getChangingUserId() { return mChangeUserId; } @@ -452,12 +463,21 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver { String[] pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); mSomePackagesChanged = true; onPackagesUnsuspended(pkgList); + } else if (Intent.ACTION_PACKAGE_STARTABLE.equals(action) + || Intent.ACTION_PACKAGE_UNSTARTABLE.equals(action) + || Intent.ACTION_PACKAGE_FULLY_LOADED.equals(action)) { + String pkg = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME); + int uid = intent.getIntExtra(Intent.EXTRA_UID, 0); + mSomePackagesChanged = false; + if (pkg != null) { + onPackageStateChanged(pkg, uid); + } } if (mSomePackagesChanged) { onSomePackagesChanged(); } - + onFinishPackageChanges(); mChangeUserId = UserHandle.USER_NULL; } diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt index addb25d717e5..ccaa1c5113b2 100644 --- a/non-updatable-api/current.txt +++ b/non-updatable-api/current.txt @@ -11718,7 +11718,10 @@ package android.content.pm { method public android.graphics.drawable.Drawable getIcon(int); method public CharSequence getLabel(); method public String getName(); + method public float getProgress(); method public android.os.UserHandle getUser(); + method public boolean isLoading(); + method public boolean isStartable(); } public class LauncherApps { @@ -11758,6 +11761,7 @@ package android.content.pm { ctor public LauncherApps.Callback(); method public abstract void onPackageAdded(String, android.os.UserHandle); method public abstract void onPackageChanged(String, android.os.UserHandle); + method public void onPackageProgressChanged(@NonNull String, @NonNull android.os.UserHandle, float); method public abstract void onPackageRemoved(String, android.os.UserHandle); method public abstract void onPackagesAvailable(String[], android.os.UserHandle, boolean); method public void onPackagesSuspended(String[], android.os.UserHandle); diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java index 43c54b4a97b3..72a21522b545 100644 --- a/services/core/java/android/content/pm/PackageManagerInternal.java +++ b/services/core/java/android/content/pm/PackageManagerInternal.java @@ -1106,4 +1106,17 @@ public abstract class PackageManagerInternal { } } + /** + * Retrieve all of the information we know about a particular activity class including its + * package states. + * + * @param packageName a specific package + * @param filterCallingUid The results will be filtered in the context of this UID instead + * of the calling UID. + * @param userId The user for whom the package is installed + * @return IncrementalStatesInfo that contains information about package states. + */ + public abstract IncrementalStatesInfo getIncrementalStatesInfo(String packageName, + int filterCallingUid, int userId); + } diff --git a/services/core/java/com/android/server/pm/IncrementalStates.java b/services/core/java/com/android/server/pm/IncrementalStates.java index 43f4a3477a98..26ace47776be 100644 --- a/services/core/java/com/android/server/pm/IncrementalStates.java +++ b/services/core/java/com/android/server/pm/IncrementalStates.java @@ -105,8 +105,8 @@ public final class IncrementalStates { if (!mStartableState.isStartable()) { mStartableState.adoptNewStartableStateLocked(true); } - if (mLoadingState.isLoading() != isIncremental) { - mLoadingState.adoptNewLoadingStateLocked(isIncremental); + if (!isIncremental) { + updateProgressLocked(1); } } mHandler.post(PooledLambda.obtainRunnable( diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java index 9bb6f7892972..8eebf2a8d9d9 100644 --- a/services/core/java/com/android/server/pm/LauncherAppsService.java +++ b/services/core/java/com/android/server/pm/LauncherAppsService.java @@ -44,6 +44,8 @@ import android.content.pm.IOnAppsChangedListener; import android.content.pm.IPackageInstallerCallback; import android.content.pm.IPackageManager; import android.content.pm.IShortcutChangeCallback; +import android.content.pm.IncrementalStatesInfo; +import android.content.pm.LauncherActivityInfoInternal; import android.content.pm.LauncherApps; import android.content.pm.LauncherApps.ShortcutQuery; import android.content.pm.PackageInfo; @@ -369,18 +371,13 @@ public class LauncherAppsService extends SystemService { } } - private ResolveInfo getHiddenAppActivityInfo(String packageName, int callingUid, - UserHandle user) { + private LauncherActivityInfoInternal getHiddenAppActivityInfo(String packageName, + int callingUid, UserHandle user) { Intent intent = new Intent(); intent.setComponent(new ComponentName(packageName, PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME)); - final PackageManagerInternal pmInt = - LocalServices.getService(PackageManagerInternal.class); - List<ResolveInfo> apps = pmInt.queryIntentActivities(intent, - intent.resolveTypeIfNeeded(mContext.getContentResolver()), - PackageManager.MATCH_DIRECT_BOOT_AWARE - | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, - callingUid, user.getIdentifier()); + final List<LauncherActivityInfoInternal> apps = queryIntentLauncherActivities(intent, + callingUid, user); if (apps.size() > 0) { return apps.get(0); } @@ -399,14 +396,14 @@ public class LauncherAppsService extends SystemService { } @Override - public ParceledListSlice<ResolveInfo> getLauncherActivities(String callingPackage, - String packageName, UserHandle user) throws RemoteException { - ParceledListSlice<ResolveInfo> launcherActivities = queryActivitiesForUser( - callingPackage, - new Intent(Intent.ACTION_MAIN) - .addCategory(Intent.CATEGORY_LAUNCHER) - .setPackage(packageName), - user); + public ParceledListSlice<LauncherActivityInfoInternal> getLauncherActivities( + String callingPackage, String packageName, UserHandle user) throws RemoteException { + ParceledListSlice<LauncherActivityInfoInternal> launcherActivities = + queryActivitiesForUser(callingPackage, + new Intent(Intent.ACTION_MAIN) + .addCategory(Intent.CATEGORY_LAUNCHER) + .setPackage(packageName), + user); if (Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.SHOW_HIDDEN_LAUNCHER_ICON_APPS_ENABLED, 1) == 0) { return launcherActivities; @@ -428,7 +425,8 @@ public class LauncherAppsService extends SystemService { return launcherActivities; } - final ArrayList<ResolveInfo> result = new ArrayList<>(launcherActivities.getList()); + final ArrayList<LauncherActivityInfoInternal> result = new ArrayList<>( + launcherActivities.getList()); final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class); if (packageName != null) { @@ -440,7 +438,8 @@ public class LauncherAppsService extends SystemService { ApplicationInfo appInfo = pmInt.getApplicationInfo(packageName, /*flags*/ 0, callingUid, user.getIdentifier()); if (shouldShowSyntheticActivity(user, appInfo)) { - ResolveInfo info = getHiddenAppActivityInfo(packageName, callingUid, user); + LauncherActivityInfoInternal info = getHiddenAppActivityInfo(packageName, + callingUid, user); if (info != null) { result.add(info); } @@ -448,8 +447,8 @@ public class LauncherAppsService extends SystemService { return new ParceledListSlice<>(result); } final HashSet<String> visiblePackages = new HashSet<>(); - for (ResolveInfo info : result) { - visiblePackages.add(info.activityInfo.packageName); + for (LauncherActivityInfoInternal info : result) { + visiblePackages.add(info.getActivityInfo().packageName); } List<ApplicationInfo> installedPackages = pmInt.getInstalledApplications(0, user.getIdentifier(), callingUid); @@ -458,8 +457,8 @@ public class LauncherAppsService extends SystemService { if (!shouldShowSyntheticActivity(user, applicationInfo)) { continue; } - ResolveInfo info = getHiddenAppActivityInfo(applicationInfo.packageName, - callingUid, user); + LauncherActivityInfoInternal info = getHiddenAppActivityInfo( + applicationInfo.packageName, callingUid, user); if (info != null) { result.add(info); } @@ -533,7 +532,7 @@ public class LauncherAppsService extends SystemService { } @Override - public ActivityInfo resolveActivity( + public LauncherActivityInfoInternal resolveLauncherActivityInternal( String callingPackage, ComponentName component, UserHandle user) throws RemoteException { if (!canAccessProfile(user.getIdentifier(), "Cannot resolve activity")) { @@ -545,10 +544,24 @@ public class LauncherAppsService extends SystemService { try { final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class); - return pmInt.getActivityInfo(component, + final ActivityInfo activityInfo = pmInt.getActivityInfo(component, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, callingUid, user.getIdentifier()); + if (activityInfo == null) { + return null; + } + if (component == null || component.getPackageName() == null) { + // should not happen + return null; + } + final IncrementalStatesInfo incrementalStatesInfo = pmInt.getIncrementalStatesInfo( + component.getPackageName(), callingUid, user.getIdentifier()); + if (incrementalStatesInfo == null) { + // package does not exist; should not happen + return null; + } + return new LauncherActivityInfoInternal(activityInfo, incrementalStatesInfo); } finally { Binder.restoreCallingIdentity(ident); } @@ -562,28 +575,51 @@ public class LauncherAppsService extends SystemService { new Intent(Intent.ACTION_CREATE_SHORTCUT).setPackage(packageName), user); } - private ParceledListSlice<ResolveInfo> queryActivitiesForUser(String callingPackage, - Intent intent, UserHandle user) { + private ParceledListSlice<LauncherActivityInfoInternal> queryActivitiesForUser( + String callingPackage, Intent intent, UserHandle user) { if (!canAccessProfile(user.getIdentifier(), "Cannot retrieve activities")) { return null; } - final int callingUid = injectBinderCallingUid(); long ident = injectClearCallingIdentity(); try { - final PackageManagerInternal pmInt = - LocalServices.getService(PackageManagerInternal.class); - List<ResolveInfo> apps = pmInt.queryIntentActivities(intent, - intent.resolveTypeIfNeeded(mContext.getContentResolver()), - PackageManager.MATCH_DIRECT_BOOT_AWARE - | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, - callingUid, user.getIdentifier()); - return new ParceledListSlice<>(apps); + return new ParceledListSlice<>(queryIntentLauncherActivities(intent, callingUid, + user)); } finally { injectRestoreCallingIdentity(ident); } } + private List<LauncherActivityInfoInternal> queryIntentLauncherActivities( + Intent intent, int callingUid, UserHandle user) { + final PackageManagerInternal pmInt = + LocalServices.getService(PackageManagerInternal.class); + List<ResolveInfo> apps = pmInt.queryIntentActivities(intent, + intent.resolveTypeIfNeeded(mContext.getContentResolver()), + PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, + callingUid, user.getIdentifier()); + final int numResolveInfos = apps.size(); + List<LauncherActivityInfoInternal> results = new ArrayList<>(); + for (int i = 0; i < numResolveInfos; i++) { + final ResolveInfo ri = apps.get(i); + final String packageName = ri.activityInfo.packageName; + if (packageName == null) { + // should not happen + continue; + } + final IncrementalStatesInfo incrementalStatesInfo = pmInt.getIncrementalStatesInfo( + packageName, callingUid, user.getIdentifier()); + if (incrementalStatesInfo == null) { + // package doesn't exist any more; should not happen + continue; + } + results.add(new LauncherActivityInfoInternal(ri.activityInfo, + incrementalStatesInfo)); + } + return results; + } + @Override public IntentSender getShortcutConfigActivityIntent(String callingPackage, ComponentName component, UserHandle user) throws RemoteException { @@ -1238,7 +1274,10 @@ public class LauncherAppsService extends SystemService { } finally { mListeners.finishBroadcast(); } - + PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class); + pmi.registerInstalledLoadingProgressCallback(packageName, + new PackageLoadingProgressCallback(packageName, user), + user.getIdentifier()); super.onPackageAdded(packageName, uid); } @@ -1266,6 +1305,11 @@ public class LauncherAppsService extends SystemService { @Override public void onPackageModified(String packageName) { + onPackageChanged(packageName); + super.onPackageModified(packageName); + } + + private void onPackageChanged(String packageName) { UserHandle user = new UserHandle(getChangingUserId()); final int n = mListeners.beginBroadcast(); try { @@ -1282,8 +1326,6 @@ public class LauncherAppsService extends SystemService { } finally { mListeners.finishBroadcast(); } - - super.onPackageModified(packageName); } @Override @@ -1435,6 +1477,7 @@ public class LauncherAppsService extends SystemService { } catch (RemoteException re) { Slog.d(TAG, "Callback failed ", re); } + } } catch (RuntimeException e) { // When the user is locked we get IllegalState, so just catch all. @@ -1443,6 +1486,12 @@ public class LauncherAppsService extends SystemService { mListeners.finishBroadcast(); } } + + @Override + public void onPackageStateChanged(String packageName, int uid) { + onPackageChanged(packageName); + super.onPackageStateChanged(packageName, uid); + } } class PackageCallbackList<T extends IInterface> extends RemoteCallbackList<T> { @@ -1451,5 +1500,38 @@ public class LauncherAppsService extends SystemService { checkCallbackCount(); } } + + class PackageLoadingProgressCallback extends + PackageManagerInternal.InstalledLoadingProgressCallback { + private String mPackageName; + private UserHandle mUser; + + PackageLoadingProgressCallback(String packageName, UserHandle user) { + super(mCallbackHandler); + mPackageName = packageName; + mUser = user; + } + + @Override + public void onLoadingProgressChanged(float progress) { + final int n = mListeners.beginBroadcast(); + try { + for (int i = 0; i < n; i++) { + IOnAppsChangedListener listener = mListeners.getBroadcastItem(i); + BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i); + if (!isEnabledProfileOf(cookie.user, mUser, "onLoadingProgressChanged")) { + continue; + } + try { + listener.onPackageProgressChanged(mUser, mPackageName, progress); + } catch (RemoteException re) { + Slog.d(TAG, "Callback failed ", re); + } + } + } finally { + mListeners.finishBroadcast(); + } + } + } } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 3f16abfa04b7..9aee3c986356 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -180,6 +180,7 @@ import android.content.pm.IPackageManager; import android.content.pm.IPackageManagerNative; import android.content.pm.IPackageMoveObserver; import android.content.pm.IPackageStatsObserver; +import android.content.pm.IncrementalStatesInfo; import android.content.pm.InstallSourceInfo; import android.content.pm.InstantAppInfo; import android.content.pm.InstantAppRequest; @@ -25749,8 +25750,20 @@ public class PackageManagerService extends IPackageManager.Stub return mIncrementalManager.unregisterLoadingProgressCallback(ps.getPathString(), (IPackageLoadingProgressCallback) callback.getBinder()); } + + @Override + public IncrementalStatesInfo getIncrementalStatesInfo( + @NonNull String packageName, int filterCallingUid, int userId) { + final PackageSetting ps = getPackageSettingForUser(packageName, filterCallingUid, + userId); + if (ps == null) { + return null; + } + return ps.getIncrementalStates(); + } } + @GuardedBy("mLock") private SparseArray<String> getAppsWithSharedUserIdsLocked() { final SparseArray<String> sharedUserIds = new SparseArray<>(); |