diff options
Diffstat (limited to 'core/java')
8 files changed, 211 insertions, 39 deletions
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..22e9712ebe3b --- /dev/null +++ b/core/java/android/content/pm/LauncherActivityInfoInternal.java @@ -0,0 +1,83 @@ +/* + * 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.compat.annotation.UnsupportedAppUsage; +import android.content.ComponentName; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * @hide + */ +public class LauncherActivityInfoInternal implements Parcelable { + @UnsupportedAppUsage + private ActivityInfo mActivityInfo; + private ComponentName mComponentName; + private IncrementalStatesInfo mIncrementalStatesInfo; + + /** + * @param info ActivityInfo from which to create the LauncherActivityInfo. + * @param incrementalStatesInfo The package's states. + */ + public LauncherActivityInfoInternal(ActivityInfo info, + 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; } |
