summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt4
-rw-r--r--core/java/android/content/pm/IPackageInstallerSession.aidl2
-rw-r--r--core/java/android/content/pm/PackageInstaller.java113
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java131
4 files changed, 28 insertions, 222 deletions
diff --git a/api/current.txt b/api/current.txt
index 6787e6014741..e0c2621ac468 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11700,11 +11700,8 @@ package android.content.pm {
field public static final int STATUS_FAILURE_ABORTED = 3; // 0x3
field public static final int STATUS_FAILURE_BLOCKED = 2; // 0x2
field public static final int STATUS_FAILURE_CONFLICT = 5; // 0x5
- field public static final int STATUS_FAILURE_ILLEGAL_STATE = 9; // 0x9
field public static final int STATUS_FAILURE_INCOMPATIBLE = 7; // 0x7
field public static final int STATUS_FAILURE_INVALID = 4; // 0x4
- field public static final int STATUS_FAILURE_NAME_NOT_FOUND = 8; // 0x8
- field public static final int STATUS_FAILURE_SECURITY = 10; // 0xa
field public static final int STATUS_FAILURE_STORAGE = 6; // 0x6
field public static final int STATUS_PENDING_USER_ACTION = -1; // 0xffffffff
field public static final int STATUS_SUCCESS = 0; // 0x0
@@ -11726,7 +11723,6 @@ package android.content.pm {
method public void removeChildSessionId(int);
method public void removeSplit(@NonNull String) throws java.io.IOException;
method public void setStagingProgress(float);
- method public void transfer(@NonNull String, @NonNull android.content.IntentSender) throws android.content.pm.PackageManager.NameNotFoundException;
method public void transfer(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
}
diff --git a/core/java/android/content/pm/IPackageInstallerSession.aidl b/core/java/android/content/pm/IPackageInstallerSession.aidl
index e9546353d5f3..e86bb250c033 100644
--- a/core/java/android/content/pm/IPackageInstallerSession.aidl
+++ b/core/java/android/content/pm/IPackageInstallerSession.aidl
@@ -36,7 +36,7 @@ interface IPackageInstallerSession {
void close();
void commit(in IntentSender statusReceiver, boolean forTransferred);
- void transfer(in String packageName, in IntentSender statusReceiver);
+ void transfer(in String packageName);
void abandon();
void addFile(String name, long lengthBytes, in byte[] metadata);
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 7a280221eb08..3c6f602e93e1 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -29,8 +29,6 @@ import android.annotation.TestApi;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.compat.annotation.UnsupportedAppUsage;
-import android.content.IIntentReceiver;
-import android.content.IIntentSender;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager.DeleteFlags;
@@ -38,11 +36,9 @@ import android.content.pm.PackageManager.InstallReason;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
-import android.os.Bundle;
import android.os.FileBridge;
import android.os.Handler;
import android.os.HandlerExecutor;
-import android.os.IBinder;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
@@ -71,8 +67,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;
@@ -182,9 +176,8 @@ public class PackageInstaller {
* {@link #STATUS_PENDING_USER_ACTION}, {@link #STATUS_SUCCESS},
* {@link #STATUS_FAILURE}, {@link #STATUS_FAILURE_ABORTED},
* {@link #STATUS_FAILURE_BLOCKED}, {@link #STATUS_FAILURE_CONFLICT},
- * {@link #STATUS_FAILURE_INCOMPATIBLE}, {@link #STATUS_FAILURE_INVALID},
- * {@link #STATUS_FAILURE_STORAGE}, {@link #STATUS_FAILURE_NAME_NOT_FOUND},
- * {@link #STATUS_FAILURE_ILLEGAL_STATE} or {@link #STATUS_FAILURE_SECURITY}.
+ * {@link #STATUS_FAILURE_INCOMPATIBLE}, {@link #STATUS_FAILURE_INVALID}, or
+ * {@link #STATUS_FAILURE_STORAGE}.
* <p>
* More information about a status may be available through additional
* extras; see the individual status documentation for details.
@@ -332,34 +325,6 @@ public class PackageInstaller {
*/
public static final int STATUS_FAILURE_INCOMPATIBLE = 7;
- /**
- * The transfer failed because a target package can't be found. For example
- * transferring a session to a non-existing package.
- * <p>
- * The result may also contain {@link #EXTRA_OTHER_PACKAGE_NAME} with the
- * missing package.
- *
- * @see #EXTRA_STATUS_MESSAGE
- * @see #EXTRA_OTHER_PACKAGE_NAME
- */
- public static final int STATUS_FAILURE_NAME_NOT_FOUND = 8;
-
- /**
- * The transfer failed because a session is in invalid state. For example
- * transferring an already committed session.
- *
- * @see #EXTRA_STATUS_MESSAGE
- */
- public static final int STATUS_FAILURE_ILLEGAL_STATE = 9;
-
- /**
- * The transfer failed for security reasons. For example transferring
- * to a package which does not have INSTALL_PACKAGES permission.
- *
- * @see #EXTRA_STATUS_MESSAGE
- */
- public static final int STATUS_FAILURE_SECURITY = 10;
-
private final IPackageInstaller mInstaller;
private final int mUserId;
private final String mInstallerPackageName;
@@ -1143,8 +1108,7 @@ public class PackageInstaller {
}
/**
- * Attempt to commit a session that has been {@link #transfer(String, IntentSender)
- * transferred}.
+ * Attempt to commit a session that has been {@link #transfer(String) transferred}.
*
* <p>If the device reboots before the session has been finalized, you may commit the
* session again.
@@ -1185,14 +1149,6 @@ public class PackageInstaller {
*
* @param packageName The package of the new owner. Needs to hold the INSTALL_PACKAGES
* permission.
- * @param statusReceiver Called when the state of the session changes. Intents sent to
- * this receiver contain {@link #EXTRA_STATUS}. Possible statuses:
- * {@link #STATUS_FAILURE_NAME_NOT_FOUND},
- * {@link #STATUS_FAILURE_ILLEGAL_STATE},
- * {@link #STATUS_FAILURE_SECURITY},
- * {@link #STATUS_FAILURE}.
- * Refer to the individual transfer status codes on how to handle
- * them.
*
* @throws PackageManager.NameNotFoundException if the new owner could not be found.
* @throws SecurityException if called after the session has been committed or abandoned.
@@ -1200,13 +1156,12 @@ public class PackageInstaller {
* @throws SecurityException if streams opened through
* {@link #openWrite(String, long, long) are still open.
*/
- public void transfer(@NonNull String packageName, @NonNull IntentSender statusReceiver)
+ public void transfer(@NonNull String packageName)
throws PackageManager.NameNotFoundException {
- Objects.requireNonNull(statusReceiver);
Objects.requireNonNull(packageName);
try {
- mSession.transfer(packageName, statusReceiver);
+ mSession.transfer(packageName);
} catch (ParcelableException e) {
e.maybeRethrow(PackageManager.NameNotFoundException.class);
throw new RuntimeException(e);
@@ -1216,64 +1171,6 @@ public class PackageInstaller {
}
/**
- * Transfer the session to a new owner.
- * This is a convenience blocking wrapper around {@link #transfer(String, IntentSender)}.
- * Converts all statuses into exceptions.
- *
- * @param packageName The package of the new owner. Needs to hold the INSTALL_PACKAGES
- * permission.
- *
- * @throws PackageManager.NameNotFoundException if the new owner could not be found.
- * @throws SecurityException if called after the session has been committed or abandoned.
- * @throws SecurityException if the session does not update the original installer
- * @throws SecurityException if streams opened through
- * {@link #openWrite(String, long, long) are still open.
- */
- public void transfer(@NonNull String packageName)
- throws PackageManager.NameNotFoundException {
- Objects.requireNonNull(packageName);
-
- CompletableFuture<Intent> intentFuture = new CompletableFuture<Intent>();
- try {
- IIntentSender localSender = new IIntentSender.Stub() {
- @Override
- public void send(int code, Intent intent, String resolvedType,
- IBinder whitelistToken,
- IIntentReceiver finishedReceiver, String requiredPermission,
- Bundle options) {
- intentFuture.complete(intent);
- }
- };
- transfer(packageName, new IntentSender(localSender));
- } catch (ParcelableException e) {
- e.maybeRethrow(PackageManager.NameNotFoundException.class);
- throw new RuntimeException(e);
- }
-
- try {
- Intent intent = intentFuture.get();
- final int status = intent.getIntExtra(EXTRA_STATUS, Integer.MIN_VALUE);
- final String statusMessage = intent.getStringExtra(EXTRA_STATUS_MESSAGE);
- switch (status) {
- case STATUS_SUCCESS:
- break;
- case STATUS_FAILURE_NAME_NOT_FOUND:
- throw new PackageManager.NameNotFoundException(statusMessage);
- case STATUS_FAILURE_ILLEGAL_STATE:
- throw new IllegalStateException(statusMessage);
- case STATUS_FAILURE_SECURITY:
- throw new SecurityException(statusMessage);
- default:
- throw new RuntimeException(statusMessage);
- }
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- } catch (ExecutionException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
* Release this session object. You can open the session again if it
* hasn't been finalized.
*/
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 71555c98f9d2..78875da9e790 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -152,7 +152,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private static final int MSG_COMMIT = 1;
private static final int MSG_ON_PACKAGE_INSTALLED = 2;
private static final int MSG_SEAL = 3;
- private static final int MSG_TRANSFER = 4;
/** XML constants used for persisting a session */
static final String TAG_SESSION = "session";
@@ -388,32 +387,19 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private final Handler.Callback mHandlerCallback = new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
- SomeArgs args;
- String packageName;
- IntentSender statusReceiver;
switch (msg.what) {
case MSG_SEAL:
- statusReceiver = (IntentSender) msg.obj;
-
- handleSeal(statusReceiver);
+ handleSeal((IntentSender) msg.obj);
break;
case MSG_COMMIT:
handleCommit();
break;
- case MSG_TRANSFER:
- args = (SomeArgs) msg.obj;
- packageName = (String) args.arg1;
- statusReceiver = (IntentSender) args.arg2;
- args.recycle();
-
- handleTransfer(statusReceiver, packageName);
- break;
case MSG_ON_PACKAGE_INSTALLED:
- args = (SomeArgs) msg.obj;
- packageName = (String) args.arg1;
+ final SomeArgs args = (SomeArgs) msg.obj;
+ final String packageName = (String) args.arg1;
final String message = (String) args.arg2;
final Bundle extras = (Bundle) args.arg3;
- statusReceiver = (IntentSender) args.arg4;
+ final IntentSender statusReceiver = (IntentSender) args.arg4;
final int returnCode = args.argi1;
args.recycle();
@@ -459,7 +445,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
* Checks if the permissions still need to be confirmed.
*
* <p>This is dependant on the identity of the installer, hence this cannot be cached if the
- * installer might still {@link #transfer(String, IntentSender) change}.
+ * installer might still {@link #transfer(String) change}.
*
* @return {@code true} iff we need to ask to confirm the permissions?
*/
@@ -1403,11 +1389,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
}
- private int assertCanBeTransferredAndReturnNewOwner(String packageName)
- throws PackageManager.NameNotFoundException {
+ @Override
+ public void transfer(String packageName) {
+ Objects.requireNonNull(packageName);
+
ApplicationInfo newOwnerAppInfo = mPm.getApplicationInfo(packageName, 0, userId);
if (newOwnerAppInfo == null) {
- throw new PackageManager.NameNotFoundException(packageName);
+ throw new ParcelableException(new PackageManager.NameNotFoundException(packageName));
}
if (PackageManager.PERMISSION_GRANTED != mPm.checkUidPermission(
@@ -1422,106 +1410,31 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
throw new SecurityException("Can only transfer sessions that use public options");
}
- return newOwnerAppInfo.uid;
- }
-
- @Override
- public void transfer(String packageName, IntentSender statusReceiver) {
- Objects.requireNonNull(statusReceiver);
- Objects.requireNonNull(packageName);
-
- try {
- assertCanBeTransferredAndReturnNewOwner(packageName);
- } catch (PackageManager.NameNotFoundException e) {
- throw new ParcelableException(e);
- }
+ List<PackageInstallerSession> childSessions = getChildSessions();
synchronized (mLock) {
assertCallerIsOwnerOrRootLocked();
assertPreparedAndNotSealedLocked("transfer");
- }
-
- final SomeArgs args = SomeArgs.obtain();
- args.arg1 = packageName;
- args.arg2 = statusReceiver;
-
- mHandler.obtainMessage(MSG_TRANSFER, args).sendToTarget();
- }
-
- private void handleTransfer(IntentSender statusReceiver, String packageName) {
- List<PackageInstallerSession> childSessions = getChildSessions();
-
- try {
- final int uid = assertCanBeTransferredAndReturnNewOwner(packageName);
-
- synchronized (mLock) {
- assertPreparedAndNotSealedLocked("transfer");
-
- try {
- sealAndValidateLocked(childSessions);
- } catch (StreamingException e) {
- throw new IllegalArgumentException("Streaming failed", e);
- } catch (PackageManagerException e) {
- throw new IllegalArgumentException("Package is not valid", e);
- }
- if (!mPackageName.equals(mInstallSource.installerPackageName)) {
- throw new SecurityException(
- "Can only transfer sessions that update the original installer");
- }
+ try {
+ sealLocked(childSessions);
+ } catch (PackageManagerException e) {
+ throw new IllegalArgumentException("Package is not valid", e);
+ }
- mInstallerUid = uid;
- mInstallSource = InstallSource.create(packageName, null, packageName);
+ if (!mPackageName.equals(mInstallSource.installerPackageName)) {
+ throw new SecurityException("Can only transfer sessions that update the original "
+ + "installer");
}
- } catch (PackageManager.NameNotFoundException e) {
- onSessionTransferStatus(statusReceiver, packageName,
- PackageInstaller.STATUS_FAILURE_NAME_NOT_FOUND, e.getMessage());
- return;
- } catch (IllegalStateException e) {
- onSessionTransferStatus(statusReceiver, packageName,
- PackageInstaller.STATUS_FAILURE_ILLEGAL_STATE, e.getMessage());
- return;
- } catch (SecurityException e) {
- onSessionTransferStatus(statusReceiver, packageName,
- PackageInstaller.STATUS_FAILURE_SECURITY, e.getMessage());
- return;
- } catch (Throwable e) {
- onSessionTransferStatus(statusReceiver, packageName, PackageInstaller.STATUS_FAILURE,
- e.getMessage());
- return;
+
+ mInstallerUid = newOwnerAppInfo.uid;
+ mInstallSource = InstallSource.create(packageName, null, packageName);
}
// Persist the fact that we've sealed ourselves to prevent
// mutations of any hard links we create. We do this without holding
// the session lock, since otherwise it's a lock inversion.
mCallback.onSessionSealedBlocking(this);
-
- // Report success.
- onSessionTransferStatus(statusReceiver, packageName, PackageInstaller.STATUS_SUCCESS, null);
- }
-
- private void onSessionTransferStatus(IntentSender statusReceiver, String otherPackageName,
- int status, String statusMessage) {
- final String packageName;
- synchronized (mLock) {
- packageName = mPackageName;
- }
-
- final Intent fillIn = new Intent();
- fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, packageName);
- fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
- fillIn.putExtra(PackageInstaller.EXTRA_OTHER_PACKAGE_NAME, otherPackageName);
-
- fillIn.putExtra(PackageInstaller.EXTRA_STATUS, status);
- if (!TextUtils.isEmpty(statusMessage)) {
- fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE, statusMessage);
- }
-
- try {
- statusReceiver.sendIntent(mContext, 0, fillIn, null, null);
- } catch (IntentSender.SendIntentException ignored) {
- }
-
}
private void handleCommit() {