Merge changes Iad51cd85,I6414d28c
* changes: Minor refactorings and cleanups. Simplifying callback calls in PackageInstallerSession.
This commit is contained in:
@@ -26,7 +26,6 @@ import android.app.AppOpsManager;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PackageDeleteObserver;
|
||||
import android.app.PackageInstallObserver;
|
||||
import android.app.admin.DevicePolicyEventLogger;
|
||||
import android.app.admin.DevicePolicyManagerInternal;
|
||||
import android.content.Context;
|
||||
@@ -994,74 +993,57 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
|
||||
}
|
||||
}
|
||||
|
||||
static class PackageInstallObserverAdapter extends PackageInstallObserver {
|
||||
private final Context mContext;
|
||||
private final IntentSender mTarget;
|
||||
private final int mSessionId;
|
||||
private final boolean mShowNotification;
|
||||
private final int mUserId;
|
||||
|
||||
public PackageInstallObserverAdapter(Context context, IntentSender target, int sessionId,
|
||||
boolean showNotification, int userId) {
|
||||
mContext = context;
|
||||
mTarget = target;
|
||||
mSessionId = sessionId;
|
||||
mShowNotification = showNotification;
|
||||
mUserId = userId;
|
||||
static void sendOnUserActionRequired(Context context, IntentSender target, int sessionId,
|
||||
Intent intent) {
|
||||
final Intent fillIn = new Intent();
|
||||
fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
|
||||
fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
|
||||
PackageInstaller.STATUS_PENDING_USER_ACTION);
|
||||
fillIn.putExtra(Intent.EXTRA_INTENT, intent);
|
||||
try {
|
||||
target.sendIntent(context, 0, fillIn, null, null);
|
||||
} catch (SendIntentException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserActionRequired(Intent intent) {
|
||||
final Intent fillIn = new Intent();
|
||||
fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, mSessionId);
|
||||
fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
|
||||
PackageInstaller.STATUS_PENDING_USER_ACTION);
|
||||
fillIn.putExtra(Intent.EXTRA_INTENT, intent);
|
||||
try {
|
||||
mTarget.sendIntent(mContext, 0, fillIn, null, null);
|
||||
} catch (SendIntentException ignored) {
|
||||
static void sendOnPackageInstalled(Context context, IntentSender target, int sessionId,
|
||||
boolean showNotification, int userId, String basePackageName, int returnCode,
|
||||
String msg, Bundle extras) {
|
||||
if (PackageManager.INSTALL_SUCCEEDED == returnCode && showNotification) {
|
||||
boolean update = (extras != null) && extras.getBoolean(Intent.EXTRA_REPLACING);
|
||||
Notification notification = buildSuccessNotification(context,
|
||||
context.getResources()
|
||||
.getString(update ? R.string.package_updated_device_owner :
|
||||
R.string.package_installed_device_owner),
|
||||
basePackageName,
|
||||
userId);
|
||||
if (notification != null) {
|
||||
NotificationManager notificationManager = (NotificationManager)
|
||||
context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager.notify(basePackageName,
|
||||
SystemMessage.NOTE_PACKAGE_STATE,
|
||||
notification);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPackageInstalled(String basePackageName, int returnCode, String msg,
|
||||
Bundle extras) {
|
||||
if (PackageManager.INSTALL_SUCCEEDED == returnCode && mShowNotification) {
|
||||
boolean update = (extras != null) && extras.getBoolean(Intent.EXTRA_REPLACING);
|
||||
Notification notification = buildSuccessNotification(mContext,
|
||||
mContext.getResources()
|
||||
.getString(update ? R.string.package_updated_device_owner :
|
||||
R.string.package_installed_device_owner),
|
||||
basePackageName,
|
||||
mUserId);
|
||||
if (notification != null) {
|
||||
NotificationManager notificationManager = (NotificationManager)
|
||||
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager.notify(basePackageName,
|
||||
SystemMessage.NOTE_PACKAGE_STATE,
|
||||
notification);
|
||||
}
|
||||
}
|
||||
final Intent fillIn = new Intent();
|
||||
fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, basePackageName);
|
||||
fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, mSessionId);
|
||||
fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
|
||||
PackageManager.installStatusToPublicStatus(returnCode));
|
||||
fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE,
|
||||
PackageManager.installStatusToString(returnCode, msg));
|
||||
fillIn.putExtra(PackageInstaller.EXTRA_LEGACY_STATUS, returnCode);
|
||||
if (extras != null) {
|
||||
final String existing = extras.getString(
|
||||
PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE);
|
||||
if (!TextUtils.isEmpty(existing)) {
|
||||
fillIn.putExtra(PackageInstaller.EXTRA_OTHER_PACKAGE_NAME, existing);
|
||||
}
|
||||
}
|
||||
try {
|
||||
mTarget.sendIntent(mContext, 0, fillIn, null, null);
|
||||
} catch (SendIntentException ignored) {
|
||||
final Intent fillIn = new Intent();
|
||||
fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, basePackageName);
|
||||
fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
|
||||
fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
|
||||
PackageManager.installStatusToPublicStatus(returnCode));
|
||||
fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE,
|
||||
PackageManager.installStatusToString(returnCode, msg));
|
||||
fillIn.putExtra(PackageInstaller.EXTRA_LEGACY_STATUS, returnCode);
|
||||
if (extras != null) {
|
||||
final String existing = extras.getString(
|
||||
PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE);
|
||||
if (!TextUtils.isEmpty(existing)) {
|
||||
fillIn.putExtra(PackageInstaller.EXTRA_OTHER_PACKAGE_NAME, existing);
|
||||
}
|
||||
}
|
||||
try {
|
||||
target.sendIntent(context, 0, fillIn, null, null);
|
||||
} catch (SendIntentException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.android.server.pm;
|
||||
|
||||
import static android.content.pm.PackageManager.INSTALL_FAILED_ABORTED;
|
||||
import static android.content.pm.PackageManager.INSTALL_FAILED_BAD_SIGNATURE;
|
||||
import static android.content.pm.PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
|
||||
import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
|
||||
import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
|
||||
import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
|
||||
@@ -79,7 +78,6 @@ import android.os.Message;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.ParcelableException;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.RevocableFileDescriptor;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.UserHandle;
|
||||
@@ -107,7 +105,6 @@ import com.android.internal.util.IndentingPrintWriter;
|
||||
import com.android.internal.util.Preconditions;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.pm.Installer.InstallerException;
|
||||
import com.android.server.pm.PackageInstallerService.PackageInstallObserverAdapter;
|
||||
import com.android.server.pm.dex.DexManager;
|
||||
import com.android.server.security.VerityUtils;
|
||||
|
||||
@@ -131,7 +128,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
private static final String TAG = "PackageInstallerSession";
|
||||
private static final boolean LOGD = true;
|
||||
private static final String REMOVE_SPLIT_MARKER_EXTENSION = ".removed";
|
||||
private static final String REMOVE_MARKER_EXTENSION = ".removed";
|
||||
|
||||
private static final int MSG_COMMIT = 1;
|
||||
private static final int MSG_ON_PACKAGE_INSTALLED = 2;
|
||||
@@ -257,7 +254,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
private final ArrayList<FileBridge> mBridges = new ArrayList<>();
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private IPackageInstallObserver2 mRemoteObserver;
|
||||
private IntentSender mRemoteStatusReceiver;
|
||||
|
||||
/** Fields derived from commit parsing */
|
||||
@GuardedBy("mLock")
|
||||
@@ -293,9 +290,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
@GuardedBy("mLock")
|
||||
private File mResolvedBaseFile;
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private File mResolvedStageDir;
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private final List<File> mResolvedStagedFiles = new ArrayList<>();
|
||||
@GuardedBy("mLock")
|
||||
@@ -315,7 +309,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
// Installers can't stage directories, so it's fine to ignore
|
||||
// entries like "lost+found".
|
||||
if (file.isDirectory()) return false;
|
||||
if (file.getName().endsWith(REMOVE_SPLIT_MARKER_EXTENSION)) return false;
|
||||
if (file.getName().endsWith(REMOVE_MARKER_EXTENSION)) return false;
|
||||
if (DexMetadataHelper.isDexMetadataFile(file)) return false;
|
||||
if (VerityUtils.isFsveritySignatureFile(file)) return false;
|
||||
return true;
|
||||
@@ -325,7 +319,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
@Override
|
||||
public boolean accept(File file) {
|
||||
if (file.isDirectory()) return false;
|
||||
if (!file.getName().endsWith(REMOVE_SPLIT_MARKER_EXTENSION)) return false;
|
||||
if (!file.getName().endsWith(REMOVE_MARKER_EXTENSION)) return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -342,14 +336,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
final String packageName = (String) args.arg1;
|
||||
final String message = (String) args.arg2;
|
||||
final Bundle extras = (Bundle) args.arg3;
|
||||
final IPackageInstallObserver2 observer = (IPackageInstallObserver2) args.arg4;
|
||||
final IntentSender statusReceiver = (IntentSender) args.arg4;
|
||||
final int returnCode = args.argi1;
|
||||
args.recycle();
|
||||
|
||||
try {
|
||||
observer.onPackageInstalled(packageName, returnCode, message, extras);
|
||||
} catch (RemoteException ignored) {
|
||||
}
|
||||
PackageInstallerService.sendOnPackageInstalled(mContext,
|
||||
statusReceiver, sessionId,
|
||||
isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId,
|
||||
packageName, returnCode, message, extras);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -559,23 +553,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the actual location where staged data should be written. This
|
||||
* might point at an ASEC mount point, which is why we delay path resolution
|
||||
* until someone actively works with the session.
|
||||
*/
|
||||
@GuardedBy("mLock")
|
||||
private File resolveStageDirLocked() throws IOException {
|
||||
if (mResolvedStageDir == null) {
|
||||
if (stageDir != null) {
|
||||
mResolvedStageDir = stageDir;
|
||||
} else {
|
||||
throw new IOException("Missing stageDir");
|
||||
}
|
||||
}
|
||||
return mResolvedStageDir;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClientProgress(float progress) {
|
||||
synchronized (mLock) {
|
||||
@@ -615,14 +592,32 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
assertCallerIsOwnerOrRootLocked();
|
||||
assertPreparedAndNotCommittedOrDestroyedLocked("getNames");
|
||||
|
||||
try {
|
||||
return resolveStageDirLocked().list();
|
||||
} catch (IOException e) {
|
||||
throw ExceptionUtils.wrap(e);
|
||||
}
|
||||
return getNamesLocked();
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private String[] getNamesLocked() {
|
||||
return stageDir.list();
|
||||
}
|
||||
|
||||
private static File[] filterFiles(File parent, String[] names, FileFilter filter) {
|
||||
return Arrays.stream(names).map(name -> new File(parent, name)).filter(
|
||||
file -> filter.accept(file)).toArray(File[]::new);
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private File[] getAddedFilesLocked() {
|
||||
String[] names = getNamesLocked();
|
||||
return filterFiles(stageDir, names, sAddedFilter);
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private File[] getRemovedFilesLocked() {
|
||||
String[] names = getNamesLocked();
|
||||
return filterFiles(stageDir, names, sRemovedFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSplit(String splitName) {
|
||||
if (TextUtils.isEmpty(params.appPackageName)) {
|
||||
@@ -641,13 +636,17 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private static String getRemoveMarkerName(String name) {
|
||||
final String markerName = name + REMOVE_MARKER_EXTENSION;
|
||||
if (!FileUtils.isValidExtFilename(markerName)) {
|
||||
throw new IllegalArgumentException("Invalid marker: " + markerName);
|
||||
}
|
||||
return markerName;
|
||||
}
|
||||
|
||||
private void createRemoveSplitMarkerLocked(String splitName) throws IOException {
|
||||
try {
|
||||
final String markerName = splitName + REMOVE_SPLIT_MARKER_EXTENSION;
|
||||
if (!FileUtils.isValidExtFilename(markerName)) {
|
||||
throw new IllegalArgumentException("Invalid marker: " + markerName);
|
||||
}
|
||||
final File target = new File(resolveStageDirLocked(), markerName);
|
||||
final File target = new File(stageDir, getRemoveMarkerName(splitName));
|
||||
target.createNewFile();
|
||||
Os.chmod(target.getAbsolutePath(), 0 /*mode*/);
|
||||
} catch (ErrnoException e) {
|
||||
@@ -681,7 +680,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
// will block any attempted install transitions.
|
||||
final RevocableFileDescriptor fd;
|
||||
final FileBridge bridge;
|
||||
final File stageDir;
|
||||
synchronized (mLock) {
|
||||
assertCallerIsOwnerOrRootLocked();
|
||||
assertPreparedAndNotSealedLocked("openWrite");
|
||||
@@ -695,8 +693,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
bridge = new FileBridge();
|
||||
mBridges.add(bridge);
|
||||
}
|
||||
|
||||
stageDir = resolveStageDirLocked();
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -802,7 +798,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
if (!FileUtils.isValidExtFilename(name)) {
|
||||
throw new IllegalArgumentException("Invalid name: " + name);
|
||||
}
|
||||
final File target = new File(resolveStageDirLocked(), name);
|
||||
final File target = new File(stageDir, name);
|
||||
final FileDescriptor targetFd = Os.open(target.getAbsolutePath(), O_RDONLY, 0);
|
||||
return new ParcelFileDescriptor(targetFd);
|
||||
} catch (ErrnoException e) {
|
||||
@@ -948,7 +944,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
* This method may be called multiple times to update the status receiver validate caller
|
||||
* permissions.
|
||||
*/
|
||||
public boolean markAsCommitted(
|
||||
private boolean markAsCommitted(
|
||||
@NonNull IntentSender statusReceiver, boolean forTransfer) {
|
||||
Preconditions.checkNotNull(statusReceiver);
|
||||
|
||||
@@ -959,10 +955,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
assertCallerIsOwnerOrRootLocked();
|
||||
assertPreparedAndNotDestroyedLocked("commit");
|
||||
|
||||
final PackageInstallObserverAdapter adapter = new PackageInstallObserverAdapter(
|
||||
mContext, statusReceiver, sessionId,
|
||||
isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId);
|
||||
mRemoteObserver = adapter.getBinder();
|
||||
mRemoteStatusReceiver = statusReceiver;
|
||||
|
||||
if (forTransfer) {
|
||||
mContext.enforceCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES, null);
|
||||
@@ -986,12 +979,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
if (!mSealed) {
|
||||
try {
|
||||
sealAndValidateLocked(childSessions);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
} catch (PackageManagerException e) {
|
||||
// Do now throw an exception here to stay compatible with O and older
|
||||
destroyInternal();
|
||||
dispatchSessionFinished(e.error, ExceptionUtils.getCompleteMessage(e), null);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1091,52 +1079,59 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
*/
|
||||
@GuardedBy("mLock")
|
||||
private void sealAndValidateLocked(List<PackageInstallerSession> childSessions)
|
||||
throws PackageManagerException, IOException {
|
||||
assertNoWriteFileTransfersOpenLocked();
|
||||
assertPreparedAndNotDestroyedLocked("sealing of session");
|
||||
throws PackageManagerException {
|
||||
try {
|
||||
assertNoWriteFileTransfersOpenLocked();
|
||||
assertPreparedAndNotDestroyedLocked("sealing of session");
|
||||
|
||||
mSealed = true;
|
||||
mSealed = true;
|
||||
|
||||
if (childSessions != null) {
|
||||
assertMultiPackageConsistencyLocked(childSessions);
|
||||
}
|
||||
|
||||
if (params.isStaged) {
|
||||
final PackageInstallerSession activeSession = mStagingManager.getActiveSession();
|
||||
final boolean anotherSessionAlreadyInProgress =
|
||||
activeSession != null && sessionId != activeSession.sessionId
|
||||
&& mParentSessionId != activeSession.sessionId;
|
||||
if (anotherSessionAlreadyInProgress) {
|
||||
throw new PackageManagerException(
|
||||
PackageManager.INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS,
|
||||
"There is already in-progress committed staged session "
|
||||
+ activeSession.sessionId, null);
|
||||
if (childSessions != null) {
|
||||
assertMultiPackageConsistencyLocked(childSessions);
|
||||
}
|
||||
}
|
||||
|
||||
// Read transfers from the original owner stay open, but as the session's data
|
||||
// cannot be modified anymore, there is no leak of information. For staged sessions,
|
||||
// further validation is performed by the staging manager.
|
||||
if (!params.isMultiPackage) {
|
||||
final PackageInfo pkgInfo = mPm.getPackageInfo(
|
||||
params.appPackageName, PackageManager.GET_SIGNATURES
|
||||
| PackageManager.MATCH_STATIC_SHARED_LIBRARIES /*flags*/, userId);
|
||||
|
||||
resolveStageDirLocked();
|
||||
|
||||
try {
|
||||
if ((params.installFlags & PackageManager.INSTALL_APEX) != 0) {
|
||||
validateApexInstallLocked();
|
||||
} else {
|
||||
validateApkInstallLocked(pkgInfo);
|
||||
if (params.isStaged) {
|
||||
final PackageInstallerSession activeSession = mStagingManager.getActiveSession();
|
||||
final boolean anotherSessionAlreadyInProgress =
|
||||
activeSession != null && sessionId != activeSession.sessionId
|
||||
&& mParentSessionId != activeSession.sessionId;
|
||||
if (anotherSessionAlreadyInProgress) {
|
||||
throw new PackageManagerException(
|
||||
PackageManager.INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS,
|
||||
"There is already in-progress committed staged session "
|
||||
+ activeSession.sessionId, null);
|
||||
}
|
||||
} catch (PackageManagerException e) {
|
||||
throw e;
|
||||
} catch (Throwable e) {
|
||||
// Convert all exceptions into package manager exceptions as only those are handled
|
||||
// in the code above
|
||||
throw new PackageManagerException(e);
|
||||
}
|
||||
|
||||
// Read transfers from the original owner stay open, but as the session's data
|
||||
// cannot be modified anymore, there is no leak of information. For staged sessions,
|
||||
// further validation is performed by the staging manager.
|
||||
if (!params.isMultiPackage) {
|
||||
final PackageInfo pkgInfo = mPm.getPackageInfo(
|
||||
params.appPackageName, PackageManager.GET_SIGNATURES
|
||||
| PackageManager.MATCH_STATIC_SHARED_LIBRARIES /*flags*/, userId);
|
||||
|
||||
try {
|
||||
if ((params.installFlags & PackageManager.INSTALL_APEX) != 0) {
|
||||
validateApexInstallLocked();
|
||||
} else {
|
||||
validateApkInstallLocked(pkgInfo);
|
||||
}
|
||||
} catch (PackageManagerException e) {
|
||||
throw e;
|
||||
} catch (Throwable e) {
|
||||
// Convert all exceptions into package manager exceptions as only those are
|
||||
// handled in the code above.
|
||||
throw new PackageManagerException(e);
|
||||
}
|
||||
}
|
||||
} catch (PackageManagerException e) {
|
||||
// Session is sealed but could not be verified, we need to destroy it.
|
||||
destroyInternal();
|
||||
// Dispatch message to remove session from PackageInstallerService
|
||||
dispatchSessionFinished(
|
||||
e.error, ExceptionUtils.getCompleteMessage(e), null);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1159,15 +1154,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
synchronized (mLock) {
|
||||
try {
|
||||
sealAndValidateLocked(childSessions);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
} catch (PackageManagerException e) {
|
||||
Slog.e(TAG, "Package not valid", e);
|
||||
// Session is sealed but could not be verified, we need to destroy it.
|
||||
destroyInternal();
|
||||
// Dispatch message to remove session from PackageInstallerService
|
||||
dispatchSessionFinished(
|
||||
e.error, ExceptionUtils.getCompleteMessage(e), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1208,13 +1196,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
|
||||
try {
|
||||
sealAndValidateLocked(childSessions);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
} catch (PackageManagerException e) {
|
||||
// Session is sealed but could not be verified, we need to destroy it
|
||||
destroyInternal();
|
||||
dispatchSessionFinished(e.error, ExceptionUtils.getCompleteMessage(e), null);
|
||||
|
||||
throw new IllegalArgumentException("Package is not valid", e);
|
||||
}
|
||||
|
||||
@@ -1299,11 +1281,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
try {
|
||||
mRemoteObserver.onPackageInstalled(
|
||||
null, failure.error, failure.getLocalizedMessage(), null);
|
||||
} catch (RemoteException ignored) {
|
||||
}
|
||||
PackageInstallerService.sendOnPackageInstalled(mContext,
|
||||
mRemoteStatusReceiver, sessionId,
|
||||
isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId, null,
|
||||
failure.error, failure.getLocalizedMessage(), null);
|
||||
return;
|
||||
}
|
||||
mPm.installStage(activeChildSessions);
|
||||
@@ -1347,10 +1328,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
final Intent intent = new Intent(PackageInstaller.ACTION_CONFIRM_INSTALL);
|
||||
intent.setPackage(mPm.getPackageInstallerPackageName());
|
||||
intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
|
||||
try {
|
||||
mRemoteObserver.onUserActionRequired(intent);
|
||||
} catch (RemoteException ignored) {
|
||||
}
|
||||
|
||||
PackageInstallerService.sendOnUserActionRequired(mContext,
|
||||
mRemoteStatusReceiver, sessionId, intent);
|
||||
|
||||
// Commit was keeping session marked as active until now; release
|
||||
// that extra refcount so session appears idle.
|
||||
@@ -1363,7 +1343,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
if (params.mode == SessionParams.MODE_INHERIT_EXISTING) {
|
||||
try {
|
||||
final List<File> fromFiles = mResolvedInheritedFiles;
|
||||
final File toDir = resolveStageDirLocked();
|
||||
final File toDir = stageDir;
|
||||
|
||||
if (LOGD) Slog.d(TAG, "Inherited files: " + mResolvedInheritedFiles);
|
||||
if (!mResolvedInheritedFiles.isEmpty() && mInheritedFilesBase == null) {
|
||||
@@ -1413,8 +1393,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
computeProgressLocked(true);
|
||||
|
||||
// Unpack native libraries
|
||||
extractNativeLibraries(mResolvedStageDir, params.abiOverride,
|
||||
mayInheritNativeLibs());
|
||||
extractNativeLibraries(stageDir, params.abiOverride, mayInheritNativeLibs());
|
||||
}
|
||||
|
||||
// We've reached point of no return; call into PMS to install the stage.
|
||||
@@ -1475,7 +1454,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
@GuardedBy("mLock")
|
||||
private void validateApexInstallLocked()
|
||||
throws PackageManagerException {
|
||||
final File[] addedFiles = mResolvedStageDir.listFiles(sAddedFilter);
|
||||
final File[] addedFiles = getAddedFilesLocked();
|
||||
if (ArrayUtils.isEmpty(addedFiles)) {
|
||||
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "No packages staged");
|
||||
}
|
||||
@@ -1485,13 +1464,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
"Too many files for apex install");
|
||||
}
|
||||
|
||||
try {
|
||||
resolveStageDirLocked();
|
||||
} catch (IOException e) {
|
||||
throw new PackageManagerException(INSTALL_FAILED_CONTAINER_ERROR,
|
||||
"Failed to resolve stage location", e);
|
||||
}
|
||||
|
||||
File addedFile = addedFiles[0]; // there is only one file
|
||||
|
||||
// Ensure file name has proper suffix
|
||||
@@ -1504,7 +1476,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
"Invalid filename: " + targetName);
|
||||
}
|
||||
|
||||
final File targetFile = new File(mResolvedStageDir, targetName);
|
||||
final File targetFile = new File(stageDir, targetName);
|
||||
resolveAndStageFile(addedFile, targetFile);
|
||||
|
||||
mResolvedBaseFile = targetFile;
|
||||
@@ -1545,25 +1517,18 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
&& params.mode == SessionParams.MODE_INHERIT_EXISTING
|
||||
&& VerityUtils.hasFsverity(pkgInfo.applicationInfo.getBaseCodePath());
|
||||
|
||||
try {
|
||||
resolveStageDirLocked();
|
||||
} catch (IOException e) {
|
||||
throw new PackageManagerException(INSTALL_FAILED_CONTAINER_ERROR,
|
||||
"Failed to resolve stage location", e);
|
||||
}
|
||||
|
||||
final File[] removedFiles = mResolvedStageDir.listFiles(sRemovedFilter);
|
||||
final File[] removedFiles = getRemovedFilesLocked();
|
||||
final List<String> removeSplitList = new ArrayList<>();
|
||||
if (!ArrayUtils.isEmpty(removedFiles)) {
|
||||
for (File removedFile : removedFiles) {
|
||||
final String fileName = removedFile.getName();
|
||||
final String splitName = fileName.substring(
|
||||
0, fileName.length() - REMOVE_SPLIT_MARKER_EXTENSION.length());
|
||||
0, fileName.length() - REMOVE_MARKER_EXTENSION.length());
|
||||
removeSplitList.add(splitName);
|
||||
}
|
||||
}
|
||||
|
||||
final File[] addedFiles = mResolvedStageDir.listFiles(sAddedFilter);
|
||||
final File[] addedFiles = getAddedFilesLocked();
|
||||
if (ArrayUtils.isEmpty(addedFiles) && removeSplitList.size() == 0) {
|
||||
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "No packages staged");
|
||||
}
|
||||
@@ -1607,7 +1572,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
"Invalid filename: " + targetName);
|
||||
}
|
||||
|
||||
final File targetFile = new File(mResolvedStageDir, targetName);
|
||||
final File targetFile = new File(stageDir, targetName);
|
||||
resolveAndStageFile(addedFile, targetFile);
|
||||
|
||||
// Base is coming from session
|
||||
@@ -1622,7 +1587,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
|
||||
"Invalid filename: " + dexMetadataFile);
|
||||
}
|
||||
final File targetDexMetadataFile = new File(mResolvedStageDir,
|
||||
final File targetDexMetadataFile = new File(stageDir,
|
||||
DexMetadataHelper.buildDexMetadataPathForApk(targetName));
|
||||
resolveAndStageFile(dexMetadataFile, targetDexMetadataFile);
|
||||
}
|
||||
@@ -2182,17 +2147,17 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
}
|
||||
|
||||
private void dispatchSessionFinished(int returnCode, String msg, Bundle extras) {
|
||||
final IPackageInstallObserver2 observer;
|
||||
final IntentSender statusReceiver;
|
||||
final String packageName;
|
||||
synchronized (mLock) {
|
||||
mFinalStatus = returnCode;
|
||||
mFinalMessage = msg;
|
||||
|
||||
observer = mRemoteObserver;
|
||||
statusReceiver = mRemoteStatusReceiver;
|
||||
packageName = mPackageName;
|
||||
}
|
||||
|
||||
if (observer != null) {
|
||||
if (statusReceiver != null) {
|
||||
// Execute observer.onPackageInstalled on different tread as we don't want callers
|
||||
// inside the system server have to worry about catching the callbacks while they are
|
||||
// calling into the session
|
||||
@@ -2200,7 +2165,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
args.arg1 = packageName;
|
||||
args.arg2 = msg;
|
||||
args.arg3 = extras;
|
||||
args.arg4 = observer;
|
||||
args.arg4 = statusReceiver;
|
||||
args.argi1 = returnCode;
|
||||
|
||||
mHandler.obtainMessage(MSG_ON_PACKAGE_INSTALLED, args).sendToTarget();
|
||||
|
||||
Reference in New Issue
Block a user