Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e8e463bd authored by Chandan Nath's avatar Chandan Nath
Browse files

[Multi-user] add PackageInstaller.installExistingPackage with IntentSender which is fired only

after the asynchronous restore is complete

This is a better alternative to the existing synchronous PackageManager.installExistingPackage
method where the restore operation happens asynchronously but the method itself will return
success before the restore finishes.

Bug: 122881085

Test: 1) cts-tradefed run cts -m CtsBackupHostTestCases
-t android.cts.backup.ProfileKeyValueBackupRestoreHostSideTest
2) atest RunBackupFrameworksServicesRoboTests
3) Install Hangouts on work profile. Then install on primary profile, backup and uninstall.
Now install again and immediately hit Open. Before this change, the app will crash after a few
seconds (when the background restore operation finishes). With this change and a corresponding
Play Store change to use this new method, Open shows up only after restore has finished so the
app doesn't crash.

Change-Id: I5d2e1f3bb5509894bedd6bbcfac32ed6cf946a80
parent a54cb88d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -11375,6 +11375,7 @@ package android.content.pm {
    method @NonNull public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getMySessions();
    method @Nullable public android.content.pm.PackageInstaller.SessionInfo getSessionInfo(int);
    method @NonNull public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getStagedSessions();
    method @RequiresPermission(allOf={android.Manifest.permission.INSTALL_PACKAGES, "com.android.permission.INSTALL_EXISTING_PACKAGES"}) public void installExistingPackage(@NonNull String, int, @Nullable android.content.IntentSender);
    method @NonNull public android.content.pm.PackageInstaller.Session openSession(int) throws java.io.IOException;
    method public void registerSessionCallback(@NonNull android.content.pm.PackageInstaller.SessionCallback);
    method public void registerSessionCallback(@NonNull android.content.pm.PackageInstaller.SessionCallback, @NonNull android.os.Handler);
+2 −2
Original line number Diff line number Diff line
@@ -1590,8 +1590,8 @@ package android.content.pm {
    method @android.content.pm.PackageManager.PermissionFlags @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS}) public abstract int getPermissionFlags(String, String, @NonNull android.os.UserHandle);
    method @NonNull @RequiresPermission(android.Manifest.permission.SUSPEND_APPS) public String[] getUnsuspendablePackages(@NonNull String[]);
    method @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public abstract void grantRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
    method public abstract int installExistingPackage(String) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract int installExistingPackage(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method @Deprecated public abstract int installExistingPackage(String) throws android.content.pm.PackageManager.NameNotFoundException;
    method @Deprecated public abstract int installExistingPackage(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceiversAsUser(android.content.Intent, int, android.os.UserHandle);
    method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List<android.content.pm.ResolveInfo> queryIntentActivitiesAsUser(@NonNull android.content.Intent, int, @NonNull android.os.UserHandle);
    method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List<android.content.pm.ResolveInfo> queryIntentContentProvidersAsUser(@NonNull android.content.Intent, int, @NonNull android.os.UserHandle);
+3 −0
Original line number Diff line number Diff line
@@ -50,5 +50,8 @@ interface IPackageInstaller {
    void uninstall(in VersionedPackage versionedPackage, String callerPackageName, int flags,
            in IntentSender statusReceiver, int userId);

    void installExistingPackage(String packageName, int installFlags, int installReason,
            in IntentSender statusReceiver, int userId);

    void setPermissionsResult(int sessionId, boolean accepted);
}
+24 −0
Original line number Diff line number Diff line
@@ -590,6 +590,30 @@ public class PackageInstaller {
        }
    }

    /**
     * Install the given package, which already exists on the device, for the user for which this
     * installer was created.
     *
     * @param packageName The package to install.
     * @param installReason Reason for install.
     * @param statusReceiver Where to deliver the result.
     */
    @RequiresPermission(allOf = {
            Manifest.permission.INSTALL_PACKAGES,
            Manifest.permission.INSTALL_EXISTING_PACKAGES})
    public void installExistingPackage(@NonNull String packageName,
            @InstallReason int installReason,
            @Nullable IntentSender statusReceiver) {
        Preconditions.checkNotNull(packageName, "packageName cannot be null");
        try {
            mInstaller.installExistingPackage(packageName, 0, installReason, statusReceiver,
                    mUserId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }


    /** {@hide} */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES)
+9 −0
Original line number Diff line number Diff line
@@ -5114,7 +5114,10 @@ public abstract class PackageManager {
     * If there is already an application with the given package name installed
     * on the system for other users, also install it for the calling user.
     * @hide
     *
     * @deprecated use {@link PackageInstaller#installExistingPackage()} instead.
     */
    @Deprecated
    @SystemApi
    public abstract int installExistingPackage(String packageName) throws NameNotFoundException;

@@ -5122,7 +5125,10 @@ public abstract class PackageManager {
     * If there is already an application with the given package name installed
     * on the system for other users, also install it for the calling user.
     * @hide
     *
     * @deprecated use {@link PackageInstaller#installExistingPackage()} instead.
     */
    @Deprecated
    @SystemApi
    public abstract int installExistingPackage(String packageName, @InstallReason int installReason)
            throws NameNotFoundException;
@@ -5131,7 +5137,10 @@ public abstract class PackageManager {
     * If there is already an application with the given package name installed
     * on the system for other users, also install it for the specified user.
     * @hide
     *
     * @deprecated use {@link PackageInstaller#installExistingPackage()} instead.
     */
    @Deprecated
    @RequiresPermission(anyOf = {
            Manifest.permission.INSTALL_EXISTING_PACKAGES,
            Manifest.permission.INSTALL_PACKAGES,
Loading