PackageManagerServicepublic class PackageManagerService extends IPackageManager.Stub Keep track of all those .apks everywhere.
This is very central to the platform's security; please run the unit
tests whenever making modifications here:
mmm frameworks/base/tests/AndroidTests
adb install -r -f out/target/product/passion/data/app/AndroidTests.apk
adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner
{@hide} |
Fields Summary |
---|
static final String | TAG | static final boolean | DEBUG_SETTINGS | static final boolean | DEBUG_PREFERRED | static final boolean | DEBUG_UPGRADE | private static final boolean | DEBUG_INSTALL | private static final boolean | DEBUG_REMOVE | private static final boolean | DEBUG_BROADCASTS | private static final boolean | DEBUG_SHOW_INFO | private static final boolean | DEBUG_PACKAGE_INFO | private static final boolean | DEBUG_INTENT_MATCHING | private static final boolean | DEBUG_PACKAGE_SCANNING | private static final boolean | DEBUG_VERIFY | private static final boolean | DEBUG_DEXOPT | private static final boolean | DEBUG_ABI_SELECTION | private static final int | RADIO_UID | private static final int | LOG_UID | private static final int | NFC_UID | private static final int | BLUETOOTH_UID | private static final int | SHELL_UID | private static final int | MAX_PERMISSION_TREE_FOOTPRINT | private static final String | INSTALL_PACKAGE_SUFFIX | static final int | SCAN_NO_DEX | static final int | SCAN_FORCE_DEX | static final int | SCAN_UPDATE_SIGNATURE | static final int | SCAN_NEW_INSTALL | static final int | SCAN_NO_PATHS | static final int | SCAN_UPDATE_TIME | static final int | SCAN_DEFER_DEX | static final int | SCAN_BOOTING | static final int | SCAN_TRUSTED_OVERLAY | static final int | SCAN_DELETE_DATA_ON_FAILURES | static final int | SCAN_REPLACING | static final int | REMOVE_CHATTY | private static final long | WATCHDOG_TIMEOUTTimeout (in milliseconds) after which the watchdog should declare that
our handler thread is wedged. The usual default for such things is one
minute but we sometimes do very lengthy I/O operations on this thread,
such as installing multi-gigabyte applications, so ours needs to be longer. | private static final long | DEFAULT_MANDATORY_FSTRIM_INTERVALWall-clock timeout (in milliseconds) after which we *require* that an fstrim
be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
settings entry if available, otherwise we use the hardcoded default. If it's been
more than this long since the last fstrim, we force one during the boot sequence.
This backstops other fstrim scheduling: if the device is alive at midnight+idle,
one gets run at the next available charging+idle time. This final mandatory
no-fstrim check kicks in only of the other scheduling criteria is never met. | private static final boolean | DEFAULT_VERIFY_ENABLEWhether verification is enabled by default. | private static final long | DEFAULT_VERIFICATION_TIMEOUTThe default maximum time to wait for the verification agent to return in
milliseconds. | private static final int | DEFAULT_VERIFICATION_RESPONSEThe default response for package verification timeout.
This can be either PackageManager.VERIFICATION_ALLOW or
PackageManager.VERIFICATION_REJECT. | static final String | DEFAULT_CONTAINER_PACKAGE | static final android.content.ComponentName | DEFAULT_CONTAINER_COMPONENT | private static final String | PACKAGE_MIME_TYPE | private static final String | VENDOR_OVERLAY_DIR | private static String | sPreferredInstructionSet | final com.android.server.ServiceThread | mHandlerThread | private static final String | IDMAP_PREFIX | private static final String | IDMAP_SUFFIX | final PackageHandler | mHandler | private ArrayList | mPostSystemReadyMessagesMessages for {@link #mHandler} that need to wait for system ready before
being dispatched. | final int | mSdkVersion | final android.content.Context | mContext | final boolean | mFactoryTest | final boolean | mOnlyCore | final boolean | mLazyDexOpt | final long | mDexOptLRUThresholdInMills | final android.util.DisplayMetrics | mMetrics | final int | mDefParseFlags | final String[] | mSeparateProcesses | final boolean | mIsUpgrade | final File | mAppDataDir | final File | mUserAppDataDir | final String | mAsecInternalPathThe location for ASEC container files on internal storage. | final Installer | mInstaller | final File | mAppInstallDirDirectory where installed third-party apps stored | private File | mAppLib32InstallDirDirectory to which applications installed internally have their
32 bit native libraries copied. | final File | mDrmAppPrivateInstallDir | final Object | mInstallLock | final android.util.ArrayMap | mPackages | final android.util.ArrayMap | mOverlays | final Settings | mSettings | boolean | mRestoredSettings | final int[] | mGlobalGids | final android.util.SparseArray | mSystemPermissions | final android.util.ArrayMap | mAvailableFeatures | boolean | mFoundPolicyFile | private boolean | mShouldRestoreconData | final android.util.ArrayMap | mSharedLibraries | final ActivityIntentResolver | mActivities | final ActivityIntentResolver | mReceivers | final ServiceIntentResolver | mServices | final ProviderIntentResolver | mProviders | final android.util.ArrayMap | mProvidersByAuthority | final android.util.ArrayMap | mInstrumentation | final android.util.ArrayMap | mPermissionGroups | final android.util.ArraySet | mTransferedPackages | final android.util.ArraySet | mProtectedBroadcasts | final android.util.SparseArray | mPendingVerificationList of packages waiting for verification. | final android.util.ArrayMap | mAppOpPermissionPackagesSet of packages associated with each app op permission. | final PackageInstallerService | mInstallerService | android.util.ArraySet | mDeferredDexOpt | android.util.SparseBooleanArray | mUserNeedsBadging | private int | mPendingVerificationTokenToken for keys in mPendingVerification. | volatile boolean | mSystemReady | volatile boolean | mSafeMode | volatile boolean | mHasSystemUidErrors | android.content.pm.ApplicationInfo | mAndroidApplication | final android.content.pm.ActivityInfo | mResolveActivity | final android.content.pm.ResolveInfo | mResolveInfo | android.content.ComponentName | mResolveComponentName | PackageParser.Package | mPlatformPackage | android.content.ComponentName | mCustomResolverComponentName | boolean | mResolverReplaced | final PendingPackageBroadcasts | mPendingBroadcasts | private com.android.internal.app.IMediaContainerService | mContainerService | static final int | SEND_PENDING_BROADCAST | static final int | MCS_BOUND | static final int | END_COPY | static final int | INIT_COPY | static final int | MCS_UNBIND | static final int | START_CLEANING_PACKAGE | static final int | FIND_INSTALL_LOC | static final int | POST_INSTALL | static final int | MCS_RECONNECT | static final int | MCS_GIVE_UP | static final int | UPDATED_MEDIA_STATUS | static final int | WRITE_SETTINGS | static final int | WRITE_PACKAGE_RESTRICTIONS | static final int | PACKAGE_VERIFIED | static final int | CHECK_PENDING_VERIFICATION | static final int | WRITE_SETTINGS_DELAY | static final int | BROADCAST_DELAY | static UserManagerService | sUserManager | private android.util.ArraySet | mDirtyUsers | private final DefaultContainerConnection | mDefContainerConn | final android.util.SparseArray | mRunningInstalls | int | mNextInstallToken | private final String | mRequiredVerifierPackage | private final PackageUsage | mPackageUsage | static final int | DEX_OPT_SKIPPED | static final int | DEX_OPT_PERFORMED | static final int | DEX_OPT_DEFERRED | static final int | DEX_OPT_FAILED | static final int | UPDATE_PERMISSIONS_ALL | static final int | UPDATE_PERMISSIONS_REPLACE_PKG | static final int | UPDATE_PERMISSIONS_REPLACE_ALL | private static final Comparator | mResolvePrioritySorter | private static final Comparator | mProviderInitOrderSorter | static final boolean | DEBUG_SD_INSTALL | private static final String | SD_ENCRYPTION_KEYSTORE_NAME | private static final String | SD_ENCRYPTION_ALGORITHM | private boolean | mMediaMounted |
Constructors Summary |
---|
public PackageManagerService(android.content.Context context, Installer installer, boolean factoryTest, boolean onlyCore)
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
SystemClock.uptimeMillis());
if (mSdkVersion <= 0) {
Slog.w(TAG, "**** ro.build.version.sdk not set!");
}
mContext = context;
mFactoryTest = factoryTest;
mOnlyCore = onlyCore;
mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
mMetrics = new DisplayMetrics();
mSettings = new Settings(context);
mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
// TODO: add a property to control this?
long dexOptLRUThresholdInMinutes;
if (mLazyDexOpt) {
dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds.
} else {
dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users.
}
mDexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000;
String separateProcesses = SystemProperties.get("debug.separate_processes");
if (separateProcesses != null && separateProcesses.length() > 0) {
if ("*".equals(separateProcesses)) {
mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
mSeparateProcesses = null;
Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
} else {
mDefParseFlags = 0;
mSeparateProcesses = separateProcesses.split(",");
Slog.w(TAG, "Running with debug.separate_processes: "
+ separateProcesses);
}
} else {
mDefParseFlags = 0;
mSeparateProcesses = null;
}
mInstaller = installer;
getDefaultDisplayMetrics(context, mMetrics);
SystemConfig systemConfig = SystemConfig.getInstance();
mGlobalGids = systemConfig.getGlobalGids();
mSystemPermissions = systemConfig.getSystemPermissions();
mAvailableFeatures = systemConfig.getAvailableFeatures();
synchronized (mInstallLock) {
// writer
synchronized (mPackages) {
mHandlerThread = new ServiceThread(TAG,
Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
mHandlerThread.start();
mHandler = new PackageHandler(mHandlerThread.getLooper());
Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
File dataDir = Environment.getDataDirectory();
mAppDataDir = new File(dataDir, "data");
mAppInstallDir = new File(dataDir, "app");
mAppLib32InstallDir = new File(dataDir, "app-lib");
mAsecInternalPath = new File(dataDir, "app-asec").getPath();
mUserAppDataDir = new File(dataDir, "user");
mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
sUserManager = new UserManagerService(context, this,
mInstallLock, mPackages);
// Propagate permission configuration in to package manager.
ArrayMap<String, SystemConfig.PermissionEntry> permConfig
= systemConfig.getPermissions();
for (int i=0; i<permConfig.size(); i++) {
SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
BasePermission bp = mSettings.mPermissions.get(perm.name);
if (bp == null) {
bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
mSettings.mPermissions.put(perm.name, bp);
}
if (perm.gids != null) {
bp.gids = appendInts(bp.gids, perm.gids);
}
}
ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
for (int i=0; i<libConfig.size(); i++) {
mSharedLibraries.put(libConfig.keyAt(i),
new SharedLibraryEntry(libConfig.valueAt(i), null));
}
mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false),
mSdkVersion, mOnlyCore);
String customResolverActivity = Resources.getSystem().getString(
R.string.config_customResolverActivity);
if (TextUtils.isEmpty(customResolverActivity)) {
customResolverActivity = null;
} else {
mCustomResolverComponentName = ComponentName.unflattenFromString(
customResolverActivity);
}
long startTime = SystemClock.uptimeMillis();
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
startTime);
// Set flag to monitor and not change apk file paths when
// scanning install directories.
final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;
final ArraySet<String> alreadyDexOpted = new ArraySet<String>();
/**
* Add everything in the in the boot class path to the
* list of process files because dexopt will have been run
* if necessary during zygote startup.
*/
final String bootClassPath = System.getenv("BOOTCLASSPATH");
final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
if (bootClassPath != null) {
String[] bootClassPathElements = splitString(bootClassPath, ':");
for (String element : bootClassPathElements) {
alreadyDexOpted.add(element);
}
} else {
Slog.w(TAG, "No BOOTCLASSPATH found!");
}
if (systemServerClassPath != null) {
String[] systemServerClassPathElements = splitString(systemServerClassPath, ':");
for (String element : systemServerClassPathElements) {
alreadyDexOpted.add(element);
}
} else {
Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
}
final List<String> allInstructionSets = getAllInstructionSets();
final String[] dexCodeInstructionSets =
getDexCodeInstructionSets(allInstructionSets.toArray(new String[allInstructionSets.size()]));
/**
* Ensure all external libraries have had dexopt run on them.
*/
if (mSharedLibraries.size() > 0) {
// NOTE: For now, we're compiling these system "shared libraries"
// (and framework jars) into all available architectures. It's possible
// to compile them only when we come across an app that uses them (there's
// already logic for that in scanPackageLI) but that adds some complexity.
for (String dexCodeInstructionSet : dexCodeInstructionSets) {
for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
final String lib = libEntry.path;
if (lib == null) {
continue;
}
try {
byte dexoptRequired = DexFile.isDexOptNeededInternal(lib, null,
dexCodeInstructionSet,
false);
if (dexoptRequired != DexFile.UP_TO_DATE) {
alreadyDexOpted.add(lib);
// The list of "shared libraries" we have at this point is
if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
} else {
mInstaller.patchoat(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
}
}
} catch (FileNotFoundException e) {
Slog.w(TAG, "Library not found: " + lib);
} catch (IOException e) {
Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
+ e.getMessage());
}
}
}
}
File frameworkDir = new File(Environment.getRootDirectory(), "framework");
// Gross hack for now: we know this file doesn't contain any
// code, so don't dexopt it to avoid the resulting log spew.
alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk");
// Gross hack for now: we know this file is only part of
// the boot class path for art, so don't dexopt it to
// avoid the resulting log spew.
alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar");
/**
* And there are a number of commands implemented in Java, which
* we currently need to do the dexopt on so that they can be
* run from a non-root shell.
*/
String[] frameworkFiles = frameworkDir.list();
if (frameworkFiles != null) {
// TODO: We could compile these only for the most preferred ABI. We should
// first double check that the dex files for these commands are not referenced
// by other system apps.
for (String dexCodeInstructionSet : dexCodeInstructionSets) {
for (int i=0; i<frameworkFiles.length; i++) {
File libPath = new File(frameworkDir, frameworkFiles[i]);
String path = libPath.getPath();
// Skip the file if we already did it.
if (alreadyDexOpted.contains(path)) {
continue;
}
// Skip the file if it is not a type we want to dexopt.
if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
continue;
}
try {
byte dexoptRequired = DexFile.isDexOptNeededInternal(path, null,
dexCodeInstructionSet,
false);
if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
} else if (dexoptRequired == DexFile.PATCHOAT_NEEDED) {
mInstaller.patchoat(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
}
} catch (FileNotFoundException e) {
Slog.w(TAG, "Jar not found: " + path);
} catch (IOException e) {
Slog.w(TAG, "Exception reading jar: " + path, e);
}
}
}
}
// Collect vendor overlay packages.
// (Do this before scanning any apps.)
// For security and version matching reason, only consider
// overlay packages if they reside in VENDOR_OVERLAY_DIR.
File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
// Find base frameworks (resource packages without code).
scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_IS_PRIVILEGED,
scanFlags | SCAN_NO_DEX, 0);
// Collected privileged system packages.
final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
// Collect ordinary system packages.
final File systemAppDir = new File(Environment.getRootDirectory(), "app");
scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
// Collect all vendor packages.
File vendorAppDir = new File("/vendor/app");
try {
vendorAppDir = vendorAppDir.getCanonicalFile();
} catch (IOException e) {
// failed to look up canonical path, continue with original one
}
scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
// Collect all OEM packages.
final File oemAppDir = new File(Environment.getOemDirectory(), "app");
scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
mInstaller.moveFiles();
// Prune any system packages that no longer exist.
final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
final ArrayMap<String, File> expectingBetter = new ArrayMap<>();
if (!mOnlyCore) {
Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
while (psit.hasNext()) {
PackageSetting ps = psit.next();
/*
* If this is not a system app, it can't be a
* disable system app.
*/
if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
continue;
}
/*
* If the package is scanned, it's not erased.
*/
final PackageParser.Package scannedPkg = mPackages.get(ps.name);
if (scannedPkg != null) {
/*
* If the system app is both scanned and in the
* disabled packages list, then it must have been
* added via OTA. Remove it from the currently
* scanned package so the previously user-installed
* application can be scanned.
*/
if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
logCriticalInfo(Log.WARN, "Expecting better updated system app for "
+ ps.name + "; removing system app. Last known codePath="
+ ps.codePathString + ", installStatus=" + ps.installStatus
+ ", versionCode=" + ps.versionCode + "; scanned versionCode="
+ scannedPkg.mVersionCode);
removePackageLI(ps, true);
expectingBetter.put(ps.name, ps.codePath);
}
continue;
}
if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
psit.remove();
logCriticalInfo(Log.WARN, "System package " + ps.name
+ " no longer exists; wiping its data");
removeDataDirsLI(ps.name);
} else {
final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
possiblyDeletedUpdatedSystemApps.add(ps.name);
}
}
}
}
//look for any incomplete package installations
ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
//clean up list
for(int i = 0; i < deletePkgsList.size(); i++) {
//clean up here
cleanupInstallFailedPackage(deletePkgsList.get(i));
}
//delete tmp files
deleteTempPackageFiles();
// Remove any shared userIDs that have no associated packages
mSettings.pruneSharedUsersLPw();
if (!mOnlyCore) {
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
SystemClock.uptimeMillis());
scanDirLI(mAppInstallDir, 0, scanFlags, 0);
scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
scanFlags, 0);
/**
* Remove disable package settings for any updated system
* apps that were removed via an OTA. If they're not a
* previously-updated app, remove them completely.
* Otherwise, just revoke their system-level permissions.
*/
for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
mSettings.removeDisabledSystemPackageLPw(deletedAppName);
String msg;
if (deletedPkg == null) {
msg = "Updated system package " + deletedAppName
+ " no longer exists; wiping its data";
removeDataDirsLI(deletedAppName);
} else {
msg = "Updated system app + " + deletedAppName
+ " no longer present; removing system privileges for "
+ deletedAppName;
deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
}
logCriticalInfo(Log.WARN, msg);
}
/**
* Make sure all system apps that we expected to appear on
* the userdata partition actually showed up. If they never
* appeared, crawl back and revive the system version.
*/
for (int i = 0; i < expectingBetter.size(); i++) {
final String packageName = expectingBetter.keyAt(i);
if (!mPackages.containsKey(packageName)) {
final File scanFile = expectingBetter.valueAt(i);
logCriticalInfo(Log.WARN, "Expected better " + packageName
+ " but never showed up; reverting to system");
final int reparseFlags;
if (FileUtils.contains(privilegedAppDir, scanFile)) {
reparseFlags = PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_IS_PRIVILEGED;
} else if (FileUtils.contains(systemAppDir, scanFile)) {
reparseFlags = PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR;
} else if (FileUtils.contains(vendorAppDir, scanFile)) {
reparseFlags = PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR;
} else if (FileUtils.contains(oemAppDir, scanFile)) {
reparseFlags = PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR;
} else {
Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
continue;
}
mSettings.enableSystemPackageLPw(packageName);
try {
scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null);
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to parse original system package: "
+ e.getMessage());
}
}
}
}
// Now that we know all of the shared libraries, update all clients to have
// the correct library paths.
updateAllSharedLibrariesLPw();
for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
// NOTE: We ignore potential failures here during a system scan (like
// the rest of the commands above) because there's precious little we
// can do about it. A settings error is reported, though.
adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
false /* force dexopt */, false /* defer dexopt */);
}
// Now that we know all the packages we are keeping,
// read and update their last usage times.
mPackageUsage.readLP();
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
SystemClock.uptimeMillis());
Slog.i(TAG, "Time to scan packages: "
+ ((SystemClock.uptimeMillis()-startTime)/1000f)
+ " seconds");
// If the platform SDK has changed since the last time we booted,
// we need to re-grant app permission to catch any new ones that
// appear. This is really a hack, and means that apps can in some
// cases get permissions that the user didn't initially explicitly
// allow... it would be nice to have some better way to handle
// this situation.
final boolean regrantPermissions = mSettings.mInternalSdkPlatform
!= mSdkVersion;
if (regrantPermissions) Slog.i(TAG, "Platform changed from "
+ mSettings.mInternalSdkPlatform + " to " + mSdkVersion
+ "; regranting permissions for internal storage");
mSettings.mInternalSdkPlatform = mSdkVersion;
updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
| (regrantPermissions
? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
: 0));
// If this is the first boot, and it is a normal boot, then
// we need to initialize the default preferred apps.
if (!mRestoredSettings && !onlyCore) {
mSettings.readDefaultPreferredAppsLPw(this, 0);
}
// If this is first boot after an OTA, and a normal boot, then
// we need to clear code cache directories.
mIsUpgrade = !Build.FINGERPRINT.equals(mSettings.mFingerprint);
if (mIsUpgrade && !onlyCore) {
Slog.i(TAG, "Build fingerprint changed; clearing code caches");
for (String pkgName : mSettings.mPackages.keySet()) {
deleteCodeCacheDirsLI(pkgName);
}
mSettings.mFingerprint = Build.FINGERPRINT;
}
// All the changes are done during package scanning.
mSettings.updateInternalDatabaseVersion();
// can downgrade to reader
mSettings.writeLPr();
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
SystemClock.uptimeMillis());
mRequiredVerifierPackage = getRequiredVerifierLPr();
} // synchronized (mPackages)
} // synchronized (mInstallLock)
mInstallerService = new PackageInstallerService(context, this, mAppInstallDir);
// Now after opening every single application zip, make sure they
// are all flushed. Not really needed, but keeps things nice and
// tidy.
Runtime.getRuntime().gc();
|
Methods Summary |
---|
public boolean | activitySupportsIntent(android.content.ComponentName component, android.content.Intent intent, java.lang.String resolvedType)
synchronized (mPackages) {
PackageParser.Activity a = mActivities.mActivities.get(component);
if (a == null) {
return false;
}
for (int i=0; i<a.intents.size(); i++) {
if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
intent.getData(), intent.getCategories(), TAG) >= 0) {
return true;
}
}
return false;
}
| public void | addCrossProfileIntentFilter(android.content.IntentFilter intentFilter, java.lang.String ownerPackage, int ownerUserId, int sourceUserId, int targetUserId, int flags)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
int callingUid = Binder.getCallingUid();
enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
if (intentFilter.countActions() == 0) {
Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
return;
}
synchronized (mPackages) {
CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
ownerPackage, UserHandle.getUserId(callingUid), targetUserId, flags);
CrossProfileIntentResolver resolver =
mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
// We have all those whose filter is equal. Now checking if the rest is equal as well.
if (existing != null) {
int size = existing.size();
for (int i = 0; i < size; i++) {
if (newFilter.equalsIgnoreFilter(existing.get(i))) {
return;
}
}
}
resolver.addFilter(newFilter);
scheduleWritePackageRestrictionsLocked(sourceUserId);
}
| private void | addPackageHoldingPermissions(java.util.ArrayList list, PackageSetting ps, java.lang.String[] permissions, boolean[] tmp, int flags, int userId)
int numMatch = 0;
final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
for (int i=0; i<permissions.length; i++) {
if (gp.grantedPermissions.contains(permissions[i])) {
tmp[i] = true;
numMatch++;
} else {
tmp[i] = false;
}
}
if (numMatch == 0) {
return;
}
PackageInfo pi;
if (ps.pkg != null) {
pi = generatePackageInfo(ps.pkg, flags, userId);
} else {
pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
}
// The above might return null in cases of uninstalled apps or install-state
// skew across users/profiles.
if (pi != null) {
if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
if (numMatch == permissions.length) {
pi.requestedPermissions = permissions;
} else {
pi.requestedPermissions = new String[numMatch];
numMatch = 0;
for (int i=0; i<permissions.length; i++) {
if (tmp[i]) {
pi.requestedPermissions[numMatch] = permissions[i];
numMatch++;
}
}
}
}
list.add(pi);
}
| public void | addPackageToPreferred(java.lang.String packageName)
Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
| public boolean | addPermission(android.content.pm.PermissionInfo info)
synchronized (mPackages) {
return addPermissionLocked(info, false);
}
| public boolean | addPermissionAsync(android.content.pm.PermissionInfo info)
synchronized (mPackages) {
return addPermissionLocked(info, true);
}
| boolean | addPermissionLocked(android.content.pm.PermissionInfo info, boolean async)
if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
throw new SecurityException("Label must be specified in permission");
}
BasePermission tree = checkPermissionTreeLP(info.name);
BasePermission bp = mSettings.mPermissions.get(info.name);
boolean added = bp == null;
boolean changed = true;
int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
if (added) {
enforcePermissionCapLocked(info, tree);
bp = new BasePermission(info.name, tree.sourcePackage,
BasePermission.TYPE_DYNAMIC);
} else if (bp.type != BasePermission.TYPE_DYNAMIC) {
throw new SecurityException(
"Not allowed to modify non-dynamic permission "
+ info.name);
} else {
if (bp.protectionLevel == fixedLevel
&& bp.perm.owner.equals(tree.perm.owner)
&& bp.uid == tree.uid
&& comparePermissionInfos(bp.perm.info, info)) {
changed = false;
}
}
bp.protectionLevel = fixedLevel;
info = new PermissionInfo(info);
info.protectionLevel = fixedLevel;
bp.perm = new PackageParser.Permission(tree.perm.owner, info);
bp.perm.info.packageName = tree.perm.info.packageName;
bp.uid = tree.uid;
if (added) {
mSettings.mPermissions.put(info.name, bp);
}
if (changed) {
if (!async) {
mSettings.writeLPr();
} else {
scheduleWriteSettingsLocked();
}
}
return added;
| public void | addPersistentPreferredActivity(android.content.IntentFilter filter, android.content.ComponentName activity, int userId)
int callingUid = Binder.getCallingUid();
if (callingUid != Process.SYSTEM_UID) {
throw new SecurityException(
"addPersistentPreferredActivity can only be run by the system");
}
if (filter.countActions() == 0) {
Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
return;
}
synchronized (mPackages) {
Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
" :");
filter.dump(new LogPrinter(Log.INFO, TAG), " ");
mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
new PersistentPreferredActivity(filter, activity));
scheduleWritePackageRestrictionsLocked(userId);
}
| public void | addPreferredActivity(android.content.IntentFilter filter, int match, android.content.ComponentName[] set, android.content.ComponentName activity, int userId)
addPreferredActivityInternal(filter, match, set, activity, true, userId,
"Adding preferred");
| private void | addPreferredActivityInternal(android.content.IntentFilter filter, int match, android.content.ComponentName[] set, android.content.ComponentName activity, boolean always, int userId, java.lang.String opname)
// writer
int callingUid = Binder.getCallingUid();
enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity");
if (filter.countActions() == 0) {
Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
return;
}
synchronized (mPackages) {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
!= PackageManager.PERMISSION_GRANTED) {
if (getUidTargetSdkVersionLockedLPr(callingUid)
< Build.VERSION_CODES.FROYO) {
Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
+ callingUid);
return;
}
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
}
PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
+ userId + ":");
filter.dump(new LogPrinter(Log.INFO, TAG), " ");
pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
scheduleWritePackageRestrictionsLocked(userId);
}
| private void | addSharedLibraryLPw(android.util.ArraySet usesLibraryFiles, com.android.server.pm.PackageManagerService$SharedLibraryEntry file, PackageParser.Package changingLib)
if (file.path != null) {
usesLibraryFiles.add(file.path);
return;
}
PackageParser.Package p = mPackages.get(file.apk);
if (changingLib != null && changingLib.packageName.equals(file.apk)) {
// If we are doing this while in the middle of updating a library apk,
// then we need to make sure to use that new apk for determining the
// dependencies here. (We haven't yet finished committing the new apk
// to the package manager state.)
if (p == null || p.packageName.equals(changingLib.packageName)) {
p = changingLib;
}
}
if (p != null) {
usesLibraryFiles.addAll(p.getAllCodePaths());
}
| private void | adjustCpuAbisForSharedUserLPw(java.util.Set packagesForUser, PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt)Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
i.e, so that all packages can be run inside a single process if required.
Optionally, callers can pass in a parsed package via {@code newPackage} in which case
this function will either try and make the ABI for all packages in {@code packagesForUser}
match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
the ABI selected for {@code packagesForUser}. This variant is used when installing or
updating a package that belongs to a shared user.
NOTE: We currently only match for the primary CPU abi string. Matching the secondary
adds unnecessary complexity.
String requiredInstructionSet = null;
if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
requiredInstructionSet = VMRuntime.getInstructionSet(
scannedPackage.applicationInfo.primaryCpuAbi);
}
PackageSetting requirer = null;
for (PackageSetting ps : packagesForUser) {
// If packagesForUser contains scannedPackage, we skip it. This will happen
// when scannedPackage is an update of an existing package. Without this check,
// we will never be able to change the ABI of any package belonging to a shared
// user, even if it's compatible with other packages.
if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
if (ps.primaryCpuAbiString == null) {
continue;
}
final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
// We have a mismatch between instruction sets (say arm vs arm64) warn about
// this but there's not much we can do.
String errorMessage = "Instruction set mismatch, "
+ ((requirer == null) ? "[caller]" : requirer)
+ " requires " + requiredInstructionSet + " whereas " + ps
+ " requires " + instructionSet;
Slog.w(TAG, errorMessage);
}
if (requiredInstructionSet == null) {
requiredInstructionSet = instructionSet;
requirer = ps;
}
}
}
if (requiredInstructionSet != null) {
String adjustedAbi;
if (requirer != null) {
// requirer != null implies that either scannedPackage was null or that scannedPackage
// did not require an ABI, in which case we have to adjust scannedPackage to match
// the ABI of the set (which is the same as requirer's ABI)
adjustedAbi = requirer.primaryCpuAbiString;
if (scannedPackage != null) {
scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
}
} else {
// requirer == null implies that we're updating all ABIs in the set to
// match scannedPackage.
adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi;
}
for (PackageSetting ps : packagesForUser) {
if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
if (ps.primaryCpuAbiString != null) {
continue;
}
ps.primaryCpuAbiString = adjustedAbi;
if (ps.pkg != null && ps.pkg.applicationInfo != null) {
ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi);
if (performDexOptLI(ps.pkg, null /* instruction sets */, forceDexOpt,
deferDexOpt, true) == DEX_OPT_FAILED) {
ps.primaryCpuAbiString = null;
ps.pkg.applicationInfo.primaryCpuAbi = null;
return;
} else {
mInstaller.rmdex(ps.codePathString,
getDexCodeInstructionSet(getPreferredInstructionSet()));
}
}
}
}
}
| static int[] | appendInts(int[] cur, int[] add)
if (add == null) return cur;
if (cur == null) return add;
final int N = add.length;
for (int i=0; i<N; i++) {
cur = appendInt(cur, add[i]);
}
return cur;
| static java.lang.String | arrayToString(int[] array)
StringBuffer buf = new StringBuffer(128);
buf.append('[");
if (array != null) {
for (int i=0; i<array.length; i++) {
if (i > 0) buf.append(", ");
buf.append(array[i]);
}
}
buf.append(']");
return buf.toString();
| private void | broadcastPackageVerified(int verificationId, android.net.Uri packageUri, int verificationCode, android.os.UserHandle user)
final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
mContext.sendBroadcastAsUser(intent, user,
android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
| private static java.lang.String | calculateBundledApkRoot(java.lang.String codePathString)
final File codePath = new File(codePathString);
final File codeRoot;
if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
codeRoot = Environment.getRootDirectory();
} else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
codeRoot = Environment.getOemDirectory();
} else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
codeRoot = Environment.getVendorDirectory();
} else {
// Unrecognized code path; take its top real segment as the apk root:
// e.g. /something/app/blah.apk => /something
try {
File f = codePath.getCanonicalFile();
File parent = f.getParentFile(); // non-null because codePath is a file
File tmp;
while ((tmp = parent.getParentFile()) != null) {
f = parent;
parent = tmp;
}
codeRoot = f;
Slog.w(TAG, "Unrecognized code path "
+ codePath + " - using " + codeRoot);
} catch (IOException e) {
// Can't canonicalize the code path -- shenanigans?
Slog.w(TAG, "Can't canonicalize code path " + codePath);
return Environment.getRootDirectory().getPath();
}
}
return codeRoot.getPath();
| int | calculateCurrentPermissionFootprintLocked(BasePermission tree)
int size = 0;
for (BasePermission perm : mSettings.mPermissions.values()) {
if (perm.uid == tree.uid) {
size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
}
}
return size;
| private static long | calculateDirectorySize(com.android.internal.app.IMediaContainerService mcs, java.io.File[] paths)
long result = 0;
for (File path : paths) {
result += mcs.calculateDirectorySize(path.getAbsolutePath());
}
return result;
| public boolean | canForwardTo(android.content.Intent intent, java.lang.String resolvedType, int sourceUserId, int targetUserId)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
List<CrossProfileIntentFilter> matches =
getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
if (matches != null) {
int size = matches.size();
for (int i = 0; i < size; i++) {
if (matches.get(i).getTargetUserId() == targetUserId) return true;
}
}
return false;
| public java.lang.String[] | canonicalToCurrentPackageNames(java.lang.String[] names)
String[] out = new String[names.length];
// reader
synchronized (mPackages) {
for (int i=names.length-1; i>=0; i--) {
String cur = mSettings.mRenamedPackages.get(names[i]);
out[i] = cur != null ? cur : names[i];
}
}
return out;
| private static void | checkDowngrade(PackageParser.Package before, android.content.pm.PackageInfoLite after)Check and throw if the given before/after packages would be considered a
downgrade.
if (after.versionCode < before.mVersionCode) {
throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
"Update version code " + after.versionCode + " is older than current "
+ before.mVersionCode);
} else if (after.versionCode == before.mVersionCode) {
if (after.baseRevisionCode < before.baseRevisionCode) {
throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
"Update base revision code " + after.baseRevisionCode
+ " is older than current " + before.baseRevisionCode);
}
if (!ArrayUtils.isEmpty(after.splitNames)) {
for (int i = 0; i < after.splitNames.length; i++) {
final String splitName = after.splitNames[i];
final int j = ArrayUtils.indexOf(before.splitNames, splitName);
if (j != -1) {
if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
"Update split " + splitName + " revision code "
+ after.splitRevisionCodes[i] + " is older than current "
+ before.splitRevisionCodes[j]);
}
}
}
}
}
| private static void | checkGrantRevokePermissions(PackageParser.Package pkg, BasePermission bp)
int index = pkg.requestedPermissions.indexOf(bp.name);
if (index == -1) {
throw new SecurityException("Package " + pkg.packageName
+ " has not requested permission " + bp.name);
}
boolean isNormal =
((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
== PermissionInfo.PROTECTION_NORMAL);
boolean isDangerous =
((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
== PermissionInfo.PROTECTION_DANGEROUS);
boolean isDevelopment =
((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0);
if (!isNormal && !isDangerous && !isDevelopment) {
throw new SecurityException("Permission " + bp.name
+ " is not a changeable permission type");
}
if (isNormal || isDangerous) {
if (pkg.requestedPermissionsRequired.get(index)) {
throw new SecurityException("Can't change " + bp.name
+ ". It is required by the application");
}
}
| public int | checkPermission(java.lang.String permName, java.lang.String pkgName)
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(pkgName);
if (p != null && p.mExtras != null) {
PackageSetting ps = (PackageSetting)p.mExtras;
if (ps.sharedUser != null) {
if (ps.sharedUser.grantedPermissions.contains(permName)) {
return PackageManager.PERMISSION_GRANTED;
}
} else if (ps.grantedPermissions.contains(permName)) {
return PackageManager.PERMISSION_GRANTED;
}
}
}
return PackageManager.PERMISSION_DENIED;
| private BasePermission | checkPermissionTreeLP(java.lang.String permName)
if (permName != null) {
BasePermission bp = findPermissionTreeLP(permName);
if (bp != null) {
if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
return bp;
}
throw new SecurityException("Calling uid "
+ Binder.getCallingUid()
+ " is not allowed to add to permission tree "
+ bp.name + " owned by uid " + bp.uid);
}
}
throw new SecurityException("No permission tree found for " + permName);
| public int | checkSignatures(java.lang.String pkg1, java.lang.String pkg2)
synchronized (mPackages) {
final PackageParser.Package p1 = mPackages.get(pkg1);
final PackageParser.Package p2 = mPackages.get(pkg2);
if (p1 == null || p1.mExtras == null
|| p2 == null || p2.mExtras == null) {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
return compareSignatures(p1.mSignatures, p2.mSignatures);
}
| private android.content.pm.ResolveInfo | checkTargetCanHandle(CrossProfileIntentFilter filter, android.content.Intent intent, java.lang.String resolvedType, int flags, int sourceUserId)
List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
resolvedType, flags, filter.getTargetUserId());
if (resultTargetUser != null && !resultTargetUser.isEmpty()) {
return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId());
}
return null;
| public int | checkUidPermission(java.lang.String permName, int uid)
synchronized (mPackages) {
Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
if (obj != null) {
GrantedPermissions gp = (GrantedPermissions)obj;
if (gp.grantedPermissions.contains(permName)) {
return PackageManager.PERMISSION_GRANTED;
}
} else {
ArraySet<String> perms = mSystemPermissions.get(uid);
if (perms != null && perms.contains(permName)) {
return PackageManager.PERMISSION_GRANTED;
}
}
}
return PackageManager.PERMISSION_DENIED;
| public int | checkUidSignatures(int uid1, int uid2)
// Map to base uids.
uid1 = UserHandle.getAppId(uid1);
uid2 = UserHandle.getAppId(uid2);
// reader
synchronized (mPackages) {
Signature[] s1;
Signature[] s2;
Object obj = mSettings.getUserIdLPr(uid1);
if (obj != null) {
if (obj instanceof SharedUserSetting) {
s1 = ((SharedUserSetting)obj).signatures.mSignatures;
} else if (obj instanceof PackageSetting) {
s1 = ((PackageSetting)obj).signatures.mSignatures;
} else {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
} else {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
obj = mSettings.getUserIdLPr(uid2);
if (obj != null) {
if (obj instanceof SharedUserSetting) {
s2 = ((SharedUserSetting)obj).signatures.mSignatures;
} else if (obj instanceof PackageSetting) {
s2 = ((PackageSetting)obj).signatures.mSignatures;
} else {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
} else {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
return compareSignatures(s1, s2);
}
| private boolean | checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg)
// Upgrade keysets are being used. Determine if new package has a superset of the
// required keys.
long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
KeySetManagerService ksms = mSettings.mKeySetManagerService;
for (int i = 0; i < upgradeKeySets.length; i++) {
Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
if (newPkg.mSigningKeys.containsAll(upgradeSet)) {
return true;
}
}
return false;
| private void | checkValidCaller(int uid, int userId)
if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0)
return;
throw new SecurityException("Caller uid=" + uid
+ " is not privileged to communicate with user=" + userId);
| private android.content.pm.ResolveInfo | chooseBestActivity(android.content.Intent intent, java.lang.String resolvedType, int flags, java.util.List query, int userId)
if (query != null) {
final int N = query.size();
if (N == 1) {
return query.get(0);
} else if (N > 1) {
final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
// If there is more than one activity with the same priority,
// then let the user decide between them.
ResolveInfo r0 = query.get(0);
ResolveInfo r1 = query.get(1);
if (DEBUG_INTENT_MATCHING || debug) {
Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
+ r1.activityInfo.name + "=" + r1.priority);
}
// If the first activity has a higher priority, or a different
// default, then it is always desireable to pick it.
if (r0.priority != r1.priority
|| r0.preferredOrder != r1.preferredOrder
|| r0.isDefault != r1.isDefault) {
return query.get(0);
}
// If we have saved a preference for a preferred activity for
// this Intent, use that.
ResolveInfo ri = findPreferredActivity(intent, resolvedType,
flags, query, r0.priority, true, false, debug, userId);
if (ri != null) {
return ri;
}
if (userId != 0) {
ri = new ResolveInfo(mResolveInfo);
ri.activityInfo = new ActivityInfo(ri.activityInfo);
ri.activityInfo.applicationInfo = new ApplicationInfo(
ri.activityInfo.applicationInfo);
ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
return ri;
}
return mResolveInfo;
}
}
return null;
| static java.lang.String | cidFromCodePath(java.lang.String fullCodePath)Extract the MountService "container ID" from the full code path of an
.apk.
int eidx = fullCodePath.lastIndexOf("/");
String subStr1 = fullCodePath.substring(0, eidx);
int sidx = subStr1.lastIndexOf("/");
return subStr1.substring(sidx+1, eidx);
| void | cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty)
int N = pkg.providers.size();
StringBuilder r = null;
int i;
for (i=0; i<N; i++) {
PackageParser.Provider p = pkg.providers.get(i);
mProviders.removeProvider(p);
if (p.info.authority == null) {
/* There was another ContentProvider with this authority when
* this app was installed so this authority is null,
* Ignore it as we don't have to unregister the provider.
*/
continue;
}
String names[] = p.info.authority.split(";");
for (int j = 0; j < names.length; j++) {
if (mProvidersByAuthority.get(names[j]) == p) {
mProvidersByAuthority.remove(names[j]);
if (DEBUG_REMOVE) {
if (chatty)
Log.d(TAG, "Unregistered content provider: " + names[j]
+ ", className = " + p.info.name + ", isSyncable = "
+ p.info.isSyncable);
}
}
}
if (DEBUG_REMOVE && chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append(p.info.name);
}
}
if (r != null) {
if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r);
}
N = pkg.services.size();
r = null;
for (i=0; i<N; i++) {
PackageParser.Service s = pkg.services.get(i);
mServices.removeService(s);
if (chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append(s.info.name);
}
}
if (r != null) {
if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r);
}
N = pkg.receivers.size();
r = null;
for (i=0; i<N; i++) {
PackageParser.Activity a = pkg.receivers.get(i);
mReceivers.removeActivity(a, "receiver");
if (DEBUG_REMOVE && chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append(a.info.name);
}
}
if (r != null) {
if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r);
}
N = pkg.activities.size();
r = null;
for (i=0; i<N; i++) {
PackageParser.Activity a = pkg.activities.get(i);
mActivities.removeActivity(a, "activity");
if (DEBUG_REMOVE && chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append(a.info.name);
}
}
if (r != null) {
if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r);
}
N = pkg.permissions.size();
r = null;
for (i=0; i<N; i++) {
PackageParser.Permission p = pkg.permissions.get(i);
BasePermission bp = mSettings.mPermissions.get(p.info.name);
if (bp == null) {
bp = mSettings.mPermissionTrees.get(p.info.name);
}
if (bp != null && bp.perm == p) {
bp.perm = null;
if (DEBUG_REMOVE && chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append(p.info.name);
}
}
if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name);
if (appOpPerms != null) {
appOpPerms.remove(pkg.packageName);
}
}
}
if (r != null) {
if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
}
N = pkg.requestedPermissions.size();
r = null;
for (i=0; i<N; i++) {
String perm = pkg.requestedPermissions.get(i);
BasePermission bp = mSettings.mPermissions.get(perm);
if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm);
if (appOpPerms != null) {
appOpPerms.remove(pkg.packageName);
if (appOpPerms.isEmpty()) {
mAppOpPermissionPackages.remove(perm);
}
}
}
}
if (r != null) {
if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
}
N = pkg.instrumentation.size();
r = null;
for (i=0; i<N; i++) {
PackageParser.Instrumentation a = pkg.instrumentation.get(i);
mInstrumentation.remove(a.getComponentName());
if (DEBUG_REMOVE && chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append(a.info.name);
}
}
if (r != null) {
if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r);
}
r = null;
if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
// Only system apps can hold shared libraries.
if (pkg.libraryNames != null) {
for (i=0; i<pkg.libraryNames.size(); i++) {
String name = pkg.libraryNames.get(i);
SharedLibraryEntry cur = mSharedLibraries.get(name);
if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
mSharedLibraries.remove(name);
if (DEBUG_REMOVE && chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append(name);
}
}
}
}
}
if (r != null) {
if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r);
}
| void | cleanUpUserLILPw(UserManagerService userManager, int userHandle)Called by UserManagerService
mDirtyUsers.remove(userHandle);
mSettings.removeUserLPw(userHandle);
mPendingBroadcasts.remove(userHandle);
if (mInstaller != null) {
// Technically, we shouldn't be doing this with the package lock
// held. However, this is very rare, and there is already so much
// other disk I/O going on, that we'll let it slide for now.
mInstaller.removeUserDataDirs(userHandle);
}
mUserNeedsBadging.delete(userHandle);
removeUnusedPackagesLILPw(userManager, userHandle);
| void | cleanupInstallFailedPackage(PackageSetting ps)
logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name);
removeDataDirsLI(ps.name);
if (ps.codePath != null) {
if (ps.codePath.isDirectory()) {
FileUtils.deleteContents(ps.codePath);
}
ps.codePath.delete();
}
if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) {
if (ps.resourcePath.isDirectory()) {
FileUtils.deleteContents(ps.resourcePath);
}
ps.resourcePath.delete();
}
mSettings.removePackageLPw(ps.name);
| public void | clearApplicationUserData(java.lang.String packageName, android.content.pm.IPackageDataObserver observer, int userId)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CLEAR_APP_USER_DATA, null);
enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data");
// Queue up an async operation since the package deletion may take a little while.
mHandler.post(new Runnable() {
public void run() {
mHandler.removeCallbacks(this);
final boolean succeeded;
synchronized (mInstallLock) {
succeeded = clearApplicationUserDataLI(packageName, userId);
}
clearExternalStorageDataSync(packageName, userId, true);
if (succeeded) {
// invoke DeviceStorageMonitor's update method to clear any notifications
DeviceStorageMonitorInternal
dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
if (dsm != null) {
dsm.checkMemory();
}
}
if(observer != null) {
try {
observer.onRemoveCompleted(packageName, succeeded);
} catch (RemoteException e) {
Log.i(TAG, "Observer no longer exists.");
}
} //end if observer
} //end run
});
| private boolean | clearApplicationUserDataLI(java.lang.String packageName, int userId)
if (packageName == null) {
Slog.w(TAG, "Attempt to delete null packageName.");
return false;
}
// Try finding details about the requested package
PackageParser.Package pkg;
synchronized (mPackages) {
pkg = mPackages.get(packageName);
if (pkg == null) {
final PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps != null) {
pkg = ps.pkg;
}
}
}
if (pkg == null) {
Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
}
// Always delete data directories for package, even if we found no other
// record of app. This helps users recover from UID mismatches without
// resorting to a full data wipe.
int retCode = mInstaller.clearUserData(packageName, userId);
if (retCode < 0) {
Slog.w(TAG, "Couldn't remove cache files for package: " + packageName);
return false;
}
if (pkg == null) {
return false;
}
if (pkg != null && pkg.applicationInfo != null) {
final int appId = pkg.applicationInfo.uid;
removeKeystoreDataIfNeeded(userId, appId);
}
// Create a native library symlink only if we have native libraries
// and if the native libraries are 32 bit libraries. We do not provide
// this symlink for 64 bit libraries.
if (pkg != null && pkg.applicationInfo.primaryCpuAbi != null &&
!VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) {
Slog.w(TAG, "Failed linking native library dir");
return false;
}
}
return true;
| public void | clearCrossProfileIntentFilters(int sourceUserId, java.lang.String ownerPackage, int ownerUserId)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
int callingUid = Binder.getCallingUid();
enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
int callingUserId = UserHandle.getUserId(callingUid);
synchronized (mPackages) {
CrossProfileIntentResolver resolver =
mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
ArraySet<CrossProfileIntentFilter> set =
new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
for (CrossProfileIntentFilter filter : set) {
if (filter.getOwnerPackage().equals(ownerPackage)
&& filter.getOwnerUserId() == callingUserId) {
resolver.removeFilter(filter);
}
}
scheduleWritePackageRestrictionsLocked(sourceUserId);
}
| private static void | clearDirectory(com.android.internal.app.IMediaContainerService mcs, java.io.File[] paths)
for (File path : paths) {
try {
mcs.clearDirectory(path.getAbsolutePath());
} catch (RemoteException e) {
}
}
| private void | clearExternalStorageDataSync(java.lang.String packageName, int userId, boolean allData)
final boolean mounted;
if (Environment.isExternalStorageEmulated()) {
mounted = true;
} else {
final String status = Environment.getExternalStorageState();
mounted = status.equals(Environment.MEDIA_MOUNTED)
|| status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
}
if (!mounted) {
return;
}
final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
int[] users;
if (userId == UserHandle.USER_ALL) {
users = sUserManager.getUserIds();
} else {
users = new int[] { userId };
}
final ClearStorageConnection conn = new ClearStorageConnection();
if (mContext.bindServiceAsUser(
containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
try {
for (int curUser : users) {
long timeout = SystemClock.uptimeMillis() + 5000;
synchronized (conn) {
long now = SystemClock.uptimeMillis();
while (conn.mContainerService == null && now < timeout) {
try {
conn.wait(timeout - now);
} catch (InterruptedException e) {
}
}
}
if (conn.mContainerService == null) {
return;
}
final UserEnvironment userEnv = new UserEnvironment(curUser);
clearDirectory(conn.mContainerService,
userEnv.buildExternalStorageAppCacheDirs(packageName));
if (allData) {
clearDirectory(conn.mContainerService,
userEnv.buildExternalStorageAppDataDirs(packageName));
clearDirectory(conn.mContainerService,
userEnv.buildExternalStorageAppMediaDirs(packageName));
}
}
} finally {
mContext.unbindService(conn);
}
}
| public void | clearPackagePersistentPreferredActivities(java.lang.String packageName, int userId)
int callingUid = Binder.getCallingUid();
if (callingUid != Process.SYSTEM_UID) {
throw new SecurityException(
"clearPackagePersistentPreferredActivities can only be run by the system");
}
ArrayList<PersistentPreferredActivity> removed = null;
boolean changed = false;
synchronized (mPackages) {
for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
.valueAt(i);
if (userId != thisUserId) {
continue;
}
Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
while (it.hasNext()) {
PersistentPreferredActivity ppa = it.next();
// Mark entry for removal only if it matches the package name.
if (ppa.mComponent.getPackageName().equals(packageName)) {
if (removed == null) {
removed = new ArrayList<PersistentPreferredActivity>();
}
removed.add(ppa);
}
}
if (removed != null) {
for (int j=0; j<removed.size(); j++) {
PersistentPreferredActivity ppa = removed.get(j);
ppir.removeFilter(ppa);
}
changed = true;
}
}
if (changed) {
scheduleWritePackageRestrictionsLocked(userId);
}
}
| public void | clearPackagePreferredActivities(java.lang.String packageName)
final int uid = Binder.getCallingUid();
// writer
synchronized (mPackages) {
PackageParser.Package pkg = mPackages.get(packageName);
if (pkg == null || pkg.applicationInfo.uid != uid) {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
!= PackageManager.PERMISSION_GRANTED) {
if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
< Build.VERSION_CODES.FROYO) {
Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
+ Binder.getCallingUid());
return;
}
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
}
}
int user = UserHandle.getCallingUserId();
if (clearPackagePreferredActivitiesLPw(packageName, user)) {
scheduleWritePackageRestrictionsLocked(user);
}
}
| boolean | clearPackagePreferredActivitiesLPw(java.lang.String packageName, int userId)This method takes a specific user id as well as UserHandle.USER_ALL.
ArrayList<PreferredActivity> removed = null;
boolean changed = false;
for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
if (userId != UserHandle.USER_ALL && userId != thisUserId) {
continue;
}
Iterator<PreferredActivity> it = pir.filterIterator();
while (it.hasNext()) {
PreferredActivity pa = it.next();
// Mark entry for removal only if it matches the package name
// and the entry is of type "always".
if (packageName == null ||
(pa.mPref.mComponent.getPackageName().equals(packageName)
&& pa.mPref.mAlways)) {
if (removed == null) {
removed = new ArrayList<PreferredActivity>();
}
removed.add(pa);
}
}
if (removed != null) {
for (int j=0; j<removed.size(); j++) {
PreferredActivity pa = removed.get(j);
pir.removeFilter(pa);
}
changed = true;
}
}
return changed;
| private void | collectCertificatesLI(android.content.pm.PackageParser pp, PackageSetting ps, PackageParser.Package pkg, java.io.File srcFile, int parseFlags)
if (ps != null
&& ps.codePath.equals(srcFile)
&& ps.timeStamp == srcFile.lastModified()
&& !isCompatSignatureUpdateNeeded(pkg)
&& !isRecoverSignatureUpdateNeeded(pkg)) {
long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
if (ps.signatures.mSignatures != null
&& ps.signatures.mSignatures.length != 0
&& mSigningKeySetId != PackageKeySetData.KEYSET_UNASSIGNED) {
// Optimization: reuse the existing cached certificates
// if the package appears to be unchanged.
pkg.mSignatures = ps.signatures.mSignatures;
KeySetManagerService ksms = mSettings.mKeySetManagerService;
synchronized (mPackages) {
pkg.mSigningKeys = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
}
return;
}
Slog.w(TAG, "PackageSetting for " + ps.name
+ " is missing signatures. Collecting certs again to recover them.");
} else {
Log.i(TAG, srcFile.toString() + " changed; collecting certs");
}
try {
pp.collectCertificates(pkg, parseFlags);
pp.collectManifestDigest(pkg);
} catch (PackageParserException e) {
throw PackageManagerException.from(e);
}
| static boolean | comparePermissionInfos(android.content.pm.PermissionInfo pi1, android.content.pm.PermissionInfo pi2)
if (pi1.icon != pi2.icon) return false;
if (pi1.logo != pi2.logo) return false;
if (pi1.protectionLevel != pi2.protectionLevel) return false;
if (!compareStrings(pi1.name, pi2.name)) return false;
if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
// We'll take care of setting this one.
if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
// These are not currently stored in settings.
//if (!compareStrings(pi1.group, pi2.group)) return false;
//if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
//if (pi1.labelRes != pi2.labelRes) return false;
//if (pi1.descriptionRes != pi2.descriptionRes) return false;
return true;
| static int | compareSignatures(android.content.pm.Signature[] s1, android.content.pm.Signature[] s2)Compares two sets of signatures. Returns:
{@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
{@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
{@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
{@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
{@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
if (s1 == null) {
return s2 == null
? PackageManager.SIGNATURE_NEITHER_SIGNED
: PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
}
if (s2 == null) {
return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
}
if (s1.length != s2.length) {
return PackageManager.SIGNATURE_NO_MATCH;
}
// Since both signature sets are of size 1, we can compare without HashSets.
if (s1.length == 1) {
return s1[0].equals(s2[0]) ?
PackageManager.SIGNATURE_MATCH :
PackageManager.SIGNATURE_NO_MATCH;
}
ArraySet<Signature> set1 = new ArraySet<Signature>();
for (Signature sig : s1) {
set1.add(sig);
}
ArraySet<Signature> set2 = new ArraySet<Signature>();
for (Signature sig : s2) {
set2.add(sig);
}
// Make sure s2 contains all signatures in s1.
if (set1.equals(set2)) {
return PackageManager.SIGNATURE_MATCH;
}
return PackageManager.SIGNATURE_NO_MATCH;
| private int | compareSignaturesCompat(PackageSignatures existingSigs, PackageParser.Package scannedPkg)Used for backward compatibility to make sure any packages with
certificate chains get upgraded to the new style. {@code existingSigs}
will be in the old format (since they were stored on disk from before the
system upgrade) and {@code scannedSigs} will be in the newer format.
if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
return PackageManager.SIGNATURE_NO_MATCH;
}
ArraySet<Signature> existingSet = new ArraySet<Signature>();
for (Signature sig : existingSigs.mSignatures) {
existingSet.add(sig);
}
ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
for (Signature sig : scannedPkg.mSignatures) {
try {
Signature[] chainSignatures = sig.getChainSignatures();
for (Signature chainSig : chainSignatures) {
scannedCompatSet.add(chainSig);
}
} catch (CertificateEncodingException e) {
scannedCompatSet.add(sig);
}
}
/*
* Make sure the expanded scanned set contains all signatures in the
* existing one.
*/
if (scannedCompatSet.equals(existingSet)) {
// Migrate the old signatures to the new scheme.
existingSigs.assignSignatures(scannedPkg.mSignatures);
// The new KeySets will be re-added later in the scanning process.
synchronized (mPackages) {
mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
}
return PackageManager.SIGNATURE_MATCH;
}
return PackageManager.SIGNATURE_NO_MATCH;
| private int | compareSignaturesRecover(PackageSignatures existingSigs, PackageParser.Package scannedPkg)
if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
return PackageManager.SIGNATURE_NO_MATCH;
}
String msg = null;
try {
if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
+ scannedPkg.packageName);
return PackageManager.SIGNATURE_MATCH;
}
} catch (CertificateException e) {
msg = e.getMessage();
}
logCriticalInfo(Log.INFO,
"Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
return PackageManager.SIGNATURE_NO_MATCH;
| static boolean | compareStrings(java.lang.CharSequence s1, java.lang.CharSequence s2)
if (s1 == null) {
return s2 == null;
}
if (s2 == null) {
return false;
}
if (s1.getClass() != s2.getClass()) {
return false;
}
return s1.equals(s2);
| private int | createDataDirsLI(java.lang.String packageName, int uid, java.lang.String seinfo)
int[] users = sUserManager.getUserIds();
int res = mInstaller.install(packageName, uid, uid, seinfo);
if (res < 0) {
return res;
}
for (int user : users) {
if (user != 0) {
res = mInstaller.createUserData(packageName,
UserHandle.getUid(user, uid), user, seinfo);
if (res < 0) {
return res;
}
}
}
return res;
| private android.content.pm.ResolveInfo | createForwardingResolveInfo(android.content.IntentFilter filter, int sourceUserId, int targetUserId)
ResolveInfo forwardingResolveInfo = new ResolveInfo();
String className;
if (targetUserId == UserHandle.USER_OWNER) {
className = FORWARD_INTENT_TO_USER_OWNER;
} else {
className = FORWARD_INTENT_TO_MANAGED_PROFILE;
}
ComponentName forwardingActivityComponentName = new ComponentName(
mAndroidApplication.packageName, className);
ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
sourceUserId);
if (targetUserId == UserHandle.USER_OWNER) {
forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER;
forwardingResolveInfo.noResourceId = true;
}
forwardingResolveInfo.activityInfo = forwardingActivityInfo;
forwardingResolveInfo.priority = 0;
forwardingResolveInfo.preferredOrder = 0;
forwardingResolveInfo.match = 0;
forwardingResolveInfo.isDefault = true;
forwardingResolveInfo.filter = filter;
forwardingResolveInfo.targetUserId = targetUserId;
return forwardingResolveInfo;
| private boolean | createIdmapForPackagePairLI(PackageParser.Package pkg, PackageParser.Package opkg)
if (!opkg.mTrustedOverlay) {
Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
opkg.baseCodePath + ": overlay not trusted");
return false;
}
ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
if (overlaySet == null) {
Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
opkg.baseCodePath + " but target package has no known overlays");
return false;
}
final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
// TODO: generate idmap for split APKs
if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) {
Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
+ opkg.baseCodePath);
return false;
}
PackageParser.Package[] overlayArray =
overlaySet.values().toArray(new PackageParser.Package[0]);
Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
public int compare(PackageParser.Package p1, PackageParser.Package p2) {
return p1.mOverlayPriority - p2.mOverlayPriority;
}
};
Arrays.sort(overlayArray, cmp);
pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
int i = 0;
for (PackageParser.Package p : overlayArray) {
pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
}
return true;
| private void | createIdmapsForPackageLI(PackageParser.Package pkg)
ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
if (overlays == null) {
Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
return;
}
for (PackageParser.Package opkg : overlays.values()) {
// Not much to do if idmap fails: we already logged the error
// and we certainly don't want to abort installation of pkg simply
// because an overlay didn't fit properly. For these reasons,
// ignore the return value of createIdmapForPackagePairLI.
createIdmapForPackagePairLI(pkg, opkg);
}
| private com.android.server.pm.PackageManagerService$InstallArgs | createInstallArgs(com.android.server.pm.PackageManagerService$InstallParams params)
if (installOnSd(params.installFlags) || params.isForwardLocked()) {
return new AsecInstallArgs(params);
} else {
return new FileInstallArgs(params);
}
| private com.android.server.pm.PackageManagerService$InstallArgs | createInstallArgsForExisting(int installFlags, java.lang.String codePath, java.lang.String resourcePath, java.lang.String nativeLibraryRoot, java.lang.String[] instructionSets)Create args that describe an existing installed package. Typically used
when cleaning up old installs, or used as a move source.
final boolean isInAsec;
if (installOnSd(installFlags)) {
/* Apps on SD card are always in ASEC containers. */
isInAsec = true;
} else if (installForwardLocked(installFlags)
&& !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
/*
* Forward-locked apps are only in ASEC containers if they're the
* new style
*/
isInAsec = true;
} else {
isInAsec = false;
}
if (isInAsec) {
return new AsecInstallArgs(codePath, instructionSets,
installOnSd(installFlags), installForwardLocked(installFlags));
} else {
return new FileInstallArgs(codePath, resourcePath, nativeLibraryRoot,
instructionSets);
}
| void | createNewUserLILPw(int userHandle, java.io.File path)Called by UserManagerService
if (mInstaller != null) {
mInstaller.createUserConfig(userHandle);
mSettings.createNewUserLILPw(this, mInstaller, userHandle, path);
}
| public java.lang.String[] | currentToCanonicalPackageNames(java.lang.String[] names)
String[] out = new String[names.length];
// reader
synchronized (mPackages) {
for (int i=names.length-1; i>=0; i--) {
PackageSetting ps = mSettings.mPackages.get(names[i]);
out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
}
}
return out;
| public void | deleteApplicationCacheFiles(java.lang.String packageName, android.content.pm.IPackageDataObserver observer)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.DELETE_CACHE_FILES, null);
// Queue up an async operation since the package deletion may take a little while.
final int userId = UserHandle.getCallingUserId();
mHandler.post(new Runnable() {
public void run() {
mHandler.removeCallbacks(this);
final boolean succeded;
synchronized (mInstallLock) {
succeded = deleteApplicationCacheFilesLI(packageName, userId);
}
clearExternalStorageDataSync(packageName, userId, false);
if(observer != null) {
try {
observer.onRemoveCompleted(packageName, succeded);
} catch (RemoteException e) {
Log.i(TAG, "Observer no longer exists.");
}
} //end if observer
} //end run
});
| private boolean | deleteApplicationCacheFilesLI(java.lang.String packageName, int userId)
if (packageName == null) {
Slog.w(TAG, "Attempt to delete null packageName.");
return false;
}
PackageParser.Package p;
synchronized (mPackages) {
p = mPackages.get(packageName);
}
if (p == null) {
Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
return false;
}
final ApplicationInfo applicationInfo = p.applicationInfo;
if (applicationInfo == null) {
Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
return false;
}
int retCode = mInstaller.deleteCacheFiles(packageName, userId);
if (retCode < 0) {
Slog.w(TAG, "Couldn't remove cache files for package: "
+ packageName + " u" + userId);
return false;
}
return true;
| private int | deleteCodeCacheDirsLI(java.lang.String packageName)
int[] users = sUserManager.getUserIds();
int res = 0;
for (int user : users) {
int resInner = mInstaller.deleteCodeCacheFiles(packageName, user);
if (resInner < 0) {
res = resInner;
}
}
return res;
| private boolean | deleteInstalledPackageLI(PackageSetting ps, boolean deleteCodeAndResources, int flags, int[] allUserHandles, boolean[] perUserInstalled, com.android.server.pm.PackageManagerService$PackageRemovedInfo outInfo, boolean writeSettings)
if (outInfo != null) {
outInfo.uid = ps.appId;
}
// Delete package data from internal structures and also remove data if flag is set
removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings);
// Delete application code and resources
if (deleteCodeAndResources && (outInfo != null)) {
outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
getAppDexInstructionSets(ps));
if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
}
return true;
| public void | deletePackage(java.lang.String packageName, android.content.pm.IPackageDeleteObserver2 observer, int userId, int flags)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.DELETE_PACKAGES, null);
final int uid = Binder.getCallingUid();
if (UserHandle.getUserId(uid) != userId) {
mContext.enforceCallingPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
"deletePackage for user " + userId);
}
if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
try {
observer.onPackageDeleted(packageName,
PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
} catch (RemoteException re) {
}
return;
}
boolean uninstallBlocked = false;
if ((flags & PackageManager.DELETE_ALL_USERS) != 0) {
int[] users = sUserManager.getUserIds();
for (int i = 0; i < users.length; ++i) {
if (getBlockUninstallForUser(packageName, users[i])) {
uninstallBlocked = true;
break;
}
}
} else {
uninstallBlocked = getBlockUninstallForUser(packageName, userId);
}
if (uninstallBlocked) {
try {
observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED,
null);
} catch (RemoteException re) {
}
return;
}
if (DEBUG_REMOVE) {
Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId);
}
// Queue up an async operation since the package deletion may take a little while.
mHandler.post(new Runnable() {
public void run() {
mHandler.removeCallbacks(this);
final int returnCode = deletePackageX(packageName, userId, flags);
if (observer != null) {
try {
observer.onPackageDeleted(packageName, returnCode, null);
} catch (RemoteException e) {
Log.i(TAG, "Observer no longer exists.");
} //end catch
} //end if
} //end run
});
| public void | deletePackageAsUser(java.lang.String packageName, android.content.pm.IPackageDeleteObserver observer, int userId, int flags)
deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
flags);
| private boolean | deletePackageLI(java.lang.String packageName, android.os.UserHandle user, boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled, int flags, com.android.server.pm.PackageManagerService$PackageRemovedInfo outInfo, boolean writeSettings)
if (packageName == null) {
Slog.w(TAG, "Attempt to delete null packageName.");
return false;
}
if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
PackageSetting ps;
boolean dataOnly = false;
int removeUser = -1;
int appId = -1;
synchronized (mPackages) {
ps = mSettings.mPackages.get(packageName);
if (ps == null) {
Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
return false;
}
if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
&& user.getIdentifier() != UserHandle.USER_ALL) {
// The caller is asking that the package only be deleted for a single
// user. To do this, we just mark its uninstalled state and delete
// its data. If this is a system app, we only allow this to happen if
// they have set the special DELETE_SYSTEM_APP which requests different
// semantics than normal for uninstalling system apps.
if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user");
ps.setUserState(user.getIdentifier(),
COMPONENT_ENABLED_STATE_DEFAULT,
false, //installed
true, //stopped
true, //notLaunched
false, //hidden
null, null, null,
false // blockUninstall
);
if (!isSystemApp(ps)) {
if (ps.isAnyInstalled(sUserManager.getUserIds())) {
// Other user still have this package installed, so all
// we need to do is clear this user's data and save that
// it is uninstalled.
if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
removeUser = user.getIdentifier();
appId = ps.appId;
mSettings.writePackageRestrictionsLPr(removeUser);
} else {
// We need to set it back to 'installed' so the uninstall
// broadcasts will be sent correctly.
if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
ps.setInstalled(true, user.getIdentifier());
}
} else {
// This is a system app, so we assume that the
// other users still have this package installed, so all
// we need to do is clear this user's data and save that
// it is uninstalled.
if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
removeUser = user.getIdentifier();
appId = ps.appId;
mSettings.writePackageRestrictionsLPr(removeUser);
}
}
}
if (removeUser >= 0) {
// From above, we determined that we are deleting this only
// for a single user. Continue the work here.
if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser);
if (outInfo != null) {
outInfo.removedPackage = packageName;
outInfo.removedAppId = appId;
outInfo.removedUsers = new int[] {removeUser};
}
mInstaller.clearUserData(packageName, removeUser);
removeKeystoreDataIfNeeded(removeUser, appId);
schedulePackageCleaning(packageName, removeUser, false);
return true;
}
if (dataOnly) {
// Delete application data first
if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only");
removePackageDataLI(ps, null, null, outInfo, flags, writeSettings);
return true;
}
boolean ret = false;
if (isSystemApp(ps)) {
if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name);
// When an updated system application is deleted we delete the existing resources as well and
// fall back to existing code in system partition
ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
flags, outInfo, writeSettings);
} else {
if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name);
// Kill application pre-emptively especially for apps on sd.
killApplication(packageName, ps.appId, "uninstall pkg");
ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
allUserHandles, perUserInstalled,
outInfo, writeSettings);
}
return ret;
| private int | deletePackageX(java.lang.String packageName, int userId, int flags)This method is an internal method that could be get invoked either
to delete an installed package or to clean up a failed installation.
After deleting an installed package, a broadcast is sent to notify any
listeners that the package has been installed. For cleaning up a failed
installation, the broadcast is not necessary since the package's
installation wouldn't have sent the initial broadcast either
The key steps in deleting a package are
deleting the package information in internal structures like mPackages,
deleting the packages base directories through installd
updating mSettings to reflect current status
persisting settings for later use
sending a broadcast if necessary
final PackageRemovedInfo info = new PackageRemovedInfo();
final boolean res;
final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0
? UserHandle.ALL : new UserHandle(userId);
if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) {
Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
}
boolean removedForAllUsers = false;
boolean systemUpdate = false;
// for the uninstall-updates case and restricted profiles, remember the per-
// userhandle installed state
int[] allUsers;
boolean[] perUserInstalled;
synchronized (mPackages) {
PackageSetting ps = mSettings.mPackages.get(packageName);
allUsers = sUserManager.getUserIds();
perUserInstalled = new boolean[allUsers.length];
for (int i = 0; i < allUsers.length; i++) {
perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
}
}
synchronized (mInstallLock) {
if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
res = deletePackageLI(packageName, removeForUser,
true, allUsers, perUserInstalled,
flags | REMOVE_CHATTY, info, true);
systemUpdate = info.isRemovedPackageSystemUpdate;
if (res && !systemUpdate && mPackages.get(packageName) == null) {
removedForAllUsers = true;
}
if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate
+ " removedForAllUsers=" + removedForAllUsers);
}
if (res) {
info.sendBroadcast(true, systemUpdate, removedForAllUsers);
// If the removed package was a system update, the old system package
// was re-enabled; we need to broadcast this information
if (systemUpdate) {
Bundle extras = new Bundle(1);
extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0
? info.removedAppId : info.uid);
extras.putBoolean(Intent.EXTRA_REPLACING, true);
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
extras, null, null, null);
sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
extras, null, null, null);
sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
null, packageName, null, null);
}
}
// Force a gc here.
Runtime.getRuntime().gc();
// Delete the resources here after sending the broadcast to let
// other processes clean up before deleting resources.
if (info.args != null) {
synchronized (mInstallLock) {
info.args.doPostDeleteLI(true);
}
}
return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
| private boolean | deleteSystemPackageLI(PackageSetting newPs, int[] allUserHandles, boolean[] perUserInstalled, int flags, com.android.server.pm.PackageManagerService$PackageRemovedInfo outInfo, boolean writeSettings)
final boolean applyUserRestrictions
= (allUserHandles != null) && (perUserInstalled != null);
PackageSetting disabledPs = null;
// Confirm if the system package has been updated
// An updated system app can be deleted. This will also have to restore
// the system pkg from system partition
// reader
synchronized (mPackages) {
disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
}
if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs
+ " disabledPs=" + disabledPs);
if (disabledPs == null) {
Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
return false;
} else if (DEBUG_REMOVE) {
Slog.d(TAG, "Deleting system pkg from data partition");
}
if (DEBUG_REMOVE) {
if (applyUserRestrictions) {
Slog.d(TAG, "Remembering install states:");
for (int i = 0; i < allUserHandles.length; i++) {
Slog.d(TAG, " u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]);
}
}
}
// Delete the updated package
outInfo.isRemovedPackageSystemUpdate = true;
if (disabledPs.versionCode < newPs.versionCode) {
// Delete data for downgrades
flags &= ~PackageManager.DELETE_KEEP_DATA;
} else {
// Preserve data by setting flag
flags |= PackageManager.DELETE_KEEP_DATA;
}
boolean ret = deleteInstalledPackageLI(newPs, true, flags,
allUserHandles, perUserInstalled, outInfo, writeSettings);
if (!ret) {
return false;
}
// writer
synchronized (mPackages) {
// Reinstate the old system package
mSettings.enableSystemPackageLPw(newPs.name);
// Remove any native libraries from the upgraded package.
NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString);
}
// Install the system package
if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM;
if (locationIsPrivileged(disabledPs.codePath)) {
parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
}
final PackageParser.Package newPkg;
try {
newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
} catch (PackageManagerException e) {
Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage());
return false;
}
// writer
synchronized (mPackages) {
PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
updatePermissionsLPw(newPkg.packageName, newPkg,
UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
if (applyUserRestrictions) {
if (DEBUG_REMOVE) {
Slog.d(TAG, "Propagating install state across reinstall");
}
for (int i = 0; i < allUserHandles.length; i++) {
if (DEBUG_REMOVE) {
Slog.d(TAG, " user " + allUserHandles[i]
+ " => " + perUserInstalled[i]);
}
ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
}
// Regardless of writeSettings we need to ensure that this restriction
// state propagation is persisted
mSettings.writeAllUsersPackageRestrictionsLPr();
}
// can downgrade to reader here
if (writeSettings) {
mSettings.writeLPr();
}
}
return true;
| private void | deleteTempPackageFiles()
final FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.startsWith("vmdl") && name.endsWith(".tmp");
}
};
for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
file.delete();
}
| private static java.lang.String | deriveAbiOverride(java.lang.String abiOverride, PackageSetting settings)Derive the value of the {@code cpuAbiOverride} based on the provided
value and an optional stored value from the package settings.
String cpuAbiOverride = null;
if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
cpuAbiOverride = null;
} else if (abiOverride != null) {
cpuAbiOverride = abiOverride;
} else if (settings != null) {
cpuAbiOverride = settings.cpuAbiOverrideString;
}
return cpuAbiOverride;
| static java.lang.String | deriveCodePathName(java.lang.String codePath)
if (codePath == null) {
return null;
}
final File codeFile = new File(codePath);
final String name = codeFile.getName();
if (codeFile.isDirectory()) {
return name;
} else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
final int lastDot = name.lastIndexOf('.");
return name.substring(0, lastDot);
} else {
Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
return null;
}
| protected void | dump(java.io.FileDescriptor fd, java.io.PrintWriter pw, java.lang.String[] args)
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
pw.println("Permission Denial: can't dump ActivityManager from from pid="
+ Binder.getCallingPid()
+ ", uid=" + Binder.getCallingUid()
+ " without permission "
+ android.Manifest.permission.DUMP);
return;
}
DumpState dumpState = new DumpState();
boolean fullPreferred = false;
boolean checkin = false;
String packageName = null;
int opti = 0;
while (opti < args.length) {
String opt = args[opti];
if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-") {
break;
}
opti++;
if ("-a".equals(opt)) {
// Right now we only know how to print all.
} else if ("-h".equals(opt)) {
pw.println("Package manager dump options:");
pw.println(" [-h] [-f] [--checkin] [cmd] ...");
pw.println(" --checkin: dump for a checkin");
pw.println(" -f: print details of intent filters");
pw.println(" -h: print this help");
pw.println(" cmd may be one of:");
pw.println(" l[ibraries]: list known shared libraries");
pw.println(" f[ibraries]: list device features");
pw.println(" k[eysets]: print known keysets");
pw.println(" r[esolvers]: dump intent resolvers");
pw.println(" perm[issions]: dump permissions");
pw.println(" pref[erred]: print preferred package settings");
pw.println(" preferred-xml [--full]: print preferred package settings as xml");
pw.println(" prov[iders]: dump content providers");
pw.println(" p[ackages]: dump installed packages");
pw.println(" s[hared-users]: dump shared user IDs");
pw.println(" m[essages]: print collected runtime messages");
pw.println(" v[erifiers]: print package verifier info");
pw.println(" version: print database version info");
pw.println(" write: write current settings now");
pw.println(" <package.name>: info about given package");
pw.println(" installs: details about install sessions");
return;
} else if ("--checkin".equals(opt)) {
checkin = true;
} else if ("-f".equals(opt)) {
dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
} else {
pw.println("Unknown argument: " + opt + "; use -h for help");
}
}
// Is the caller requesting to dump a particular piece of data?
if (opti < args.length) {
String cmd = args[opti];
opti++;
// Is this a package name?
if ("android".equals(cmd) || cmd.contains(".")) {
packageName = cmd;
// When dumping a single package, we always dump all of its
// filter information since the amount of data will be reasonable.
dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
} else if ("l".equals(cmd) || "libraries".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_LIBS);
} else if ("f".equals(cmd) || "features".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_FEATURES);
} else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_RESOLVERS);
} else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_PERMISSIONS);
} else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_PREFERRED);
} else if ("preferred-xml".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
if (opti < args.length && "--full".equals(args[opti])) {
fullPreferred = true;
opti++;
}
} else if ("p".equals(cmd) || "packages".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_PACKAGES);
} else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_SHARED_USERS);
} else if ("prov".equals(cmd) || "providers".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_PROVIDERS);
} else if ("m".equals(cmd) || "messages".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_MESSAGES);
} else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_VERIFIERS);
} else if ("version".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_VERSION);
} else if ("k".equals(cmd) || "keysets".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_KEYSETS);
} else if ("installs".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_INSTALLS);
} else if ("write".equals(cmd)) {
synchronized (mPackages) {
mSettings.writeLPr();
pw.println("Settings written.");
return;
}
}
}
if (checkin) {
pw.println("vers,1");
}
// reader
synchronized (mPackages) {
if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
if (!checkin) {
if (dumpState.onTitlePrinted())
pw.println();
pw.println("Database versions:");
pw.print(" SDK Version:");
pw.print(" internal=");
pw.print(mSettings.mInternalSdkPlatform);
pw.print(" external=");
pw.println(mSettings.mExternalSdkPlatform);
pw.print(" DB Version:");
pw.print(" internal=");
pw.print(mSettings.mInternalDatabaseVersion);
pw.print(" external=");
pw.println(mSettings.mExternalDatabaseVersion);
}
}
if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
if (!checkin) {
if (dumpState.onTitlePrinted())
pw.println();
pw.println("Verifiers:");
pw.print(" Required: ");
pw.print(mRequiredVerifierPackage);
pw.print(" (uid=");
pw.print(getPackageUid(mRequiredVerifierPackage, 0));
pw.println(")");
} else if (mRequiredVerifierPackage != null) {
pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0));
}
}
if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
boolean printedHeader = false;
final Iterator<String> it = mSharedLibraries.keySet().iterator();
while (it.hasNext()) {
String name = it.next();
SharedLibraryEntry ent = mSharedLibraries.get(name);
if (!checkin) {
if (!printedHeader) {
if (dumpState.onTitlePrinted())
pw.println();
pw.println("Libraries:");
printedHeader = true;
}
pw.print(" ");
} else {
pw.print("lib,");
}
pw.print(name);
if (!checkin) {
pw.print(" -> ");
}
if (ent.path != null) {
if (!checkin) {
pw.print("(jar) ");
pw.print(ent.path);
} else {
pw.print(",jar,");
pw.print(ent.path);
}
} else {
if (!checkin) {
pw.print("(apk) ");
pw.print(ent.apk);
} else {
pw.print(",apk,");
pw.print(ent.apk);
}
}
pw.println();
}
}
if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
if (dumpState.onTitlePrinted())
pw.println();
if (!checkin) {
pw.println("Features:");
}
Iterator<String> it = mAvailableFeatures.keySet().iterator();
while (it.hasNext()) {
String name = it.next();
if (!checkin) {
pw.print(" ");
} else {
pw.print("feat,");
}
pw.println(name);
}
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
: "Activity Resolver Table:", " ", packageName,
dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
dumpState.setTitlePrinted(true);
}
if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
: "Receiver Resolver Table:", " ", packageName,
dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
dumpState.setTitlePrinted(true);
}
if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
: "Service Resolver Table:", " ", packageName,
dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
dumpState.setTitlePrinted(true);
}
if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
: "Provider Resolver Table:", " ", packageName,
dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
dumpState.setTitlePrinted(true);
}
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
int user = mSettings.mPreferredActivities.keyAt(i);
if (pir.dump(pw,
dumpState.getTitlePrinted()
? "\nPreferred Activities User " + user + ":"
: "Preferred Activities User " + user + ":", " ",
packageName, true, false)) {
dumpState.setTitlePrinted(true);
}
}
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
pw.flush();
FileOutputStream fout = new FileOutputStream(fd);
BufferedOutputStream str = new BufferedOutputStream(fout);
XmlSerializer serializer = new FastXmlSerializer();
try {
serializer.setOutput(str, "utf-8");
serializer.startDocument(null, true);
serializer.setFeature(
"http://xmlpull.org/v1/doc/features.html#indent-output", true);
mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
serializer.endDocument();
serializer.flush();
} catch (IllegalArgumentException e) {
pw.println("Failed writing: " + e);
} catch (IllegalStateException e) {
pw.println("Failed writing: " + e);
} catch (IOException e) {
pw.println("Failed writing: " + e);
}
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
if (packageName == null) {
for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
if (iperm == 0) {
if (dumpState.onTitlePrinted())
pw.println();
pw.println("AppOp Permissions:");
}
pw.print(" AppOp Permission ");
pw.print(mAppOpPermissionPackages.keyAt(iperm));
pw.println(":");
ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
pw.print(" "); pw.println(pkgs.valueAt(ipkg));
}
}
}
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
boolean printedSomething = false;
for (PackageParser.Provider p : mProviders.mProviders.values()) {
if (packageName != null && !packageName.equals(p.info.packageName)) {
continue;
}
if (!printedSomething) {
if (dumpState.onTitlePrinted())
pw.println();
pw.println("Registered ContentProviders:");
printedSomething = true;
}
pw.print(" "); p.printComponentShortName(pw); pw.println(":");
pw.print(" "); pw.println(p.toString());
}
printedSomething = false;
for (Map.Entry<String, PackageParser.Provider> entry :
mProvidersByAuthority.entrySet()) {
PackageParser.Provider p = entry.getValue();
if (packageName != null && !packageName.equals(p.info.packageName)) {
continue;
}
if (!printedSomething) {
if (dumpState.onTitlePrinted())
pw.println();
pw.println("ContentProvider Authorities:");
printedSomething = true;
}
pw.print(" ["); pw.print(entry.getKey()); pw.println("]:");
pw.print(" "); pw.println(p.toString());
if (p.info != null && p.info.applicationInfo != null) {
final String appInfo = p.info.applicationInfo.toString();
pw.print(" applicationInfo="); pw.println(appInfo);
}
}
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
}
if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin);
}
if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
mSettings.dumpSharedUsersLPr(pw, packageName, dumpState, checkin);
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
// XXX should handle packageName != null by dumping only install data that
// the given package is involved with.
if (dumpState.onTitlePrinted()) pw.println();
mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120));
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
if (dumpState.onTitlePrinted()) pw.println();
mSettings.dumpReadMessagesLPr(pw, dumpState);
pw.println();
pw.println("Package warning messages:");
BufferedReader in = null;
String line = null;
try {
in = new BufferedReader(new FileReader(getSettingsProblemFile()));
while ((line = in.readLine()) != null) {
if (line.contains("ignored: updated version")) continue;
pw.println(line);
}
} catch (IOException ignored) {
} finally {
IoUtils.closeQuietly(in);
}
}
if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
BufferedReader in = null;
String line = null;
try {
in = new BufferedReader(new FileReader(getSettingsProblemFile()));
while ((line = in.readLine()) != null) {
if (line.contains("ignored: updated version")) continue;
pw.print("msg,");
pw.println(line);
}
} catch (IOException ignored) {
} finally {
IoUtils.closeQuietly(in);
}
}
}
| void | enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, java.lang.String message)Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
if (userId < 0) {
throw new IllegalArgumentException("Invalid userId " + userId);
}
if (checkShell) {
enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
}
if (userId == UserHandle.getUserId(callingUid)) return;
if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
if (requireFullPermission) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
} else {
try {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
} catch (SecurityException se) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS, message);
}
}
}
| private void | enforceOwnerRights(java.lang.String pkg, int userId, int callingUid)
// The system owns everything.
if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
return;
}
int callingUserId = UserHandle.getUserId(callingUid);
if (callingUserId != userId) {
throw new SecurityException("calling uid " + callingUid
+ " pretends to own " + pkg + " on user " + userId + " but belongs to user "
+ callingUserId);
}
PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
if (pi == null) {
throw new IllegalArgumentException("Unknown package " + pkg + " on user "
+ callingUserId);
}
if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
throw new SecurityException("Calling uid " + callingUid
+ " does not own package " + pkg);
}
| void | enforcePermissionCapLocked(android.content.pm.PermissionInfo info, BasePermission tree)
// We calculate the max size of permissions defined by this uid and throw
// if that plus the size of 'info' would exceed our stated maximum.
if (tree.uid != Process.SYSTEM_UID) {
final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
throw new SecurityException("Permission tree size cap exceeded");
}
}
| void | enforceShellRestriction(java.lang.String restriction, int callingUid, int userHandle)
if (callingUid == Process.SHELL_UID) {
if (userHandle >= 0
&& sUserManager.hasUserRestriction(restriction, userHandle)) {
throw new SecurityException("Shell does not have permission to access user "
+ userHandle);
} else if (userHandle < 0) {
Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
+ Debug.getCallers(3));
}
}
| private static final void | enforceSystemOrRoot(java.lang.String message)Enforces that only the system UID or root's UID can call a method exposed
via Binder.
final int uid = Binder.getCallingUid();
if (uid != Process.SYSTEM_UID && uid != 0) {
throw new SecurityException(message);
}
| public void | enterSafeMode()
enforceSystemOrRoot("Only the system can request entering safe mode");
if (!mSystemReady) {
mSafeMode = true;
}
| public void | extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
"Only package verification agents can extend verification timeouts");
final PackageVerificationState state = mPendingVerification.get(id);
final PackageVerificationResponse response = new PackageVerificationResponse(
verificationCodeAtTimeout, Binder.getCallingUid());
if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
}
if (millisecondsToDelay < 0) {
millisecondsToDelay = 0;
}
if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
&& (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
}
if ((state != null) && !state.timeoutExtended()) {
state.extendTimeout();
final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
msg.arg1 = id;
msg.obj = response;
mHandler.sendMessageDelayed(msg, millisecondsToDelay);
}
| android.os.Bundle | extrasForInstallResult(com.android.server.pm.PackageManagerService$PackageInstalledInfo res)
Bundle extras = null;
switch (res.returnCode) {
case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
extras = new Bundle();
extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
res.origPermission);
extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
res.origPackage);
break;
}
}
return extras;
| private void | filterRecentlyUsedApps(java.util.Collection pkgs)
// Filter out packages that aren't recently used.
//
// The exception is first boot of a non-eng device (aka !mLazyDexOpt), which
// should do a full dexopt.
if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) {
int total = pkgs.size();
int skipped = 0;
long now = System.currentTimeMillis();
for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) {
PackageParser.Package pkg = i.next();
long then = pkg.mLastPackageUsageTimeInMills;
if (then + mDexOptLRUThresholdInMills < now) {
if (DEBUG_DEXOPT) {
Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " +
((then == 0) ? "never" : new Date(then)));
}
i.remove();
skipped++;
}
}
if (DEBUG_DEXOPT) {
Log.i(TAG, "Skipped optimizing " + skipped + " of " + total);
}
}
| private BasePermission | findPermissionTreeLP(java.lang.String permName)
for(BasePermission bp : mSettings.mPermissionTrees.values()) {
if (permName.startsWith(bp.name) &&
permName.length() > bp.name.length() &&
permName.charAt(bp.name.length()) == '.") {
return bp;
}
}
return null;
| private android.content.pm.ResolveInfo | findPersistentPreferredActivityLP(android.content.Intent intent, java.lang.String resolvedType, int flags, java.util.List query, boolean debug, int userId)
final int N = query.size();
PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
.get(userId);
// Get the list of persistent preferred activities that handle the intent
if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
List<PersistentPreferredActivity> pprefs = ppir != null
? ppir.queryIntent(intent, resolvedType,
(flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
: null;
if (pprefs != null && pprefs.size() > 0) {
final int M = pprefs.size();
for (int i=0; i<M; i++) {
final PersistentPreferredActivity ppa = pprefs.get(i);
if (DEBUG_PREFERRED || debug) {
Slog.v(TAG, "Checking PersistentPreferredActivity ds="
+ (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
+ "\n component=" + ppa.mComponent);
ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
}
final ActivityInfo ai = getActivityInfo(ppa.mComponent,
flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
if (DEBUG_PREFERRED || debug) {
Slog.v(TAG, "Found persistent preferred activity:");
if (ai != null) {
ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
} else {
Slog.v(TAG, " null");
}
}
if (ai == null) {
// This previously registered persistent preferred activity
// component is no longer known. Ignore it and do NOT remove it.
continue;
}
for (int j=0; j<N; j++) {
final ResolveInfo ri = query.get(j);
if (!ri.activityInfo.applicationInfo.packageName
.equals(ai.applicationInfo.packageName)) {
continue;
}
if (!ri.activityInfo.name.equals(ai.name)) {
continue;
}
// Found a persistent preference that can handle the intent.
if (DEBUG_PREFERRED || debug) {
Slog.v(TAG, "Returning persistent preferred activity: " +
ri.activityInfo.packageName + "/" + ri.activityInfo.name);
}
return ri;
}
}
}
return null;
| android.content.pm.ResolveInfo | findPreferredActivity(android.content.Intent intent, java.lang.String resolvedType, int flags, java.util.List query, int priority, boolean always, boolean removeMatches, boolean debug, int userId)
if (!sUserManager.exists(userId)) return null;
// writer
synchronized (mPackages) {
if (intent.getSelector() != null) {
intent = intent.getSelector();
}
if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
// Try to find a matching persistent preferred activity.
ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
debug, userId);
// If a persistent preferred activity matched, use it.
if (pri != null) {
return pri;
}
PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
// Get the list of preferred activities that handle the intent
if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
List<PreferredActivity> prefs = pir != null
? pir.queryIntent(intent, resolvedType,
(flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
: null;
if (prefs != null && prefs.size() > 0) {
boolean changed = false;
try {
// First figure out how good the original match set is.
// We will only allow preferred activities that came
// from the same match quality.
int match = 0;
if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
final int N = query.size();
for (int j=0; j<N; j++) {
final ResolveInfo ri = query.get(j);
if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
+ ": 0x" + Integer.toHexString(match));
if (ri.match > match) {
match = ri.match;
}
}
if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
+ Integer.toHexString(match));
match &= IntentFilter.MATCH_CATEGORY_MASK;
final int M = prefs.size();
for (int i=0; i<M; i++) {
final PreferredActivity pa = prefs.get(i);
if (DEBUG_PREFERRED || debug) {
Slog.v(TAG, "Checking PreferredActivity ds="
+ (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
+ "\n component=" + pa.mPref.mComponent);
pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
}
if (pa.mPref.mMatch != match) {
if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
+ Integer.toHexString(pa.mPref.mMatch));
continue;
}
// If it's not an "always" type preferred activity and that's what we're
// looking for, skip it.
if (always && !pa.mPref.mAlways) {
if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
continue;
}
final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
if (DEBUG_PREFERRED || debug) {
Slog.v(TAG, "Found preferred activity:");
if (ai != null) {
ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
} else {
Slog.v(TAG, " null");
}
}
if (ai == null) {
// This previously registered preferred activity
// component is no longer known. Most likely an update
// to the app was installed and in the new version this
// component no longer exists. Clean it up by removing
// it from the preferred activities list, and skip it.
Slog.w(TAG, "Removing dangling preferred activity: "
+ pa.mPref.mComponent);
pir.removeFilter(pa);
changed = true;
continue;
}
for (int j=0; j<N; j++) {
final ResolveInfo ri = query.get(j);
if (!ri.activityInfo.applicationInfo.packageName
.equals(ai.applicationInfo.packageName)) {
continue;
}
if (!ri.activityInfo.name.equals(ai.name)) {
continue;
}
if (removeMatches) {
pir.removeFilter(pa);
changed = true;
if (DEBUG_PREFERRED) {
Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
}
break;
}
// Okay we found a previously set preferred or last chosen app.
// If the result set is different from when this
// was created, we need to clear it and re-ask the
// user their preference, if we're looking for an "always" type entry.
if (always && !pa.mPref.sameSet(query)) {
Slog.i(TAG, "Result set changed, dropping preferred activity for "
+ intent + " type " + resolvedType);
if (DEBUG_PREFERRED) {
Slog.v(TAG, "Removing preferred activity since set changed "
+ pa.mPref.mComponent);
}
pir.removeFilter(pa);
// Re-add the filter as a "last chosen" entry (!always)
PreferredActivity lastChosen = new PreferredActivity(
pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
pir.addFilter(lastChosen);
changed = true;
return null;
}
// Yay! Either the set matched or we're looking for the last chosen
if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
+ ri.activityInfo.packageName + "/" + ri.activityInfo.name);
return ri;
}
}
} finally {
if (changed) {
if (DEBUG_PREFERRED) {
Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
}
scheduleWritePackageRestrictionsLocked(userId);
}
}
}
}
if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
return null;
| public void | finishPackageInstall(int token)
enforceSystemOrRoot("Only the system is allowed to finish installs");
if (DEBUG_INSTALL) {
Slog.v(TAG, "BM finishing package install for " + token);
}
final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
mHandler.sendMessage(msg);
| private static java.lang.String | fixProcessName(java.lang.String defProcessName, java.lang.String processName, int uid)
if (processName == null) {
return defProcessName;
}
return processName;
| public void | forceDexOpt(java.lang.String packageName)
enforceSystemOrRoot("forceDexOpt");
PackageParser.Package pkg;
synchronized (mPackages) {
pkg = mPackages.get(packageName);
if (pkg == null) {
throw new IllegalArgumentException("Missing package: " + packageName);
}
}
synchronized (mInstallLock) {
final String[] instructionSets = new String[] {
getPrimaryInstructionSet(pkg.applicationInfo) };
final int res = performDexOptLI(pkg, instructionSets, true, false, true);
if (res != DEX_OPT_PERFORMED) {
throw new IllegalStateException("Failed to dexopt: " + res);
}
}
| public void | freeStorage(long freeStorageSize, android.content.IntentSender pi)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CLEAR_APP_CACHE, null);
// Queue up an async operation since clearing cache may take a little while.
mHandler.post(new Runnable() {
public void run() {
mHandler.removeCallbacks(this);
int retCode = -1;
synchronized (mInstallLock) {
retCode = mInstaller.freeCache(freeStorageSize);
if (retCode < 0) {
Slog.w(TAG, "Couldn't clear application caches");
}
}
if(pi != null) {
try {
// Callback via pending intent
int code = (retCode >= 0) ? 1 : 0;
pi.sendIntent(null, code, null,
null, null);
} catch (SendIntentException e1) {
Slog.i(TAG, "Failed to send pending intent");
}
}
}
});
| void | freeStorage(long freeStorageSize)
synchronized (mInstallLock) {
if (mInstaller.freeCache(freeStorageSize) < 0) {
throw new IOException("Failed to free enough space");
}
}
| public void | freeStorageAndNotify(long freeStorageSize, android.content.pm.IPackageDataObserver observer)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CLEAR_APP_CACHE, null);
// Queue up an async operation since clearing cache may take a little while.
mHandler.post(new Runnable() {
public void run() {
mHandler.removeCallbacks(this);
int retCode = -1;
synchronized (mInstallLock) {
retCode = mInstaller.freeCache(freeStorageSize);
if (retCode < 0) {
Slog.w(TAG, "Couldn't clear application caches");
}
}
if (observer != null) {
try {
observer.onRemoveCompleted(null, (retCode >= 0));
} catch (RemoteException e) {
Slog.w(TAG, "RemoveException when invoking call back");
}
}
}
});
| private android.content.pm.ApplicationInfo | generateApplicationInfoFromSettingsLPw(java.lang.String packageName, int flags, int userId)
if (!sUserManager.exists(userId)) return null;
PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps != null) {
if (ps.pkg == null) {
PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName,
flags, userId);
if (pInfo != null) {
return pInfo.applicationInfo;
}
return null;
}
return PackageParser.generateApplicationInfo(ps.pkg, flags,
ps.readUserState(userId), userId);
}
return null;
| android.content.pm.PackageInfo | generatePackageInfo(PackageParser.Package p, int flags, int userId)
if (!sUserManager.exists(userId)) return null;
final PackageSetting ps = (PackageSetting) p.mExtras;
if (ps == null) {
return null;
}
final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
final PackageUserState state = ps.readUserState(userId);
return PackageParser.generatePackageInfo(p, gp.gids, flags,
ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions,
state, userId);
| private android.content.pm.PackageInfo | generatePackageInfoFromSettingsLPw(java.lang.String packageName, int flags, int userId)
if (!sUserManager.exists(userId)) return null;
PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps != null) {
PackageParser.Package pkg = ps.pkg;
if (pkg == null) {
if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) {
return null;
}
// Only data remains, so we aren't worried about code paths
pkg = new PackageParser.Package(packageName);
pkg.applicationInfo.packageName = packageName;
pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
pkg.applicationInfo.dataDir =
getDataPathForPackage(packageName, 0).getPath();
pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
}
return generatePackageInfo(pkg, flags, userId);
}
return null;
| static final android.content.pm.PermissionInfo | generatePermissionInfo(BasePermission bp, int flags)
if (bp.perm != null) {
return PackageParser.generatePermissionInfo(bp.perm, flags);
}
PermissionInfo pi = new PermissionInfo();
pi.name = bp.name;
pi.packageName = bp.sourcePackage;
pi.nonLocalizedLabel = bp.name;
pi.protectionLevel = bp.protectionLevel;
return pi;
| public android.content.pm.ActivityInfo | getActivityInfo(android.content.ComponentName component, int flags, int userId)
if (!sUserManager.exists(userId)) return null;
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info");
synchronized (mPackages) {
PackageParser.Activity a = mActivities.mActivities.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
userId);
}
if (mResolveComponentName.equals(component)) {
return PackageParser.generateActivityInfo(mResolveActivity, flags,
new PackageUserState(), userId);
}
}
return null;
| public static java.lang.String[] | getAllDexCodeInstructionSets()Returns deduplicated list of supported instructions for dex code.
String[] supportedInstructionSets = new String[Build.SUPPORTED_ABIS.length];
for (int i = 0; i < supportedInstructionSets.length; i++) {
String abi = Build.SUPPORTED_ABIS[i];
supportedInstructionSets[i] = VMRuntime.getInstructionSet(abi);
}
return getDexCodeInstructionSets(supportedInstructionSets);
| private static java.util.List | getAllInstructionSets()
final String[] allAbis = Build.SUPPORTED_ABIS;
final List<String> allInstructionSets = new ArrayList<String>(allAbis.length);
for (String abi : allAbis) {
final String instructionSet = VMRuntime.getInstructionSet(abi);
if (!allInstructionSets.contains(instructionSet)) {
allInstructionSets.add(instructionSet);
}
}
return allInstructionSets;
| public java.util.List | getAllPermissionGroups(int flags)
// reader
synchronized (mPackages) {
final int N = mPermissionGroups.size();
ArrayList<PermissionGroupInfo> out
= new ArrayList<PermissionGroupInfo>(N);
for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
}
return out;
}
| private static java.lang.String[] | getAppDexInstructionSets(android.content.pm.ApplicationInfo info)
if (info.primaryCpuAbi != null) {
if (info.secondaryCpuAbi != null) {
return new String[] {
VMRuntime.getInstructionSet(info.primaryCpuAbi),
VMRuntime.getInstructionSet(info.secondaryCpuAbi) };
} else {
return new String[] {
VMRuntime.getInstructionSet(info.primaryCpuAbi) };
}
}
return new String[] { getPreferredInstructionSet() };
| private static java.lang.String[] | getAppDexInstructionSets(PackageSetting ps)
if (ps.primaryCpuAbiString != null) {
if (ps.secondaryCpuAbiString != null) {
return new String[] {
VMRuntime.getInstructionSet(ps.primaryCpuAbiString),
VMRuntime.getInstructionSet(ps.secondaryCpuAbiString) };
} else {
return new String[] {
VMRuntime.getInstructionSet(ps.primaryCpuAbiString) };
}
}
return new String[] { getPreferredInstructionSet() };
| public java.lang.String[] | getAppOpPermissionPackages(java.lang.String permissionName)
synchronized (mPackages) {
ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
if (pkgs == null) {
return null;
}
return pkgs.toArray(new String[pkgs.size()]);
}
| public int | getApplicationEnabledSetting(java.lang.String packageName, int userId)
if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
int uid = Binder.getCallingUid();
enforceCrossUserPermission(uid, userId, false, false, "get enabled");
// reader
synchronized (mPackages) {
return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
}
| public boolean | getApplicationHiddenSettingAsUser(java.lang.String packageName, int userId)Returns true if application is not found or there was an error. Otherwise it returns
the hidden state of the package for the given user.
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
enforceCrossUserPermission(Binder.getCallingUid(), userId, true,
false, "getApplicationHidden for user " + userId);
PackageSetting pkgSetting;
long callingId = Binder.clearCallingIdentity();
try {
// writer
synchronized (mPackages) {
pkgSetting = mSettings.mPackages.get(packageName);
if (pkgSetting == null) {
return true;
}
return pkgSetting.getHidden(userId);
}
} finally {
Binder.restoreCallingIdentity(callingId);
}
| public android.content.pm.ApplicationInfo | getApplicationInfo(java.lang.String packageName, int flags, int userId)
if (!sUserManager.exists(userId)) return null;
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info");
// writer
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
if (DEBUG_PACKAGE_INFO) Log.v(
TAG, "getApplicationInfo " + packageName
+ ": " + p);
if (p != null) {
PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps == null) return null;
// Note: isEnabledLP() does not apply here - always return info
return PackageParser.generateApplicationInfo(
p, flags, ps.readUserState(userId), userId);
}
if ("android".equals(packageName)||"system".equals(packageName)) {
return mAndroidApplication;
}
if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
}
}
return null;
| static java.lang.String | getAsecPackageName(java.lang.String packageCid)
int idx = packageCid.lastIndexOf("-");
if (idx == -1) {
return packageCid;
}
return packageCid.substring(0, idx);
| public boolean | getBlockUninstallForUser(java.lang.String packageName, int userId)
synchronized (mPackages) {
PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps == null) {
Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
return false;
}
return ps.getBlockUninstall(userId);
}
| public int | getComponentEnabledSetting(android.content.ComponentName componentName, int userId)
if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
int uid = Binder.getCallingUid();
enforceCrossUserPermission(uid, userId, false, false, "get component enabled");
// reader
synchronized (mPackages) {
return mSettings.getComponentEnabledSettingLPr(componentName, userId);
}
| private java.io.File | getDataPathForPackage(java.lang.String packageName, int userId)
/*
* Until we fully support multiple users, return the directory we
* previously would have. The PackageManagerTests will need to be
* revised when this is changed back..
*/
if (userId == 0) {
return new File(mAppDataDir, packageName);
} else {
return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId
+ File.separator + packageName);
}
| java.io.File | getDataPathForUser(int userId)
return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId);
| private static void | getDefaultDisplayMetrics(android.content.Context context, android.util.DisplayMetrics metrics)
DisplayManager displayManager = (DisplayManager) context.getSystemService(
Context.DISPLAY_SERVICE);
displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
| private int | getDefaultVerificationResponse()Get the default verification agent response code.
return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
DEFAULT_VERIFICATION_RESPONSE);
| private static java.lang.String | getDexCodeInstructionSet(java.lang.String sharedLibraryIsa)Returns the instruction set that should be used to compile dex code. In the presence of
a native bridge this might be different than the one shared libraries use.
String dexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + sharedLibraryIsa);
return (dexCodeIsa.isEmpty() ? sharedLibraryIsa : dexCodeIsa);
| private static java.lang.String[] | getDexCodeInstructionSets(java.lang.String[] instructionSets)
ArraySet<String> dexCodeInstructionSets = new ArraySet<String>(instructionSets.length);
for (String instructionSet : instructionSets) {
dexCodeInstructionSets.add(getDexCodeInstructionSet(instructionSet));
}
return dexCodeInstructionSets.toArray(new String[dexCodeInstructionSets.size()]);
| static java.lang.String | getEncryptKey()
try {
String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
SD_ENCRYPTION_KEYSTORE_NAME);
if (sdEncKey == null) {
sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
if (sdEncKey == null) {
Slog.e(TAG, "Failed to create encryption keys");
return null;
}
}
return sdEncKey;
} catch (NoSuchAlgorithmException nsae) {
Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
return null;
} catch (IOException ioe) {
Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
return null;
}
| public int | getFlagsForUid(int uid)
synchronized (mPackages) {
Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
if (obj instanceof SharedUserSetting) {
final SharedUserSetting sus = (SharedUserSetting) obj;
return sus.pkgFlags;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
return ps.pkgFlags;
}
}
return 0;
| public android.content.ComponentName | getHomeActivities(java.util.List allHomeCandidates)
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
final int callingUserId = UserHandle.getCallingUserId();
List<ResolveInfo> list = queryIntentActivities(intent, null,
PackageManager.GET_META_DATA, callingUserId);
ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
true, false, false, callingUserId);
allHomeCandidates.clear();
if (list != null) {
for (ResolveInfo ri : list) {
allHomeCandidates.add(ri);
}
}
return (preferred == null || preferred.activityInfo == null)
? null
: new ComponentName(preferred.activityInfo.packageName,
preferred.activityInfo.name);
| public int | getInstallLocation()
return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
PackageHelper.APP_INSTALL_AUTO);
| public android.content.pm.ParceledListSlice | getInstalledApplications(int flags, int userId)
if (!sUserManager.exists(userId)) return null;
final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
// writer
synchronized (mPackages) {
ArrayList<ApplicationInfo> list;
if (listUninstalled) {
list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
for (PackageSetting ps : mSettings.mPackages.values()) {
ApplicationInfo ai;
if (ps.pkg != null) {
ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
ps.readUserState(userId), userId);
} else {
ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
}
if (ai != null) {
list.add(ai);
}
}
} else {
list = new ArrayList<ApplicationInfo>(mPackages.size());
for (PackageParser.Package p : mPackages.values()) {
if (p.mExtras != null) {
ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
((PackageSetting)p.mExtras).readUserState(userId), userId);
if (ai != null) {
list.add(ai);
}
}
}
}
return new ParceledListSlice<ApplicationInfo>(list);
}
| public android.content.pm.ParceledListSlice | getInstalledPackages(int flags, int userId)
final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages");
// writer
synchronized (mPackages) {
ArrayList<PackageInfo> list;
if (listUninstalled) {
list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
for (PackageSetting ps : mSettings.mPackages.values()) {
PackageInfo pi;
if (ps.pkg != null) {
pi = generatePackageInfo(ps.pkg, flags, userId);
} else {
pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
}
if (pi != null) {
list.add(pi);
}
}
} else {
list = new ArrayList<PackageInfo>(mPackages.size());
for (PackageParser.Package p : mPackages.values()) {
PackageInfo pi = generatePackageInfo(p, flags, userId);
if (pi != null) {
list.add(pi);
}
}
}
return new ParceledListSlice<PackageInfo>(list);
}
| public java.lang.String | getInstallerPackageName(java.lang.String packageName)
// reader
synchronized (mPackages) {
return mSettings.getInstallerPackageNameLPr(packageName);
}
| public android.content.pm.InstrumentationInfo | getInstrumentationInfo(android.content.ComponentName name, int flags)
// reader
synchronized (mPackages) {
final PackageParser.Instrumentation i = mInstrumentation.get(name);
return PackageParser.generateInstrumentationInfo(i, flags);
}
| public android.content.pm.KeySet | getKeySetByAlias(java.lang.String packageName, java.lang.String alias)
if (packageName == null || alias == null) {
return null;
}
synchronized(mPackages) {
final PackageParser.Package pkg = mPackages.get(packageName);
if (pkg == null) {
Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
throw new IllegalArgumentException("Unknown package: " + packageName);
}
KeySetManagerService ksms = mSettings.mKeySetManagerService;
return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
}
| public android.content.pm.ResolveInfo | getLastChosenActivity(android.content.Intent intent, java.lang.String resolvedType, int flags)
final int userId = UserHandle.getCallingUserId();
if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
return findPreferredActivity(intent, resolvedType, flags, query, 0,
false, false, false, userId);
| private java.util.List | getMatchingCrossProfileIntentFilters(android.content.Intent intent, java.lang.String resolvedType, int userId)
CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
if (resolver != null) {
return resolver.queryIntent(intent, resolvedType, false, userId);
}
return null;
| public java.lang.String | getNameForUid(int uid)
// reader
synchronized (mPackages) {
Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
if (obj instanceof SharedUserSetting) {
final SharedUserSetting sus = (SharedUserSetting) obj;
return sus.name + ":" + sus.userId;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
return ps.name;
}
}
return null;
| private static java.lang.String | getNextCodePath(java.lang.String oldCodePath, java.lang.String prefix, java.lang.String suffix)
String idxStr = "";
int idx = 1;
// Fall back to default value of idx=1 if prefix is not
// part of oldCodePath
if (oldCodePath != null) {
String subStr = oldCodePath;
// Drop the suffix right away
if (suffix != null && subStr.endsWith(suffix)) {
subStr = subStr.substring(0, subStr.length() - suffix.length());
}
// If oldCodePath already contains prefix find out the
// ending index to either increment or decrement.
int sidx = subStr.lastIndexOf(prefix);
if (sidx != -1) {
subStr = subStr.substring(sidx + prefix.length());
if (subStr != null) {
if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
}
try {
idx = Integer.parseInt(subStr);
if (idx <= 1) {
idx++;
} else {
idx--;
}
} catch(NumberFormatException e) {
}
}
}
}
idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
return prefix + idxStr;
| private java.io.File | getNextCodePath(java.lang.String packageName)
int suffix = 1;
File result;
do {
result = new File(mAppInstallDir, packageName + "-" + suffix);
suffix++;
} while (result.exists());
return result;
| public int[] | getPackageGids(java.lang.String packageName)
// reader
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
if (DEBUG_PACKAGE_INFO)
Log.v(TAG, "getPackageGids" + packageName + ": " + p);
if (p != null) {
final PackageSetting ps = (PackageSetting)p.mExtras;
return ps.getGids();
}
}
// stupid thing to indicate an error.
return new int[0];
| public android.content.pm.PackageInfo | getPackageInfo(java.lang.String packageName, int flags, int userId)
if (!sUserManager.exists(userId)) return null;
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info");
// reader
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
if (DEBUG_PACKAGE_INFO)
Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
if (p != null) {
return generatePackageInfo(p, flags, userId);
}
if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
}
}
return null;
| public android.content.pm.IPackageInstaller | getPackageInstaller()
return mInstallerService;
| private android.util.ArraySet | getPackageNamesForIntent(android.content.Intent intent)
List<ResolveInfo> ris = null;
try {
ris = AppGlobals.getPackageManager().queryIntentReceivers(
intent, null, 0, UserHandle.USER_OWNER);
} catch (RemoteException e) {
}
ArraySet<String> pkgNames = new ArraySet<String>();
if (ris != null) {
for (ResolveInfo ri : ris) {
pkgNames.add(ri.activityInfo.packageName);
}
}
return pkgNames;
| public void | getPackageSizeInfo(java.lang.String packageName, int userHandle, android.content.pm.IPackageStatsObserver observer)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.GET_PACKAGE_SIZE, null);
if (packageName == null) {
throw new IllegalArgumentException("Attempt to get size of null packageName");
}
PackageStats stats = new PackageStats(packageName, userHandle);
/*
* Queue up an async operation since the package measurement may take a
* little while.
*/
Message msg = mHandler.obtainMessage(INIT_COPY);
msg.obj = new MeasureParams(stats, observer);
mHandler.sendMessage(msg);
| private boolean | getPackageSizeInfoLI(java.lang.String packageName, int userHandle, android.content.pm.PackageStats pStats)
if (packageName == null) {
Slog.w(TAG, "Attempt to get size of null packageName.");
return false;
}
PackageParser.Package p;
boolean dataOnly = false;
String libDirRoot = null;
String asecPath = null;
PackageSetting ps = null;
synchronized (mPackages) {
p = mPackages.get(packageName);
ps = mSettings.mPackages.get(packageName);
if(p == null) {
dataOnly = true;
if((ps == null) || (ps.pkg == null)) {
Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
return false;
}
p = ps.pkg;
}
if (ps != null) {
libDirRoot = ps.legacyNativeLibraryPathString;
}
if (p != null && (isExternal(p) || isForwardLocked(p))) {
String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath());
if (secureContainerId != null) {
asecPath = PackageHelper.getSdFilesystem(secureContainerId);
}
}
}
String publicSrcDir = null;
if(!dataOnly) {
final ApplicationInfo applicationInfo = p.applicationInfo;
if (applicationInfo == null) {
Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
return false;
}
if (isForwardLocked(p)) {
publicSrcDir = applicationInfo.getBaseResourcePath();
}
}
// TODO: extend to measure size of split APKs
// TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree,
// not just the first level.
// TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not
// just the primary.
String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps));
int res = mInstaller.getSizeInfo(packageName, userHandle, p.baseCodePath, libDirRoot,
publicSrcDir, asecPath, dexCodeInstructionSets, pStats);
if (res < 0) {
return false;
}
// Fix-up for forward-locked applications in ASEC containers.
if (!isExternal(p)) {
pStats.codeSize += pStats.externalCodeSize;
pStats.externalCodeSize = 0L;
}
return true;
| public int | getPackageUid(java.lang.String packageName, int userId)
if (!sUserManager.exists(userId)) return -1;
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid");
// reader
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
if(p != null) {
return UserHandle.getUid(userId, p.applicationInfo.uid);
}
PackageSetting ps = mSettings.mPackages.get(packageName);
if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) {
return -1;
}
p = ps.pkg;
return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1;
}
| public java.lang.String[] | getPackagesForUid(int uid)
uid = UserHandle.getAppId(uid);
// reader
synchronized (mPackages) {
Object obj = mSettings.getUserIdLPr(uid);
if (obj instanceof SharedUserSetting) {
final SharedUserSetting sus = (SharedUserSetting) obj;
final int N = sus.packages.size();
final String[] res = new String[N];
final Iterator<PackageSetting> it = sus.packages.iterator();
int i = 0;
while (it.hasNext()) {
res[i++] = it.next().name;
}
return res;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
return new String[] { ps.name };
}
}
return null;
| public android.content.pm.ParceledListSlice | getPackagesHoldingPermissions(java.lang.String[] permissions, int flags, int userId)
if (!sUserManager.exists(userId)) return null;
final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
// writer
synchronized (mPackages) {
ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
boolean[] tmpBools = new boolean[permissions.length];
if (listUninstalled) {
for (PackageSetting ps : mSettings.mPackages.values()) {
addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
}
} else {
for (PackageParser.Package pkg : mPackages.values()) {
PackageSetting ps = (PackageSetting)pkg.mExtras;
if (ps != null) {
addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
userId);
}
}
}
return new ParceledListSlice<PackageInfo>(list);
}
| public android.util.ArraySet | getPackagesThatNeedDexOpt()
ArraySet<String> pkgs = null;
synchronized (mPackages) {
for (PackageParser.Package p : mPackages.values()) {
if (DEBUG_DEXOPT) {
Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray());
}
if (!p.mDexOptPerformed.isEmpty()) {
continue;
}
if (pkgs == null) {
pkgs = new ArraySet<String>();
}
pkgs.add(p.packageName);
}
}
return pkgs;
| public android.content.pm.PermissionGroupInfo | getPermissionGroupInfo(java.lang.String name, int flags)
// reader
synchronized (mPackages) {
return PackageParser.generatePermissionGroupInfo(
mPermissionGroups.get(name), flags);
}
| public android.content.pm.PermissionInfo | getPermissionInfo(java.lang.String name, int flags)
// reader
synchronized (mPackages) {
final BasePermission p = mSettings.mPermissions.get(name);
if (p != null) {
return generatePermissionInfo(p, flags);
}
return null;
}
| public java.util.List | getPersistentApplications(int flags)
final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
// reader
synchronized (mPackages) {
final Iterator<PackageParser.Package> i = mPackages.values().iterator();
final int userId = UserHandle.getCallingUserId();
while (i.hasNext()) {
final PackageParser.Package p = i.next();
if (p.applicationInfo != null
&& (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
&& (!mSafeMode || isSystemApp(p))) {
PackageSetting ps = mSettings.mPackages.get(p.packageName);
if (ps != null) {
ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
ps.readUserState(userId), userId);
if (ai != null) {
finalList.add(ai);
}
}
}
}
}
return finalList;
| public int | getPreferredActivities(java.util.List outFilters, java.util.List outActivities, java.lang.String packageName)
int num = 0;
final int userId = UserHandle.getCallingUserId();
// reader
synchronized (mPackages) {
PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
if (pir != null) {
final Iterator<PreferredActivity> it = pir.filterIterator();
while (it.hasNext()) {
final PreferredActivity pa = it.next();
if (packageName == null
|| (pa.mPref.mComponent.getPackageName().equals(packageName)
&& pa.mPref.mAlways)) {
if (outFilters != null) {
outFilters.add(new IntentFilter(pa));
}
if (outActivities != null) {
outActivities.add(pa.mPref.mComponent);
}
}
}
}
}
return num;
| private static java.lang.String | getPreferredInstructionSet()
if (sPreferredInstructionSet == null) {
sPreferredInstructionSet = VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);
}
return sPreferredInstructionSet;
| public java.util.List | getPreferredPackages(int flags)
return new ArrayList<PackageInfo>();
| private static java.lang.String | getPrimaryInstructionSet(android.content.pm.ApplicationInfo info)
if (info.primaryCpuAbi == null) {
return getPreferredInstructionSet();
}
return VMRuntime.getInstructionSet(info.primaryCpuAbi);
| public android.content.pm.ProviderInfo | getProviderInfo(android.content.ComponentName component, int flags, int userId)
if (!sUserManager.exists(userId)) return null;
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info");
synchronized (mPackages) {
PackageParser.Provider p = mProviders.mProviders.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(
TAG, "getProviderInfo " + component + ": " + p);
if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
userId);
}
}
return null;
| public android.content.pm.ActivityInfo | getReceiverInfo(android.content.ComponentName component, int flags, int userId)
if (!sUserManager.exists(userId)) return null;
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info");
synchronized (mPackages) {
PackageParser.Activity a = mReceivers.mActivities.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(
TAG, "getReceiverInfo " + component + ": " + a);
if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
userId);
}
}
return null;
| private java.lang.String | getRequiredVerifierLPr()
final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */);
String requiredVerifier = null;
final int N = receivers.size();
for (int i = 0; i < N; i++) {
final ResolveInfo info = receivers.get(i);
if (info.activityInfo == null) {
continue;
}
final String packageName = info.activityInfo.packageName;
final PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps == null) {
continue;
}
final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
if (!gp.grantedPermissions
.contains(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT)) {
continue;
}
if (requiredVerifier != null) {
throw new RuntimeException("There can be only one required verifier");
}
requiredVerifier = packageName;
}
return requiredVerifier;
| public android.content.pm.ServiceInfo | getServiceInfo(android.content.ComponentName component, int flags, int userId)
if (!sUserManager.exists(userId)) return null;
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info");
synchronized (mPackages) {
PackageParser.Service s = mServices.mServices.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(
TAG, "getServiceInfo " + component + ": " + s);
if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
userId);
}
}
return null;
| private static java.io.File | getSettingsProblemFile()
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
File fname = new File(systemDir, "uiderrors.txt");
return fname;
| public android.content.pm.KeySet | getSigningKeySet(java.lang.String packageName)
if (packageName == null) {
return null;
}
synchronized(mPackages) {
final PackageParser.Package pkg = mPackages.get(packageName);
if (pkg == null) {
Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
throw new IllegalArgumentException("Unknown package: " + packageName);
}
if (pkg.applicationInfo.uid != Binder.getCallingUid()
&& Process.SYSTEM_UID != Binder.getCallingUid()) {
throw new SecurityException("May not access signing KeySet of other apps.");
}
KeySetManagerService ksms = mSettings.mKeySetManagerService;
return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
}
| public android.content.pm.FeatureInfo[] | getSystemAvailableFeatures()
Collection<FeatureInfo> featSet;
synchronized (mPackages) {
featSet = mAvailableFeatures.values();
int size = featSet.size();
if (size > 0) {
FeatureInfo[] features = new FeatureInfo[size+1];
featSet.toArray(features);
FeatureInfo fi = new FeatureInfo();
fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
FeatureInfo.GL_ES_VERSION_UNDEFINED);
features[size] = fi;
return features;
}
}
return null;
| public java.lang.String[] | getSystemSharedLibraryNames()
Set<String> libSet;
synchronized (mPackages) {
libSet = mSharedLibraries.keySet();
int size = libSet.size();
if (size > 0) {
String[] libs = new String[size];
libSet.toArray(libs);
return libs;
}
}
return null;
| public int | getUidForSharedUser(java.lang.String sharedUserName)
if(sharedUserName == null) {
return -1;
}
// reader
synchronized (mPackages) {
final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, false);
if (suid == null) {
return -1;
}
return suid.userId;
}
| private int | getUidForVerifier(android.content.pm.VerifierInfo verifierInfo)
synchronized (mPackages) {
final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
if (pkg == null) {
return -1;
} else if (pkg.mSignatures.length != 1) {
Slog.i(TAG, "Verifier package " + verifierInfo.packageName
+ " has more than one signature; ignoring");
return -1;
}
/*
* If the public key of the package's signature does not match
* our expected public key, then this is a different package and
* we should skip.
*/
final byte[] expectedPublicKey;
try {
final Signature verifierSig = pkg.mSignatures[0];
final PublicKey publicKey = verifierSig.getPublicKey();
expectedPublicKey = publicKey.getEncoded();
} catch (CertificateException e) {
return -1;
}
final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
Slog.i(TAG, "Verifier package " + verifierInfo.packageName
+ " does not have the expected public key; ignoring");
return -1;
}
return pkg.applicationInfo.uid;
}
| private int | getUidTargetSdkVersionLockedLPr(int uid)
Object obj = mSettings.getUserIdLPr(uid);
if (obj instanceof SharedUserSetting) {
final SharedUserSetting sus = (SharedUserSetting) obj;
int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
final Iterator<PackageSetting> it = sus.packages.iterator();
while (it.hasNext()) {
final PackageSetting ps = it.next();
if (ps.pkg != null) {
int v = ps.pkg.applicationInfo.targetSdkVersion;
if (v < vers) vers = v;
}
}
return vers;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
if (ps.pkg != null) {
return ps.pkg.applicationInfo.targetSdkVersion;
}
}
return Build.VERSION_CODES.CUR_DEVELOPMENT;
| private int | getUnknownSourcesSettings()Get the "allow unknown sources" setting.
return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
android.provider.Settings.Global.INSTALL_NON_MARKET_APPS,
-1);
| public void | getUsageStatsIfNoPackageUsageInfo()
if (!mPackageUsage.isHistoricalPackageUsageAvailable()) {
UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE);
if (usm == null) {
throw new IllegalStateException("UsageStatsManager must be initialized");
}
long now = System.currentTimeMillis();
Map<String, UsageStats> stats = usm.queryAndAggregateUsageStats(now - mDexOptLRUThresholdInMills, now);
for (Map.Entry<String, UsageStats> entry : stats.entrySet()) {
String packageName = entry.getKey();
PackageParser.Package pkg = mPackages.get(packageName);
if (pkg == null) {
continue;
}
UsageStats usage = entry.getValue();
pkg.mLastPackageUsageTimeInMills = usage.getLastTimeUsed();
mPackageUsage.mIsHistoricalPackageUsageAvailable = true;
}
}
| private long | getVerificationTimeout()Get the verification agent timeout.
return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
DEFAULT_VERIFICATION_TIMEOUT);
| public android.content.pm.VerifierDeviceIdentity | getVerifierDeviceIdentity()
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
"Only package verification agents can read the verifier device identity");
synchronized (mPackages) {
return mSettings.getVerifierDeviceIdentityLPw();
}
| public void | grantPermission(java.lang.String packageName, java.lang.String permissionName)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
synchronized (mPackages) {
final PackageParser.Package pkg = mPackages.get(packageName);
if (pkg == null) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
final BasePermission bp = mSettings.mPermissions.get(permissionName);
if (bp == null) {
throw new IllegalArgumentException("Unknown permission: " + permissionName);
}
checkGrantRevokePermissions(pkg, bp);
final PackageSetting ps = (PackageSetting) pkg.mExtras;
if (ps == null) {
return;
}
final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
if (gp.grantedPermissions.add(permissionName)) {
if (ps.haveGids) {
gp.gids = appendInts(gp.gids, bp.gids);
}
mSettings.writeLPr();
}
}
| private void | grantPermissionsLPw(PackageParser.Package pkg, boolean replace, java.lang.String packageOfInterest)
final PackageSetting ps = (PackageSetting) pkg.mExtras;
if (ps == null) {
return;
}
final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
ArraySet<String> origPermissions = gp.grantedPermissions;
boolean changedPermission = false;
if (replace) {
ps.permissionsFixed = false;
if (gp == ps) {
origPermissions = new ArraySet<String>(gp.grantedPermissions);
gp.grantedPermissions.clear();
gp.gids = mGlobalGids;
}
}
if (gp.gids == null) {
gp.gids = mGlobalGids;
}
final int N = pkg.requestedPermissions.size();
for (int i=0; i<N; i++) {
final String name = pkg.requestedPermissions.get(i);
final boolean required = pkg.requestedPermissionsRequired.get(i);
final BasePermission bp = mSettings.mPermissions.get(name);
if (DEBUG_INSTALL) {
if (gp != ps) {
Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
}
}
if (bp == null || bp.packageSetting == null) {
if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
Slog.w(TAG, "Unknown permission " + name
+ " in package " + pkg.packageName);
}
continue;
}
final String perm = bp.name;
boolean allowed;
boolean allowedSig = false;
if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
// Keep track of app op permissions.
ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
if (pkgs == null) {
pkgs = new ArraySet<>();
mAppOpPermissionPackages.put(bp.name, pkgs);
}
pkgs.add(pkg.packageName);
}
final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
if (level == PermissionInfo.PROTECTION_NORMAL
|| level == PermissionInfo.PROTECTION_DANGEROUS) {
// We grant a normal or dangerous permission if any of the following
// are true:
// 1) The permission is required
// 2) The permission is optional, but was granted in the past
// 3) The permission is optional, but was requested by an
// app in /system (not /data)
//
// Otherwise, reject the permission.
allowed = (required || origPermissions.contains(perm)
|| (isSystemApp(ps) && !isUpdatedSystemApp(ps)));
} else if (bp.packageSetting == null) {
// This permission is invalid; skip it.
allowed = false;
} else if (level == PermissionInfo.PROTECTION_SIGNATURE) {
allowed = grantSignaturePermission(perm, pkg, bp, origPermissions);
if (allowed) {
allowedSig = true;
}
} else {
allowed = false;
}
if (DEBUG_INSTALL) {
if (gp != ps) {
Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
}
}
if (allowed) {
if (!isSystemApp(ps) && ps.permissionsFixed) {
// If this is an existing, non-system package, then
// we can't add any new permissions to it.
if (!allowedSig && !gp.grantedPermissions.contains(perm)) {
// Except... if this is a permission that was added
// to the platform (note: need to only do this when
// updating the platform).
allowed = isNewPlatformPermissionForPackage(perm, pkg);
}
}
if (allowed) {
if (!gp.grantedPermissions.contains(perm)) {
changedPermission = true;
gp.grantedPermissions.add(perm);
gp.gids = appendInts(gp.gids, bp.gids);
} else if (!ps.haveGids) {
gp.gids = appendInts(gp.gids, bp.gids);
}
} else {
if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
Slog.w(TAG, "Not granting permission " + perm
+ " to package " + pkg.packageName
+ " because it was previously installed without");
}
}
} else {
if (gp.grantedPermissions.remove(perm)) {
changedPermission = true;
gp.gids = removeInts(gp.gids, bp.gids);
Slog.i(TAG, "Un-granting permission " + perm
+ " from package " + pkg.packageName
+ " (protectionLevel=" + bp.protectionLevel
+ " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
+ ")");
} else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
// Don't print warning for app op permissions, since it is fine for them
// not to be granted, there is a UI for the user to decide.
if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
Slog.w(TAG, "Not granting permission " + perm
+ " to package " + pkg.packageName
+ " (protectionLevel=" + bp.protectionLevel
+ " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
+ ")");
}
}
}
}
if ((changedPermission || replace) && !ps.permissionsFixed &&
!isSystemApp(ps) || isUpdatedSystemApp(ps)){
// This is the first that we have heard about this package, so the
// permissions we have now selected are fixed until explicitly
// changed.
ps.permissionsFixed = true;
}
ps.haveGids = true;
| private boolean | grantSignaturePermission(java.lang.String perm, PackageParser.Package pkg, BasePermission bp, android.util.ArraySet origPermissions)
boolean allowed;
allowed = (compareSignatures(
bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
== PackageManager.SIGNATURE_MATCH)
|| (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
== PackageManager.SIGNATURE_MATCH);
if (!allowed && (bp.protectionLevel
& PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
if (isSystemApp(pkg)) {
// For updated system applications, a system permission
// is granted only if it had been defined by the original application.
if (isUpdatedSystemApp(pkg)) {
final PackageSetting sysPs = mSettings
.getDisabledSystemPkgLPr(pkg.packageName);
final GrantedPermissions origGp = sysPs.sharedUser != null
? sysPs.sharedUser : sysPs;
if (origGp.grantedPermissions.contains(perm)) {
// If the original was granted this permission, we take
// that grant decision as read and propagate it to the
// update.
if (sysPs.isPrivileged()) {
allowed = true;
}
} else {
// The system apk may have been updated with an older
// version of the one on the data partition, but which
// granted a new system permission that it didn't have
// before. In this case we do want to allow the app to
// now get the new permission if the ancestral apk is
// privileged to get it.
if (sysPs.pkg != null && sysPs.isPrivileged()) {
for (int j=0;
j<sysPs.pkg.requestedPermissions.size(); j++) {
if (perm.equals(
sysPs.pkg.requestedPermissions.get(j))) {
allowed = true;
break;
}
}
}
}
} else {
allowed = isPrivilegedApp(pkg);
}
}
}
if (!allowed && (bp.protectionLevel
& PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
// For development permissions, a development permission
// is granted only if it was already granted.
allowed = origPermissions.contains(perm);
}
return allowed;
| private static boolean | hasPermission(PackageParser.Package pkgInfo, java.lang.String perm)
for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
return true;
}
}
return false;
| private static boolean | hasString(java.util.List list, java.util.List which)
if (list == null) {
return false;
}
for (int i=list.size()-1; i>=0; i--) {
for (int j=which.size()-1; j>=0; j--) {
if (which.get(j).equals(list.get(i))) {
return true;
}
}
}
return false;
| public boolean | hasSystemFeature(java.lang.String name)
synchronized (mPackages) {
return mAvailableFeatures.containsKey(name);
}
| public boolean | hasSystemUidErrors()
return mHasSystemUidErrors;
| private static boolean | ignoreCodePath(java.lang.String fullPathStr)
String apkName = deriveCodePathName(fullPathStr);
int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX);
if (idx != -1 && ((idx+1) < apkName.length())) {
// Make sure the package ends with a numeral
String version = apkName.substring(idx+1);
try {
Integer.parseInt(version);
return true;
} catch (NumberFormatException e) {}
}
return false;
| public int | installExistingPackageAsUser(java.lang.String packageName, int userId)
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
null);
PackageSetting pkgSetting;
final int uid = Binder.getCallingUid();
enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user "
+ userId);
if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
}
long callingId = Binder.clearCallingIdentity();
try {
boolean sendAdded = false;
Bundle extras = new Bundle(1);
// writer
synchronized (mPackages) {
pkgSetting = mSettings.mPackages.get(packageName);
if (pkgSetting == null) {
return PackageManager.INSTALL_FAILED_INVALID_URI;
}
if (!pkgSetting.getInstalled(userId)) {
pkgSetting.setInstalled(true, userId);
pkgSetting.setHidden(false, userId);
mSettings.writePackageRestrictionsLPr(userId);
sendAdded = true;
}
}
if (sendAdded) {
sendPackageAddedForUser(packageName, pkgSetting, userId);
}
} finally {
Binder.restoreCallingIdentity(callingId);
}
return PackageManager.INSTALL_SUCCEEDED;
| private static boolean | installForwardLocked(int installFlags)Used during creation of InstallArgs
return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
| private void | installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, android.os.UserHandle user, java.lang.String installerPackageName, com.android.server.pm.PackageManagerService$PackageInstalledInfo res)
// Remember this for later, in case we need to rollback this install
String pkgName = pkg.packageName;
if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists();
synchronized(mPackages) {
if (mSettings.mRenamedPackages.containsKey(pkgName)) {
// A package with the same name is already installed, though
// it has been renamed to an older name. The package we
// are trying to install should be installed as an update to
// the existing one, but that has not been requested, so bail.
res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
+ " without first uninstalling package running as "
+ mSettings.mRenamedPackages.get(pkgName));
return;
}
if (mPackages.containsKey(pkgName)) {
// Don't allow installation over an existing package with the same name.
res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
+ " without first uninstalling.");
return;
}
}
try {
PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanFlags,
System.currentTimeMillis(), user);
updateSettingsLI(newPackage, installerPackageName, null, null, res);
// delete the partially installed application. the data directory will have to be
// restored if it was already existing
if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
// remove package from internal structures. Note that we want deletePackageX to
// delete the package data and cache directories that it created in
// scanPackageLocked, unless those directories existed before we even tried to
// install.
deletePackageLI(pkgName, UserHandle.ALL, false, null, null,
dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0,
res.removedInfo, true);
}
} catch (PackageManagerException e) {
res.setError("Package couldn't be installed in " + pkg.codePath, e);
}
| private static boolean | installOnSd(int installFlags)Used during creation of InstallArgs
if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
return false;
}
if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
return true;
}
return false;
| public void | installPackage(java.lang.String originPath, android.content.pm.IPackageInstallObserver2 observer, int installFlags, java.lang.String installerPackageName, android.content.pm.VerificationParams verificationParams, java.lang.String packageAbiOverride)
installPackageAsUser(originPath, observer, installFlags, installerPackageName, verificationParams,
packageAbiOverride, UserHandle.getCallingUserId());
| public void | installPackageAsUser(java.lang.String originPath, android.content.pm.IPackageInstallObserver2 observer, int installFlags, java.lang.String installerPackageName, android.content.pm.VerificationParams verificationParams, java.lang.String packageAbiOverride, int userId)
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
final int callingUid = Binder.getCallingUid();
enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser");
if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
try {
if (observer != null) {
observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
}
} catch (RemoteException re) {
}
return;
}
if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
installFlags |= PackageManager.INSTALL_FROM_ADB;
} else {
// Caller holds INSTALL_PACKAGES permission, so we're less strict
// about installerPackageName.
installFlags &= ~PackageManager.INSTALL_FROM_ADB;
installFlags &= ~PackageManager.INSTALL_ALL_USERS;
}
UserHandle user;
if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
user = UserHandle.ALL;
} else {
user = new UserHandle(userId);
}
verificationParams.setInstallerUid(callingUid);
final File originFile = new File(originPath);
final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
final Message msg = mHandler.obtainMessage(INIT_COPY);
msg.obj = new InstallParams(origin, observer, installFlags,
installerPackageName, verificationParams, user, packageAbiOverride);
mHandler.sendMessage(msg);
| private void | installPackageLI(com.android.server.pm.PackageManagerService$InstallArgs args, com.android.server.pm.PackageManagerService$PackageInstalledInfo res)
final int installFlags = args.installFlags;
String installerPackageName = args.installerPackageName;
File tmpPackageFile = new File(args.getCodePath());
boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
boolean onSd = ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0);
boolean replace = false;
final int scanFlags = SCAN_NEW_INSTALL | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE;
// Result object to be returned
res.returnCode = PackageManager.INSTALL_SUCCEEDED;
if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
// Retrieve PackageSettings and parse package
final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
| (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
| (onSd ? PackageParser.PARSE_ON_SDCARD : 0);
PackageParser pp = new PackageParser();
pp.setSeparateProcesses(mSeparateProcesses);
pp.setDisplayMetrics(mMetrics);
final PackageParser.Package pkg;
try {
pkg = pp.parsePackage(tmpPackageFile, parseFlags);
} catch (PackageParserException e) {
res.setError("Failed parse during installPackageLI", e);
return;
}
// Mark that we have an install time CPU ABI override.
pkg.cpuAbiOverride = args.abiOverride;
String pkgName = res.name = pkg.packageName;
if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
return;
}
}
try {
pp.collectCertificates(pkg, parseFlags);
pp.collectManifestDigest(pkg);
} catch (PackageParserException e) {
res.setError("Failed collect during installPackageLI", e);
return;
}
/* If the installer passed in a manifest digest, compare it now. */
if (args.manifestDigest != null) {
if (DEBUG_INSTALL) {
final String parsedManifest = pkg.manifestDigest == null ? "null"
: pkg.manifestDigest.toString();
Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
+ parsedManifest);
}
if (!args.manifestDigest.equals(pkg.manifestDigest)) {
res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed");
return;
}
} else if (DEBUG_INSTALL) {
final String parsedManifest = pkg.manifestDigest == null
? "null" : pkg.manifestDigest.toString();
Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest);
}
// Get rid of all references to package scan path via parser.
pp = null;
String oldCodePath = null;
boolean systemApp = false;
synchronized (mPackages) {
// Check if installing already existing package
if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
String oldName = mSettings.mRenamedPackages.get(pkgName);
if (pkg.mOriginalPackages != null
&& pkg.mOriginalPackages.contains(oldName)
&& mPackages.containsKey(oldName)) {
// This package is derived from an original package,
// and this device has been updating from that original
// name. We must continue using the original name, so
// rename the new package here.
pkg.setPackageName(oldName);
pkgName = pkg.packageName;
replace = true;
if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
+ oldName + " pkgName=" + pkgName);
} else if (mPackages.containsKey(pkgName)) {
// This package, under its official name, already exists
// on the device; we should replace it.
replace = true;
if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
}
}
PackageSetting ps = mSettings.mPackages.get(pkgName);
if (ps != null) {
if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
// Quick sanity check that we're signed correctly if updating;
// we'll check this again later when scanning, but we want to
// bail early here before tripping over redefined permissions.
if (!ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) {
try {
verifySignaturesLP(ps, pkg);
} catch (PackageManagerException e) {
res.setError(e.error, e.getMessage());
return;
}
} else {
if (!checkUpgradeKeySetLP(ps, pkg)) {
res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
+ pkg.packageName + " upgrade keys do not match the "
+ "previously installed version");
return;
}
}
oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
if (ps.pkg != null && ps.pkg.applicationInfo != null) {
systemApp = (ps.pkg.applicationInfo.flags &
ApplicationInfo.FLAG_SYSTEM) != 0;
}
res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
}
// Check whether the newly-scanned package wants to define an already-defined perm
int N = pkg.permissions.size();
for (int i = N-1; i >= 0; i--) {
PackageParser.Permission perm = pkg.permissions.get(i);
BasePermission bp = mSettings.mPermissions.get(perm.info.name);
if (bp != null) {
// If the defining package is signed with our cert, it's okay. This
// also includes the "updating the same package" case, of course.
// "updating same package" could also involve key-rotation.
final boolean sigsOk;
if (!bp.sourcePackage.equals(pkg.packageName)
|| !(bp.packageSetting instanceof PackageSetting)
|| !bp.packageSetting.keySetData.isUsingUpgradeKeySets()
|| ((PackageSetting) bp.packageSetting).sharedUser != null) {
sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
} else {
sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
}
if (!sigsOk) {
// If the owning package is the system itself, we log but allow
// install to proceed; we fail the install on all other permission
// redefinitions.
if (!bp.sourcePackage.equals("android")) {
res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
+ pkg.packageName + " attempting to redeclare permission "
+ perm.info.name + " already owned by " + bp.sourcePackage);
res.origPermission = perm.info.name;
res.origPackage = bp.sourcePackage;
return;
} else {
Slog.w(TAG, "Package " + pkg.packageName
+ " attempting to redeclare system permission "
+ perm.info.name + "; ignoring new declaration");
pkg.permissions.remove(i);
}
}
}
}
}
if (systemApp && onSd) {
// Disable updates to system apps on sdcard
res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
"Cannot install updates to system apps on sdcard");
return;
}
if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
return;
}
if (replace) {
replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
installerPackageName, res);
} else {
installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
args.user, installerPackageName, res);
}
synchronized (mPackages) {
final PackageSetting ps = mSettings.mPackages.get(pkgName);
if (ps != null) {
res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
}
}
| void | installStage(java.lang.String packageName, java.io.File stagedDir, java.lang.String stagedCid, android.content.pm.IPackageInstallObserver2 observer, PackageInstaller.SessionParams params, java.lang.String installerPackageName, int installerUid, android.os.UserHandle user)
final VerificationParams verifParams = new VerificationParams(null, params.originatingUri,
params.referrerUri, installerUid, null);
final OriginInfo origin;
if (stagedDir != null) {
origin = OriginInfo.fromStagedFile(stagedDir);
} else {
origin = OriginInfo.fromStagedContainer(stagedCid);
}
final Message msg = mHandler.obtainMessage(INIT_COPY);
msg.obj = new InstallParams(origin, observer, params.installFlags,
installerPackageName, verifParams, user, params.abiOverride);
mHandler.sendMessage(msg);
| private boolean | isAsecExternal(java.lang.String cid)
final String asecPath = PackageHelper.getSdFilesystem(cid);
return !asecPath.startsWith(mAsecInternalPath);
| private boolean | isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg)If the database version for this type of package (internal storage or
external storage) is less than the version where package signatures
were updated, return true.
return (isExternal(scannedPkg) && mSettings.isExternalDatabaseVersionOlderThan(
DatabaseVersion.SIGNATURE_END_ENTITY))
|| (!isExternal(scannedPkg) && mSettings.isInternalDatabaseVersionOlderThan(
DatabaseVersion.SIGNATURE_END_ENTITY));
| private static boolean | isExternal(PackageParser.Package pkg)
return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
| private static boolean | isExternal(PackageSetting ps)
return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
| private static boolean | isExternal(android.content.pm.ApplicationInfo info)
return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
| private boolean | isExternalMediaAvailable()Check if the external storage media is available. This is true if there
is a mounted external storage medium or if the external storage is
emulated.
return mMediaMounted || Environment.isExternalStorageEmulated();
| public boolean | isFirstBoot()
return !mRestoredSettings;
| private static boolean | isForwardLocked(PackageParser.Package pkg)
return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
| private static boolean | isForwardLocked(android.content.pm.ApplicationInfo info)
return (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
| private boolean | isForwardLocked(PackageSetting ps)
return (ps.pkgFlags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
| private static boolean | isMultiArch(PackageSetting ps)
return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0;
| private static boolean | isMultiArch(android.content.pm.ApplicationInfo info)
return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
| private boolean | isNewPlatformPermissionForPackage(java.lang.String perm, PackageParser.Package pkg)
boolean allowed = false;
final int NP = PackageParser.NEW_PERMISSIONS.length;
for (int ip=0; ip<NP; ip++) {
final PackageParser.NewPermissionInfo npi
= PackageParser.NEW_PERMISSIONS[ip];
if (npi.name.equals(perm)
&& pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
allowed = true;
Log.i(TAG, "Auto-granting " + perm + " to old pkg "
+ pkg.packageName);
break;
}
}
return allowed;
| public boolean | isOnlyCoreApps()
return mOnlyCore;
| public boolean | isPackageAvailable(java.lang.String packageName, int userId)
if (!sUserManager.exists(userId)) return false;
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available");
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
if (p != null) {
final PackageSetting ps = (PackageSetting) p.mExtras;
if (ps != null) {
final PackageUserState state = ps.readUserState(userId);
if (state != null) {
return PackageParser.isAvailable(state);
}
}
}
}
return false;
| private boolean | isPackageDeviceAdmin(java.lang.String packageName, int userId)
IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
try {
if (dpm != null) {
if (dpm.isDeviceOwner(packageName)) {
return true;
}
int[] users;
if (userId == UserHandle.USER_ALL) {
users = sUserManager.getUserIds();
} else {
users = new int[]{userId};
}
for (int i = 0; i < users.length; ++i) {
if (dpm.packageHasActiveAdmins(packageName, users[i])) {
return true;
}
}
}
} catch (RemoteException e) {
}
return false;
| public boolean | isPackageSignedByKeySet(java.lang.String packageName, android.content.pm.KeySet ks)
if (packageName == null || ks == null) {
return false;
}
synchronized(mPackages) {
final PackageParser.Package pkg = mPackages.get(packageName);
if (pkg == null) {
Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
throw new IllegalArgumentException("Unknown package: " + packageName);
}
IBinder ksh = ks.getToken();
if (ksh instanceof KeySetHandle) {
KeySetManagerService ksms = mSettings.mKeySetManagerService;
return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
}
return false;
}
| public boolean | isPackageSignedByKeySetExactly(java.lang.String packageName, android.content.pm.KeySet ks)
if (packageName == null || ks == null) {
return false;
}
synchronized(mPackages) {
final PackageParser.Package pkg = mPackages.get(packageName);
if (pkg == null) {
Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
throw new IllegalArgumentException("Unknown package: " + packageName);
}
IBinder ksh = ks.getToken();
if (ksh instanceof KeySetHandle) {
KeySetManagerService ksms = mSettings.mKeySetManagerService;
return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
}
return false;
}
| public boolean | isPermissionEnforced(java.lang.String permission)
return true;
| private static boolean | isPrivilegedApp(PackageParser.Package pkg)
return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PRIVILEGED) != 0;
| public boolean | isProtectedBroadcast(java.lang.String actionName)
synchronized (mPackages) {
return mProtectedBroadcasts.contains(actionName);
}
| private boolean | isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg)
if (isExternal(scannedPkg)) {
return mSettings.isExternalDatabaseVersionOlderThan(
DatabaseVersion.SIGNATURE_MALFORMED_RECOVER);
} else {
return mSettings.isInternalDatabaseVersionOlderThan(
DatabaseVersion.SIGNATURE_MALFORMED_RECOVER);
}
| public boolean | isSafeMode()
return mSafeMode;
| public boolean | isStorageLow()
final long token = Binder.clearCallingIdentity();
try {
final DeviceStorageMonitorInternal
dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
if (dsm != null) {
return dsm.isMemoryLow();
} else {
return false;
}
} finally {
Binder.restoreCallingIdentity(token);
}
| private static boolean | isSystemApp(PackageParser.Package pkg)
return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
| private static boolean | isSystemApp(android.content.pm.ApplicationInfo info)
return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
| private static boolean | isSystemApp(PackageSetting ps)
return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
| public boolean | isUidPrivileged(int uid)
uid = UserHandle.getAppId(uid);
// reader
synchronized (mPackages) {
Object obj = mSettings.getUserIdLPr(uid);
if (obj instanceof SharedUserSetting) {
final SharedUserSetting sus = (SharedUserSetting) obj;
final Iterator<PackageSetting> it = sus.packages.iterator();
while (it.hasNext()) {
if (it.next().isPrivileged()) {
return true;
}
}
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
return ps.isPrivileged();
}
}
return false;
| private static boolean | isUpdatedSystemApp(PackageSetting ps)
return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
| private static boolean | isUpdatedSystemApp(PackageParser.Package pkg)
return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
| private static boolean | isUpdatedSystemApp(android.content.pm.ApplicationInfo info)
return (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
| public boolean | isUpgrade()
return mIsUpgrade;
| boolean | isUserRestricted(int userId, java.lang.String restrictionKey)
Bundle restrictions = sUserManager.getUserRestrictions(userId);
if (restrictions.getBoolean(restrictionKey, false)) {
Log.w(TAG, "User is restricted: " + restrictionKey);
return true;
}
return false;
| private boolean | isVerificationEnabled(int userId, int installFlags)Check whether or not package verification has been enabled.
if (!DEFAULT_VERIFY_ENABLE) {
return false;
}
boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
// Check if installing from ADB
if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
// Do not run verification in a test harness environment
if (ActivityManager.isRunningInTestHarness()) {
return false;
}
if (ensureVerifyAppsEnabled) {
return true;
}
// Check if the developer does not want package verification for ADB installs
if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
return false;
}
}
if (ensureVerifyAppsEnabled) {
return true;
}
return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
| private void | killApplication(java.lang.String pkgName, int appId, java.lang.String reason)
// Request the ActivityManager to kill the process(only for existing packages)
// so that we do not end up in a confused state while the user is still using the older
// version of the application while the new one gets installed.
IActivityManager am = ActivityManagerNative.getDefault();
if (am != null) {
try {
am.killApplicationWithAppId(pkgName, appId, reason);
} catch (RemoteException e) {
}
}
| private void | loadMediaPackages(android.util.ArrayMap processCids, int[] uidArr)
ArrayList<String> pkgList = new ArrayList<String>();
Set<AsecInstallArgs> keys = processCids.keySet();
for (AsecInstallArgs args : keys) {
String codePath = processCids.get(args);
if (DEBUG_SD_INSTALL)
Log.i(TAG, "Loading container : " + args.cid);
int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
try {
// Make sure there are no container errors first.
if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
Slog.e(TAG, "Failed to mount cid : " + args.cid
+ " when installing from sdcard");
continue;
}
// Check code path here.
if (codePath == null || !codePath.startsWith(args.getCodePath())) {
Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
+ " does not match one in settings " + codePath);
continue;
}
// Parse package
int parseFlags = mDefParseFlags;
if (args.isExternal()) {
parseFlags |= PackageParser.PARSE_ON_SDCARD;
}
if (args.isFwdLocked()) {
parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
}
synchronized (mInstallLock) {
PackageParser.Package pkg = null;
try {
pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null);
} catch (PackageManagerException e) {
Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
}
// Scan the package
if (pkg != null) {
/*
* TODO why is the lock being held? doPostInstall is
* called in other places without the lock. This needs
* to be straightened out.
*/
// writer
synchronized (mPackages) {
retCode = PackageManager.INSTALL_SUCCEEDED;
pkgList.add(pkg.packageName);
// Post process args
args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
pkg.applicationInfo.uid);
}
} else {
Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard");
}
}
} finally {
if (retCode != PackageManager.INSTALL_SUCCEEDED) {
Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
}
}
}
// writer
synchronized (mPackages) {
// If the platform SDK has changed since the last time we booted,
// we need to re-grant app permission to catch any new ones that
// appear. This is really a hack, and means that apps can in some
// cases get permissions that the user didn't initially explicitly
// allow... it would be nice to have some better way to handle
// this situation.
final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion;
if (regrantPermissions)
Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to "
+ mSdkVersion + "; regranting permissions for external storage");
mSettings.mExternalSdkPlatform = mSdkVersion;
// Make sure group IDs have been assigned, and any permission
// changes in other apps are accounted for
updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
| (regrantPermissions
? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
: 0));
mSettings.updateExternalDatabaseVersion();
// can downgrade to reader
// Persist settings
mSettings.writeLPr();
}
// Send a broadcast to let everyone know we are done processing
if (pkgList.size() > 0) {
sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
}
| static boolean | locationIsPrivileged(java.io.File path)
try {
final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
.getCanonicalPath();
return path.getCanonicalPath().startsWith(privilegedAppDir);
} catch (IOException e) {
Slog.e(TAG, "Unable to access code path " + path);
}
return false;
| static void | logCriticalInfo(int priority, java.lang.String msg)
Slog.println(priority, TAG, msg);
EventLogTags.writePmCriticalInfo(msg);
try {
File fname = getSettingsProblemFile();
FileOutputStream out = new FileOutputStream(fname, true);
PrintWriter pw = new FastPrintWriter(out);
SimpleDateFormat formatter = new SimpleDateFormat();
String dateString = formatter.format(new Date(System.currentTimeMillis()));
pw.println(dateString + ": " + msg);
pw.close();
FileUtils.setPermissions(
fname.toString(),
FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
-1, -1);
} catch (java.io.IOException e) {
}
| public static final com.android.server.pm.PackageManagerService | main(android.content.Context context, Installer installer, boolean factoryTest, boolean onlyCore)
PackageManagerService m = new PackageManagerService(context, installer,
factoryTest, onlyCore);
ServiceManager.addService("package", m);
return m;
| private android.content.ComponentName | matchComponentForVerifier(java.lang.String packageName, java.util.List receivers)
ActivityInfo targetReceiver = null;
final int NR = receivers.size();
for (int i = 0; i < NR; i++) {
final ResolveInfo info = receivers.get(i);
if (info.activityInfo == null) {
continue;
}
if (packageName.equals(info.activityInfo.packageName)) {
targetReceiver = info.activityInfo;
break;
}
}
if (targetReceiver == null) {
return null;
}
return new ComponentName(targetReceiver.packageName, targetReceiver.name);
| private java.util.List | matchVerifiers(android.content.pm.PackageInfoLite pkgInfo, java.util.List receivers, PackageVerificationState verificationState)
if (pkgInfo.verifiers.length == 0) {
return null;
}
final int N = pkgInfo.verifiers.length;
final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
for (int i = 0; i < N; i++) {
final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
receivers);
if (comp == null) {
continue;
}
final int verifierUid = getUidForVerifier(verifierInfo);
if (verifierUid == -1) {
continue;
}
if (DEBUG_VERIFY) {
Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
+ " with the correct signature");
}
sufficientVerifiers.add(comp);
verificationState.addSufficientVerifier(verifierUid);
}
return sufficientVerifiers;
| private static void | maybeThrowExceptionForMultiArchCopy(java.lang.String message, int copyRet)
if (copyRet < 0) {
if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
throw new PackageManagerException(copyRet, message);
}
}
| public void | movePackage(java.lang.String packageName, android.content.pm.IPackageMoveObserver observer, int flags)Binder call
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
UserHandle user = new UserHandle(UserHandle.getCallingUserId());
int returnCode = PackageManager.MOVE_SUCCEEDED;
int currInstallFlags = 0;
int newInstallFlags = 0;
File codeFile = null;
String installerPackageName = null;
String packageAbiOverride = null;
// reader
synchronized (mPackages) {
final PackageParser.Package pkg = mPackages.get(packageName);
final PackageSetting ps = mSettings.mPackages.get(packageName);
if (pkg == null || ps == null) {
returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
} else {
// Disable moving fwd locked apps and system packages
if (pkg.applicationInfo != null && isSystemApp(pkg)) {
Slog.w(TAG, "Cannot move system application");
returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
} else if (pkg.mOperationPending) {
Slog.w(TAG, "Attempt to move package which has pending operations");
returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING;
} else {
// Find install location first
if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
&& (flags & PackageManager.MOVE_INTERNAL) != 0) {
Slog.w(TAG, "Ambigous flags specified for move location.");
returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
} else {
newInstallFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
currInstallFlags = isExternal(pkg)
? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
if (newInstallFlags == currInstallFlags) {
Slog.w(TAG, "No move required. Trying to move to same location");
returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
} else {
if (isForwardLocked(pkg)) {
currInstallFlags |= PackageManager.INSTALL_FORWARD_LOCK;
newInstallFlags |= PackageManager.INSTALL_FORWARD_LOCK;
}
}
}
if (returnCode == PackageManager.MOVE_SUCCEEDED) {
pkg.mOperationPending = true;
}
}
codeFile = new File(pkg.codePath);
installerPackageName = ps.installerPackageName;
packageAbiOverride = ps.cpuAbiOverrideString;
}
}
if (returnCode != PackageManager.MOVE_SUCCEEDED) {
try {
observer.packageMoved(packageName, returnCode);
} catch (RemoteException ignored) {
}
return;
}
final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
@Override
public void onUserActionRequired(Intent intent) throws RemoteException {
throw new IllegalStateException();
}
@Override
public void onPackageInstalled(String basePackageName, int returnCode, String msg,
Bundle extras) throws RemoteException {
Slog.d(TAG, "Install result for move: "
+ PackageManager.installStatusToString(returnCode, msg));
// We usually have a new package now after the install, but if
// we failed we need to clear the pending flag on the original
// package object.
synchronized (mPackages) {
final PackageParser.Package pkg = mPackages.get(packageName);
if (pkg != null) {
pkg.mOperationPending = false;
}
}
final int status = PackageManager.installStatusToPublicStatus(returnCode);
switch (status) {
case PackageInstaller.STATUS_SUCCESS:
observer.packageMoved(packageName, PackageManager.MOVE_SUCCEEDED);
break;
case PackageInstaller.STATUS_FAILURE_STORAGE:
observer.packageMoved(packageName, PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
break;
default:
observer.packageMoved(packageName, PackageManager.MOVE_FAILED_INTERNAL_ERROR);
break;
}
}
};
// Treat a move like reinstalling an existing app, which ensures that we
// process everythign uniformly, like unpacking native libraries.
newInstallFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
final Message msg = mHandler.obtainMessage(INIT_COPY);
final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
msg.obj = new InstallParams(origin, installObserver, newInstallFlags,
installerPackageName, null, user, packageAbiOverride);
mHandler.sendMessage(msg);
| public android.content.pm.PackageCleanItem | nextPackageToClean(android.content.pm.PackageCleanItem lastPackage)
// writer
synchronized (mPackages) {
if (!isExternalMediaAvailable()) {
// If the external storage is no longer mounted at this point,
// the caller may not have been able to delete all of this
// packages files and can not delete any more. Bail.
return null;
}
final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
if (lastPackage != null) {
pkgs.remove(lastPackage);
}
if (pkgs.size() > 0) {
return pkgs.get(0);
}
}
return null;
| public boolean | onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags)
try {
return super.onTransact(code, data, reply, flags);
} catch (RuntimeException e) {
if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
Slog.wtf(TAG, "Package Manager Crash", e);
}
throw e;
}
| private int | packageFlagsToInstallFlags(PackageSetting ps)
int installFlags = 0;
if (isExternal(ps)) {
installFlags |= PackageManager.INSTALL_EXTERNAL;
}
if (isForwardLocked(ps)) {
installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
}
return installFlags;
| public void | performBootDexOpt()
enforceSystemOrRoot("Only the system can request dexopt be performed");
// Before everything else, see whether we need to fstrim.
try {
IMountService ms = PackageHelper.getMountService();
if (ms != null) {
final boolean isUpgrade = isUpgrade();
boolean doTrim = isUpgrade;
if (doTrim) {
Slog.w(TAG, "Running disk maintenance immediately due to system update");
} else {
final long interval = android.provider.Settings.Global.getLong(
mContext.getContentResolver(),
android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
DEFAULT_MANDATORY_FSTRIM_INTERVAL);
if (interval > 0) {
final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance();
if (timeSinceLast > interval) {
doTrim = true;
Slog.w(TAG, "No disk maintenance in " + timeSinceLast
+ "; running immediately");
}
}
}
if (doTrim) {
if (!isFirstBoot()) {
try {
ActivityManagerNative.getDefault().showBootMessage(
mContext.getResources().getString(
R.string.android_upgrading_fstrim), true);
} catch (RemoteException e) {
}
}
ms.runMaintenance();
}
} else {
Slog.e(TAG, "Mount service unavailable!");
}
} catch (RemoteException e) {
// Can't happen; MountService is local
}
final ArraySet<PackageParser.Package> pkgs;
synchronized (mPackages) {
pkgs = mDeferredDexOpt;
mDeferredDexOpt = null;
}
if (pkgs != null) {
// Sort apps by importance for dexopt ordering. Important apps are given more priority
// in case the device runs out of space.
ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>();
// Give priority to core apps.
for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
PackageParser.Package pkg = it.next();
if (pkg.coreApp) {
if (DEBUG_DEXOPT) {
Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName);
}
sortedPkgs.add(pkg);
it.remove();
}
}
// Give priority to system apps that listen for pre boot complete.
Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
ArraySet<String> pkgNames = getPackageNamesForIntent(intent);
for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
PackageParser.Package pkg = it.next();
if (pkgNames.contains(pkg.packageName)) {
if (DEBUG_DEXOPT) {
Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName);
}
sortedPkgs.add(pkg);
it.remove();
}
}
// Give priority to system apps.
for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
PackageParser.Package pkg = it.next();
if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
if (DEBUG_DEXOPT) {
Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName);
}
sortedPkgs.add(pkg);
it.remove();
}
}
// Give priority to updated system apps.
for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
PackageParser.Package pkg = it.next();
if (isUpdatedSystemApp(pkg)) {
if (DEBUG_DEXOPT) {
Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName);
}
sortedPkgs.add(pkg);
it.remove();
}
}
// Give priority to apps that listen for boot complete.
intent = new Intent(Intent.ACTION_BOOT_COMPLETED);
pkgNames = getPackageNamesForIntent(intent);
for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
PackageParser.Package pkg = it.next();
if (pkgNames.contains(pkg.packageName)) {
if (DEBUG_DEXOPT) {
Log.i(TAG, "Adding boot app " + sortedPkgs.size() + ": " + pkg.packageName);
}
sortedPkgs.add(pkg);
it.remove();
}
}
// Filter out packages that aren't recently used.
filterRecentlyUsedApps(pkgs);
// Add all remaining apps.
for (PackageParser.Package pkg : pkgs) {
if (DEBUG_DEXOPT) {
Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName);
}
sortedPkgs.add(pkg);
}
// If we want to be lazy, filter everything that wasn't recently used.
if (mLazyDexOpt) {
filterRecentlyUsedApps(sortedPkgs);
}
int i = 0;
int total = sortedPkgs.size();
File dataDir = Environment.getDataDirectory();
long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir);
if (lowThreshold == 0) {
throw new IllegalStateException("Invalid low memory threshold");
}
for (PackageParser.Package pkg : sortedPkgs) {
long usableSpace = dataDir.getUsableSpace();
if (usableSpace < lowThreshold) {
Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace);
break;
}
performBootDexOpt(pkg, ++i, total);
}
}
| private void | performBootDexOpt(PackageParser.Package pkg, int curr, int total)
if (DEBUG_DEXOPT) {
Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName);
}
if (!isFirstBoot()) {
try {
ActivityManagerNative.getDefault().showBootMessage(
mContext.getResources().getString(R.string.android_upgrading_apk,
curr, total), true);
} catch (RemoteException e) {
}
}
PackageParser.Package p = pkg;
synchronized (mInstallLock) {
performDexOptLI(p, null /* instruction sets */, false /* force dex */,
false /* defer */, true /* include dependencies */);
}
| public boolean | performDexOpt(java.lang.String packageName, java.lang.String instructionSet, boolean backgroundDexopt)
boolean dexopt = mLazyDexOpt || backgroundDexopt;
boolean updateUsage = !backgroundDexopt; // Don't update usage if this is just a backgroundDexopt
if (!dexopt && !updateUsage) {
// We aren't going to dexopt or update usage, so bail early.
return false;
}
PackageParser.Package p;
final String targetInstructionSet;
synchronized (mPackages) {
p = mPackages.get(packageName);
if (p == null) {
return false;
}
if (updateUsage) {
p.mLastPackageUsageTimeInMills = System.currentTimeMillis();
}
mPackageUsage.write(false);
if (!dexopt) {
// We aren't going to dexopt, so bail early.
return false;
}
targetInstructionSet = instructionSet != null ? instructionSet :
getPrimaryInstructionSet(p.applicationInfo);
if (p.mDexOptPerformed.contains(targetInstructionSet)) {
return false;
}
}
synchronized (mInstallLock) {
final String[] instructionSets = new String[] { targetInstructionSet };
return performDexOptLI(p, instructionSets, false /* force dex */, false /* defer */,
true /* include dependencies */) == DEX_OPT_PERFORMED;
}
| public boolean | performDexOptIfNeeded(java.lang.String packageName, java.lang.String instructionSet)
return performDexOpt(packageName, instructionSet, false);
| private int | performDexOptLI(PackageParser.Package pkg, java.lang.String[] targetInstructionSets, boolean forceDex, boolean defer, android.util.ArraySet done)
final String[] instructionSets = targetInstructionSets != null ?
targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
if (done != null) {
done.add(pkg.packageName);
if (pkg.usesLibraries != null) {
performDexOptLibsLI(pkg.usesLibraries, instructionSets, forceDex, defer, done);
}
if (pkg.usesOptionalLibraries != null) {
performDexOptLibsLI(pkg.usesOptionalLibraries, instructionSets, forceDex, defer, done);
}
}
if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) == 0) {
return DEX_OPT_SKIPPED;
}
final boolean vmSafeMode = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0;
final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly();
boolean performedDexOpt = false;
// There are three basic cases here:
// 1.) we need to dexopt, either because we are forced or it is needed
// 2.) we are defering a needed dexopt
// 3.) we are skipping an unneeded dexopt
final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
for (String dexCodeInstructionSet : dexCodeInstructionSets) {
if (!forceDex && pkg.mDexOptPerformed.contains(dexCodeInstructionSet)) {
continue;
}
for (String path : paths) {
try {
// This will return DEXOPT_NEEDED if we either cannot find any odex file for this
// patckage or the one we find does not match the image checksum (i.e. it was
// compiled against an old image). It will return PATCHOAT_NEEDED if we can find a
// odex file and it matches the checksum of the image but not its base address,
// meaning we need to move it.
final byte isDexOptNeeded = DexFile.isDexOptNeededInternal(path,
pkg.packageName, dexCodeInstructionSet, defer);
if (forceDex || (!defer && isDexOptNeeded == DexFile.DEXOPT_NEEDED)) {
Log.i(TAG, "Running dexopt on: " + path + " pkg="
+ pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
+ " vmSafeMode=" + vmSafeMode);
final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
final int ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg),
pkg.packageName, dexCodeInstructionSet, vmSafeMode);
if (ret < 0) {
// Don't bother running dexopt again if we failed, it will probably
// just result in an error again. Also, don't bother dexopting for other
// paths & ISAs.
return DEX_OPT_FAILED;
}
performedDexOpt = true;
} else if (!defer && isDexOptNeeded == DexFile.PATCHOAT_NEEDED) {
Log.i(TAG, "Running patchoat on: " + pkg.applicationInfo.packageName);
final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
final int ret = mInstaller.patchoat(path, sharedGid, !isForwardLocked(pkg),
pkg.packageName, dexCodeInstructionSet);
if (ret < 0) {
// Don't bother running patchoat again if we failed, it will probably
// just result in an error again. Also, don't bother dexopting for other
// paths & ISAs.
return DEX_OPT_FAILED;
}
performedDexOpt = true;
}
// We're deciding to defer a needed dexopt. Don't bother dexopting for other
// paths and instruction sets. We'll deal with them all together when we process
// our list of deferred dexopts.
if (defer && isDexOptNeeded != DexFile.UP_TO_DATE) {
if (mDeferredDexOpt == null) {
mDeferredDexOpt = new ArraySet<PackageParser.Package>();
}
mDeferredDexOpt.add(pkg);
return DEX_OPT_DEFERRED;
}
} catch (FileNotFoundException e) {
Slog.w(TAG, "Apk not found for dexopt: " + path);
return DEX_OPT_FAILED;
} catch (IOException e) {
Slog.w(TAG, "IOException reading apk: " + path, e);
return DEX_OPT_FAILED;
} catch (StaleDexCacheError e) {
Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e);
return DEX_OPT_FAILED;
} catch (Exception e) {
Slog.w(TAG, "Exception when doing dexopt : ", e);
return DEX_OPT_FAILED;
}
}
// At this point we haven't failed dexopt and we haven't deferred dexopt. We must
// either have either succeeded dexopt, or have had isDexOptNeededInternal tell us
// it isn't required. We therefore mark that this package doesn't need dexopt unless
// it's forced. performedDexOpt will tell us whether we performed dex-opt or skipped
// it.
pkg.mDexOptPerformed.add(dexCodeInstructionSet);
}
// If we've gotten here, we're sure that no error occurred and that we haven't
// deferred dex-opt. We've either dex-opted one more paths or instruction sets or
// we've skipped all of them because they are up to date. In both cases this
// package doesn't need dexopt any longer.
return performedDexOpt ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
| private int | performDexOptLI(PackageParser.Package pkg, java.lang.String[] instructionSets, boolean forceDex, boolean defer, boolean inclDependencies)
ArraySet<String> done;
if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
done = new ArraySet<String>();
done.add(pkg.packageName);
} else {
done = null;
}
return performDexOptLI(pkg, instructionSets, forceDex, defer, done);
| private void | performDexOptLibsLI(java.util.ArrayList libs, java.lang.String[] instructionSets, boolean forceDex, boolean defer, android.util.ArraySet done)
for (int i=0; i<libs.size(); i++) {
PackageParser.Package libPkg;
String libName;
synchronized (mPackages) {
libName = libs.get(i);
SharedLibraryEntry lib = mSharedLibraries.get(libName);
if (lib != null && lib.apk != null) {
libPkg = mPackages.get(lib.apk);
} else {
libPkg = null;
}
}
if (libPkg != null && !done.contains(libName)) {
performDexOptLI(libPkg, instructionSets, forceDex, defer, done);
}
}
| int | permissionInfoFootprint(android.content.pm.PermissionInfo info)
int size = info.name.length();
if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
return size;
| private void | processPendingInstall(com.android.server.pm.PackageManagerService$InstallArgs args, int currentStatus)
// Queue up an async operation since the package installation may take a little while.
mHandler.post(new Runnable() {
public void run() {
mHandler.removeCallbacks(this);
// Result object to be returned
PackageInstalledInfo res = new PackageInstalledInfo();
res.returnCode = currentStatus;
res.uid = -1;
res.pkg = null;
res.removedInfo = new PackageRemovedInfo();
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
args.doPreInstall(res.returnCode);
synchronized (mInstallLock) {
installPackageLI(args, res);
}
args.doPostInstall(res.returnCode, res.uid);
}
// A restore should be performed at this point if (a) the install
// succeeded, (b) the operation is not an update, and (c) the new
// package has not opted out of backup participation.
final boolean update = res.removedInfo.removedPackage != null;
final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
boolean doRestore = !update
&& ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
// Set up the post-install work request bookkeeping. This will be used
// and cleaned up by the post-install event handling regardless of whether
// there's a restore pass performed. Token values are >= 1.
int token;
if (mNextInstallToken < 0) mNextInstallToken = 1;
token = mNextInstallToken++;
PostInstallData data = new PostInstallData(args, res);
mRunningInstalls.put(token, data);
if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
// Pass responsibility to the Backup Manager. It will perform a
// restore if appropriate, then pass responsibility back to the
// Package Manager to run the post-install observer callbacks
// and broadcasts.
IBackupManager bm = IBackupManager.Stub.asInterface(
ServiceManager.getService(Context.BACKUP_SERVICE));
if (bm != null) {
if (DEBUG_INSTALL) Log.v(TAG, "token " + token
+ " to BM for possible restore");
try {
if (bm.isBackupServiceActive(UserHandle.USER_OWNER)) {
bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
} else {
doRestore = false;
}
} catch (RemoteException e) {
// can't happen; the backup manager is local
} catch (Exception e) {
Slog.e(TAG, "Exception trying to enqueue restore", e);
doRestore = false;
}
} else {
Slog.e(TAG, "Backup Manager not found!");
doRestore = false;
}
}
if (!doRestore) {
// No restore possible, or the Backup Manager was mysteriously not
// available -- just fire the post-install work request directly.
if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
mHandler.sendMessage(msg);
}
}
});
| public java.util.List | queryContentProviders(java.lang.String processName, int uid, int flags)
ArrayList<ProviderInfo> finalList = null;
// reader
synchronized (mPackages) {
final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
final int userId = processName != null ?
UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
while (i.hasNext()) {
final PackageParser.Provider p = i.next();
PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
if (ps != null && p.info.authority != null
&& (processName == null
|| (p.info.processName.equals(processName)
&& UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
&& mSettings.isEnabledLPr(p.info, flags, userId)
&& (!mSafeMode
|| (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
if (finalList == null) {
finalList = new ArrayList<ProviderInfo>(3);
}
ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
ps.readUserState(userId), userId);
if (info != null) {
finalList.add(info);
}
}
}
}
if (finalList != null) {
Collections.sort(finalList, mProviderInitOrderSorter);
}
return finalList;
| private android.content.pm.ResolveInfo | queryCrossProfileIntents(java.util.List matchingFilters, android.content.Intent intent, java.lang.String resolvedType, int flags, int sourceUserId)
if (matchingFilters != null) {
// Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
// match the same intent. For performance reasons, it is better not to
// run queryIntent twice for the same userId
SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
int size = matchingFilters.size();
for (int i = 0; i < size; i++) {
CrossProfileIntentFilter filter = matchingFilters.get(i);
int targetUserId = filter.getTargetUserId();
if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0
&& !alreadyTriedUserIds.get(targetUserId)) {
// Checking if there are activities in the target user that can handle the
// intent.
ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
flags, sourceUserId);
if (resolveInfo != null) return resolveInfo;
alreadyTriedUserIds.put(targetUserId, true);
}
}
}
return null;
| public java.util.List | queryInstrumentation(java.lang.String targetPackage, int flags)
ArrayList<InstrumentationInfo> finalList =
new ArrayList<InstrumentationInfo>();
// reader
synchronized (mPackages) {
final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
while (i.hasNext()) {
final PackageParser.Instrumentation p = i.next();
if (targetPackage == null
|| targetPackage.equals(p.info.targetPackage)) {
InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
flags);
if (ii != null) {
finalList.add(ii);
}
}
}
}
return finalList;
| public java.util.List | queryIntentActivities(android.content.Intent intent, java.lang.String resolvedType, int flags, int userId)
if (!sUserManager.exists(userId)) return Collections.emptyList();
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities");
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
intent = intent.getSelector();
comp = intent.getComponent();
}
}
if (comp != null) {
final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
final ActivityInfo ai = getActivityInfo(comp, flags, userId);
if (ai != null) {
final ResolveInfo ri = new ResolveInfo();
ri.activityInfo = ai;
list.add(ri);
}
return list;
}
// reader
synchronized (mPackages) {
final String pkgName = intent.getPackage();
if (pkgName == null) {
List<CrossProfileIntentFilter> matchingFilters =
getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
// Check for results that need to skip the current profile.
ResolveInfo resolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent,
resolvedType, flags, userId);
if (resolveInfo != null) {
List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
result.add(resolveInfo);
return result;
}
// Check for cross profile results.
resolveInfo = queryCrossProfileIntents(
matchingFilters, intent, resolvedType, flags, userId);
// Check for results in the current profile.
List<ResolveInfo> result = mActivities.queryIntent(
intent, resolvedType, flags, userId);
if (resolveInfo != null) {
result.add(resolveInfo);
Collections.sort(result, mResolvePrioritySorter);
}
return result;
}
final PackageParser.Package pkg = mPackages.get(pkgName);
if (pkg != null) {
return mActivities.queryIntentForPackage(intent, resolvedType, flags,
pkg.activities, userId);
}
return new ArrayList<ResolveInfo>();
}
| public java.util.List | queryIntentActivityOptions(android.content.ComponentName caller, android.content.Intent[] specifics, java.lang.String[] specificTypes, android.content.Intent intent, java.lang.String resolvedType, int flags, int userId)
if (!sUserManager.exists(userId)) return Collections.emptyList();
enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
false, "query intent activity options");
final String resultsAction = intent.getAction();
List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
| PackageManager.GET_RESOLVED_FILTER, userId);
if (DEBUG_INTENT_MATCHING) {
Log.v(TAG, "Query " + intent + ": " + results);
}
int specificsPos = 0;
int N;
// todo: note that the algorithm used here is O(N^2). This
// isn't a problem in our current environment, but if we start running
// into situations where we have more than 5 or 10 matches then this
// should probably be changed to something smarter...
// First we go through and resolve each of the specific items
// that were supplied, taking care of removing any corresponding
// duplicate items in the generic resolve list.
if (specifics != null) {
for (int i=0; i<specifics.length; i++) {
final Intent sintent = specifics[i];
if (sintent == null) {
continue;
}
if (DEBUG_INTENT_MATCHING) {
Log.v(TAG, "Specific #" + i + ": " + sintent);
}
String action = sintent.getAction();
if (resultsAction != null && resultsAction.equals(action)) {
// If this action was explicitly requested, then don't
// remove things that have it.
action = null;
}
ResolveInfo ri = null;
ActivityInfo ai = null;
ComponentName comp = sintent.getComponent();
if (comp == null) {
ri = resolveIntent(
sintent,
specificTypes != null ? specificTypes[i] : null,
flags, userId);
if (ri == null) {
continue;
}
if (ri == mResolveInfo) {
// ACK! Must do something better with this.
}
ai = ri.activityInfo;
comp = new ComponentName(ai.applicationInfo.packageName,
ai.name);
} else {
ai = getActivityInfo(comp, flags, userId);
if (ai == null) {
continue;
}
}
// Look for any generic query activities that are duplicates
// of this specific one, and remove them from the results.
if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
N = results.size();
int j;
for (j=specificsPos; j<N; j++) {
ResolveInfo sri = results.get(j);
if ((sri.activityInfo.name.equals(comp.getClassName())
&& sri.activityInfo.applicationInfo.packageName.equals(
comp.getPackageName()))
|| (action != null && sri.filter.matchAction(action))) {
results.remove(j);
if (DEBUG_INTENT_MATCHING) Log.v(
TAG, "Removing duplicate item from " + j
+ " due to specific " + specificsPos);
if (ri == null) {
ri = sri;
}
j--;
N--;
}
}
// Add this specific item to its proper place.
if (ri == null) {
ri = new ResolveInfo();
ri.activityInfo = ai;
}
results.add(specificsPos, ri);
ri.specificIndex = i;
specificsPos++;
}
}
// Now we go through the remaining generic results and remove any
// duplicate actions that are found here.
N = results.size();
for (int i=specificsPos; i<N-1; i++) {
final ResolveInfo rii = results.get(i);
if (rii.filter == null) {
continue;
}
// Iterate over all of the actions of this result's intent
// filter... typically this should be just one.
final Iterator<String> it = rii.filter.actionsIterator();
if (it == null) {
continue;
}
while (it.hasNext()) {
final String action = it.next();
if (resultsAction != null && resultsAction.equals(action)) {
// If this action was explicitly requested, then don't
// remove things that have it.
continue;
}
for (int j=i+1; j<N; j++) {
final ResolveInfo rij = results.get(j);
if (rij.filter != null && rij.filter.hasAction(action)) {
results.remove(j);
if (DEBUG_INTENT_MATCHING) Log.v(
TAG, "Removing duplicate item from " + j
+ " due to action " + action + " at " + i);
j--;
N--;
}
}
}
// If the caller didn't request filter information, drop it now
// so we don't have to marshall/unmarshall it.
if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
rii.filter = null;
}
}
// Filter out the caller activity if so requested.
if (caller != null) {
N = results.size();
for (int i=0; i<N; i++) {
ActivityInfo ainfo = results.get(i).activityInfo;
if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
&& caller.getClassName().equals(ainfo.name)) {
results.remove(i);
break;
}
}
}
// If the caller didn't request filter information,
// drop them now so we don't have to
// marshall/unmarshall it.
if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
N = results.size();
for (int i=0; i<N; i++) {
results.get(i).filter = null;
}
}
if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
return results;
| public java.util.List | queryIntentContentProviders(android.content.Intent intent, java.lang.String resolvedType, int flags, int userId)
if (!sUserManager.exists(userId)) return Collections.emptyList();
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
intent = intent.getSelector();
comp = intent.getComponent();
}
}
if (comp != null) {
final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
final ProviderInfo pi = getProviderInfo(comp, flags, userId);
if (pi != null) {
final ResolveInfo ri = new ResolveInfo();
ri.providerInfo = pi;
list.add(ri);
}
return list;
}
// reader
synchronized (mPackages) {
String pkgName = intent.getPackage();
if (pkgName == null) {
return mProviders.queryIntent(intent, resolvedType, flags, userId);
}
final PackageParser.Package pkg = mPackages.get(pkgName);
if (pkg != null) {
return mProviders.queryIntentForPackage(
intent, resolvedType, flags, pkg.providers, userId);
}
return null;
}
| public java.util.List | queryIntentReceivers(android.content.Intent intent, java.lang.String resolvedType, int flags, int userId)
if (!sUserManager.exists(userId)) return Collections.emptyList();
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
intent = intent.getSelector();
comp = intent.getComponent();
}
}
if (comp != null) {
List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
ActivityInfo ai = getReceiverInfo(comp, flags, userId);
if (ai != null) {
ResolveInfo ri = new ResolveInfo();
ri.activityInfo = ai;
list.add(ri);
}
return list;
}
// reader
synchronized (mPackages) {
String pkgName = intent.getPackage();
if (pkgName == null) {
return mReceivers.queryIntent(intent, resolvedType, flags, userId);
}
final PackageParser.Package pkg = mPackages.get(pkgName);
if (pkg != null) {
return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
userId);
}
return null;
}
| public java.util.List | queryIntentServices(android.content.Intent intent, java.lang.String resolvedType, int flags, int userId)
if (!sUserManager.exists(userId)) return Collections.emptyList();
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
intent = intent.getSelector();
comp = intent.getComponent();
}
}
if (comp != null) {
final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
final ServiceInfo si = getServiceInfo(comp, flags, userId);
if (si != null) {
final ResolveInfo ri = new ResolveInfo();
ri.serviceInfo = si;
list.add(ri);
}
return list;
}
// reader
synchronized (mPackages) {
String pkgName = intent.getPackage();
if (pkgName == null) {
return mServices.queryIntent(intent, resolvedType, flags, userId);
}
final PackageParser.Package pkg = mPackages.get(pkgName);
if (pkg != null) {
return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
userId);
}
return null;
}
| public java.util.List | queryPermissionsByGroup(java.lang.String group, int flags)
// reader
synchronized (mPackages) {
ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
for (BasePermission p : mSettings.mPermissions.values()) {
if (group == null) {
if (p.perm == null || p.perm.info.group == null) {
out.add(generatePermissionInfo(p, flags));
}
} else {
if (p.perm != null && group.equals(p.perm.info.group)) {
out.add(PackageParser.generatePermissionInfo(p.perm, flags));
}
}
}
if (out.size() > 0) {
return out;
}
return mPermissionGroups.containsKey(group) ? out : null;
}
| private android.content.pm.ResolveInfo | querySkipCurrentProfileIntents(java.util.List matchingFilters, android.content.Intent intent, java.lang.String resolvedType, int flags, int sourceUserId)
if (matchingFilters != null) {
int size = matchingFilters.size();
for (int i = 0; i < size; i ++) {
CrossProfileIntentFilter filter = matchingFilters.get(i);
if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
// Checking if there are activities in the target user that can handle the
// intent.
ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
flags, sourceUserId);
if (resolveInfo != null) {
return resolveInfo;
}
}
}
}
return null;
| public void | querySyncProviders(java.util.List outNames, java.util.List outInfo)
// reader
synchronized (mPackages) {
final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
.entrySet().iterator();
final int userId = UserHandle.getCallingUserId();
while (i.hasNext()) {
Map.Entry<String, PackageParser.Provider> entry = i.next();
PackageParser.Provider p = entry.getValue();
PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
if (ps != null && p.syncable
&& (!mSafeMode || (p.info.applicationInfo.flags
&ApplicationInfo.FLAG_SYSTEM) != 0)) {
ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
ps.readUserState(userId), userId);
if (info != null) {
outNames.add(entry.getKey());
outInfo.add(info);
}
}
}
}
| private int | removeDataDirsLI(java.lang.String packageName)
int[] users = sUserManager.getUserIds();
int res = 0;
for (int user : users) {
int resInner = mInstaller.remove(packageName, user);
if (resInner < 0) {
res = resInner;
}
}
return res;
| void | removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty)
if (DEBUG_INSTALL) {
if (chatty)
Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
}
// writer
synchronized (mPackages) {
mPackages.remove(pkg.applicationInfo.packageName);
cleanPackageDataStructuresLILPw(pkg, chatty);
}
| static int[] | removeInts(int[] cur, int[] rem)
if (rem == null) return cur;
if (cur == null) return cur;
final int N = rem.length;
for (int i=0; i<N; i++) {
cur = removeInt(cur, rem[i]);
}
return cur;
| private static void | removeKeystoreDataIfNeeded(int userId, int appId)Remove entries from the keystore daemon. Will only remove it if the
{@code appId} is valid.
if (appId < 0) {
return;
}
final KeyStore keyStore = KeyStore.getInstance();
if (keyStore != null) {
if (userId == UserHandle.USER_ALL) {
for (final int individual : sUserManager.getUserIds()) {
keyStore.clearUid(UserHandle.getUid(individual, appId));
}
} else {
keyStore.clearUid(UserHandle.getUid(userId, appId));
}
} else {
Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
}
| private void | removePackageDataLI(PackageSetting ps, int[] allUserHandles, boolean[] perUserInstalled, com.android.server.pm.PackageManagerService$PackageRemovedInfo outInfo, int flags, boolean writeSettings)
String packageName = ps.name;
if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
// Retrieve object to delete permissions for shared user later on
final PackageSetting deletedPs;
// reader
synchronized (mPackages) {
deletedPs = mSettings.mPackages.get(packageName);
if (outInfo != null) {
outInfo.removedPackage = packageName;
outInfo.removedUsers = deletedPs != null
? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
: null;
}
}
if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
removeDataDirsLI(packageName);
schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
}
// writer
synchronized (mPackages) {
if (deletedPs != null) {
if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
if (outInfo != null) {
mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
outInfo.removedAppId = mSettings.removePackageLPw(packageName);
}
if (deletedPs != null) {
updatePermissionsLPw(deletedPs.name, null, 0);
if (deletedPs.sharedUser != null) {
// remove permissions associated with package
mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids);
}
}
clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
}
// make sure to preserve per-user disabled state if this removal was just
// a downgrade of a system app to the factory package
if (allUserHandles != null && perUserInstalled != null) {
if (DEBUG_REMOVE) {
Slog.d(TAG, "Propagating install state across downgrade");
}
for (int i = 0; i < allUserHandles.length; i++) {
if (DEBUG_REMOVE) {
Slog.d(TAG, " user " + allUserHandles[i]
+ " => " + perUserInstalled[i]);
}
ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
}
}
}
// can downgrade to reader
if (writeSettings) {
// Save settings now
mSettings.writeLPr();
}
}
if (outInfo != null) {
// A user ID was deleted here. Go through all users and remove it
// from KeyStore.
removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
}
| public void | removePackageFromPreferred(java.lang.String packageName)
Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
| void | removePackageLI(PackageSetting ps, boolean chatty)
if (DEBUG_INSTALL) {
if (chatty)
Log.d(TAG, "Removing package " + ps.name);
}
// writer
synchronized (mPackages) {
mPackages.remove(ps.name);
final PackageParser.Package pkg = ps.pkg;
if (pkg != null) {
cleanPackageDataStructuresLILPw(pkg, chatty);
}
}
| public void | removePermission(java.lang.String name)
synchronized (mPackages) {
checkPermissionTreeLP(name);
BasePermission bp = mSettings.mPermissions.get(name);
if (bp != null) {
if (bp.type != BasePermission.TYPE_DYNAMIC) {
throw new SecurityException(
"Not allowed to modify non-dynamic permission "
+ name);
}
mSettings.mPermissions.remove(name);
mSettings.writeLPr();
}
}
| private void | removeUnusedPackagesLILPw(UserManagerService userManager, int userHandle)We're removing userHandle and would like to remove any downloaded packages
that are no longer in use by any other user.
final boolean DEBUG_CLEAN_APKS = false;
int [] users = userManager.getUserIdsLPr();
Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
while (psit.hasNext()) {
PackageSetting ps = psit.next();
if (ps.pkg == null) {
continue;
}
final String packageName = ps.pkg.packageName;
// Skip over if system app
if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
continue;
}
if (DEBUG_CLEAN_APKS) {
Slog.i(TAG, "Checking package " + packageName);
}
boolean keep = false;
for (int i = 0; i < users.length; i++) {
if (users[i] != userHandle && ps.getInstalled(users[i])) {
keep = true;
if (DEBUG_CLEAN_APKS) {
Slog.i(TAG, " Keeping package " + packageName + " for user "
+ users[i]);
}
break;
}
}
if (!keep) {
if (DEBUG_CLEAN_APKS) {
Slog.i(TAG, " Removing package " + packageName);
}
mHandler.post(new Runnable() {
public void run() {
deletePackageX(packageName, userHandle, 0);
} //end run
});
}
}
| private void | replaceNonSystemPackageLI(PackageParser.Package deletedPackage, PackageParser.Package pkg, int parseFlags, int scanFlags, android.os.UserHandle user, int[] allUsers, boolean[] perUserInstalled, java.lang.String installerPackageName, com.android.server.pm.PackageManagerService$PackageInstalledInfo res)
String pkgName = deletedPackage.packageName;
boolean deletedPkg = true;
boolean updatedSettings = false;
if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
+ deletedPackage);
long origUpdateTime;
if (pkg.mExtras != null) {
origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
} else {
origUpdateTime = 0;
}
// First delete the existing package while retaining the data directory
if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA,
res.removedInfo, true)) {
// If the existing package wasn't successfully deleted
res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
deletedPkg = false;
} else {
// Successfully deleted the old package; proceed with replace.
// If deleted package lived in a container, give users a chance to
// relinquish resources before killing.
if (isForwardLocked(deletedPackage) || isExternal(deletedPackage)) {
if (DEBUG_INSTALL) {
Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
}
final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
final ArrayList<String> pkgList = new ArrayList<String>(1);
pkgList.add(deletedPackage.applicationInfo.packageName);
sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
}
deleteCodeCacheDirsLI(pkgName);
try {
final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags,
scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
updatedSettings = true;
} catch (PackageManagerException e) {
res.setError("Package couldn't be installed in " + pkg.codePath, e);
}
}
if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
// remove package from internal structures. Note that we want deletePackageX to
// delete the package data and cache directories that it created in
// scanPackageLocked, unless those directories existed before we even tried to
// install.
if(updatedSettings) {
if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
deletePackageLI(
pkgName, null, true, allUsers, perUserInstalled,
PackageManager.DELETE_KEEP_DATA,
res.removedInfo, true);
}
// Since we failed to install the new package we need to restore the old
// package that we deleted.
if (deletedPkg) {
if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
File restoreFile = new File(deletedPackage.codePath);
// Parse old package
boolean oldOnSd = isExternal(deletedPackage);
int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY |
(isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) |
(oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0);
int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
try {
scanPackageLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, null);
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
+ e.getMessage());
return;
}
// Restore of old package succeeded. Update permissions.
// writer
synchronized (mPackages) {
updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
UPDATE_PERMISSIONS_ALL);
// can downgrade to reader
mSettings.writeLPr();
}
Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
}
}
| private void | replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, android.os.UserHandle user, java.lang.String installerPackageName, com.android.server.pm.PackageManagerService$PackageInstalledInfo res)
PackageParser.Package oldPackage;
String pkgName = pkg.packageName;
int[] allUsers;
boolean[] perUserInstalled;
// First find the old package info and check signatures
synchronized(mPackages) {
oldPackage = mPackages.get(pkgName);
if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
PackageSetting ps = mSettings.mPackages.get(pkgName);
if (ps == null || !ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) {
// default to original signature matching
if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
!= PackageManager.SIGNATURE_MATCH) {
res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
"New package has a different signature: " + pkgName);
return;
}
} else {
if(!checkUpgradeKeySetLP(ps, pkg)) {
res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
"New package not signed by keys specified by upgrade-keysets: "
+ pkgName);
return;
}
}
// In case of rollback, remember per-user/profile install state
allUsers = sUserManager.getUserIds();
perUserInstalled = new boolean[allUsers.length];
for (int i = 0; i < allUsers.length; i++) {
perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
}
}
boolean sysPkg = (isSystemApp(oldPackage));
if (sysPkg) {
replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
user, allUsers, perUserInstalled, installerPackageName, res);
} else {
replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
user, allUsers, perUserInstalled, installerPackageName, res);
}
| public void | replacePreferredActivity(android.content.IntentFilter filter, int match, android.content.ComponentName[] set, android.content.ComponentName activity, int userId)
if (filter.countActions() != 1) {
throw new IllegalArgumentException(
"replacePreferredActivity expects filter to have only 1 action.");
}
if (filter.countDataAuthorities() != 0
|| filter.countDataPaths() != 0
|| filter.countDataSchemes() > 1
|| filter.countDataTypes() != 0) {
throw new IllegalArgumentException(
"replacePreferredActivity expects filter to have no data authorities, " +
"paths, or types; and at most one scheme.");
}
final int callingUid = Binder.getCallingUid();
enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity");
synchronized (mPackages) {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
!= PackageManager.PERMISSION_GRANTED) {
if (getUidTargetSdkVersionLockedLPr(callingUid)
< Build.VERSION_CODES.FROYO) {
Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
+ Binder.getCallingUid());
return;
}
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
}
PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
if (pir != null) {
// Get all of the existing entries that exactly match this filter.
ArrayList<PreferredActivity> existing = pir.findFilters(filter);
if (existing != null && existing.size() == 1) {
PreferredActivity cur = existing.get(0);
if (DEBUG_PREFERRED) {
Slog.i(TAG, "Checking replace of preferred:");
filter.dump(new LogPrinter(Log.INFO, TAG), " ");
if (!cur.mPref.mAlways) {
Slog.i(TAG, " -- CUR; not mAlways!");
} else {
Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch);
Slog.i(TAG, " -- CUR: mSet="
+ Arrays.toString(cur.mPref.mSetComponents));
Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent);
Slog.i(TAG, " -- NEW: mMatch="
+ (match&IntentFilter.MATCH_CATEGORY_MASK));
Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set));
Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString());
}
}
if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
&& cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
&& cur.mPref.sameSet(set)) {
// Setting the preferred activity to what it happens to be already
if (DEBUG_PREFERRED) {
Slog.i(TAG, "Replacing with same preferred activity "
+ cur.mPref.mShortComponent + " for user "
+ userId + ":");
filter.dump(new LogPrinter(Log.INFO, TAG), " ");
}
return;
}
}
if (existing != null) {
if (DEBUG_PREFERRED) {
Slog.i(TAG, existing.size() + " existing preferred matches for:");
filter.dump(new LogPrinter(Log.INFO, TAG), " ");
}
for (int i = 0; i < existing.size(); i++) {
PreferredActivity pa = existing.get(i);
if (DEBUG_PREFERRED) {
Slog.i(TAG, "Removing existing preferred activity "
+ pa.mPref.mComponent + ":");
pa.dump(new LogPrinter(Log.INFO, TAG), " ");
}
pir.removeFilter(pa);
}
}
}
addPreferredActivityInternal(filter, match, set, activity, true, userId,
"Replacing preferred");
}
| private void | replaceSystemPackageLI(PackageParser.Package deletedPackage, PackageParser.Package pkg, int parseFlags, int scanFlags, android.os.UserHandle user, int[] allUsers, boolean[] perUserInstalled, java.lang.String installerPackageName, com.android.server.pm.PackageManagerService$PackageInstalledInfo res)
if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
+ ", old=" + deletedPackage);
boolean disabledSystem = false;
boolean updatedSettings = false;
parseFlags |= PackageParser.PARSE_IS_SYSTEM;
if ((deletedPackage.applicationInfo.flags&ApplicationInfo.FLAG_PRIVILEGED) != 0) {
parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
}
String packageName = deletedPackage.packageName;
if (packageName == null) {
res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
"Attempt to delete null packageName.");
return;
}
PackageParser.Package oldPkg;
PackageSetting oldPkgSetting;
// reader
synchronized (mPackages) {
oldPkg = mPackages.get(packageName);
oldPkgSetting = mSettings.mPackages.get(packageName);
if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
(oldPkgSetting == null)) {
res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
"Couldn't find package:" + packageName + " information");
return;
}
}
killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg");
res.removedInfo.uid = oldPkg.applicationInfo.uid;
res.removedInfo.removedPackage = packageName;
// Remove existing system package
removePackageLI(oldPkgSetting, true);
// writer
synchronized (mPackages) {
disabledSystem = mSettings.disableSystemPackageLPw(packageName);
if (!disabledSystem && deletedPackage != null) {
// We didn't need to disable the .apk as a current system package,
// which means we are replacing another update that is already
// installed. We need to make sure to delete the older one's .apk.
res.removedInfo.args = createInstallArgsForExisting(0,
deletedPackage.applicationInfo.getCodePath(),
deletedPackage.applicationInfo.getResourcePath(),
deletedPackage.applicationInfo.nativeLibraryRootDir,
getAppDexInstructionSets(deletedPackage.applicationInfo));
} else {
res.removedInfo.args = null;
}
}
// Successfully disabled the old package. Now proceed with re-installation
deleteCodeCacheDirsLI(packageName);
res.returnCode = PackageManager.INSTALL_SUCCEEDED;
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
PackageParser.Package newPackage = null;
try {
newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 0, user);
if (newPackage.mExtras != null) {
final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras;
newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
newPkgSetting.lastUpdateTime = System.currentTimeMillis();
// is the update attempting to change shared user? that isn't going to work...
if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) {
res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
"Forbidding shared user change from " + oldPkgSetting.sharedUser
+ " to " + newPkgSetting.sharedUser);
updatedSettings = true;
}
}
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
updatedSettings = true;
}
} catch (PackageManagerException e) {
res.setError("Package couldn't be installed in " + pkg.codePath, e);
}
if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
// Re installation failed. Restore old information
// Remove new pkg information
if (newPackage != null) {
removeInstalledPackageLI(newPackage, true);
}
// Add back the old system package
try {
scanPackageLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
}
// Restore the old system information in Settings
synchronized (mPackages) {
if (disabledSystem) {
mSettings.enableSystemPackageLPw(packageName);
}
if (updatedSettings) {
mSettings.setInstallerPackageName(packageName,
oldPkgSetting.installerPackageName);
}
mSettings.writeLPr();
}
}
| static void | reportSettingsProblem(int priority, java.lang.String msg)
logCriticalInfo(priority, msg);
| public void | resetPreferredActivities(int userId)
/* TODO: Actually use userId. Why is it being passed in? */
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
// writer
synchronized (mPackages) {
int user = UserHandle.getCallingUserId();
clearPackagePreferredActivitiesLPw(null, user);
mSettings.readDefaultPreferredAppsLPw(this, user);
scheduleWritePackageRestrictionsLocked(user);
}
| public android.content.pm.ProviderInfo | resolveContentProvider(java.lang.String name, int flags, int userId)
if (!sUserManager.exists(userId)) return null;
// reader
synchronized (mPackages) {
final PackageParser.Provider provider = mProvidersByAuthority.get(name);
PackageSetting ps = provider != null
? mSettings.mPackages.get(provider.owner.packageName)
: null;
return ps != null
&& mSettings.isEnabledLPr(provider.info, flags, userId)
&& (!mSafeMode || (provider.info.applicationInfo.flags
&ApplicationInfo.FLAG_SYSTEM) != 0)
? PackageParser.generateProviderInfo(provider, flags,
ps.readUserState(userId), userId)
: null;
}
| public android.content.pm.ResolveInfo | resolveIntent(android.content.Intent intent, java.lang.String resolvedType, int flags, int userId)
if (!sUserManager.exists(userId)) return null;
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
return chooseBestActivity(intent, resolvedType, flags, query, userId);
| public android.content.pm.ResolveInfo | resolveService(android.content.Intent intent, java.lang.String resolvedType, int flags, int userId)
List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
if (!sUserManager.exists(userId)) return null;
if (query != null) {
if (query.size() >= 1) {
// If there is more than one service with the same priority,
// just arbitrarily pick the first one.
return query.get(0);
}
}
return null;
| public void | revokePermission(java.lang.String packageName, java.lang.String permissionName)
int changedAppId = -1;
synchronized (mPackages) {
final PackageParser.Package pkg = mPackages.get(packageName);
if (pkg == null) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
if (pkg.applicationInfo.uid != Binder.getCallingUid()) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
}
final BasePermission bp = mSettings.mPermissions.get(permissionName);
if (bp == null) {
throw new IllegalArgumentException("Unknown permission: " + permissionName);
}
checkGrantRevokePermissions(pkg, bp);
final PackageSetting ps = (PackageSetting) pkg.mExtras;
if (ps == null) {
return;
}
final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
if (gp.grantedPermissions.remove(permissionName)) {
gp.grantedPermissions.remove(permissionName);
if (ps.haveGids) {
gp.gids = removeInts(gp.gids, bp.gids);
}
mSettings.writeLPr();
changedAppId = ps.appId;
}
}
if (changedAppId >= 0) {
// We changed the perm on someone, kill its processes.
IActivityManager am = ActivityManagerNative.getDefault();
if (am != null) {
final int callingUserId = UserHandle.getCallingUserId();
final long ident = Binder.clearCallingIdentity();
try {
//XXX we should only revoke for the calling user's app permissions,
// but for now we impact all users.
//am.killUid(UserHandle.getUid(callingUserId, changedAppId),
// "revoke " + permissionName);
int[] users = sUserManager.getUserIds();
for (int user : users) {
am.killUid(UserHandle.getUid(user, changedAppId),
"revoke " + permissionName);
}
} catch (RemoteException e) {
} finally {
Binder.restoreCallingIdentity(ident);
}
}
}
| public void | scanAvailableAsecs()Called by MountService when the initial ASECs to scan are available.
Should block until all the ASEC containers are finished being scanned.
updateExternalMediaStatusInner(true, false, false);
if (mShouldRestoreconData) {
SELinuxMMAC.setRestoreconDone();
mShouldRestoreconData = false;
}
| private void | scanDirLI(java.io.File dir, int parseFlags, int scanFlags, long currentTime)
final File[] files = dir.listFiles();
if (ArrayUtils.isEmpty(files)) {
Log.d(TAG, "No files in app dir " + dir);
return;
}
if (DEBUG_PACKAGE_SCANNING) {
Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
+ " flags=0x" + Integer.toHexString(parseFlags));
}
for (File file : files) {
final boolean isPackage = (isApkFile(file) || file.isDirectory())
&& !PackageInstallerService.isStageName(file.getName());
if (!isPackage) {
// Ignore entries which are not packages
continue;
}
try {
scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
scanFlags, currentTime, null);
} catch (PackageManagerException e) {
Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
// Delete invalid userdata apps
if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
if (file.isDirectory()) {
FileUtils.deleteContents(file);
}
file.delete();
}
}
}
| private PackageParser.Package | scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags, int scanFlags, long currentTime, android.os.UserHandle user)
final File scanFile = new File(pkg.codePath);
if (pkg.applicationInfo.getCodePath() == null ||
pkg.applicationInfo.getResourcePath() == null) {
// Bail out. The resource and code paths haven't been set.
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
"Code and resource paths haven't been set correctly");
}
if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
} else {
// Only allow system apps to be flagged as core apps.
pkg.coreApp = false;
}
if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_PRIVILEGED;
}
if (mCustomResolverComponentName != null &&
mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
setUpCustomResolverActivity(pkg);
}
if (pkg.packageName.equals("android")) {
synchronized (mPackages) {
if (mAndroidApplication != null) {
Slog.w(TAG, "*************************************************");
Slog.w(TAG, "Core android package being redefined. Skipping.");
Slog.w(TAG, " file=" + scanFile);
Slog.w(TAG, "*************************************************");
throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
"Core android package being redefined. Skipping.");
}
// Set up information for our fall-back user intent resolution activity.
mPlatformPackage = pkg;
pkg.mVersionCode = mSdkVersion;
mAndroidApplication = pkg.applicationInfo;
if (!mResolverReplaced) {
mResolveActivity.applicationInfo = mAndroidApplication;
mResolveActivity.name = ResolverActivity.class.getName();
mResolveActivity.packageName = mAndroidApplication.packageName;
mResolveActivity.processName = "system:ui";
mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert;
mResolveActivity.exported = true;
mResolveActivity.enabled = true;
mResolveInfo.activityInfo = mResolveActivity;
mResolveInfo.priority = 0;
mResolveInfo.preferredOrder = 0;
mResolveInfo.match = 0;
mResolveComponentName = new ComponentName(
mAndroidApplication.packageName, mResolveActivity.name);
}
}
}
if (DEBUG_PACKAGE_SCANNING) {
if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
Log.d(TAG, "Scanning package " + pkg.packageName);
}
if (mPackages.containsKey(pkg.packageName)
|| mSharedLibraries.containsKey(pkg.packageName)) {
throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
"Application package " + pkg.packageName
+ " already installed. Skipping duplicate.");
}
// Initialize package source and resource directories
File destCodeFile = new File(pkg.applicationInfo.getCodePath());
File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
SharedUserSetting suid = null;
PackageSetting pkgSetting = null;
if (!isSystemApp(pkg)) {
// Only system apps can use these features.
pkg.mOriginalPackages = null;
pkg.mRealPackage = null;
pkg.mAdoptPermissions = null;
}
// writer
synchronized (mPackages) {
if (pkg.mSharedUserId != null) {
suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, true);
if (suid == null) {
throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
"Creating application package " + pkg.packageName
+ " for shared user failed");
}
if (DEBUG_PACKAGE_SCANNING) {
if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
+ "): packages=" + suid.packages);
}
}
// Check if we are renaming from an original package name.
PackageSetting origPackage = null;
String realName = null;
if (pkg.mOriginalPackages != null) {
// This package may need to be renamed to a previously
// installed name. Let's check on that...
final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
if (pkg.mOriginalPackages.contains(renamed)) {
// This package had originally been installed as the
// original name, and we have already taken care of
// transitioning to the new one. Just update the new
// one to continue using the old name.
realName = pkg.mRealPackage;
if (!pkg.packageName.equals(renamed)) {
// Callers into this function may have already taken
// care of renaming the package; only do it here if
// it is not already done.
pkg.setPackageName(renamed);
}
} else {
for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
if ((origPackage = mSettings.peekPackageLPr(
pkg.mOriginalPackages.get(i))) != null) {
// We do have the package already installed under its
// original name... should we use it?
if (!verifyPackageUpdateLPr(origPackage, pkg)) {
// New package is not compatible with original.
origPackage = null;
continue;
} else if (origPackage.sharedUser != null) {
// Make sure uid is compatible between packages.
if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
Slog.w(TAG, "Unable to migrate data from " + origPackage.name
+ " to " + pkg.packageName + ": old uid "
+ origPackage.sharedUser.name
+ " differs from " + pkg.mSharedUserId);
origPackage = null;
continue;
}
} else {
if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
+ pkg.packageName + " to old name " + origPackage.name);
}
break;
}
}
}
}
if (mTransferedPackages.contains(pkg.packageName)) {
Slog.w(TAG, "Package " + pkg.packageName
+ " was transferred to another, but its .apk remains");
}
// Just create the setting, don't add it yet. For already existing packages
// the PkgSetting exists already and doesn't have to be created.
pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
pkg.applicationInfo.primaryCpuAbi,
pkg.applicationInfo.secondaryCpuAbi,
pkg.applicationInfo.flags, user, false);
if (pkgSetting == null) {
throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
"Creating application package " + pkg.packageName + " failed");
}
if (pkgSetting.origPackage != null) {
// If we are first transitioning from an original package,
// fix up the new package's name now. We need to do this after
// looking up the package under its new name, so getPackageLP
// can take care of fiddling things correctly.
pkg.setPackageName(origPackage.name);
// File a report about this.
String msg = "New package " + pkgSetting.realName
+ " renamed to replace old package " + pkgSetting.name;
reportSettingsProblem(Log.WARN, msg);
// Make a note of it.
mTransferedPackages.add(origPackage.name);
// No longer need to retain this.
pkgSetting.origPackage = null;
}
if (realName != null) {
// Make a note of it.
mTransferedPackages.add(pkg.packageName);
}
if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
}
if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
// Check all shared libraries and map to their actual file path.
// We only do this here for apps not on a system dir, because those
// are the only ones that can fail an install due to this. We
// will take care of the system apps by updating all of their
// library paths after the scan is done.
updateSharedLibrariesLPw(pkg, null);
}
if (mFoundPolicyFile) {
SELinuxMMAC.assignSeinfoValue(pkg);
}
pkg.applicationInfo.uid = pkgSetting.appId;
pkg.mExtras = pkgSetting;
if (!pkgSetting.keySetData.isUsingUpgradeKeySets() || pkgSetting.sharedUser != null) {
try {
verifySignaturesLP(pkgSetting, pkg);
// We just determined the app is signed correctly, so bring
// over the latest parsed certs.
pkgSetting.signatures.mSignatures = pkg.mSignatures;
} catch (PackageManagerException e) {
if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
throw e;
}
// The signature has changed, but this package is in the system
// image... let's recover!
pkgSetting.signatures.mSignatures = pkg.mSignatures;
// However... if this package is part of a shared user, but it
// doesn't match the signature of the shared user, let's fail.
// What this means is that you can't change the signatures
// associated with an overall shared user, which doesn't seem all
// that unreasonable.
if (pkgSetting.sharedUser != null) {
if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
throw new PackageManagerException(
INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
"Signature mismatch for shared user : "
+ pkgSetting.sharedUser);
}
}
// File a report about this.
String msg = "System package " + pkg.packageName
+ " signature changed; retaining data.";
reportSettingsProblem(Log.WARN, msg);
}
} else {
if (!checkUpgradeKeySetLP(pkgSetting, pkg)) {
throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
+ pkg.packageName + " upgrade keys do not match the "
+ "previously installed version");
} else {
// We just determined the app is signed correctly, so bring
// over the latest parsed certs.
pkgSetting.signatures.mSignatures = pkg.mSignatures;
}
}
// Verify that this new package doesn't have any content providers
// that conflict with existing packages. Only do this if the
// package isn't already installed, since we don't want to break
// things that are installed.
if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
final int N = pkg.providers.size();
int i;
for (i=0; i<N; i++) {
PackageParser.Provider p = pkg.providers.get(i);
if (p.info.authority != null) {
String names[] = p.info.authority.split(";");
for (int j = 0; j < names.length; j++) {
if (mProvidersByAuthority.containsKey(names[j])) {
PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
final String otherPackageName =
((other != null && other.getComponentName() != null) ?
other.getComponentName().getPackageName() : "?");
throw new PackageManagerException(
INSTALL_FAILED_CONFLICTING_PROVIDER,
"Can't install because provider name " + names[j]
+ " (in package " + pkg.applicationInfo.packageName
+ ") is already used by " + otherPackageName);
}
}
}
}
}
if (pkg.mAdoptPermissions != null) {
// This package wants to adopt ownership of permissions from
// another package.
for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
final String origName = pkg.mAdoptPermissions.get(i);
final PackageSetting orig = mSettings.peekPackageLPr(origName);
if (orig != null) {
if (verifyPackageUpdateLPr(orig, pkg)) {
Slog.i(TAG, "Adopting permissions from " + origName + " to "
+ pkg.packageName);
mSettings.transferPermissionsLPw(origName, pkg.packageName);
}
}
}
}
}
final String pkgName = pkg.packageName;
final long scanFileTime = scanFile.lastModified();
final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
pkg.applicationInfo.processName = fixProcessName(
pkg.applicationInfo.packageName,
pkg.applicationInfo.processName,
pkg.applicationInfo.uid);
File dataPath;
if (mPlatformPackage == pkg) {
// The system package is special.
dataPath = new File(Environment.getDataDirectory(), "system");
pkg.applicationInfo.dataDir = dataPath.getPath();
} else {
// This is a normal package, need to make its data directory.
dataPath = getDataPathForPackage(pkg.packageName, 0);
boolean uidError = false;
if (dataPath.exists()) {
int currentUid = 0;
try {
StructStat stat = Os.stat(dataPath.getPath());
currentUid = stat.st_uid;
} catch (ErrnoException e) {
Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
}
// If we have mismatched owners for the data path, we have a problem.
if (currentUid != pkg.applicationInfo.uid) {
boolean recovered = false;
if (currentUid == 0) {
// The directory somehow became owned by root. Wow.
// This is probably because the system was stopped while
// installd was in the middle of messing with its libs
// directory. Ask installd to fix that.
int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid,
pkg.applicationInfo.uid);
if (ret >= 0) {
recovered = true;
String msg = "Package " + pkg.packageName
+ " unexpectedly changed to uid 0; recovered to " +
+ pkg.applicationInfo.uid;
reportSettingsProblem(Log.WARN, msg);
}
}
if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
|| (scanFlags&SCAN_BOOTING) != 0)) {
// If this is a system app, we can at least delete its
// current data so the application will still work.
int ret = removeDataDirsLI(pkgName);
if (ret >= 0) {
// TODO: Kill the processes first
// Old data gone!
String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
? "System package " : "Third party package ";
String msg = prefix + pkg.packageName
+ " has changed from uid: "
+ currentUid + " to "
+ pkg.applicationInfo.uid + "; old data erased";
reportSettingsProblem(Log.WARN, msg);
recovered = true;
// And now re-install the app.
ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
pkg.applicationInfo.seinfo);
if (ret == -1) {
// Ack should not happen!
msg = prefix + pkg.packageName
+ " could not have data directory re-created after delete.";
reportSettingsProblem(Log.WARN, msg);
throw new PackageManagerException(
INSTALL_FAILED_INSUFFICIENT_STORAGE, msg);
}
}
if (!recovered) {
mHasSystemUidErrors = true;
}
} else if (!recovered) {
// If we allow this install to proceed, we will be broken.
// Abort, abort!
throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED,
"scanPackageLI");
}
if (!recovered) {
pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
+ pkg.applicationInfo.uid + "/fs_"
+ currentUid;
pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir;
String msg = "Package " + pkg.packageName
+ " has mismatched uid: "
+ currentUid + " on disk, "
+ pkg.applicationInfo.uid + " in settings";
// writer
synchronized (mPackages) {
mSettings.mReadMessages.append(msg);
mSettings.mReadMessages.append('\n");
uidError = true;
if (!pkgSetting.uidError) {
reportSettingsProblem(Log.ERROR, msg);
}
}
}
}
pkg.applicationInfo.dataDir = dataPath.getPath();
if (mShouldRestoreconData) {
Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued.");
mInstaller.restoreconData(pkg.packageName, pkg.applicationInfo.seinfo,
pkg.applicationInfo.uid);
}
} else {
if (DEBUG_PACKAGE_SCANNING) {
if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
Log.v(TAG, "Want this data dir: " + dataPath);
}
//invoke installer to do the actual installation
int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
pkg.applicationInfo.seinfo);
if (ret < 0) {
// Error from installer
throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
"Unable to create data dirs [errorCode=" + ret + "]");
}
if (dataPath.exists()) {
pkg.applicationInfo.dataDir = dataPath.getPath();
} else {
Slog.w(TAG, "Unable to create data directory: " + dataPath);
pkg.applicationInfo.dataDir = null;
}
}
pkgSetting.uidError = uidError;
}
final String path = scanFile.getPath();
final String codePath = pkg.applicationInfo.getCodePath();
final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
setBundledAppAbisAndRoots(pkg, pkgSetting);
// If we haven't found any native libraries for the app, check if it has
// renderscript code. We'll need to force the app to 32 bit if it has
// renderscript bitcode.
if (pkg.applicationInfo.primaryCpuAbi == null
&& pkg.applicationInfo.secondaryCpuAbi == null
&& Build.SUPPORTED_64_BIT_ABIS.length > 0) {
NativeLibraryHelper.Handle handle = null;
try {
handle = NativeLibraryHelper.Handle.create(scanFile);
if (NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
}
} catch (IOException ioe) {
Slog.w(TAG, "Error scanning system app : " + ioe);
} finally {
IoUtils.closeQuietly(handle);
}
}
setNativeLibraryPaths(pkg);
} else {
// TODO: We can probably be smarter about this stuff. For installed apps,
// we can calculate this information at install time once and for all. For
// system apps, we can probably assume that this information doesn't change
// after the first boot scan. As things stand, we do lots of unnecessary work.
// Give ourselves some initial paths; we'll come back for another
// pass once we've determined ABI below.
setNativeLibraryPaths(pkg);
final boolean isAsec = isForwardLocked(pkg) || isExternal(pkg);
final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
NativeLibraryHelper.Handle handle = null;
try {
handle = NativeLibraryHelper.Handle.create(scanFile);
// TODO(multiArch): This can be null for apps that didn't go through the
// usual installation process. We can calculate it again, like we
// do during install time.
//
// TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
// unnecessary.
final File nativeLibraryRoot = new File(nativeLibraryRootStr);
// Null out the abis so that they can be recalculated.
pkg.applicationInfo.primaryCpuAbi = null;
pkg.applicationInfo.secondaryCpuAbi = null;
if (isMultiArch(pkg.applicationInfo)) {
// Warn if we've set an abiOverride for multi-lib packages..
// By definition, we need to copy both 32 and 64 bit libraries for
// such packages.
if (pkg.cpuAbiOverride != null
&& !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
}
int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
if (isAsec) {
abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
} else {
abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
useIsaSpecificSubdirs);
}
}
maybeThrowExceptionForMultiArchCopy(
"Error unpackaging 32 bit native libs for multiarch app.", abi32);
if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
if (isAsec) {
abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
} else {
abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
useIsaSpecificSubdirs);
}
}
maybeThrowExceptionForMultiArchCopy(
"Error unpackaging 64 bit native libs for multiarch app.", abi64);
if (abi64 >= 0) {
pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
}
if (abi32 >= 0) {
final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
if (abi64 >= 0) {
pkg.applicationInfo.secondaryCpuAbi = abi;
} else {
pkg.applicationInfo.primaryCpuAbi = abi;
}
}
} else {
String[] abiList = (cpuAbiOverride != null) ?
new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
// Enable gross and lame hacks for apps that are built with old
// SDK tools. We must scan their APKs for renderscript bitcode and
// not launch them if it's present. Don't bother checking on devices
// that don't have 64 bit support.
boolean needsRenderScriptOverride = false;
if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
abiList = Build.SUPPORTED_32_BIT_ABIS;
needsRenderScriptOverride = true;
}
final int copyRet;
if (isAsec) {
copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
} else {
copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
}
if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
"Error unpackaging native libs for app, errorCode=" + copyRet);
}
if (copyRet >= 0) {
pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
} else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
} else if (needsRenderScriptOverride) {
pkg.applicationInfo.primaryCpuAbi = abiList[0];
}
}
} catch (IOException ioe) {
Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
} finally {
IoUtils.closeQuietly(handle);
}
// Now that we've calculated the ABIs and determined if it's an internal app,
// we will go ahead and populate the nativeLibraryPath.
setNativeLibraryPaths(pkg);
if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
final int[] userIds = sUserManager.getUserIds();
synchronized (mInstallLock) {
// Create a native library symlink only if we have native libraries
// and if the native libraries are 32 bit libraries. We do not provide
// this symlink for 64 bit libraries.
if (pkg.applicationInfo.primaryCpuAbi != null &&
!VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
for (int userId : userIds) {
if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) {
throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
"Failed linking native library dir (user=" + userId + ")");
}
}
}
}
}
// This is a special case for the "system" package, where the ABI is
// dictated by the zygote configuration (and init.rc). We should keep track
// of this ABI so that we can deal with "normal" applications that run under
// the same UID correctly.
if (mPlatformPackage == pkg) {
pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
}
pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
// Copy the derived override back to the parsed package, so that we can
// update the package settings accordingly.
pkg.cpuAbiOverride = cpuAbiOverride;
if (DEBUG_ABI_SELECTION) {
Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
+ " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
+ pkg.applicationInfo.nativeLibraryRootRequiresIsa);
}
// Push the derived path down into PackageSettings so we know what to
// clean up at uninstall time.
pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
if (DEBUG_ABI_SELECTION) {
Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
" primary=" + pkg.applicationInfo.primaryCpuAbi +
" secondary=" + pkg.applicationInfo.secondaryCpuAbi);
}
if ((scanFlags&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
// We don't do this here during boot because we can do it all
// at once after scanning all existing packages.
//
// We also do this *before* we perform dexopt on this package, so that
// we can avoid redundant dexopts, and also to make sure we've got the
// code and package path correct.
adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0);
}
if ((scanFlags & SCAN_NO_DEX) == 0) {
if (performDexOptLI(pkg, null /* instruction sets */, forceDex,
(scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI");
}
}
if (mFactoryTest && pkg.requestedPermissions.contains(
android.Manifest.permission.FACTORY_TEST)) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
}
ArrayList<PackageParser.Package> clientLibPkgs = null;
// writer
synchronized (mPackages) {
if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
// Only system apps can add new shared libraries.
if (pkg.libraryNames != null) {
for (int i=0; i<pkg.libraryNames.size(); i++) {
String name = pkg.libraryNames.get(i);
boolean allowed = false;
if (isUpdatedSystemApp(pkg)) {
// New library entries can only be added through the
// system image. This is important to get rid of a lot
// of nasty edge cases: for example if we allowed a non-
// system update of the app to add a library, then uninstalling
// the update would make the library go away, and assumptions
// we made such as through app install filtering would now
// have allowed apps on the device which aren't compatible
// with it. Better to just have the restriction here, be
// conservative, and create many fewer cases that can negatively
// impact the user experience.
final PackageSetting sysPs = mSettings
.getDisabledSystemPkgLPr(pkg.packageName);
if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
if (name.equals(sysPs.pkg.libraryNames.get(j))) {
allowed = true;
allowed = true;
break;
}
}
}
} else {
allowed = true;
}
if (allowed) {
if (!mSharedLibraries.containsKey(name)) {
mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
} else if (!name.equals(pkg.packageName)) {
Slog.w(TAG, "Package " + pkg.packageName + " library "
+ name + " already exists; skipping");
}
} else {
Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
+ name + " that is not declared on system image; skipping");
}
}
if ((scanFlags&SCAN_BOOTING) == 0) {
// If we are not booting, we need to update any applications
// that are clients of our shared library. If we are booting,
// this will all be done once the scan is complete.
clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
}
}
}
}
// We also need to dexopt any apps that are dependent on this library. Note that
// if these fail, we should abort the install since installing the library will
// result in some apps being broken.
if (clientLibPkgs != null) {
if ((scanFlags & SCAN_NO_DEX) == 0) {
for (int i = 0; i < clientLibPkgs.size(); i++) {
PackageParser.Package clientPkg = clientLibPkgs.get(i);
if (performDexOptLI(clientPkg, null /* instruction sets */, forceDex,
(scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
throw new PackageManagerException(INSTALL_FAILED_DEXOPT,
"scanPackageLI failed to dexopt clientLibPkgs");
}
}
}
}
// Request the ActivityManager to kill the process(only for existing packages)
// so that we do not end up in a confused state while the user is still using the older
// version of the application while the new one gets installed.
if ((scanFlags & SCAN_REPLACING) != 0) {
killApplication(pkg.applicationInfo.packageName,
pkg.applicationInfo.uid, "update pkg");
}
// Also need to kill any apps that are dependent on the library.
if (clientLibPkgs != null) {
for (int i=0; i<clientLibPkgs.size(); i++) {
PackageParser.Package clientPkg = clientLibPkgs.get(i);
killApplication(clientPkg.applicationInfo.packageName,
clientPkg.applicationInfo.uid, "update lib");
}
}
// writer
synchronized (mPackages) {
// We don't expect installation to fail beyond this point
// Add the new setting to mSettings
mSettings.insertPackageSettingLPw(pkgSetting, pkg);
// Add the new setting to mPackages
mPackages.put(pkg.applicationInfo.packageName, pkg);
// Make sure we don't accidentally delete its data.
final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
while (iter.hasNext()) {
PackageCleanItem item = iter.next();
if (pkgName.equals(item.packageName)) {
iter.remove();
}
}
// Take care of first install / last update times.
if (currentTime != 0) {
if (pkgSetting.firstInstallTime == 0) {
pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
} else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
pkgSetting.lastUpdateTime = currentTime;
}
} else if (pkgSetting.firstInstallTime == 0) {
// We need *something*. Take time time stamp of the file.
pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
} else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
if (scanFileTime != pkgSetting.timeStamp) {
// A package on the system image has changed; consider this
// to be an update.
pkgSetting.lastUpdateTime = scanFileTime;
}
}
// Add the package's KeySets to the global KeySetManagerService
KeySetManagerService ksms = mSettings.mKeySetManagerService;
try {
// Old KeySetData no longer valid.
ksms.removeAppKeySetDataLPw(pkg.packageName);
ksms.addSigningKeySetToPackageLPw(pkg.packageName, pkg.mSigningKeys);
if (pkg.mKeySetMapping != null) {
for (Map.Entry<String, ArraySet<PublicKey>> entry :
pkg.mKeySetMapping.entrySet()) {
if (entry.getValue() != null) {
ksms.addDefinedKeySetToPackageLPw(pkg.packageName,
entry.getValue(), entry.getKey());
}
}
if (pkg.mUpgradeKeySets != null) {
for (String upgradeAlias : pkg.mUpgradeKeySets) {
ksms.addUpgradeKeySetToPackageLPw(pkg.packageName, upgradeAlias);
}
}
}
} catch (NullPointerException e) {
Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e);
} catch (IllegalArgumentException e) {
Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e);
}
int N = pkg.providers.size();
StringBuilder r = null;
int i;
for (i=0; i<N; i++) {
PackageParser.Provider p = pkg.providers.get(i);
p.info.processName = fixProcessName(pkg.applicationInfo.processName,
p.info.processName, pkg.applicationInfo.uid);
mProviders.addProvider(p);
p.syncable = p.info.isSyncable;
if (p.info.authority != null) {
String names[] = p.info.authority.split(";");
p.info.authority = null;
for (int j = 0; j < names.length; j++) {
if (j == 1 && p.syncable) {
// We only want the first authority for a provider to possibly be
// syncable, so if we already added this provider using a different
// authority clear the syncable flag. We copy the provider before
// changing it because the mProviders object contains a reference
// to a provider that we don't want to change.
// Only do this for the second authority since the resulting provider
// object can be the same for all future authorities for this provider.
p = new PackageParser.Provider(p);
p.syncable = false;
}
if (!mProvidersByAuthority.containsKey(names[j])) {
mProvidersByAuthority.put(names[j], p);
if (p.info.authority == null) {
p.info.authority = names[j];
} else {
p.info.authority = p.info.authority + ";" + names[j];
}
if (DEBUG_PACKAGE_SCANNING) {
if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
Log.d(TAG, "Registered content provider: " + names[j]
+ ", className = " + p.info.name + ", isSyncable = "
+ p.info.isSyncable);
}
} else {
PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
Slog.w(TAG, "Skipping provider name " + names[j] +
" (in package " + pkg.applicationInfo.packageName +
"): name already used by "
+ ((other != null && other.getComponentName() != null)
? other.getComponentName().getPackageName() : "?"));
}
}
}
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append(p.info.name);
}
}
if (r != null) {
if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r);
}
N = pkg.services.size();
r = null;
for (i=0; i<N; i++) {
PackageParser.Service s = pkg.services.get(i);
s.info.processName = fixProcessName(pkg.applicationInfo.processName,
s.info.processName, pkg.applicationInfo.uid);
mServices.addService(s);
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append(s.info.name);
}
}
if (r != null) {
if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r);
}
N = pkg.receivers.size();
r = null;
for (i=0; i<N; i++) {
PackageParser.Activity a = pkg.receivers.get(i);
a.info.processName = fixProcessName(pkg.applicationInfo.processName,
a.info.processName, pkg.applicationInfo.uid);
mReceivers.addActivity(a, "receiver");
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append(a.info.name);
}
}
if (r != null) {
if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r);
}
N = pkg.activities.size();
r = null;
for (i=0; i<N; i++) {
PackageParser.Activity a = pkg.activities.get(i);
a.info.processName = fixProcessName(pkg.applicationInfo.processName,
a.info.processName, pkg.applicationInfo.uid);
mActivities.addActivity(a, "activity");
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append(a.info.name);
}
}
if (r != null) {
if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r);
}
N = pkg.permissionGroups.size();
r = null;
for (i=0; i<N; i++) {
PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
if (cur == null) {
mPermissionGroups.put(pg.info.name, pg);
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append(pg.info.name);
}
} else {
Slog.w(TAG, "Permission group " + pg.info.name + " from package "
+ pg.info.packageName + " ignored: original from "
+ cur.info.packageName);
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append("DUP:");
r.append(pg.info.name);
}
}
}
if (r != null) {
if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r);
}
N = pkg.permissions.size();
r = null;
for (i=0; i<N; i++) {
PackageParser.Permission p = pkg.permissions.get(i);
ArrayMap<String, BasePermission> permissionMap =
p.tree ? mSettings.mPermissionTrees
: mSettings.mPermissions;
p.group = mPermissionGroups.get(p.info.group);
if (p.info.group == null || p.group != null) {
BasePermission bp = permissionMap.get(p.info.name);
// Allow system apps to redefine non-system permissions
if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
final boolean currentOwnerIsSystem = (bp.perm != null
&& isSystemApp(bp.perm.owner));
if (isSystemApp(p.owner)) {
if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
// It's a built-in permission and no owner, take ownership now
bp.packageSetting = pkgSetting;
bp.perm = p;
bp.uid = pkg.applicationInfo.uid;
bp.sourcePackage = p.info.packageName;
} else if (!currentOwnerIsSystem) {
String msg = "New decl " + p.owner + " of permission "
+ p.info.name + " is system; overriding " + bp.sourcePackage;
reportSettingsProblem(Log.WARN, msg);
bp = null;
}
}
}
if (bp == null) {
bp = new BasePermission(p.info.name, p.info.packageName,
BasePermission.TYPE_NORMAL);
permissionMap.put(p.info.name, bp);
}
if (bp.perm == null) {
if (bp.sourcePackage == null
|| bp.sourcePackage.equals(p.info.packageName)) {
BasePermission tree = findPermissionTreeLP(p.info.name);
if (tree == null
|| tree.sourcePackage.equals(p.info.packageName)) {
bp.packageSetting = pkgSetting;
bp.perm = p;
bp.uid = pkg.applicationInfo.uid;
bp.sourcePackage = p.info.packageName;
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append(p.info.name);
}
} else {
Slog.w(TAG, "Permission " + p.info.name + " from package "
+ p.info.packageName + " ignored: base tree "
+ tree.name + " is from package "
+ tree.sourcePackage);
}
} else {
Slog.w(TAG, "Permission " + p.info.name + " from package "
+ p.info.packageName + " ignored: original from "
+ bp.sourcePackage);
}
} else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append("DUP:");
r.append(p.info.name);
}
if (bp.perm == p) {
bp.protectionLevel = p.info.protectionLevel;
}
} else {
Slog.w(TAG, "Permission " + p.info.name + " from package "
+ p.info.packageName + " ignored: no group "
+ p.group);
}
}
if (r != null) {
if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r);
}
N = pkg.instrumentation.size();
r = null;
for (i=0; i<N; i++) {
PackageParser.Instrumentation a = pkg.instrumentation.get(i);
a.info.packageName = pkg.applicationInfo.packageName;
a.info.sourceDir = pkg.applicationInfo.sourceDir;
a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
a.info.dataDir = pkg.applicationInfo.dataDir;
// TODO: Update instrumentation.nativeLibraryDir as well ? Does it
// need other information about the application, like the ABI and what not ?
a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
mInstrumentation.put(a.getComponentName(), a);
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append(a.info.name);
}
}
if (r != null) {
if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r);
}
if (pkg.protectedBroadcasts != null) {
N = pkg.protectedBroadcasts.size();
for (i=0; i<N; i++) {
mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
}
}
pkgSetting.setTimeStamp(scanFileTime);
// Create idmap files for pairs of (packages, overlay packages).
// Note: "android", ie framework-res.apk, is handled by native layers.
if (pkg.mOverlayTarget != null) {
// This is an overlay package.
if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
mOverlays.put(pkg.mOverlayTarget,
new ArrayMap<String, PackageParser.Package>());
}
ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
map.put(pkg.packageName, pkg);
PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
"scanPackageLI failed to createIdmap");
}
}
} else if (mOverlays.containsKey(pkg.packageName) &&
!pkg.packageName.equals("android")) {
// This is a regular package, with one or more known overlay packages.
createIdmapsForPackageLI(pkg);
}
}
return pkg;
| private PackageParser.Package | scanPackageLI(java.io.File scanFile, int parseFlags, int scanFlags, long currentTime, android.os.UserHandle user)
if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
parseFlags |= mDefParseFlags;
PackageParser pp = new PackageParser();
pp.setSeparateProcesses(mSeparateProcesses);
pp.setOnlyCoreApps(mOnlyCore);
pp.setDisplayMetrics(mMetrics);
if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
}
final PackageParser.Package pkg;
try {
pkg = pp.parsePackage(scanFile, parseFlags);
} catch (PackageParserException e) {
throw PackageManagerException.from(e);
}
PackageSetting ps = null;
PackageSetting updatedPkg;
// reader
synchronized (mPackages) {
// Look to see if we already know about this package.
String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
// This package has been renamed to its original name. Let's
// use that.
ps = mSettings.peekPackageLPr(oldName);
}
// If there was no original package, see one for the real package name.
if (ps == null) {
ps = mSettings.peekPackageLPr(pkg.packageName);
}
// Check to see if this package could be hiding/updating a system
// package. Must look for it either under the original or real
// package name depending on our state.
updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
}
boolean updatedPkgBetter = false;
// First check if this is a system package that may involve an update
if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
// If new package is not located in "/system/priv-app" (e.g. due to an OTA),
// it needs to drop FLAG_PRIVILEGED.
if (locationIsPrivileged(scanFile)) {
updatedPkg.pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED;
} else {
updatedPkg.pkgFlags &= ~ApplicationInfo.FLAG_PRIVILEGED;
}
if (ps != null && !ps.codePath.equals(scanFile)) {
// The path has changed from what was last scanned... check the
// version of the new path against what we have stored to determine
// what to do.
if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
if (pkg.mVersionCode <= ps.versionCode) {
// The system package has been updated and the code path does not match
// Ignore entry. Skip it.
Slog.i(TAG, "Package " + ps.name + " at " + scanFile
+ " ignored: updated version " + ps.versionCode
+ " better than this " + pkg.mVersionCode);
if (!updatedPkg.codePath.equals(scanFile)) {
Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : "
+ ps.name + " changing from " + updatedPkg.codePathString
+ " to " + scanFile);
updatedPkg.codePath = scanFile;
updatedPkg.codePathString = scanFile.toString();
}
updatedPkg.pkg = pkg;
throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, null);
} else {
// The current app on the system partition is better than
// what we have updated to on the data partition; switch
// back to the system partition version.
// At this point, its safely assumed that package installation for
// apps in system partition will go through. If not there won't be a working
// version of the app
// writer
synchronized (mPackages) {
// Just remove the loaded entries from package lists.
mPackages.remove(ps.name);
}
logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
+ " reverting from " + ps.codePathString
+ ": new version " + pkg.mVersionCode
+ " better than installed " + ps.versionCode);
InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
getAppDexInstructionSets(ps));
synchronized (mInstallLock) {
args.cleanUpResourcesLI();
}
synchronized (mPackages) {
mSettings.enableSystemPackageLPw(ps.name);
}
updatedPkgBetter = true;
}
}
}
if (updatedPkg != null) {
// An updated system app will not have the PARSE_IS_SYSTEM flag set
// initially
parseFlags |= PackageParser.PARSE_IS_SYSTEM;
// An updated privileged app will not have the PARSE_IS_PRIVILEGED
// flag set initially
if ((updatedPkg.pkgFlags & ApplicationInfo.FLAG_PRIVILEGED) != 0) {
parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
}
}
// Verify certificates against what was last scanned
collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags);
/*
* A new system app appeared, but we already had a non-system one of the
* same name installed earlier.
*/
boolean shouldHideSystemApp = false;
if (updatedPkg == null && ps != null
&& (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
/*
* Check to make sure the signatures match first. If they don't,
* wipe the installed application and its data.
*/
if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
!= PackageManager.SIGNATURE_MATCH) {
logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
+ " signatures don't match existing userdata copy; removing");
deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
ps = null;
} else {
/*
* If the newly-added system app is an older version than the
* already installed version, hide it. It will be scanned later
* and re-added like an update.
*/
if (pkg.mVersionCode <= ps.versionCode) {
shouldHideSystemApp = true;
logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
+ " but new version " + pkg.mVersionCode + " better than installed "
+ ps.versionCode + "; hiding system");
} else {
/*
* The newly found system app is a newer version that the
* one previously installed. Simply remove the
* already-installed application and replace it with our own
* while keeping the application data.
*/
logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
+ " reverting from " + ps.codePathString + ": new version "
+ pkg.mVersionCode + " better than installed " + ps.versionCode);
InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
getAppDexInstructionSets(ps));
synchronized (mInstallLock) {
args.cleanUpResourcesLI();
}
}
}
}
// The apk is forward locked (not public) if its code and resources
// are kept in different files. (except for app in either system or
// vendor path).
// TODO grab this value from PackageSettings
if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
}
}
// TODO: extend to support forward-locked splits
String resourcePath = null;
String baseResourcePath = null;
if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
if (ps != null && ps.resourcePathString != null) {
resourcePath = ps.resourcePathString;
baseResourcePath = ps.resourcePathString;
} else {
// Should not happen at all. Just log an error.
Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
}
} else {
resourcePath = pkg.codePath;
baseResourcePath = pkg.baseCodePath;
}
// Set application objects path explicitly.
pkg.applicationInfo.setCodePath(pkg.codePath);
pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
pkg.applicationInfo.setResourcePath(resourcePath);
pkg.applicationInfo.setBaseResourcePath(baseResourcePath);
pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
// Note that we invoke the following method only if we are about to unpack an application
PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags
| SCAN_UPDATE_SIGNATURE, currentTime, user);
/*
* If the system app should be overridden by a previously installed
* data, hide the system app now and let the /data/app scan pick it up
* again.
*/
if (shouldHideSystemApp) {
synchronized (mPackages) {
/*
* We have to grant systems permissions before we hide, because
* grantPermissions will assume the package update is trying to
* expand its permissions.
*/
grantPermissionsLPw(pkg, true, pkg.packageName);
mSettings.disableSystemPackageLPw(pkg.packageName);
}
}
return scannedPkg;
| private PackageParser.Package | scanPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, long currentTime, android.os.UserHandle user)
boolean success = false;
try {
final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags,
currentTime, user);
success = true;
return res;
} finally {
if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
removeDataDirsLI(pkg.packageName);
}
}
| void | schedulePackageCleaning(java.lang.String packageName, int userId, boolean andCode)
final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
userId, andCode ? 1 : 0, packageName);
if (mSystemReady) {
msg.sendToTarget();
} else {
if (mPostSystemReadyMessages == null) {
mPostSystemReadyMessages = new ArrayList<>();
}
mPostSystemReadyMessages.add(msg);
}
| void | scheduleWritePackageRestrictionsLocked(int userId)
if (!sUserManager.exists(userId)) return;
mDirtyUsers.add(userId);
if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
}
| void | scheduleWriteSettingsLocked()
if (!mHandler.hasMessages(WRITE_SETTINGS)) {
mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
}
| private void | sendApplicationHiddenForUser(java.lang.String packageName, PackageSetting pkgSetting, int userId)
final PackageRemovedInfo info = new PackageRemovedInfo();
info.removedPackage = packageName;
info.removedUsers = new int[] {userId};
info.uid = UserHandle.getUid(userId, pkgSetting.appId);
info.sendBroadcast(false, false, false);
| private void | sendPackageAddedForUser(java.lang.String packageName, PackageSetting pkgSetting, int userId)
Bundle extras = new Bundle(1);
extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
packageName, extras, null, null, new int[] {userId});
try {
IActivityManager am = ActivityManagerNative.getDefault();
final boolean isSystem =
isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
if (isSystem && am.isUserRunning(userId, false)) {
// The just-installed/enabled app is bundled on the system, so presumed
// to be able to run automatically without needing an explicit launch.
// Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
.setPackage(packageName);
am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
android.app.AppOpsManager.OP_NONE, false, false, userId);
}
} catch (RemoteException e) {
// shouldn't happen
Slog.w(TAG, "Unable to bootstrap installed package", e);
}
| static final void | sendPackageBroadcast(java.lang.String action, java.lang.String pkg, android.os.Bundle extras, java.lang.String targetPkg, android.content.IIntentReceiver finishedReceiver, int[] userIds)
IActivityManager am = ActivityManagerNative.getDefault();
if (am != null) {
try {
if (userIds == null) {
userIds = am.getRunningUserIds();
}
for (int id : userIds) {
final Intent intent = new Intent(action,
pkg != null ? Uri.fromParts("package", pkg, null) : null);
if (extras != null) {
intent.putExtras(extras);
}
if (targetPkg != null) {
intent.setPackage(targetPkg);
}
// Modify the UID when posting to other users
int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
if (uid > 0 && UserHandle.getUserId(uid) != id) {
uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
intent.putExtra(Intent.EXTRA_UID, uid);
}
intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
if (DEBUG_BROADCASTS) {
RuntimeException here = new RuntimeException("here");
here.fillInStackTrace();
Slog.d(TAG, "Sending to user " + id + ": "
+ intent.toShortString(false, true, false, false)
+ " " + intent.getExtras(), here);
}
am.broadcastIntent(null, intent, null, finishedReceiver,
0, null, null, null, android.app.AppOpsManager.OP_NONE,
finishedReceiver != null, false, id);
}
} catch (RemoteException ex) {
}
}
| private void | sendPackageChangedBroadcast(java.lang.String packageName, boolean killFlag, java.util.ArrayList componentNames, int packageUid)
if (DEBUG_INSTALL)
Log.v(TAG, "Sending package changed: package=" + packageName + " components="
+ componentNames);
Bundle extras = new Bundle(4);
extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
String nameList[] = new String[componentNames.size()];
componentNames.toArray(nameList);
extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
extras.putInt(Intent.EXTRA_UID, packageUid);
sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null,
new int[] {UserHandle.getUserId(packageUid)});
| private void | sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, java.util.ArrayList pkgList, int[] uidArr, android.content.IIntentReceiver finishedReceiver)
int size = pkgList.size();
if (size > 0) {
// Send broadcasts here
Bundle extras = new Bundle();
extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList
.toArray(new String[size]));
if (uidArr != null) {
extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
}
if (replacing) {
extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
}
String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
: Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
sendPackageBroadcast(action, null, extras, null, finishedReceiver, null);
}
| public void | setApplicationEnabledSetting(java.lang.String appPackageName, int newState, int flags, int userId, java.lang.String callingPackage)
if (!sUserManager.exists(userId)) return;
if (callingPackage == null) {
callingPackage = Integer.toString(Binder.getCallingUid());
}
setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
| public boolean | setApplicationHiddenSettingAsUser(java.lang.String packageName, boolean hidden, int userId)
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
PackageSetting pkgSetting;
final int uid = Binder.getCallingUid();
enforceCrossUserPermission(uid, userId, true, true,
"setApplicationHiddenSetting for user " + userId);
if (hidden && isPackageDeviceAdmin(packageName, userId)) {
Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
return false;
}
long callingId = Binder.clearCallingIdentity();
try {
boolean sendAdded = false;
boolean sendRemoved = false;
// writer
synchronized (mPackages) {
pkgSetting = mSettings.mPackages.get(packageName);
if (pkgSetting == null) {
return false;
}
if (pkgSetting.getHidden(userId) != hidden) {
pkgSetting.setHidden(hidden, userId);
mSettings.writePackageRestrictionsLPr(userId);
if (hidden) {
sendRemoved = true;
} else {
sendAdded = true;
}
}
}
if (sendAdded) {
sendPackageAddedForUser(packageName, pkgSetting, userId);
return true;
}
if (sendRemoved) {
killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
"hiding pkg");
sendApplicationHiddenForUser(packageName, pkgSetting, userId);
}
} finally {
Binder.restoreCallingIdentity(callingId);
}
return false;
| public boolean | setBlockUninstallForUser(java.lang.String packageName, boolean blockUninstall, int userId)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.DELETE_PACKAGES, null);
synchronized (mPackages) {
PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps == null) {
Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
return false;
}
if (!ps.getInstalled(userId)) {
// Can't block uninstall for an app that is not installed or enabled.
Log.i(TAG, "Package not installed in set block uninstall " + packageName);
return false;
}
ps.setBlockUninstall(blockUninstall, userId);
mSettings.writePackageRestrictionsLPr(userId);
}
return true;
| private static void | setBundledAppAbi(PackageParser.Package pkg, java.lang.String apkRoot, java.lang.String apkName)Deduces the ABI of a bundled app and sets the relevant fields on the
parsed pkg object.
final File codeFile = new File(pkg.codePath);
final boolean has64BitLibs;
final boolean has32BitLibs;
if (isApkFile(codeFile)) {
// Monolithic install
has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
} else {
// Cluster install
final File rootDir = new File(codeFile, LIB_DIR_NAME);
if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
&& !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
has64BitLibs = (new File(rootDir, isa)).exists();
} else {
has64BitLibs = false;
}
if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
&& !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
has32BitLibs = (new File(rootDir, isa)).exists();
} else {
has32BitLibs = false;
}
}
if (has64BitLibs && !has32BitLibs) {
// The package has 64 bit libs, but not 32 bit libs. Its primary
// ABI should be 64 bit. We can safely assume here that the bundled
// native libraries correspond to the most preferred ABI in the list.
pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
pkg.applicationInfo.secondaryCpuAbi = null;
} else if (has32BitLibs && !has64BitLibs) {
// The package has 32 bit libs but not 64 bit libs. Its primary
// ABI should be 32 bit.
pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
pkg.applicationInfo.secondaryCpuAbi = null;
} else if (has32BitLibs && has64BitLibs) {
// The application has both 64 and 32 bit bundled libraries. We check
// here that the app declares multiArch support, and warn if it doesn't.
//
// We will be lenient here and record both ABIs. The primary will be the
// ABI that's higher on the list, i.e, a device that's configured to prefer
// 64 bit apps will see a 64 bit primary ABI,
if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
Slog.e(TAG, "Package: " + pkg + " has multiple bundled libs, but is not multiarch.");
}
if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
} else {
pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
}
} else {
pkg.applicationInfo.primaryCpuAbi = null;
pkg.applicationInfo.secondaryCpuAbi = null;
}
| private void | setBundledAppAbisAndRoots(PackageParser.Package pkg, PackageSetting pkgSetting)Calculate the abis and roots for a bundled app. These can uniquely
be determined from the contents of the system partition, i.e whether
it contains 64 or 32 bit shared libraries etc. We do not validate any
of this information, and instead assume that the system was built
sensibly.
final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
// If "/system/lib64/apkname" exists, assume that is the per-package
// native library directory to use; otherwise use "/system/lib/apkname".
final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
setBundledAppAbi(pkg, apkRoot, apkName);
// pkgSetting might be null during rescan following uninstall of updates
// to a bundled app, so accommodate that possibility. The settings in
// that case will be established later from the parsed package.
//
// If the settings aren't null, sync them up with what we've just derived.
// note that apkRoot isn't stored in the package settings.
if (pkgSetting != null) {
pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
}
| public void | setComponentEnabledSetting(android.content.ComponentName componentName, int newState, int flags, int userId)
if (!sUserManager.exists(userId)) return;
setEnabledSetting(componentName.getPackageName(),
componentName.getClassName(), newState, flags, userId, null);
| private void | setEnabledSetting(java.lang.String packageName, java.lang.String className, int newState, int flags, int userId, java.lang.String callingPackage)
if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
|| newState == COMPONENT_ENABLED_STATE_ENABLED
|| newState == COMPONENT_ENABLED_STATE_DISABLED
|| newState == COMPONENT_ENABLED_STATE_DISABLED_USER
|| newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
throw new IllegalArgumentException("Invalid new component state: "
+ newState);
}
PackageSetting pkgSetting;
final int uid = Binder.getCallingUid();
final int permission = mContext.checkCallingOrSelfPermission(
android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
enforceCrossUserPermission(uid, userId, false, true, "set enabled");
final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
boolean sendNow = false;
boolean isApp = (className == null);
String componentName = isApp ? packageName : className;
int packageUid = -1;
ArrayList<String> components;
// writer
synchronized (mPackages) {
pkgSetting = mSettings.mPackages.get(packageName);
if (pkgSetting == null) {
if (className == null) {
throw new IllegalArgumentException(
"Unknown package: " + packageName);
}
throw new IllegalArgumentException(
"Unknown component: " + packageName
+ "/" + className);
}
// Allow root and verify that userId is not being specified by a different user
if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
throw new SecurityException(
"Permission Denial: attempt to change component state from pid="
+ Binder.getCallingPid()
+ ", uid=" + uid + ", package uid=" + pkgSetting.appId);
}
if (className == null) {
// We're dealing with an application/package level state change
if (pkgSetting.getEnabled(userId) == newState) {
// Nothing to do
return;
}
if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
|| newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
// Don't care about who enables an app.
callingPackage = null;
}
pkgSetting.setEnabled(newState, userId, callingPackage);
// pkgSetting.pkg.mSetEnabled = newState;
} else {
// We're dealing with a component level state change
// First, verify that this is a valid class name.
PackageParser.Package pkg = pkgSetting.pkg;
if (pkg == null || !pkg.hasComponentClassName(className)) {
if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) {
throw new IllegalArgumentException("Component class " + className
+ " does not exist in " + packageName);
} else {
Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
+ className + " does not exist in " + packageName);
}
}
switch (newState) {
case COMPONENT_ENABLED_STATE_ENABLED:
if (!pkgSetting.enableComponentLPw(className, userId)) {
return;
}
break;
case COMPONENT_ENABLED_STATE_DISABLED:
if (!pkgSetting.disableComponentLPw(className, userId)) {
return;
}
break;
case COMPONENT_ENABLED_STATE_DEFAULT:
if (!pkgSetting.restoreComponentLPw(className, userId)) {
return;
}
break;
default:
Slog.e(TAG, "Invalid new component state: " + newState);
return;
}
}
mSettings.writePackageRestrictionsLPr(userId);
components = mPendingBroadcasts.get(userId, packageName);
final boolean newPackage = components == null;
if (newPackage) {
components = new ArrayList<String>();
}
if (!components.contains(componentName)) {
components.add(componentName);
}
if ((flags&PackageManager.DONT_KILL_APP) == 0) {
sendNow = true;
// Purge entry from pending broadcast list if another one exists already
// since we are sending one right away.
mPendingBroadcasts.remove(userId, packageName);
} else {
if (newPackage) {
mPendingBroadcasts.put(userId, packageName, components);
}
if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
// Schedule a message
mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
}
}
}
long callingId = Binder.clearCallingIdentity();
try {
if (sendNow) {
packageUid = UserHandle.getUid(userId, pkgSetting.appId);
sendPackageChangedBroadcast(packageName,
(flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
}
} finally {
Binder.restoreCallingIdentity(callingId);
}
| public boolean | setInstallLocation(int loc)
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
null);
if (getInstallLocation() == loc) {
return true;
}
if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
|| loc == PackageHelper.APP_INSTALL_EXTERNAL) {
android.provider.Settings.Global.putInt(mContext.getContentResolver(),
android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
return true;
}
return false;
| public void | setInstallerPackageName(java.lang.String targetPackage, java.lang.String installerPackageName)
final int uid = Binder.getCallingUid();
// writer
synchronized (mPackages) {
PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
if (targetPackageSetting == null) {
throw new IllegalArgumentException("Unknown target package: " + targetPackage);
}
PackageSetting installerPackageSetting;
if (installerPackageName != null) {
installerPackageSetting = mSettings.mPackages.get(installerPackageName);
if (installerPackageSetting == null) {
throw new IllegalArgumentException("Unknown installer package: "
+ installerPackageName);
}
} else {
installerPackageSetting = null;
}
Signature[] callerSignature;
Object obj = mSettings.getUserIdLPr(uid);
if (obj != null) {
if (obj instanceof SharedUserSetting) {
callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
} else if (obj instanceof PackageSetting) {
callerSignature = ((PackageSetting)obj).signatures.mSignatures;
} else {
throw new SecurityException("Bad object " + obj + " for uid " + uid);
}
} else {
throw new SecurityException("Unknown calling uid " + uid);
}
// Verify: can't set installerPackageName to a package that is
// not signed with the same cert as the caller.
if (installerPackageSetting != null) {
if (compareSignatures(callerSignature,
installerPackageSetting.signatures.mSignatures)
!= PackageManager.SIGNATURE_MATCH) {
throw new SecurityException(
"Caller does not have same cert as new installer package "
+ installerPackageName);
}
}
// Verify: if target already has an installer package, it must
// be signed with the same cert as the caller.
if (targetPackageSetting.installerPackageName != null) {
PackageSetting setting = mSettings.mPackages.get(
targetPackageSetting.installerPackageName);
// If the currently set package isn't valid, then it's always
// okay to change it.
if (setting != null) {
if (compareSignatures(callerSignature,
setting.signatures.mSignatures)
!= PackageManager.SIGNATURE_MATCH) {
throw new SecurityException(
"Caller does not have same cert as old installer package "
+ targetPackageSetting.installerPackageName);
}
}
}
// Okay!
targetPackageSetting.installerPackageName = installerPackageName;
scheduleWriteSettingsLocked();
}
| public void | setLastChosenActivity(android.content.Intent intent, java.lang.String resolvedType, int flags, android.content.IntentFilter filter, int match, android.content.ComponentName activity)
final int userId = UserHandle.getCallingUserId();
if (DEBUG_PREFERRED) {
Log.v(TAG, "setLastChosenActivity intent=" + intent
+ " resolvedType=" + resolvedType
+ " flags=" + flags
+ " filter=" + filter
+ " match=" + match
+ " activity=" + activity);
filter.dump(new PrintStreamPrinter(System.out), " ");
}
intent.setComponent(null);
List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
// Find any earlier preferred or last chosen entries and nuke them
findPreferredActivity(intent, resolvedType,
flags, query, 0, false, true, false, userId);
// Add the new activity as the last chosen for this filter
addPreferredActivityInternal(filter, match, null, activity, false, userId,
"Setting last chosen");
| private void | setNativeLibraryPaths(PackageParser.Package pkg)Derive and set the location of native libraries for the given package,
which varies depending on where and how the package was installed.
final ApplicationInfo info = pkg.applicationInfo;
final String codePath = pkg.codePath;
final File codeFile = new File(codePath);
final boolean bundledApp = isSystemApp(info) && !isUpdatedSystemApp(info);
final boolean asecApp = isForwardLocked(info) || isExternal(info);
info.nativeLibraryRootDir = null;
info.nativeLibraryRootRequiresIsa = false;
info.nativeLibraryDir = null;
info.secondaryNativeLibraryDir = null;
if (isApkFile(codeFile)) {
// Monolithic install
if (bundledApp) {
// If "/system/lib64/apkname" exists, assume that is the per-package
// native library directory to use; otherwise use "/system/lib/apkname".
final String apkRoot = calculateBundledApkRoot(info.sourceDir);
final boolean is64Bit = VMRuntime.is64BitInstructionSet(
getPrimaryInstructionSet(info));
// This is a bundled system app so choose the path based on the ABI.
// if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
// is just the default path.
final String apkName = deriveCodePathName(codePath);
final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
apkName).getAbsolutePath();
if (info.secondaryCpuAbi != null) {
final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
secondaryLibDir, apkName).getAbsolutePath();
}
} else if (asecApp) {
info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
.getAbsolutePath();
} else {
final String apkName = deriveCodePathName(codePath);
info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
.getAbsolutePath();
}
info.nativeLibraryRootRequiresIsa = false;
info.nativeLibraryDir = info.nativeLibraryRootDir;
} else {
// Cluster install
info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
info.nativeLibraryRootRequiresIsa = true;
info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
getPrimaryInstructionSet(info)).getAbsolutePath();
if (info.secondaryCpuAbi != null) {
info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
}
}
| public void | setPackageStoppedState(java.lang.String packageName, boolean stopped, int userId)
if (!sUserManager.exists(userId)) return;
final int uid = Binder.getCallingUid();
final int permission = mContext.checkCallingOrSelfPermission(
android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
enforceCrossUserPermission(uid, userId, true, true, "stop package");
// writer
synchronized (mPackages) {
if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission,
uid, userId)) {
scheduleWritePackageRestrictionsLocked(userId);
}
}
| public void | setPermissionEnforced(java.lang.String permission, boolean enforced)
mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null);
if (READ_EXTERNAL_STORAGE.equals(permission)) {
synchronized (mPackages) {
if (mSettings.mReadExternalStorageEnforced == null
|| mSettings.mReadExternalStorageEnforced != enforced) {
mSettings.mReadExternalStorageEnforced = enforced;
mSettings.writeLPr();
}
}
// kill any non-foreground processes so we restart them and
// grant/revoke the GID.
final IActivityManager am = ActivityManagerNative.getDefault();
if (am != null) {
final long token = Binder.clearCallingIdentity();
try {
am.killProcessesBelowForeground("setPermissionEnforcement");
} catch (RemoteException e) {
} finally {
Binder.restoreCallingIdentity(token);
}
}
} else {
throw new IllegalArgumentException("No selective enforcement for " + permission);
}
| private void | setUpCustomResolverActivity(PackageParser.Package pkg)
synchronized (mPackages) {
mResolverReplaced = true;
// Set up information for custom user intent resolution activity.
mResolveActivity.applicationInfo = pkg.applicationInfo;
mResolveActivity.name = mCustomResolverComponentName.getClassName();
mResolveActivity.packageName = pkg.applicationInfo.packageName;
mResolveActivity.processName = pkg.applicationInfo.packageName;
mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
mResolveActivity.theme = 0;
mResolveActivity.exported = true;
mResolveActivity.enabled = true;
mResolveInfo.activityInfo = mResolveActivity;
mResolveInfo.priority = 0;
mResolveInfo.preferredOrder = 0;
mResolveInfo.match = 0;
mResolveComponentName = mCustomResolverComponentName;
Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
mResolveComponentName);
}
| public void | shutdown()
mPackageUsage.write(true);
| static java.lang.String[] | splitString(java.lang.String str, char sep)
int count = 1;
int i = 0;
while ((i=str.indexOf(sep, i)) >= 0) {
count++;
i++;
}
String[] res = new String[count];
i=0;
count = 0;
int lastI=0;
while ((i=str.indexOf(sep, i)) >= 0) {
res[count] = str.substring(lastI, i);
count++;
i++;
lastI = i;
}
res[count] = str.substring(lastI, str.length());
return res;
| void | startCleaningPackages()
// reader
synchronized (mPackages) {
if (!isExternalMediaAvailable()) {
return;
}
if (mSettings.mPackagesToBeCleaned.isEmpty()) {
return;
}
}
Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
IActivityManager am = ActivityManagerNative.getDefault();
if (am != null) {
try {
am.startService(null, intent, null, UserHandle.USER_OWNER);
} catch (RemoteException e) {
}
}
| public void | systemReady()
mSystemReady = true;
// Read the compatibilty setting when the system is ready.
boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
mContext.getContentResolver(),
android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
if (DEBUG_SETTINGS) {
Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
}
synchronized (mPackages) {
// Verify that all of the preferred activity components actually
// exist. It is possible for applications to be updated and at
// that point remove a previously declared activity component that
// had been set as a preferred activity. We try to clean this up
// the next time we encounter that preferred activity, but it is
// possible for the user flow to never be able to return to that
// situation so here we do a sanity check to make sure we haven't
// left any junk around.
ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
removed.clear();
for (PreferredActivity pa : pir.filterSet()) {
if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
removed.add(pa);
}
}
if (removed.size() > 0) {
for (int r=0; r<removed.size(); r++) {
PreferredActivity pa = removed.get(r);
Slog.w(TAG, "Removing dangling preferred activity: "
+ pa.mPref.mComponent);
pir.removeFilter(pa);
}
mSettings.writePackageRestrictionsLPr(
mSettings.mPreferredActivities.keyAt(i));
}
}
}
sUserManager.systemReady();
// Kick off any messages waiting for system ready
if (mPostSystemReadyMessages != null) {
for (Message msg : mPostSystemReadyMessages) {
msg.sendToTarget();
}
mPostSystemReadyMessages = null;
}
| private void | unloadAllContainers(java.util.Set cidArgs)
// Just unmount all valid containers.
for (AsecInstallArgs arg : cidArgs) {
synchronized (mInstallLock) {
arg.doPostDeleteLI(false);
}
}
| private void | unloadMediaPackages(android.util.ArrayMap processCids, int[] uidArr, boolean reportStatus)
if (DEBUG_SD_INSTALL)
Log.i(TAG, "unloading media packages");
ArrayList<String> pkgList = new ArrayList<String>();
ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
final Set<AsecInstallArgs> keys = processCids.keySet();
for (AsecInstallArgs args : keys) {
String pkgName = args.getPackageName();
if (DEBUG_SD_INSTALL)
Log.i(TAG, "Trying to unload pkg : " + pkgName);
// Delete package internally
PackageRemovedInfo outInfo = new PackageRemovedInfo();
synchronized (mInstallLock) {
boolean res = deletePackageLI(pkgName, null, false, null, null,
PackageManager.DELETE_KEEP_DATA, outInfo, false);
if (res) {
pkgList.add(pkgName);
} else {
Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
failedList.add(args);
}
}
}
// reader
synchronized (mPackages) {
// We didn't update the settings after removing each package;
// write them now for all packages.
mSettings.writeLPr();
}
// We have to absolutely send UPDATED_MEDIA_STATUS only
// after confirming that all the receivers processed the ordered
// broadcast when packages get disabled, force a gc to clean things up.
// and unload all the containers.
if (pkgList.size() > 0) {
sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
new IIntentReceiver.Stub() {
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky,
int sendingUser) throws RemoteException {
Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
reportStatus ? 1 : 0, 1, keys);
mHandler.sendMessage(msg);
}
});
} else {
Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
keys);
mHandler.sendMessage(msg);
}
| private void | updateAllSharedLibrariesLPw()
for (PackageParser.Package pkg : mPackages.values()) {
try {
updateSharedLibrariesLPw(pkg, null);
} catch (PackageManagerException e) {
Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
}
}
| private java.util.ArrayList | updateAllSharedLibrariesLPw(PackageParser.Package changingPkg)
ArrayList<PackageParser.Package> res = null;
for (PackageParser.Package pkg : mPackages.values()) {
if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
|| hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
if (res == null) {
res = new ArrayList<PackageParser.Package>();
}
res.add(pkg);
try {
updateSharedLibrariesLPw(pkg, changingPkg);
} catch (PackageManagerException e) {
Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
}
}
}
return res;
| public void | updateExternalMediaStatus(boolean mediaStatus, boolean reportStatus)
int callingUid = Binder.getCallingUid();
if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
throw new SecurityException("Media status can only be updated by the system");
}
// reader; this apparently protects mMediaMounted, but should probably
// be a different lock in that case.
synchronized (mPackages) {
Log.i(TAG, "Updating external media status from "
+ (mMediaMounted ? "mounted" : "unmounted") + " to "
+ (mediaStatus ? "mounted" : "unmounted"));
if (DEBUG_SD_INSTALL)
Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
+ ", mMediaMounted=" + mMediaMounted);
if (mediaStatus == mMediaMounted) {
final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
: 0, -1);
mHandler.sendMessage(msg);
return;
}
mMediaMounted = mediaStatus;
}
// Queue up an async operation since the package installation may take a
// little while.
mHandler.post(new Runnable() {
public void run() {
updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
}
});
| private void | updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, boolean externalStorage)
ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
int[] uidArr = EmptyArray.INT;
final String[] list = PackageHelper.getSecureContainerList();
if (ArrayUtils.isEmpty(list)) {
Log.i(TAG, "No secure containers found");
} else {
// Process list of secure containers and categorize them
// as active or stale based on their package internal state.
// reader
synchronized (mPackages) {
for (String cid : list) {
// Leave stages untouched for now; installer service owns them
if (PackageInstallerService.isStageName(cid)) continue;
if (DEBUG_SD_INSTALL)
Log.i(TAG, "Processing container " + cid);
String pkgName = getAsecPackageName(cid);
if (pkgName == null) {
Slog.i(TAG, "Found stale container " + cid + " with no package name");
continue;
}
if (DEBUG_SD_INSTALL)
Log.i(TAG, "Looking for pkg : " + pkgName);
final PackageSetting ps = mSettings.mPackages.get(pkgName);
if (ps == null) {
Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
continue;
}
/*
* Skip packages that are not external if we're unmounting
* external storage.
*/
if (externalStorage && !isMounted && !isExternal(ps)) {
continue;
}
final AsecInstallArgs args = new AsecInstallArgs(cid,
getAppDexInstructionSets(ps), isForwardLocked(ps));
// The package status is changed only if the code path
// matches between settings and the container id.
if (ps.codePathString != null
&& ps.codePathString.startsWith(args.getCodePath())) {
if (DEBUG_SD_INSTALL) {
Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
+ " at code path: " + ps.codePathString);
}
// We do have a valid package installed on sdcard
processCids.put(args, ps.codePathString);
final int uid = ps.appId;
if (uid != -1) {
uidArr = ArrayUtils.appendInt(uidArr, uid);
}
} else {
Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
+ ps.codePathString);
}
}
}
Arrays.sort(uidArr);
}
// Process packages with valid entries.
if (isMounted) {
if (DEBUG_SD_INSTALL)
Log.i(TAG, "Loading packages");
loadMediaPackages(processCids, uidArr);
startCleaningPackages();
mInstallerService.onSecureContainersAvailable();
} else {
if (DEBUG_SD_INSTALL)
Log.i(TAG, "Unloading packages");
unloadMediaPackages(processCids, uidArr, reportStatus);
}
| private void | updatePermissionsLPw(java.lang.String changingPkg, PackageParser.Package pkgInfo, int flags)
// Make sure there are no dangling permission trees.
Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
while (it.hasNext()) {
final BasePermission bp = it.next();
if (bp.packageSetting == null) {
// We may not yet have parsed the package, so just see if
// we still know about its settings.
bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
}
if (bp.packageSetting == null) {
Slog.w(TAG, "Removing dangling permission tree: " + bp.name
+ " from package " + bp.sourcePackage);
it.remove();
} else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
Slog.i(TAG, "Removing old permission tree: " + bp.name
+ " from package " + bp.sourcePackage);
flags |= UPDATE_PERMISSIONS_ALL;
it.remove();
}
}
}
// Make sure all dynamic permissions have been assigned to a package,
// and make sure there are no dangling permissions.
it = mSettings.mPermissions.values().iterator();
while (it.hasNext()) {
final BasePermission bp = it.next();
if (bp.type == BasePermission.TYPE_DYNAMIC) {
if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
+ bp.name + " pkg=" + bp.sourcePackage
+ " info=" + bp.pendingInfo);
if (bp.packageSetting == null && bp.pendingInfo != null) {
final BasePermission tree = findPermissionTreeLP(bp.name);
if (tree != null && tree.perm != null) {
bp.packageSetting = tree.packageSetting;
bp.perm = new PackageParser.Permission(tree.perm.owner,
new PermissionInfo(bp.pendingInfo));
bp.perm.info.packageName = tree.perm.info.packageName;
bp.perm.info.name = bp.name;
bp.uid = tree.uid;
}
}
}
if (bp.packageSetting == null) {
// We may not yet have parsed the package, so just see if
// we still know about its settings.
bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
}
if (bp.packageSetting == null) {
Slog.w(TAG, "Removing dangling permission: " + bp.name
+ " from package " + bp.sourcePackage);
it.remove();
} else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
Slog.i(TAG, "Removing old permission: " + bp.name
+ " from package " + bp.sourcePackage);
flags |= UPDATE_PERMISSIONS_ALL;
it.remove();
}
}
}
// Now update the permissions for all packages, in particular
// replace the granted permissions of the system packages.
if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
for (PackageParser.Package pkg : mPackages.values()) {
if (pkg != pkgInfo) {
grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0,
changingPkg);
}
}
}
if (pkgInfo != null) {
grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0, changingPkg);
}
| private void | updateSettingsLI(PackageParser.Package newPackage, java.lang.String installerPackageName, int[] allUsers, boolean[] perUserInstalled, com.android.server.pm.PackageManagerService$PackageInstalledInfo res)
String pkgName = newPackage.packageName;
synchronized (mPackages) {
//write settings. the installStatus will be incomplete at this stage.
//note that the new package setting would have already been
//added to mPackages. It hasn't been persisted yet.
mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
mSettings.writeLPr();
}
if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
synchronized (mPackages) {
updatePermissionsLPw(newPackage.packageName, newPackage,
UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
? UPDATE_PERMISSIONS_ALL : 0));
// For system-bundled packages, we assume that installing an upgraded version
// of the package implies that the user actually wants to run that new code,
// so we enable the package.
if (isSystemApp(newPackage)) {
// NB: implicit assumption that system package upgrades apply to all users
if (DEBUG_INSTALL) {
Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
}
PackageSetting ps = mSettings.mPackages.get(pkgName);
if (ps != null) {
if (res.origUsers != null) {
for (int userHandle : res.origUsers) {
ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
userHandle, installerPackageName);
}
}
// Also convey the prior install/uninstall state
if (allUsers != null && perUserInstalled != null) {
for (int i = 0; i < allUsers.length; i++) {
if (DEBUG_INSTALL) {
Slog.d(TAG, " user " + allUsers[i]
+ " => " + perUserInstalled[i]);
}
ps.setInstalled(perUserInstalled[i], allUsers[i]);
}
// these install state changes will be persisted in the
// upcoming call to mSettings.writeLPr().
}
}
}
res.name = pkgName;
res.uid = newPackage.applicationInfo.uid;
res.pkg = newPackage;
mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
mSettings.setInstallerPackageName(pkgName, installerPackageName);
res.returnCode = PackageManager.INSTALL_SUCCEEDED;
//to update install status
mSettings.writeLPr();
}
| private void | updateSharedLibrariesLPw(PackageParser.Package pkg, PackageParser.Package changingLib)
if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
final ArraySet<String> usesLibraryFiles = new ArraySet<>();
int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
for (int i=0; i<N; i++) {
final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
if (file == null) {
throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
"Package " + pkg.packageName + " requires unavailable shared library "
+ pkg.usesLibraries.get(i) + "; failing!");
}
addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
}
N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
for (int i=0; i<N; i++) {
final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
if (file == null) {
Slog.w(TAG, "Package " + pkg.packageName
+ " desires unavailable shared library "
+ pkg.usesOptionalLibraries.get(i) + "; ignoring!");
} else {
addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
}
}
N = usesLibraryFiles.size();
if (N > 0) {
pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]);
} else {
pkg.usesLibraryFiles = null;
}
}
| private boolean | userNeedsBadging(int userId)
int index = mUserNeedsBadging.indexOfKey(userId);
if (index < 0) {
final UserInfo userInfo;
final long token = Binder.clearCallingIdentity();
try {
userInfo = sUserManager.getUserInfo(userId);
} finally {
Binder.restoreCallingIdentity(token);
}
final boolean b;
if (userInfo != null && userInfo.isManagedProfile()) {
b = true;
} else {
b = false;
}
mUserNeedsBadging.put(userId, b);
return b;
}
return mUserNeedsBadging.valueAt(index);
| private boolean | verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg)
if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
Slog.w(TAG, "Unable to update from " + oldPkg.name
+ " to " + newPkg.packageName
+ ": old package not in system partition");
return false;
} else if (mPackages.get(oldPkg.name) != null) {
Slog.w(TAG, "Unable to update from " + oldPkg.name
+ " to " + newPkg.packageName
+ ": old package still exists");
return false;
}
return true;
| public void | verifyPendingInstall(int id, int verificationCode)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
"Only package verification agents can verify applications");
final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
final PackageVerificationResponse response = new PackageVerificationResponse(
verificationCode, Binder.getCallingUid());
msg.arg1 = id;
msg.obj = response;
mHandler.sendMessage(msg);
| private void | verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
if (pkgSetting.signatures.mSignatures != null) {
// Already existing package. Make sure signatures match
boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
== PackageManager.SIGNATURE_MATCH;
if (!match) {
match = compareSignaturesCompat(pkgSetting.signatures, pkg)
== PackageManager.SIGNATURE_MATCH;
}
if (!match) {
match = compareSignaturesRecover(pkgSetting.signatures, pkg)
== PackageManager.SIGNATURE_MATCH;
}
if (!match) {
throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
+ pkg.packageName + " signatures do not match the "
+ "previously installed version; ignoring!");
}
}
// Check for shared user signatures
if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
// Already existing package. Make sure signatures match
boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
if (!match) {
match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
== PackageManager.SIGNATURE_MATCH;
}
if (!match) {
match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
== PackageManager.SIGNATURE_MATCH;
}
if (!match) {
throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
"Package " + pkg.packageName
+ " has no signatures that match those in shared user "
+ pkgSetting.sharedUser.name + "; ignoring!");
}
}
|
|