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.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) {
}
}
/**

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_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();