Merge changes Iad51cd85,I6414d28c

* changes:
  Minor refactorings and cleanups.
  Simplifying callback calls in PackageInstallerSession.
This commit is contained in:
Mohammad Islam
2020-03-18 11:35:00 +00:00
committed by Gerrit Code Review
2 changed files with 156 additions and 209 deletions

View File

@@ -26,7 +26,6 @@ import android.app.AppOpsManager;
import android.app.Notification; import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PackageDeleteObserver; import android.app.PackageDeleteObserver;
import android.app.PackageInstallObserver;
import android.app.admin.DevicePolicyEventLogger; import android.app.admin.DevicePolicyEventLogger;
import android.app.admin.DevicePolicyManagerInternal; import android.app.admin.DevicePolicyManagerInternal;
import android.content.Context; import android.content.Context;
@@ -994,49 +993,33 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
} }
} }
static class PackageInstallObserverAdapter extends PackageInstallObserver { static void sendOnUserActionRequired(Context context, IntentSender target, int sessionId,
private final Context mContext; Intent intent) {
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;
}
@Override
public void onUserActionRequired(Intent intent) {
final Intent fillIn = new Intent(); final Intent fillIn = new Intent();
fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, mSessionId); fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
fillIn.putExtra(PackageInstaller.EXTRA_STATUS, fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
PackageInstaller.STATUS_PENDING_USER_ACTION); PackageInstaller.STATUS_PENDING_USER_ACTION);
fillIn.putExtra(Intent.EXTRA_INTENT, intent); fillIn.putExtra(Intent.EXTRA_INTENT, intent);
try { try {
mTarget.sendIntent(mContext, 0, fillIn, null, null); target.sendIntent(context, 0, fillIn, null, null);
} catch (SendIntentException ignored) { } catch (SendIntentException ignored) {
} }
} }
@Override static void sendOnPackageInstalled(Context context, IntentSender target, int sessionId,
public void onPackageInstalled(String basePackageName, int returnCode, String msg, boolean showNotification, int userId, String basePackageName, int returnCode,
Bundle extras) { String msg, Bundle extras) {
if (PackageManager.INSTALL_SUCCEEDED == returnCode && mShowNotification) { if (PackageManager.INSTALL_SUCCEEDED == returnCode && showNotification) {
boolean update = (extras != null) && extras.getBoolean(Intent.EXTRA_REPLACING); boolean update = (extras != null) && extras.getBoolean(Intent.EXTRA_REPLACING);
Notification notification = buildSuccessNotification(mContext, Notification notification = buildSuccessNotification(context,
mContext.getResources() context.getResources()
.getString(update ? R.string.package_updated_device_owner : .getString(update ? R.string.package_updated_device_owner :
R.string.package_installed_device_owner), R.string.package_installed_device_owner),
basePackageName, basePackageName,
mUserId); userId);
if (notification != null) { if (notification != null) {
NotificationManager notificationManager = (NotificationManager) NotificationManager notificationManager = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE); context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(basePackageName, notificationManager.notify(basePackageName,
SystemMessage.NOTE_PACKAGE_STATE, SystemMessage.NOTE_PACKAGE_STATE,
notification); notification);
@@ -1044,7 +1027,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
} }
final Intent fillIn = new Intent(); final Intent fillIn = new Intent();
fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, basePackageName); fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, basePackageName);
fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, mSessionId); fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
fillIn.putExtra(PackageInstaller.EXTRA_STATUS, fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
PackageManager.installStatusToPublicStatus(returnCode)); PackageManager.installStatusToPublicStatus(returnCode));
fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE, fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE,
@@ -1058,11 +1041,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
} }
} }
try { try {
mTarget.sendIntent(mContext, 0, fillIn, null, null); target.sendIntent(context, 0, fillIn, null, null);
} catch (SendIntentException ignored) { } catch (SendIntentException ignored) {
} }
} }
}
/** /**
* Build a notification for package installation / deletion by device owners that is shown if * Build a notification for package installation / deletion by device owners that is shown if

View File

@@ -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_ABORTED;
import static android.content.pm.PackageManager.INSTALL_FAILED_BAD_SIGNATURE; 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_INSUFFICIENT_STORAGE;
import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; 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.ParcelFileDescriptor;
import android.os.ParcelableException; import android.os.ParcelableException;
import android.os.Process; import android.os.Process;
import android.os.RemoteException;
import android.os.RevocableFileDescriptor; import android.os.RevocableFileDescriptor;
import android.os.SystemProperties; import android.os.SystemProperties;
import android.os.UserHandle; import android.os.UserHandle;
@@ -107,7 +105,6 @@ import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions; import com.android.internal.util.Preconditions;
import com.android.server.LocalServices; import com.android.server.LocalServices;
import com.android.server.pm.Installer.InstallerException; 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.pm.dex.DexManager;
import com.android.server.security.VerityUtils; import com.android.server.security.VerityUtils;
@@ -131,7 +128,7 @@ import java.util.concurrent.atomic.AtomicInteger;
public class PackageInstallerSession extends IPackageInstallerSession.Stub { public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private static final String TAG = "PackageInstallerSession"; private static final String TAG = "PackageInstallerSession";
private static final boolean LOGD = true; 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_COMMIT = 1;
private static final int MSG_ON_PACKAGE_INSTALLED = 2; 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<>(); private final ArrayList<FileBridge> mBridges = new ArrayList<>();
@GuardedBy("mLock") @GuardedBy("mLock")
private IPackageInstallObserver2 mRemoteObserver; private IntentSender mRemoteStatusReceiver;
/** Fields derived from commit parsing */ /** Fields derived from commit parsing */
@GuardedBy("mLock") @GuardedBy("mLock")
@@ -293,9 +290,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
@GuardedBy("mLock") @GuardedBy("mLock")
private File mResolvedBaseFile; private File mResolvedBaseFile;
@GuardedBy("mLock")
private File mResolvedStageDir;
@GuardedBy("mLock") @GuardedBy("mLock")
private final List<File> mResolvedStagedFiles = new ArrayList<>(); private final List<File> mResolvedStagedFiles = new ArrayList<>();
@GuardedBy("mLock") @GuardedBy("mLock")
@@ -315,7 +309,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
// Installers can't stage directories, so it's fine to ignore // Installers can't stage directories, so it's fine to ignore
// entries like "lost+found". // entries like "lost+found".
if (file.isDirectory()) return false; 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 (DexMetadataHelper.isDexMetadataFile(file)) return false;
if (VerityUtils.isFsveritySignatureFile(file)) return false; if (VerityUtils.isFsveritySignatureFile(file)) return false;
return true; return true;
@@ -325,7 +319,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
@Override @Override
public boolean accept(File file) { public boolean accept(File file) {
if (file.isDirectory()) return false; 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; return true;
} }
}; };
@@ -342,14 +336,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
final String packageName = (String) args.arg1; final String packageName = (String) args.arg1;
final String message = (String) args.arg2; final String message = (String) args.arg2;
final Bundle extras = (Bundle) args.arg3; final Bundle extras = (Bundle) args.arg3;
final IPackageInstallObserver2 observer = (IPackageInstallObserver2) args.arg4; final IntentSender statusReceiver = (IntentSender) args.arg4;
final int returnCode = args.argi1; final int returnCode = args.argi1;
args.recycle(); args.recycle();
try { PackageInstallerService.sendOnPackageInstalled(mContext,
observer.onPackageInstalled(packageName, returnCode, message, extras); statusReceiver, sessionId,
} catch (RemoteException ignored) { isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId,
} packageName, returnCode, message, extras);
break; 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 @Override
public void setClientProgress(float progress) { public void setClientProgress(float progress) {
synchronized (mLock) { synchronized (mLock) {
@@ -615,12 +592,30 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
assertCallerIsOwnerOrRootLocked(); assertCallerIsOwnerOrRootLocked();
assertPreparedAndNotCommittedOrDestroyedLocked("getNames"); assertPreparedAndNotCommittedOrDestroyedLocked("getNames");
try { return getNamesLocked();
return resolveStageDirLocked().list();
} catch (IOException e) {
throw ExceptionUtils.wrap(e);
} }
} }
@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 @Override
@@ -641,13 +636,17 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
} }
} }
private void createRemoveSplitMarkerLocked(String splitName) throws IOException { private static String getRemoveMarkerName(String name) {
try { final String markerName = name + REMOVE_MARKER_EXTENSION;
final String markerName = splitName + REMOVE_SPLIT_MARKER_EXTENSION;
if (!FileUtils.isValidExtFilename(markerName)) { if (!FileUtils.isValidExtFilename(markerName)) {
throw new IllegalArgumentException("Invalid marker: " + markerName); throw new IllegalArgumentException("Invalid marker: " + markerName);
} }
final File target = new File(resolveStageDirLocked(), markerName); return markerName;
}
private void createRemoveSplitMarkerLocked(String splitName) throws IOException {
try {
final File target = new File(stageDir, getRemoveMarkerName(splitName));
target.createNewFile(); target.createNewFile();
Os.chmod(target.getAbsolutePath(), 0 /*mode*/); Os.chmod(target.getAbsolutePath(), 0 /*mode*/);
} catch (ErrnoException e) { } catch (ErrnoException e) {
@@ -681,7 +680,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
// will block any attempted install transitions. // will block any attempted install transitions.
final RevocableFileDescriptor fd; final RevocableFileDescriptor fd;
final FileBridge bridge; final FileBridge bridge;
final File stageDir;
synchronized (mLock) { synchronized (mLock) {
assertCallerIsOwnerOrRootLocked(); assertCallerIsOwnerOrRootLocked();
assertPreparedAndNotSealedLocked("openWrite"); assertPreparedAndNotSealedLocked("openWrite");
@@ -695,8 +693,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
bridge = new FileBridge(); bridge = new FileBridge();
mBridges.add(bridge); mBridges.add(bridge);
} }
stageDir = resolveStageDirLocked();
} }
try { try {
@@ -802,7 +798,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
if (!FileUtils.isValidExtFilename(name)) { if (!FileUtils.isValidExtFilename(name)) {
throw new IllegalArgumentException("Invalid name: " + 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); final FileDescriptor targetFd = Os.open(target.getAbsolutePath(), O_RDONLY, 0);
return new ParcelFileDescriptor(targetFd); return new ParcelFileDescriptor(targetFd);
} catch (ErrnoException e) { } 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 * This method may be called multiple times to update the status receiver validate caller
* permissions. * permissions.
*/ */
public boolean markAsCommitted( private boolean markAsCommitted(
@NonNull IntentSender statusReceiver, boolean forTransfer) { @NonNull IntentSender statusReceiver, boolean forTransfer) {
Preconditions.checkNotNull(statusReceiver); Preconditions.checkNotNull(statusReceiver);
@@ -959,10 +955,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
assertCallerIsOwnerOrRootLocked(); assertCallerIsOwnerOrRootLocked();
assertPreparedAndNotDestroyedLocked("commit"); assertPreparedAndNotDestroyedLocked("commit");
final PackageInstallObserverAdapter adapter = new PackageInstallObserverAdapter( mRemoteStatusReceiver = statusReceiver;
mContext, statusReceiver, sessionId,
isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId);
mRemoteObserver = adapter.getBinder();
if (forTransfer) { if (forTransfer) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES, null); mContext.enforceCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES, null);
@@ -986,12 +979,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
if (!mSealed) { if (!mSealed) {
try { try {
sealAndValidateLocked(childSessions); sealAndValidateLocked(childSessions);
} catch (IOException e) {
throw new IllegalArgumentException(e);
} catch (PackageManagerException 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; return false;
} }
} }
@@ -1091,7 +1079,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
*/ */
@GuardedBy("mLock") @GuardedBy("mLock")
private void sealAndValidateLocked(List<PackageInstallerSession> childSessions) private void sealAndValidateLocked(List<PackageInstallerSession> childSessions)
throws PackageManagerException, IOException { throws PackageManagerException {
try {
assertNoWriteFileTransfersOpenLocked(); assertNoWriteFileTransfersOpenLocked();
assertPreparedAndNotDestroyedLocked("sealing of session"); assertPreparedAndNotDestroyedLocked("sealing of session");
@@ -1122,8 +1111,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
params.appPackageName, PackageManager.GET_SIGNATURES params.appPackageName, PackageManager.GET_SIGNATURES
| PackageManager.MATCH_STATIC_SHARED_LIBRARIES /*flags*/, userId); | PackageManager.MATCH_STATIC_SHARED_LIBRARIES /*flags*/, userId);
resolveStageDirLocked();
try { try {
if ((params.installFlags & PackageManager.INSTALL_APEX) != 0) { if ((params.installFlags & PackageManager.INSTALL_APEX) != 0) {
validateApexInstallLocked(); validateApexInstallLocked();
@@ -1133,11 +1120,19 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
} catch (PackageManagerException e) { } catch (PackageManagerException e) {
throw e; throw e;
} catch (Throwable e) { } catch (Throwable e) {
// Convert all exceptions into package manager exceptions as only those are handled // Convert all exceptions into package manager exceptions as only those are
// in the code above // handled in the code above.
throw new PackageManagerException(e); 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) { synchronized (mLock) {
try { try {
sealAndValidateLocked(childSessions); sealAndValidateLocked(childSessions);
} catch (IOException e) {
throw new IllegalStateException(e);
} catch (PackageManagerException e) { } catch (PackageManagerException e) {
Slog.e(TAG, "Package not valid", 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 { try {
sealAndValidateLocked(childSessions); sealAndValidateLocked(childSessions);
} catch (IOException e) {
throw new IllegalStateException(e);
} catch (PackageManagerException 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); throw new IllegalArgumentException("Package is not valid", e);
} }
@@ -1299,11 +1281,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
} }
} }
if (!success) { if (!success) {
try { PackageInstallerService.sendOnPackageInstalled(mContext,
mRemoteObserver.onPackageInstalled( mRemoteStatusReceiver, sessionId,
null, failure.error, failure.getLocalizedMessage(), null); isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId, null,
} catch (RemoteException ignored) { failure.error, failure.getLocalizedMessage(), null);
}
return; return;
} }
mPm.installStage(activeChildSessions); mPm.installStage(activeChildSessions);
@@ -1347,10 +1328,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
final Intent intent = new Intent(PackageInstaller.ACTION_CONFIRM_INSTALL); final Intent intent = new Intent(PackageInstaller.ACTION_CONFIRM_INSTALL);
intent.setPackage(mPm.getPackageInstallerPackageName()); intent.setPackage(mPm.getPackageInstallerPackageName());
intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId); intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
try {
mRemoteObserver.onUserActionRequired(intent); PackageInstallerService.sendOnUserActionRequired(mContext,
} catch (RemoteException ignored) { mRemoteStatusReceiver, sessionId, intent);
}
// Commit was keeping session marked as active until now; release // Commit was keeping session marked as active until now; release
// that extra refcount so session appears idle. // that extra refcount so session appears idle.
@@ -1363,7 +1343,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
if (params.mode == SessionParams.MODE_INHERIT_EXISTING) { if (params.mode == SessionParams.MODE_INHERIT_EXISTING) {
try { try {
final List<File> fromFiles = mResolvedInheritedFiles; final List<File> fromFiles = mResolvedInheritedFiles;
final File toDir = resolveStageDirLocked(); final File toDir = stageDir;
if (LOGD) Slog.d(TAG, "Inherited files: " + mResolvedInheritedFiles); if (LOGD) Slog.d(TAG, "Inherited files: " + mResolvedInheritedFiles);
if (!mResolvedInheritedFiles.isEmpty() && mInheritedFilesBase == null) { if (!mResolvedInheritedFiles.isEmpty() && mInheritedFilesBase == null) {
@@ -1413,8 +1393,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
computeProgressLocked(true); computeProgressLocked(true);
// Unpack native libraries // Unpack native libraries
extractNativeLibraries(mResolvedStageDir, params.abiOverride, extractNativeLibraries(stageDir, params.abiOverride, mayInheritNativeLibs());
mayInheritNativeLibs());
} }
// We've reached point of no return; call into PMS to install the stage. // 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") @GuardedBy("mLock")
private void validateApexInstallLocked() private void validateApexInstallLocked()
throws PackageManagerException { throws PackageManagerException {
final File[] addedFiles = mResolvedStageDir.listFiles(sAddedFilter); final File[] addedFiles = getAddedFilesLocked();
if (ArrayUtils.isEmpty(addedFiles)) { if (ArrayUtils.isEmpty(addedFiles)) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "No packages staged"); 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"); "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 File addedFile = addedFiles[0]; // there is only one file
// Ensure file name has proper suffix // Ensure file name has proper suffix
@@ -1504,7 +1476,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
"Invalid filename: " + targetName); "Invalid filename: " + targetName);
} }
final File targetFile = new File(mResolvedStageDir, targetName); final File targetFile = new File(stageDir, targetName);
resolveAndStageFile(addedFile, targetFile); resolveAndStageFile(addedFile, targetFile);
mResolvedBaseFile = targetFile; mResolvedBaseFile = targetFile;
@@ -1545,25 +1517,18 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
&& params.mode == SessionParams.MODE_INHERIT_EXISTING && params.mode == SessionParams.MODE_INHERIT_EXISTING
&& VerityUtils.hasFsverity(pkgInfo.applicationInfo.getBaseCodePath()); && VerityUtils.hasFsverity(pkgInfo.applicationInfo.getBaseCodePath());
try { final File[] removedFiles = getRemovedFilesLocked();
resolveStageDirLocked();
} catch (IOException e) {
throw new PackageManagerException(INSTALL_FAILED_CONTAINER_ERROR,
"Failed to resolve stage location", e);
}
final File[] removedFiles = mResolvedStageDir.listFiles(sRemovedFilter);
final List<String> removeSplitList = new ArrayList<>(); final List<String> removeSplitList = new ArrayList<>();
if (!ArrayUtils.isEmpty(removedFiles)) { if (!ArrayUtils.isEmpty(removedFiles)) {
for (File removedFile : removedFiles) { for (File removedFile : removedFiles) {
final String fileName = removedFile.getName(); final String fileName = removedFile.getName();
final String splitName = fileName.substring( final String splitName = fileName.substring(
0, fileName.length() - REMOVE_SPLIT_MARKER_EXTENSION.length()); 0, fileName.length() - REMOVE_MARKER_EXTENSION.length());
removeSplitList.add(splitName); removeSplitList.add(splitName);
} }
} }
final File[] addedFiles = mResolvedStageDir.listFiles(sAddedFilter); final File[] addedFiles = getAddedFilesLocked();
if (ArrayUtils.isEmpty(addedFiles) && removeSplitList.size() == 0) { if (ArrayUtils.isEmpty(addedFiles) && removeSplitList.size() == 0) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "No packages staged"); throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "No packages staged");
} }
@@ -1607,7 +1572,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
"Invalid filename: " + targetName); "Invalid filename: " + targetName);
} }
final File targetFile = new File(mResolvedStageDir, targetName); final File targetFile = new File(stageDir, targetName);
resolveAndStageFile(addedFile, targetFile); resolveAndStageFile(addedFile, targetFile);
// Base is coming from session // Base is coming from session
@@ -1622,7 +1587,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
"Invalid filename: " + dexMetadataFile); "Invalid filename: " + dexMetadataFile);
} }
final File targetDexMetadataFile = new File(mResolvedStageDir, final File targetDexMetadataFile = new File(stageDir,
DexMetadataHelper.buildDexMetadataPathForApk(targetName)); DexMetadataHelper.buildDexMetadataPathForApk(targetName));
resolveAndStageFile(dexMetadataFile, targetDexMetadataFile); resolveAndStageFile(dexMetadataFile, targetDexMetadataFile);
} }
@@ -2182,17 +2147,17 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
} }
private void dispatchSessionFinished(int returnCode, String msg, Bundle extras) { private void dispatchSessionFinished(int returnCode, String msg, Bundle extras) {
final IPackageInstallObserver2 observer; final IntentSender statusReceiver;
final String packageName; final String packageName;
synchronized (mLock) { synchronized (mLock) {
mFinalStatus = returnCode; mFinalStatus = returnCode;
mFinalMessage = msg; mFinalMessage = msg;
observer = mRemoteObserver; statusReceiver = mRemoteStatusReceiver;
packageName = mPackageName; packageName = mPackageName;
} }
if (observer != null) { if (statusReceiver != null) {
// Execute observer.onPackageInstalled on different tread as we don't want callers // 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 // inside the system server have to worry about catching the callbacks while they are
// calling into the session // calling into the session
@@ -2200,7 +2165,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
args.arg1 = packageName; args.arg1 = packageName;
args.arg2 = msg; args.arg2 = msg;
args.arg3 = extras; args.arg3 = extras;
args.arg4 = observer; args.arg4 = statusReceiver;
args.argi1 = returnCode; args.argi1 = returnCode;
mHandler.obtainMessage(MSG_ON_PACKAGE_INSTALLED, args).sendToTarget(); mHandler.obtainMessage(MSG_ON_PACKAGE_INSTALLED, args).sendToTarget();