PackageManagerServicepublic class PackageManagerService extends IPackageManager.Stub
Fields Summary |
---|
private static final String | TAG | private static final boolean | DEBUG_SETTINGS | private static final boolean | DEBUG_PREFERRED | private static final boolean | MULTIPLE_APPLICATION_UIDS | private static final int | RADIO_UID | private static final int | FIRST_APPLICATION_UID | private static final int | MAX_APPLICATION_UIDS | private static final boolean | SHOW_INFO | private static final boolean | GET_CERTIFICATES | private static final int | REMOVE_EVENTS | private static final int | ADD_EVENTS | private static final int | OBSERVER_EVENTS | static final int | SCAN_MONITOR | static final int | SCAN_NO_DEX | static final int | SCAN_FORCE_DEX | static final int | SCAN_UPDATE_SIGNATURE | static final int | SCAN_FORWARD_LOCKED | static final int | SCAN_NEW_INSTALL | static final int | LOG_BOOT_PROGRESS_PMS_START | static final int | LOG_BOOT_PROGRESS_PMS_SYSTEM_SCAN_START | static final int | LOG_BOOT_PROGRESS_PMS_DATA_SCAN_START | static final int | LOG_BOOT_PROGRESS_PMS_SCAN_END | static final int | LOG_BOOT_PROGRESS_PMS_READY | final android.os.HandlerThread | mHandlerThread | final android.os.Handler | mHandler | final int | mSdkVersion | final android.content.Context | mContext | final boolean | mFactoryTest | final DisplayMetrics | mMetrics | final int | mDefParseFlags | final String[] | mSeparateProcesses | final File | mAppDataDir | final android.os.FileObserver | mFrameworkInstallObserver | final android.os.FileObserver | mSystemInstallObserver | final android.os.FileObserver | mAppInstallObserver | final android.os.FileObserver | mDrmAppInstallObserver | final Installer | mInstaller | final File | mFrameworkDir | final File | mSystemAppDir | final File | mAppInstallDir | final File | mDrmAppPrivateInstallDir | final Object | mInstallLock | final HashMap | mAppDirs | File | mScanningPath | int | mLastScanError | final int[] | mOutPermissions | final HashMap | mPackages | final Settings | mSettings | boolean | mRestoredSettings | boolean | mReportedUidError | int[] | mGlobalGids | final SparseArray | mSystemPermissions | final HashMap | mSharedLibraries | final ActivityIntentResolver | mActivities | final ActivityIntentResolver | mReceivers | final ServiceIntentResolver | mServices | final HashMap | mProvidersByComponent | final HashMap | mProviders | final HashMap | mInstrumentation | final HashMap | mPermissionGroups | boolean | mSystemReady | boolean | mSafeMode | 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 | private static final Comparator | mResolvePrioritySorter | private static final Comparator | mProviderInitOrderSorter |
Constructors Summary |
---|
public PackageManagerService(android.content.Context context, boolean factoryTest)
EventLog.writeEvent(LOG_BOOT_PROGRESS_PMS_START,
SystemClock.uptimeMillis());
if (mSdkVersion <= 0) {
Log.w(TAG, "**** ro.build.version.sdk not set!");
}
mContext = context;
mFactoryTest = factoryTest;
mMetrics = new DisplayMetrics();
mSettings = new Settings();
mSettings.addSharedUserLP("android.uid.system",
Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM);
mSettings.addSharedUserLP("android.uid.phone",
MULTIPLE_APPLICATION_UIDS
? RADIO_UID : FIRST_APPLICATION_UID,
ApplicationInfo.FLAG_SYSTEM);
String separateProcesses = SystemProperties.get("debug.separate_processes");
if (separateProcesses != null && separateProcesses.length() > 0) {
if ("*".equals(separateProcesses)) {
mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
mSeparateProcesses = null;
Log.w(TAG, "Running with debug.separate_processes: * (ALL)");
} else {
mDefParseFlags = 0;
mSeparateProcesses = separateProcesses.split(",");
Log.w(TAG, "Running with debug.separate_processes: "
+ separateProcesses);
}
} else {
mDefParseFlags = 0;
mSeparateProcesses = null;
}
Installer installer = new Installer();
// Little hacky thing to check if installd is here, to determine
// whether we are running on the simulator and thus need to take
// care of building the /data file structure ourself.
// (apparently the sim now has a working installer)
if (installer.ping() && Process.supportsProcesses()) {
mInstaller = installer;
} else {
mInstaller = null;
}
WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
Display d = wm.getDefaultDisplay();
d.getMetrics(mMetrics);
synchronized (mInstallLock) {
synchronized (mPackages) {
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
File dataDir = Environment.getDataDirectory();
mAppDataDir = new File(dataDir, "data");
mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
if (mInstaller == null) {
// Make sure these dirs exist, when we are running in
// the simulator.
// Make a wide-open directory for random misc stuff.
File miscDir = new File(dataDir, "misc");
miscDir.mkdirs();
mAppDataDir.mkdirs();
mDrmAppPrivateInstallDir.mkdirs();
}
readPermissions();
mRestoredSettings = mSettings.readLP();
long startTime = SystemClock.uptimeMillis();
EventLog.writeEvent(LOG_BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
startTime);
int scanMode = SCAN_MONITOR;
final HashSet<String> libFiles = new HashSet<String>();
mFrameworkDir = new File(Environment.getRootDirectory(), "framework");
if (mInstaller != null) {
/**
* Out of paranoia, ensure that everything in the boot class
* path has been dexed.
*/
String bootClassPath = System.getProperty("java.boot.class.path");
if (bootClassPath != null) {
String[] paths = splitString(bootClassPath, ':");
for (int i=0; i<paths.length; i++) {
try {
if (dalvik.system.DexFile.isDexOptNeeded(paths[i])) {
libFiles.add(paths[i]);
mInstaller.dexopt(paths[i], Process.SYSTEM_UID, true);
}
} catch (FileNotFoundException e) {
Log.w(TAG, "Boot class path not found: " + paths[i]);
} catch (IOException e) {
Log.w(TAG, "Exception reading boot class path: " + paths[i], e);
}
}
} else {
Log.w(TAG, "No BOOTCLASSPATH found!");
}
/**
* Also ensure all external libraries have had dexopt run on them.
*/
if (mSharedLibraries.size() > 0) {
Iterator<String> libs = mSharedLibraries.values().iterator();
while (libs.hasNext()) {
String lib = libs.next();
try {
if (dalvik.system.DexFile.isDexOptNeeded(lib)) {
libFiles.add(lib);
mInstaller.dexopt(lib, Process.SYSTEM_UID, true);
}
} catch (FileNotFoundException e) {
Log.w(TAG, "Library not found: " + lib);
} catch (IOException e) {
Log.w(TAG, "Exception reading library: " + lib, e);
}
}
}
// Gross hack for now: we know this file doesn't contain any
// code, so don't dexopt it to avoid the resulting log spew.
libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk");
/**
* 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 = mFrameworkDir.list();
if (frameworkFiles != null && mInstaller != null) {
for (int i=0; i<frameworkFiles.length; i++) {
File libPath = new File(mFrameworkDir, frameworkFiles[i]);
String path = libPath.getPath();
// Skip the file if we alrady did it.
if (libFiles.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 {
if (dalvik.system.DexFile.isDexOptNeeded(path)) {
mInstaller.dexopt(path, Process.SYSTEM_UID, true);
}
} catch (FileNotFoundException e) {
Log.w(TAG, "Jar not found: " + path);
} catch (IOException e) {
Log.w(TAG, "Exception reading jar: " + path, e);
}
}
}
}
mFrameworkInstallObserver = new AppDirObserver(
mFrameworkDir.getPath(), OBSERVER_EVENTS, true);
mFrameworkInstallObserver.startWatching();
scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM,
scanMode | SCAN_NO_DEX);
mSystemAppDir = new File(Environment.getRootDirectory(), "app");
mSystemInstallObserver = new AppDirObserver(
mSystemAppDir.getPath(), OBSERVER_EVENTS, true);
mSystemInstallObserver.startWatching();
scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM, scanMode);
mAppInstallDir = new File(dataDir, "app");
if (mInstaller == null) {
// Make sure these dirs exist, when we are running in
// the simulator.
mAppInstallDir.mkdirs(); // scanDirLI() assumes this dir exists
}
//look for any incomplete package installations
ArrayList<String> deletePkgsList = mSettings.getListOfIncompleteInstallPackages();
//clean up list
for(int i = 0; i < deletePkgsList.size(); i++) {
//clean up here
cleanupInstallFailedPackage(deletePkgsList.get(i));
}
//delete tmp files
deleteTempPackageFiles();
EventLog.writeEvent(LOG_BOOT_PROGRESS_PMS_DATA_SCAN_START,
SystemClock.uptimeMillis());
mAppInstallObserver = new AppDirObserver(
mAppInstallDir.getPath(), OBSERVER_EVENTS, false);
mAppInstallObserver.startWatching();
scanDirLI(mAppInstallDir, 0, scanMode);
mDrmAppInstallObserver = new AppDirObserver(
mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);
mDrmAppInstallObserver.startWatching();
scanDirLI(mDrmAppPrivateInstallDir, 0, scanMode);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PMS_SCAN_END,
SystemClock.uptimeMillis());
Log.i(TAG, "Time to scan packages: "
+ ((SystemClock.uptimeMillis()-startTime)/1000f)
+ " seconds");
updatePermissionsLP();
mSettings.writeLP();
EventLog.writeEvent(LOG_BOOT_PROGRESS_PMS_READY,
SystemClock.uptimeMillis());
// 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();
} // synchronized (mPackages)
} // synchronized (mInstallLock)
|
Methods Summary |
---|
public void | addPackageToPreferred(java.lang.String packageName)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
if (p == null) {
return;
}
PackageSetting ps = (PackageSetting)p.mExtras;
if (ps != null) {
mSettings.mPreferredPackages.remove(ps);
mSettings.mPreferredPackages.add(0, ps);
updatePreferredIndicesLP();
mSettings.writeLP();
}
}
| public boolean | addPermission(android.content.pm.PermissionInfo info)
synchronized (mPackages) {
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;
if (added) {
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);
}
bp.perm = new PackageParser.Permission(tree.perm.owner,
new PermissionInfo(info));
bp.perm.info.packageName = tree.perm.info.packageName;
bp.uid = tree.uid;
if (added) {
mSettings.mPermissions.put(info.name, bp);
}
mSettings.writeLP();
return added;
}
| public void | addPreferredActivity(android.content.IntentFilter filter, int match, android.content.ComponentName[] set, android.content.ComponentName activity)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
synchronized (mPackages) {
Log.i(TAG, "Adding preferred activity " + activity + ":");
filter.dump(new LogPrinter(Log.INFO, TAG), " ");
mSettings.mPreferredActivities.addFilter(
new PreferredActivity(filter, match, set, activity));
mSettings.writeLP();
}
| static int[] | appendInt(int[] cur, int val)
if (cur == null) {
return new int[] { val };
}
final int N = cur.length;
for (int i=0; i<N; i++) {
if (cur[i] == val) {
return cur;
}
}
int[] ret = new int[N+1];
System.arraycopy(cur, 0, ret, 0, N);
ret[N] = val;
return ret;
| 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 | cachePackageSharedLibsLI(PackageParser.Package pkg, java.io.File dataPath, java.io.File scanFile)
File sharedLibraryDir = new File(dataPath.getPath() + "/lib");
final String sharedLibraryABI = "armeabi";
final String apkLibraryDirectory = "lib/" + sharedLibraryABI + "/";
final String apkSharedLibraryPrefix = apkLibraryDirectory + "lib";
final String sharedLibrarySuffix = ".so";
boolean createdSharedLib = false;
try {
ZipFile zipFile = new ZipFile(scanFile);
Enumeration<ZipEntry> entries =
(Enumeration<ZipEntry>) zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (entry.isDirectory()) {
continue;
}
String entryName = entry.getName();
if (! (entryName.startsWith(apkSharedLibraryPrefix)
&& entryName.endsWith(sharedLibrarySuffix))) {
continue;
}
String libFileName = entryName.substring(
apkLibraryDirectory.length());
if (libFileName.contains("/")
|| (!FileUtils.isFilenameSafe(new File(libFileName)))) {
continue;
}
String sharedLibraryFilePath = sharedLibraryDir.getPath() +
File.separator + libFileName;
File sharedLibraryFile = new File(sharedLibraryFilePath);
if (! sharedLibraryFile.exists() ||
sharedLibraryFile.length() != entry.getSize() ||
sharedLibraryFile.lastModified() != entry.getTime()) {
if (Config.LOGD) {
Log.d(TAG, "Caching shared lib " + entry.getName());
}
if (mInstaller == null) {
sharedLibraryDir.mkdir();
createdSharedLib = true;
}
cacheSharedLibLI(pkg, zipFile, entry, sharedLibraryDir,
sharedLibraryFile);
}
}
} catch (IOException e) {
Log.e(TAG, "Failed to cache package shared libs", e);
if(createdSharedLib) {
sharedLibraryDir.delete();
}
throw e;
}
| private void | cacheSharedLibLI(PackageParser.Package pkg, java.util.zip.ZipFile zipFile, java.util.zip.ZipEntry entry, java.io.File sharedLibraryDir, java.io.File sharedLibraryFile)
InputStream inputStream = zipFile.getInputStream(entry);
try {
File tempFile = File.createTempFile("tmp", "tmp", sharedLibraryDir);
String tempFilePath = tempFile.getPath();
// XXX package manager can't change owner, so the lib files for
// now need to be left as world readable and owned by the system.
if (! FileUtils.copyToFile(inputStream, tempFile) ||
! tempFile.setLastModified(entry.getTime()) ||
FileUtils.setPermissions(tempFilePath,
FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP
|FileUtils.S_IROTH, -1, -1) != 0 ||
! tempFile.renameTo(sharedLibraryFile)) {
// Failed to properly write file.
tempFile.delete();
throw new IOException("Couldn't create cached shared lib "
+ sharedLibraryFile + " in " + sharedLibraryDir);
}
} finally {
inputStream.close();
}
| 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 com.android.server.PackageManagerService$BasePermission | checkPermissionTreeLP(java.lang.String permName)
if (permName != null) {
BasePermission bp = findPermissionTreeLP(permName);
if (bp != null) {
if (bp.uid == 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) {
PackageParser.Package p1 = mPackages.get(pkg1);
PackageParser.Package p2 = mPackages.get(pkg2);
if (p1 == null || p1.mExtras == null
|| p2 == null || p2.mExtras == null) {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
return checkSignaturesLP(p1, p2);
}
| int | checkSignaturesLP(PackageParser.Package p1, PackageParser.Package p2)
if (p1.mSignatures == null) {
return p2.mSignatures == null
? PackageManager.SIGNATURE_NEITHER_SIGNED
: PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
}
if (p2.mSignatures == null) {
return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
}
final int N1 = p1.mSignatures.length;
final int N2 = p2.mSignatures.length;
for (int i=0; i<N1; i++) {
boolean match = false;
for (int j=0; j<N2; j++) {
if (p1.mSignatures[i].equals(p2.mSignatures[j])) {
match = true;
break;
}
}
if (!match) {
return PackageManager.SIGNATURE_NO_MATCH;
}
}
return PackageManager.SIGNATURE_MATCH;
| public int | checkUidPermission(java.lang.String permName, int uid)
synchronized (mPackages) {
Object obj = mSettings.getUserIdLP(uid);
if (obj != null) {
if (obj instanceof SharedUserSetting) {
SharedUserSetting sus = (SharedUserSetting)obj;
if (sus.grantedPermissions.contains(permName)) {
return PackageManager.PERMISSION_GRANTED;
}
} else if (obj instanceof PackageSetting) {
PackageSetting ps = (PackageSetting)obj;
if (ps.grantedPermissions.contains(permName)) {
return PackageManager.PERMISSION_GRANTED;
}
}
} else {
HashSet<String> perms = mSystemPermissions.get(uid);
if (perms != null && perms.contains(permName)) {
return PackageManager.PERMISSION_GRANTED;
}
}
}
return PackageManager.PERMISSION_DENIED;
| void | cleanupInstallFailedPackage(java.lang.String packageName)
if (mInstaller != null) {
int retCode = mInstaller.remove(packageName);
if (retCode < 0) {
Log.w(TAG, "Couldn't remove app data directory for package: "
+ packageName + ", retcode=" + retCode);
}
} else {
//for emulator
PackageParser.Package pkg = mPackages.get(packageName);
File dataDir = new File(pkg.applicationInfo.dataDir);
dataDir.delete();
}
mSettings.removePackageLP(packageName);
| public void | clearApplicationUserData(java.lang.String packageName, android.content.pm.IPackageDataObserver observer)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CLEAR_APP_USER_DATA, null);
// 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);
}
if (succeeded) {
// invoke DeviceStorageMonitor's update method to clear any notifications
DeviceStorageMonitorService dsm = (DeviceStorageMonitorService)
ServiceManager.getService(DeviceStorageMonitorService.SERVICE);
if (dsm != null) {
dsm.updateMemory();
}
}
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)
if (packageName == null) {
Log.w(TAG, "Attempt to delete null packageName.");
return false;
}
PackageParser.Package p;
boolean dataOnly = false;
synchronized (mPackages) {
p = mPackages.get(packageName);
if(p == null) {
dataOnly = true;
PackageSetting ps = mSettings.mPackages.get(packageName);
if((ps == null) || (ps.pkg == null)) {
Log.w(TAG, "Package named '" + packageName +"' doesn't exist.");
return false;
}
p = ps.pkg;
}
}
if(!dataOnly) {
//need to check this only for fully installed applications
if (p == null) {
Log.w(TAG, "Package named '" + packageName +"' doesn't exist.");
return false;
}
final ApplicationInfo applicationInfo = p.applicationInfo;
if (applicationInfo == null) {
Log.w(TAG, "Package " + packageName + " has no applicationInfo.");
return false;
}
}
if (mInstaller != null) {
int retCode = mInstaller.clearUserData(packageName);
if (retCode < 0) {
Log.w(TAG, "Couldn't remove cache files for package: "
+ packageName);
return false;
}
}
return true;
| public void | clearPackagePreferredActivities(java.lang.String packageName)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
synchronized (mPackages) {
if (clearPackagePreferredActivitiesLP(packageName)) {
mSettings.writeLP();
}
}
| boolean | clearPackagePreferredActivitiesLP(java.lang.String packageName)
boolean changed = false;
Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator();
while (it.hasNext()) {
PreferredActivity pa = it.next();
if (pa.mActivity.getPackageName().equals(packageName)) {
it.remove();
changed = true;
}
}
return changed;
| private boolean | collectCertificatesLI(android.content.pm.PackageParser pp, com.android.server.PackageManagerService$PackageSetting ps, PackageParser.Package pkg, java.io.File srcFile, int parseFlags)
if (GET_CERTIFICATES) {
if (ps == null || !ps.codePath.equals(srcFile)
|| ps.getTimeStamp() != srcFile.lastModified()) {
Log.i(TAG, srcFile.toString() + " changed; collecting certs");
if (!pp.collectCertificates(pkg, parseFlags)) {
mLastScanError = pp.getParseError();
return false;
}
}
}
return true;
| private static void | copyZipEntry(java.util.zip.ZipEntry zipEntry, java.util.zip.ZipFile inZipFile, java.util.zip.ZipOutputStream outZipStream)
byte[] buffer = new byte[4096];
int num;
ZipEntry newEntry;
if (zipEntry.getMethod() == ZipEntry.STORED) {
// Preserve the STORED method of the input entry.
newEntry = new ZipEntry(zipEntry);
} else {
// Create a new entry so that the compressed len is recomputed.
newEntry = new ZipEntry(zipEntry.getName());
}
outZipStream.putNextEntry(newEntry);
InputStream data = inZipFile.getInputStream(zipEntry);
while ((num = data.read(buffer)) > 0) {
outZipStream.write(buffer, 0, num);
}
outZipStream.flush();
| private java.io.File | createTempPackageFile()
File tmpPackageFile;
try {
tmpPackageFile = File.createTempFile("vmdl", ".tmp", mAppInstallDir);
} catch (IOException e) {
Log.e(TAG, "Couldn't create temp file for downloaded package file.");
return null;
}
try {
FileUtils.setPermissions(
tmpPackageFile.getCanonicalPath(), FileUtils.S_IRUSR|FileUtils.S_IWUSR,
-1, -1);
} catch (IOException e) {
Log.e(TAG, "Trouble getting the canoncical path for a temp file.");
return null;
}
return tmpPackageFile;
| 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.
mHandler.post(new Runnable() {
public void run() {
mHandler.removeCallbacks(this);
final boolean succeded;
synchronized (mInstallLock) {
succeded = deleteApplicationCacheFilesLI(packageName);
}
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)
if (packageName == null) {
Log.w(TAG, "Attempt to delete null packageName.");
return false;
}
PackageParser.Package p;
synchronized (mPackages) {
p = mPackages.get(packageName);
}
if (p == null) {
Log.w(TAG, "Package named '" + packageName +"' doesn't exist.");
return false;
}
final ApplicationInfo applicationInfo = p.applicationInfo;
if (applicationInfo == null) {
Log.w(TAG, "Package " + packageName + " has no applicationInfo.");
return false;
}
if (mInstaller != null) {
int retCode = mInstaller.deleteCacheFiles(packageName);
if (retCode < 0) {
Log.w(TAG, "Couldn't remove cache files for package: "
+ packageName);
return false;
}
}
return true;
| private boolean | deleteInstalledPackageLI(PackageParser.Package p, boolean deleteCodeAndResources, int flags, com.android.server.PackageManagerService$PackageRemovedInfo outInfo)
ApplicationInfo applicationInfo = p.applicationInfo;
if (applicationInfo == null) {
Log.w(TAG, "Package " + p.packageName + " has no applicationInfo.");
return false;
}
// Delete application's source directory
File sourceFile = new File(applicationInfo.sourceDir);
if (!sourceFile.exists()) {
Log.w(TAG, "Package source " + applicationInfo.sourceDir + " does not exist.");
}
outInfo.uid = applicationInfo.uid;
// Delete package data from internal structures and also remove data if flag is set
removePackageDataLI(p, outInfo, flags);
// Delete application code and resources
if (deleteCodeAndResources) {
sourceFile.delete();
final File publicSourceFile = new File(applicationInfo.publicSourceDir);
if (publicSourceFile.exists()) {
publicSourceFile.delete();
}
if (mInstaller != null) {
int retCode = mInstaller.rmdex(sourceFile.toString());
if (retCode < 0) {
Log.w(TAG, "Couldn't remove dex file for package: "
+ p.packageName + " at location " + sourceFile.toString() + ", retcode=" + retCode);
// we don't consider this to be a failure of the core package deletion
}
}
}
return true;
| public void | deletePackage(java.lang.String packageName, android.content.pm.IPackageDeleteObserver observer, int flags)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.DELETE_PACKAGES, null);
// 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 succeded = deletePackageX(packageName, true, true, flags);
if (observer != null) {
try {
observer.packageDeleted(succeded);
} catch (RemoteException e) {
Log.i(TAG, "Observer no longer exists.");
} //end catch
} //end if
} //end run
});
| private boolean | deletePackageLI(java.lang.String packageName, boolean deleteCodeAndResources, int flags, com.android.server.PackageManagerService$PackageRemovedInfo outInfo)
if (packageName == null) {
Log.w(TAG, "Attempt to delete null packageName.");
return false;
}
PackageParser.Package p;
boolean dataOnly = false;
synchronized (mPackages) {
p = mPackages.get(packageName);
if (p == null) {
//this retrieves partially installed apps
dataOnly = true;
PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps == null) {
Log.w(TAG, "Package named '" + packageName +"' doesn't exist.");
return false;
}
p = ps.pkg;
}
}
if (p == null) {
Log.w(TAG, "Package named '" + packageName +"' doesn't exist.");
return false;
}
if (dataOnly) {
// Delete application data first
removePackageDataLI(p, outInfo, flags);
return true;
}
// At this point the package should have ApplicationInfo associated with it
if (p.applicationInfo == null) {
Log.w(TAG, "Package " + p.packageName + " has no applicationInfo.");
return false;
}
if ( (p.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
Log.i(TAG, "Removing system package:"+p.packageName);
// When an updated system application is deleted we delete the existing resources as well and
// fall back to existing code in system partition
return deleteSystemPackageLI(p, true, flags, outInfo);
}
Log.i(TAG, "Removing non-system package:"+p.packageName);
return deleteInstalledPackageLI (p, deleteCodeAndResources, flags, outInfo);
| private boolean | deletePackageX(java.lang.String packageName, boolean sendBroadCast, boolean deleteCodeAndResources, 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
PackageRemovedInfo info = new PackageRemovedInfo();
boolean res;
synchronized (mInstallLock) {
res = deletePackageLI(packageName, deleteCodeAndResources, flags, info);
}
if(res && sendBroadCast) {
boolean systemUpdate = info.isRemovedPackageSystemUpdate;
info.sendBroadcast(deleteCodeAndResources, systemUpdate);
// If the removed package was a system update, the old system packaged
// was re-enabled; we need to broadcast this information
if (systemUpdate) {
Bundle extras = new Bundle(1);
extras.putInt(Intent.EXTRA_UID, info.removedUid >= 0 ? info.removedUid : info.uid);
extras.putBoolean(Intent.EXTRA_REPLACING, true);
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, extras);
sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName, extras);
}
}
return res;
| private boolean | deleteSystemPackageLI(PackageParser.Package p, boolean deleteCodeAndResources, int flags, com.android.server.PackageManagerService$PackageRemovedInfo outInfo)
ApplicationInfo applicationInfo = p.applicationInfo;
//applicable for non-partially installed applications only
if (applicationInfo == null) {
Log.w(TAG, "Package " + p.packageName + " has no applicationInfo.");
return false;
}
PackageSetting ps = 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
synchronized (mPackages) {
ps = mSettings.getDisabledSystemPkg(p.packageName);
}
if (ps == null) {
Log.w(TAG, "Attempt to delete system package "+ p.packageName);
return false;
} else {
Log.i(TAG, "Deleting system pkg from data partition");
}
// Delete the updated package
outInfo.isRemovedPackageSystemUpdate = true;
boolean ret = deleteInstalledPackageLI(p, deleteCodeAndResources, flags, outInfo);
if (!ret) {
return false;
}
synchronized (mPackages) {
// Reinstate the old system package
mSettings.enableSystemPackageLP(p.packageName);
}
// Install the system package
PackageParser.Package newPkg = scanPackageLI(ps.codePath, ps.codePath, ps.resourcePath,
PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM,
SCAN_MONITOR);
if (newPkg == null) {
Log.w(TAG, "Failed to restore system package:"+p.packageName+" with error:" + mLastScanError);
return false;
}
synchronized (mPackages) {
mSettings.writeLP();
}
return true;
| private void | deleteTempPackageFiles()
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.startsWith("vmdl") && name.endsWith(".tmp");
}
};
String tmpFilesList[] = mAppInstallDir.list(filter);
if(tmpFilesList == null) {
return;
}
for(int i = 0; i < tmpFilesList.length; i++) {
File tmpFile = new File(mAppInstallDir, tmpFilesList[i]);
tmpFile.delete();
}
| 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;
}
Printer printer = new PrintWriterPrinter(pw);
synchronized (mPackages) {
pw.println("Activity Resolver Table:");
mActivities.dump(printer, " ");
pw.println(" ");
pw.println("Receiver Resolver Table:");
mReceivers.dump(printer, " ");
pw.println(" ");
pw.println("Service Resolver Table:");
mServices.dump(printer, " ");
pw.println(" ");
pw.println("Preferred Activities:");
mSettings.mPreferredActivities.dump(printer, " ");
pw.println(" ");
pw.println("Preferred Packages:");
{
for (PackageSetting ps : mSettings.mPreferredPackages) {
pw.println(" " + ps.name);
}
}
pw.println(" ");
pw.println("Permissions:");
{
for (BasePermission p : mSettings.mPermissions.values()) {
pw.println(" Permission [" + p.name + "] ("
+ Integer.toHexString(System.identityHashCode(p))
+ "):");
pw.println(" sourcePackage=" + p.sourcePackage);
pw.println(" uid=" + p.uid
+ " gids=" + arrayToString(p.gids)
+ " type=" + p.type);
}
}
pw.println(" ");
pw.println("Packages:");
{
for (PackageSetting ps : mSettings.mPackages.values()) {
pw.println(" Package [" + ps.name + "] ("
+ Integer.toHexString(System.identityHashCode(ps))
+ "):");
pw.println(" userId=" + ps.userId
+ " gids=" + arrayToString(ps.gids));
pw.println(" sharedUser=" + ps.sharedUser);
pw.println(" pkg=" + ps.pkg);
pw.println(" codePath=" + ps.codePathString);
pw.println(" resourcePath=" + ps.resourcePathString);
if (ps.pkg != null) {
pw.println(" dataDir=" + ps.pkg.applicationInfo.dataDir);
}
pw.println(" timeStamp=" + ps.getTimeStampStr());
pw.println(" signatures=" + ps.signatures);
pw.println(" permissionsFixed=" + ps.permissionsFixed
+ " pkgFlags=0x" + Integer.toHexString(ps.pkgFlags)
+ " installStatus=" + ps.installStatus
+ " enabled=" + ps.enabled);
if (ps.disabledComponents.size() > 0) {
pw.println(" disabledComponents:");
for (String s : ps.disabledComponents) {
pw.println(" " + s);
}
}
if (ps.enabledComponents.size() > 0) {
pw.println(" enabledComponents:");
for (String s : ps.enabledComponents) {
pw.println(" " + s);
}
}
pw.println(" grantedPermissions:");
for (String s : ps.grantedPermissions) {
pw.println(" " + s);
}
pw.println(" loadedPermissions:");
for (String s : ps.loadedPermissions) {
pw.println(" " + s);
}
}
}
pw.println(" ");
pw.println("Shared Users:");
{
for (SharedUserSetting su : mSettings.mSharedUsers.values()) {
pw.println(" SharedUser [" + su.name + "] ("
+ Integer.toHexString(System.identityHashCode(su))
+ "):");
pw.println(" userId=" + su.userId
+ " gids=" + arrayToString(su.gids));
pw.println(" grantedPermissions:");
for (String s : su.grantedPermissions) {
pw.println(" " + s);
}
pw.println(" loadedPermissions:");
for (String s : su.loadedPermissions) {
pw.println(" " + s);
}
}
}
pw.println(" ");
pw.println("Settings parse messages:");
pw.println(mSettings.mReadMessages.toString());
}
| public void | enterSafeMode()
if (!mSystemReady) {
mSafeMode = true;
}
| private void | extractPublicFiles(PackageParser.Package newPackage, java.io.File publicZipFile)
final ZipOutputStream publicZipOutStream =
new ZipOutputStream(new FileOutputStream(publicZipFile));
final ZipFile privateZip = new ZipFile(newPackage.mPath);
// Copy manifest, resources.arsc and res directory to public zip
final Enumeration<? extends ZipEntry> privateZipEntries = privateZip.entries();
while (privateZipEntries.hasMoreElements()) {
final ZipEntry zipEntry = privateZipEntries.nextElement();
final String zipEntryName = zipEntry.getName();
if ("AndroidManifest.xml".equals(zipEntryName)
|| "resources.arsc".equals(zipEntryName)
|| zipEntryName.startsWith("res/")) {
try {
copyZipEntry(zipEntry, privateZip, publicZipOutStream);
} catch (IOException e) {
try {
publicZipOutStream.close();
throw e;
} finally {
publicZipFile.delete();
}
}
}
}
publicZipOutStream.close();
FileUtils.setPermissions(
publicZipFile.getAbsolutePath(),
FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP|FileUtils.S_IROTH,
-1, -1);
| private com.android.server.PackageManagerService$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;
| android.content.pm.ResolveInfo | findPreferredActivity(android.content.Intent intent, java.lang.String resolvedType, int flags, java.util.List query, int priority)
synchronized (mPackages) {
if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
List<PreferredActivity> prefs =
mSettings.mPreferredActivities.queryIntent(null,
intent, resolvedType,
(flags&PackageManager.MATCH_DEFAULT_ONLY) != 0);
if (prefs != null && prefs.size() > 0) {
// 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;
final int N = query.size();
if (DEBUG_PREFERRED) Log.v(TAG, "Figuring out best match...");
for (int j=0; j<N; j++) {
ResolveInfo ri = query.get(j);
if (DEBUG_PREFERRED) Log.v(TAG, "Match for " + ri.activityInfo
+ ": 0x" + Integer.toHexString(match));
if (ri.match > match) match = ri.match;
}
if (DEBUG_PREFERRED) Log.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++) {
PreferredActivity pa = prefs.get(i);
if (pa.mMatch != match) {
continue;
}
ActivityInfo ai = getActivityInfo(pa.mActivity, flags);
if (DEBUG_PREFERRED) {
Log.v(TAG, "Got preferred activity:");
ai.dump(new LogPrinter(Log.INFO, TAG), " ");
}
if (ai != null) {
for (int j=0; j<N; j++) {
ResolveInfo ri = query.get(j);
if (!ri.activityInfo.applicationInfo.packageName
.equals(ai.applicationInfo.packageName)) {
continue;
}
if (!ri.activityInfo.name.equals(ai.name)) {
continue;
}
// Okay we found a previously set preferred 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 (!pa.sameSet(query, priority)) {
Log.i(TAG, "Result set changed, dropping preferred activity for "
+ intent + " type " + resolvedType);
mSettings.mPreferredActivities.removeFilter(pa);
return null;
}
// Yay!
return ri;
}
}
}
}
}
return null;
| 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 | freeStorage(long freeStorageSize, android.app.PendingIntent opFinishedIntent)
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;
if (mInstaller != null) {
retCode = mInstaller.freeCache(freeStorageSize);
if (retCode < 0) {
Log.w(TAG, "Couldn't clear application caches");
}
}
if(opFinishedIntent != null) {
try {
// Callback via pending intent
opFinishedIntent.send((retCode >= 0) ? 1 : 0);
} catch (CanceledException e1) {
Log.i(TAG, "Failed to send pending intent");
}
}
}
});
| 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;
if (mInstaller != null) {
retCode = mInstaller.freeCache(freeStorageSize);
if (retCode < 0) {
Log.w(TAG, "Couldn't clear application caches");
}
} //end if mInstaller
if (observer != null) {
try {
observer.onRemoveCompleted(null, (retCode >= 0));
} catch (RemoteException e) {
Log.w(TAG, "RemoveException when invoking call back");
}
}
}
});
| private android.content.pm.ApplicationInfo | generateApplicationInfoFromSettingsLP(java.lang.String packageName, int flags)
PackageSetting ps = mSettings.mPackages.get(packageName);
if(ps != null) {
if(ps.pkg == null) {
PackageInfo pInfo = generatePackageInfoFromSettingsLP(packageName, flags);
if(pInfo != null) {
return pInfo.applicationInfo;
}
return null;
}
return PackageParser.generateApplicationInfo(ps.pkg, flags);
}
return null;
| android.content.pm.PackageInfo | generatePackageInfo(PackageParser.Package p, int flags)
final PackageSetting ps = (PackageSetting)p.mExtras;
if (ps == null) {
return null;
}
final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
return PackageParser.generatePackageInfo(p, gp.gids, flags);
| private android.content.pm.PackageInfo | generatePackageInfoFromSettingsLP(java.lang.String packageName, int flags)
PackageSetting ps = mSettings.mPackages.get(packageName);
if(ps != null) {
if(ps.pkg == null) {
ps.pkg = new PackageParser.Package(packageName);
ps.pkg.applicationInfo.packageName = packageName;
}
return generatePackageInfo(ps.pkg, flags);
}
return null;
| public android.content.pm.ActivityInfo | getActivityInfo(android.content.ComponentName component, int flags)
synchronized (mPackages) {
PackageParser.Activity a = mActivities.mActivities.get(component);
if (Config.LOGV) Log.v(
TAG, "getActivityInfo " + component + ": " + a);
if (a != null && mSettings.isEnabledLP(a.info, flags)) {
return PackageParser.generateActivityInfo(a, flags);
}
if (mResolveComponentName.equals(component)) {
return mResolveActivity;
}
}
return null;
| public java.util.List | getAllPermissionGroups(int flags)
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;
}
| public int | getApplicationEnabledSetting(java.lang.String appPackageName)
synchronized (mPackages) {
PackageSetting pkg = mSettings.mPackages.get(appPackageName);
if (pkg == null) {
throw new IllegalArgumentException("Unknown package: " + appPackageName);
}
return pkg.enabled;
}
| public android.content.pm.ApplicationInfo | getApplicationInfo(java.lang.String packageName, int flags)
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
if (Config.LOGV) Log.v(
TAG, "getApplicationInfo " + packageName
+ ": " + p);
if (p != null) {
// Note: isEnabledLP() does not apply here - always return info
return PackageParser.generateApplicationInfo(p, flags);
}
if ("android".equals(packageName)||"system".equals(packageName)) {
return mAndroidApplication;
}
if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
return generateApplicationInfoFromSettingsLP(packageName, flags);
}
}
return null;
| public int | getComponentEnabledSetting(android.content.ComponentName componentName)
synchronized (mPackages) {
final String packageNameStr = componentName.getPackageName();
PackageSetting pkg = mSettings.mPackages.get(packageNameStr);
if (pkg == null) {
throw new IllegalArgumentException("Unknown component: " + componentName);
}
final String classNameStr = componentName.getClassName();
return pkg.currentEnabledStateLP(classNameStr);
}
| public java.util.List | getInstalledApplications(int flags)
ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
synchronized(mPackages) {
if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
Iterator<PackageSetting> i = mSettings.mPackages.values().iterator();
while (i.hasNext()) {
final PackageSetting ps = i.next();
ApplicationInfo ai = generateApplicationInfoFromSettingsLP(ps.name, flags);
if(ai != null) {
finalList.add(ai);
}
}
}
else {
Iterator<PackageParser.Package> i = mPackages.values().iterator();
while (i.hasNext()) {
final PackageParser.Package p = i.next();
if (p.applicationInfo != null) {
ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags);
if(ai != null) {
finalList.add(ai);
}
}
}
}
}
return finalList;
| public java.util.List | getInstalledPackages(int flags)
ArrayList<PackageInfo> finalList = new ArrayList<PackageInfo>();
synchronized (mPackages) {
if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
Iterator<PackageSetting> i = mSettings.mPackages.values().iterator();
while (i.hasNext()) {
final PackageSetting ps = i.next();
PackageInfo psPkg = generatePackageInfoFromSettingsLP(ps.name, flags);
if(psPkg != null) {
finalList.add(psPkg);
}
}
}
else {
Iterator<PackageParser.Package> i = mPackages.values().iterator();
while (i.hasNext()) {
final PackageParser.Package p = i.next();
if (p.applicationInfo != null) {
PackageInfo pi = generatePackageInfo(p, flags);
if(pi != null) {
finalList.add(pi);
}
}
}
}
}
return finalList;
| public android.content.pm.InstrumentationInfo | getInstrumentationInfo(android.content.ComponentName name, int flags)
synchronized (mPackages) {
final PackageParser.Instrumentation i = mInstrumentation.get(name);
return PackageParser.generateInstrumentationInfo(i, flags);
}
| public java.lang.String | getNameForUid(int uid)
synchronized (mPackages) {
Object obj = mSettings.getUserIdLP(uid);
if (obj instanceof SharedUserSetting) {
SharedUserSetting sus = (SharedUserSetting)obj;
return sus.name + ":" + sus.userId;
} else if (obj instanceof PackageSetting) {
PackageSetting ps = (PackageSetting)obj;
return ps.name;
}
}
return null;
| public int[] | getPackageGids(java.lang.String packageName)
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
if (Config.LOGV) Log.v(
TAG, "getApplicationInfo " + packageName
+ ": " + p);
if (p != null) {
final PackageSetting ps = (PackageSetting)p.mExtras;
final SharedUserSetting suid = ps.sharedUser;
return suid != null ? suid.gids : ps.gids;
}
}
// stupid thing to indicate an error.
return new int[0];
| public android.content.pm.PackageInfo | getPackageInfo(java.lang.String packageName, int flags)
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
if (Config.LOGV) Log.v(
TAG, "getApplicationInfo " + packageName
+ ": " + p);
if (p != null) {
return generatePackageInfo(p, flags);
}
if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
return generatePackageInfoFromSettingsLP(packageName, flags);
}
}
return null;
| public void | getPackageSizeInfo(java.lang.String packageName, android.content.pm.IPackageStatsObserver observer)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.GET_PACKAGE_SIZE, null);
// Queue up an async operation since the package deletion may take a little while.
mHandler.post(new Runnable() {
public void run() {
mHandler.removeCallbacks(this);
PackageStats lStats = new PackageStats(packageName);
final boolean succeded;
synchronized (mInstallLock) {
succeded = getPackageSizeInfoLI(packageName, lStats);
}
if(observer != null) {
try {
observer.onGetStatsCompleted(lStats, succeded);
} catch (RemoteException e) {
Log.i(TAG, "Observer no longer exists.");
}
} //end if observer
} //end run
});
| private boolean | getPackageSizeInfoLI(java.lang.String packageName, android.content.pm.PackageStats pStats)
if (packageName == null) {
Log.w(TAG, "Attempt to get size of null packageName.");
return false;
}
PackageParser.Package p;
boolean dataOnly = false;
synchronized (mPackages) {
p = mPackages.get(packageName);
if(p == null) {
dataOnly = true;
PackageSetting ps = mSettings.mPackages.get(packageName);
if((ps == null) || (ps.pkg == null)) {
Log.w(TAG, "Package named '" + packageName +"' doesn't exist.");
return false;
}
p = ps.pkg;
}
}
String publicSrcDir = null;
if(!dataOnly) {
final ApplicationInfo applicationInfo = p.applicationInfo;
if (applicationInfo == null) {
Log.w(TAG, "Package " + packageName + " has no applicationInfo.");
return false;
}
publicSrcDir = isForwardLocked(p) ? applicationInfo.publicSourceDir : null;
}
if (mInstaller != null) {
int res = mInstaller.getSizeInfo(packageName, p.mPath,
publicSrcDir, pStats);
if (res < 0) {
return false;
} else {
return true;
}
}
return true;
| public int | getPackageUid(java.lang.String packageName)
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
if(p != null) {
return 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 ? p.applicationInfo.uid : -1;
}
| public java.lang.String[] | getPackagesForUid(int uid)
synchronized (mPackages) {
Object obj = mSettings.getUserIdLP(uid);
if (obj instanceof SharedUserSetting) {
SharedUserSetting sus = (SharedUserSetting)obj;
final int N = sus.packages.size();
String[] res = new String[N];
Iterator<PackageSetting> it = sus.packages.iterator();
int i=0;
while (it.hasNext()) {
res[i++] = it.next().name;
}
return res;
} else if (obj instanceof PackageSetting) {
PackageSetting ps = (PackageSetting)obj;
return new String[] { ps.name };
}
}
return null;
| public android.content.pm.PermissionGroupInfo | getPermissionGroupInfo(java.lang.String name, int flags)
synchronized (mPackages) {
return PackageParser.generatePermissionGroupInfo(
mPermissionGroups.get(name), flags);
}
| public android.content.pm.PermissionInfo | getPermissionInfo(java.lang.String name, int flags)
synchronized (mPackages) {
final BasePermission p = mSettings.mPermissions.get(name);
if (p != null && p.perm != null) {
return PackageParser.generatePermissionInfo(p.perm, flags);
}
return null;
}
| public java.util.List | getPersistentApplications(int flags)
ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
synchronized (mPackages) {
Iterator<PackageParser.Package> i = mPackages.values().iterator();
while (i.hasNext()) {
PackageParser.Package p = i.next();
if (p.applicationInfo != null
&& (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
&& (!mSafeMode || (p.applicationInfo.flags
&ApplicationInfo.FLAG_SYSTEM) != 0)) {
finalList.add(p.applicationInfo);
}
}
}
return finalList;
| public int | getPreferredActivities(java.util.List outFilters, java.util.List outActivities, java.lang.String packageName)
int num = 0;
synchronized (mPackages) {
Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator();
while (it.hasNext()) {
PreferredActivity pa = it.next();
if (packageName == null
|| pa.mActivity.getPackageName().equals(packageName)) {
if (outFilters != null) {
outFilters.add(new IntentFilter(pa));
}
if (outActivities != null) {
outActivities.add(pa.mActivity);
}
}
}
}
return num;
| public java.util.List | getPreferredPackages(int flags)
synchronized (mPackages) {
final ArrayList<PackageInfo> res = new ArrayList<PackageInfo>();
final ArrayList<PackageSetting> pref = mSettings.mPreferredPackages;
final int N = pref.size();
for (int i=0; i<N; i++) {
res.add(generatePackageInfo(pref.get(i).pkg, flags));
}
return res;
}
| public android.content.pm.ActivityInfo | getReceiverInfo(android.content.ComponentName component, int flags)
synchronized (mPackages) {
PackageParser.Activity a = mReceivers.mActivities.get(component);
if (Config.LOGV) Log.v(
TAG, "getReceiverInfo " + component + ": " + a);
if (a != null && mSettings.isEnabledLP(a.info, flags)) {
return PackageParser.generateActivityInfo(a, flags);
}
}
return null;
| public android.content.pm.ServiceInfo | getServiceInfo(android.content.ComponentName component, int flags)
synchronized (mPackages) {
PackageParser.Service s = mServices.mServices.get(component);
if (Config.LOGV) Log.v(
TAG, "getServiceInfo " + component + ": " + s);
if (s != null && mSettings.isEnabledLP(s.info, flags)) {
return PackageParser.generateServiceInfo(s, flags);
}
}
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;
}
synchronized (mPackages) {
SharedUserSetting suid = mSettings.getSharedUserLP(sharedUserName, 0, false);
if(suid == null) {
return -1;
}
return suid.userId;
}
| private void | grantPermissionsLP(PackageParser.Package pkg, boolean replace)
final PackageSetting ps = (PackageSetting)pkg.mExtras;
if (ps == null) {
return;
}
final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
boolean addedPermission = false;
if (replace) {
ps.permissionsFixed = false;
if (gp == ps) {
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++) {
String name = pkg.requestedPermissions.get(i);
BasePermission bp = mSettings.mPermissions.get(name);
PackageParser.Permission p = bp != null ? bp.perm : null;
if (false) {
if (gp != ps) {
Log.i(TAG, "Package " + pkg.packageName + " checking " + name
+ ": " + p);
}
}
if (p != null) {
final String perm = p.info.name;
boolean allowed;
if (p.info.protectionLevel == PermissionInfo.PROTECTION_NORMAL
|| p.info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS) {
allowed = true;
} else if (p.info.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE
|| p.info.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM) {
allowed = (checkSignaturesLP(p.owner, pkg)
== PackageManager.SIGNATURE_MATCH)
|| (checkSignaturesLP(mPlatformPackage, pkg)
== PackageManager.SIGNATURE_MATCH);
if (p.info.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM) {
if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
// For updated system applications, the signatureOrSystem permission
// is granted only if it had been defined by the original application.
if ((pkg.applicationInfo.flags
& ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
PackageSetting sysPs = mSettings.getDisabledSystemPkg(pkg.packageName);
if(sysPs.grantedPermissions.contains(perm)) {
allowed = true;
} else {
allowed = false;
}
} else {
allowed = true;
}
}
}
} else {
allowed = false;
}
if (false) {
if (gp != ps) {
Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
}
}
if (allowed) {
if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
&& ps.permissionsFixed) {
// If this is an existing, non-system package, then
// we can't add any new permissions to it.
if (!gp.loadedPermissions.contains(perm)) {
allowed = false;
}
}
if (allowed) {
if (!gp.grantedPermissions.contains(perm)) {
addedPermission = true;
gp.grantedPermissions.add(perm);
gp.gids = appendInts(gp.gids, bp.gids);
}
} else {
Log.w(TAG, "Not granting permission " + perm
+ " to package " + pkg.packageName
+ " because it was previously installed without");
}
} else {
Log.w(TAG, "Not granting permission " + perm
+ " to package " + pkg.packageName
+ " (protectionLevel=" + p.info.protectionLevel
+ " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
+ ")");
}
} else {
Log.w(TAG, "Unknown permission " + name
+ " in package " + pkg.packageName);
}
}
if ((addedPermission || replace) && !ps.permissionsFixed &&
(ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
// 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;
gp.loadedPermissions = new HashSet<String>(gp.grantedPermissions);
}
| public boolean | hasSystemUidErrors()
return mHasSystemUidErrors;
| private void | installNewPackageLI(java.lang.String pkgName, java.io.File tmpPackageFile, java.lang.String destFilePath, java.io.File destPackageFile, java.io.File destResourceFile, PackageParser.Package pkg, boolean forwardLocked, boolean newInstall, com.android.server.PackageManagerService$PackageInstalledInfo res)
// Remember this for later, in case we need to rollback this install
boolean dataDirExists = (new File(mAppDataDir, pkgName)).exists();
res.name = pkgName;
synchronized(mPackages) {
if (mPackages.containsKey(pkgName) || mAppDirs.containsKey(destFilePath)) {
// Don't allow installation over an existing package with the same name.
Log.w(TAG, "Attempt to re-install " + pkgName
+ " without first uninstalling.");
res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
return;
}
}
if (destPackageFile.exists()) {
// It's safe to do this because we know (from the above check) that the file
// isn't currently used for an installed package.
destPackageFile.delete();
}
mLastScanError = PackageManager.INSTALL_SUCCEEDED;
PackageParser.Package newPackage = scanPackageLI(tmpPackageFile, destPackageFile,
destResourceFile, pkg, 0,
SCAN_MONITOR | SCAN_FORCE_DEX
| SCAN_UPDATE_SIGNATURE
| (forwardLocked ? SCAN_FORWARD_LOCKED : 0)
| (newInstall ? SCAN_NEW_INSTALL : 0));
if (newPackage == null) {
Log.w(TAG, "Package couldn't be installed in " + destPackageFile);
if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
}
} else {
updateSettingsLI(pkgName, tmpPackageFile,
destFilePath, destPackageFile,
destResourceFile, pkg,
newPackage,
true,
forwardLocked,
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, true,
dataDirExists ? PackageManager.DONT_DELETE_DATA : 0,
res.removedInfo);
}
}
| public void | installPackage(android.net.Uri packageURI, android.content.pm.IPackageInstallObserver observer, int flags)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.INSTALL_PACKAGES, null);
// Queue up an async operation since the package installation may take a little while.
mHandler.post(new Runnable() {
public void run() {
mHandler.removeCallbacks(this);
PackageInstalledInfo res;
synchronized (mInstallLock) {
res = installPackageLI(packageURI, flags, true);
}
if (observer != null) {
try {
observer.packageInstalled(res.name, res.returnCode);
} catch (RemoteException e) {
Log.i(TAG, "Observer no longer exists.");
}
}
// There appears to be a subtle deadlock condition if the sendPackageBroadcast
// call appears in the synchronized block above.
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
res.removedInfo.sendBroadcast(false, true);
Bundle extras = new Bundle(1);
extras.putInt(Intent.EXTRA_UID, res.uid);
final boolean update = res.removedInfo.removedPackage != null;
if (update) {
extras.putBoolean(Intent.EXTRA_REPLACING, true);
}
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
res.pkg.applicationInfo.packageName,
extras);
if (update) {
sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
res.pkg.applicationInfo.packageName,
extras);
}
}
Runtime.getRuntime().gc();
}
});
| private com.android.server.PackageManagerService$PackageInstalledInfo | installPackageLI(android.net.Uri pPackageURI, int pFlags, boolean newInstall)
File tmpPackageFile = null;
String pkgName = null;
boolean forwardLocked = false;
boolean replacingExistingPackage = false;
// Result object to be returned
PackageInstalledInfo res = new PackageInstalledInfo();
res.returnCode = PackageManager.INSTALL_SUCCEEDED;
res.uid = -1;
res.pkg = null;
res.removedInfo = new PackageRemovedInfo();
main_flow: try {
tmpPackageFile = createTempPackageFile();
if (tmpPackageFile == null) {
res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
break main_flow;
}
tmpPackageFile.deleteOnExit(); // paranoia
if (pPackageURI.getScheme().equals("file")) {
final File srcPackageFile = new File(pPackageURI.getPath());
// We copy the source package file to a temp file and then rename it to the
// destination file in order to eliminate a window where the package directory
// scanner notices the new package file but it's not completely copied yet.
if (!FileUtils.copyFile(srcPackageFile, tmpPackageFile)) {
Log.e(TAG, "Couldn't copy package file to temp file.");
res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
break main_flow;
}
} else if (pPackageURI.getScheme().equals("content")) {
ParcelFileDescriptor fd;
try {
fd = mContext.getContentResolver().openFileDescriptor(pPackageURI, "r");
} catch (FileNotFoundException e) {
Log.e(TAG, "Couldn't open file descriptor from download service.");
res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
break main_flow;
}
if (fd == null) {
Log.e(TAG, "Couldn't open file descriptor from download service (null).");
res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
break main_flow;
}
if (Config.LOGV) {
Log.v(TAG, "Opened file descriptor from download service.");
}
ParcelFileDescriptor.AutoCloseInputStream
dlStream = new ParcelFileDescriptor.AutoCloseInputStream(fd);
// We copy the source package file to a temp file and then rename it to the
// destination file in order to eliminate a window where the package directory
// scanner notices the new package file but it's not completely copied yet.
if (!FileUtils.copyToFile(dlStream, tmpPackageFile)) {
Log.e(TAG, "Couldn't copy package stream to temp file.");
res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
break main_flow;
}
} else {
Log.e(TAG, "Package URI is not 'file:' or 'content:' - " + pPackageURI);
res.returnCode = PackageManager.INSTALL_FAILED_INVALID_URI;
break main_flow;
}
pkgName = PackageParser.parsePackageName(
tmpPackageFile.getAbsolutePath(), 0);
if (pkgName == null) {
Log.e(TAG, "Couldn't find a package name in : " + tmpPackageFile);
res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
break main_flow;
}
res.name = pkgName;
//initialize some variables before installing pkg
final String pkgFileName = pkgName + ".apk";
final File destDir = ((pFlags&PackageManager.FORWARD_LOCK_PACKAGE) != 0)
? mDrmAppPrivateInstallDir
: mAppInstallDir;
final File destPackageFile = new File(destDir, pkgFileName);
final String destFilePath = destPackageFile.getAbsolutePath();
File destResourceFile;
if ((pFlags&PackageManager.FORWARD_LOCK_PACKAGE) != 0) {
final String publicZipFileName = pkgName + ".zip";
destResourceFile = new File(mAppInstallDir, publicZipFileName);
forwardLocked = true;
} else {
destResourceFile = destPackageFile;
}
// Retrieve PackageSettings and parse package
int parseFlags = PackageParser.PARSE_CHATTY;
parseFlags |= mDefParseFlags;
PackageParser pp = new PackageParser(tmpPackageFile.getPath());
pp.setSeparateProcesses(mSeparateProcesses);
pp.setSdkVersion(mSdkVersion);
final PackageParser.Package pkg = pp.parsePackage(tmpPackageFile,
destPackageFile.getAbsolutePath(), mMetrics, parseFlags);
if (pkg == null) {
res.returnCode = pp.getParseError();
break main_flow;
}
if (GET_CERTIFICATES && !pp.collectCertificates(pkg, parseFlags)) {
res.returnCode = pp.getParseError();
break main_flow;
}
synchronized (mPackages) {
//check if installing already existing package
if ((pFlags&PackageManager.REPLACE_EXISTING_PACKAGE) != 0
&& mPackages.containsKey(pkgName)) {
replacingExistingPackage = true;
}
}
if(replacingExistingPackage) {
replacePackageLI(pkgName,
tmpPackageFile,
destFilePath, destPackageFile, destResourceFile,
pkg, forwardLocked, newInstall,
res);
} else {
installNewPackageLI(pkgName,
tmpPackageFile,
destFilePath, destPackageFile, destResourceFile,
pkg, forwardLocked, newInstall,
res);
}
} finally {
if (tmpPackageFile != null && tmpPackageFile.exists()) {
tmpPackageFile.delete();
}
}
return res;
| private boolean | isForwardLocked(PackageParser.Package deletedPackage)
final ApplicationInfo applicationInfo = deletedPackage.applicationInfo;
return applicationInfo.sourceDir.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath());
| private static final boolean | isPackageFilename(java.lang.String name)
return name != null && name.endsWith(".apk");
| public boolean | isSafeMode()
return mSafeMode;
| public static final android.content.pm.IPackageManager | main(android.content.Context context, boolean factoryTest)
PackageManagerService m = new PackageManagerService(context, factoryTest);
ServiceManager.addService("package", m);
return m;
| 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)) {
Log.e(TAG, "Package Manager Crash", e);
}
throw e;
}
| public java.util.List | queryContentProviders(java.lang.String processName, int uid, int flags)
ArrayList<ProviderInfo> finalList = null;
synchronized (mPackages) {
Iterator<PackageParser.Provider> i = mProvidersByComponent.values().iterator();
while (i.hasNext()) {
PackageParser.Provider p = i.next();
if (p.info.authority != null
&& (processName == null ||
(p.info.processName.equals(processName)
&& p.info.applicationInfo.uid == uid))
&& mSettings.isEnabledLP(p.info, flags)
&& (!mSafeMode || (p.info.applicationInfo.flags
&ApplicationInfo.FLAG_SYSTEM) != 0)) {
if (finalList == null) {
finalList = new ArrayList<ProviderInfo>(3);
}
finalList.add(PackageParser.generateProviderInfo(p,
flags));
}
}
}
if (finalList != null) {
Collections.sort(finalList, mProviderInitOrderSorter);
}
return finalList;
| public java.util.List | queryInstrumentation(java.lang.String targetPackage, int flags)
ArrayList<InstrumentationInfo> finalList =
new ArrayList<InstrumentationInfo>();
synchronized (mPackages) {
Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
while (i.hasNext()) {
PackageParser.Instrumentation p = i.next();
if (targetPackage == null
|| targetPackage.equals(p.info.targetPackage)) {
finalList.add(PackageParser.generateInstrumentationInfo(p,
flags));
}
}
}
return finalList;
| public java.util.List | queryIntentActivities(android.content.Intent intent, java.lang.String resolvedType, int flags)
ComponentName comp = intent.getComponent();
if (comp != null) {
List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
ActivityInfo ai = getActivityInfo(comp, flags);
if (ai != null) {
ResolveInfo ri = new ResolveInfo();
ri.activityInfo = ai;
list.add(ri);
}
return list;
}
synchronized (mPackages) {
return (List<ResolveInfo>)mActivities.
queryIntent(null, intent, resolvedType, flags);
}
| 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)
final String resultsAction = intent.getAction();
List<ResolveInfo> results = queryIntentActivities(
intent, resolvedType, flags|PackageManager.GET_RESOLVED_FILTER);
if (Config.LOGV) 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 (Config.LOGV) 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;
}
ComponentName comp = sintent.getComponent();
ResolveInfo ri = null;
ActivityInfo ai = null;
if (comp == null) {
ri = resolveIntent(
sintent,
specificTypes != null ? specificTypes[i] : null,
flags);
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);
if (ai == null) {
continue;
}
}
// Look for any generic query activities that are duplicates
// of this specific one, and remove them from the results.
if (Config.LOGV) 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 (Config.LOGV) 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 (Config.LOGV) 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 (Config.LOGV) Log.v(TAG, "Result: " + results);
return results;
| public java.util.List | queryIntentReceivers(android.content.Intent intent, java.lang.String resolvedType, int flags)
synchronized (mPackages) {
return (List<ResolveInfo>)mReceivers.
queryIntent(null, intent, resolvedType, flags);
}
| public java.util.List | queryIntentServices(android.content.Intent intent, java.lang.String resolvedType, int flags)
ComponentName comp = intent.getComponent();
if (comp != null) {
List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
ServiceInfo si = getServiceInfo(comp, flags);
if (si != null) {
ResolveInfo ri = new ResolveInfo();
ri.serviceInfo = si;
list.add(ri);
}
return list;
}
synchronized (mPackages) {
return (List<ResolveInfo>)mServices.
queryIntent(null, intent, resolvedType, flags);
}
| public java.util.List | queryPermissionsByGroup(java.lang.String group, int flags)
synchronized (mPackages) {
ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
for (BasePermission p : mSettings.mPermissions.values()) {
if (group == null) {
if (p.perm.info.group == null) {
out.add(PackageParser.generatePermissionInfo(p.perm, flags));
}
} else {
if (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;
}
| public void | querySyncProviders(java.util.List outNames, java.util.List outInfo)
synchronized (mPackages) {
Iterator<Map.Entry<String, PackageParser.Provider>> i
= mProviders.entrySet().iterator();
while (i.hasNext()) {
Map.Entry<String, PackageParser.Provider> entry = i.next();
PackageParser.Provider p = entry.getValue();
if (p.syncable
&& (!mSafeMode || (p.info.applicationInfo.flags
&ApplicationInfo.FLAG_SYSTEM) != 0)) {
outNames.add(entry.getKey());
outInfo.add(PackageParser.generateProviderInfo(p, 0));
}
}
}
| void | readPermission(org.xmlpull.v1.XmlPullParser parser, java.lang.String name)
name = name.intern();
BasePermission bp = mSettings.mPermissions.get(name);
if (bp == null) {
bp = new BasePermission(name, null, BasePermission.TYPE_BUILTIN);
mSettings.mPermissions.put(name, bp);
}
int outerDepth = parser.getDepth();
int type;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG
|| parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG
|| type == XmlPullParser.TEXT) {
continue;
}
String tagName = parser.getName();
if ("group".equals(tagName)) {
String gidStr = parser.getAttributeValue(null, "gid");
if (gidStr != null) {
int gid = Process.getGidForName(gidStr);
bp.gids = appendInt(bp.gids, gid);
} else {
Log.w(TAG, "<group> without gid at "
+ parser.getPositionDescription());
}
}
XmlUtils.skipCurrentTag(parser);
}
| void | readPermissions()
// Read permissions from .../etc/permission directory.
File libraryDir = new File(Environment.getRootDirectory(), "etc/permissions");
if (!libraryDir.exists() || !libraryDir.isDirectory()) {
Log.w(TAG, "No directory " + libraryDir + ", skipping");
return;
}
if (!libraryDir.canRead()) {
Log.w(TAG, "Directory " + libraryDir + " cannot be read");
return;
}
// Iterate over the files in the directory and scan .xml files
for (File f : libraryDir.listFiles()) {
// We'll read platform.xml last
if (f.getPath().endsWith("etc/permissions/platform.xml")) {
continue;
}
if (!f.getPath().endsWith(".xml")) {
Log.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring");
continue;
}
if (!f.canRead()) {
Log.w(TAG, "Permissions library file " + f + " cannot be read");
continue;
}
readPermissionsFromXml(f);
}
// Read permissions from .../etc/permissions/platform.xml last so it will take precedence
final File permFile = new File(Environment.getRootDirectory(),
"etc/permissions/platform.xml");
readPermissionsFromXml(permFile);
| private void | readPermissionsFromXml(java.io.File permFile)
FileReader permReader = null;
try {
permReader = new FileReader(permFile);
} catch (FileNotFoundException e) {
Log.w(TAG, "Couldn't find or open permissions file " + permFile);
return;
}
try {
XmlPullParser parser = Xml.newPullParser();
parser.setInput(permReader);
XmlUtils.beginDocument(parser, "permissions");
while (true) {
XmlUtils.nextElement(parser);
if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
break;
}
String name = parser.getName();
if ("group".equals(name)) {
String gidStr = parser.getAttributeValue(null, "gid");
if (gidStr != null) {
int gid = Integer.parseInt(gidStr);
mGlobalGids = appendInt(mGlobalGids, gid);
} else {
Log.w(TAG, "<group> without gid at "
+ parser.getPositionDescription());
}
XmlUtils.skipCurrentTag(parser);
continue;
} else if ("permission".equals(name)) {
String perm = parser.getAttributeValue(null, "name");
if (perm == null) {
Log.w(TAG, "<permission> without name at "
+ parser.getPositionDescription());
XmlUtils.skipCurrentTag(parser);
continue;
}
perm = perm.intern();
readPermission(parser, perm);
} else if ("assign-permission".equals(name)) {
String perm = parser.getAttributeValue(null, "name");
if (perm == null) {
Log.w(TAG, "<assign-permission> without name at "
+ parser.getPositionDescription());
XmlUtils.skipCurrentTag(parser);
continue;
}
String uidStr = parser.getAttributeValue(null, "uid");
if (uidStr == null) {
Log.w(TAG, "<assign-permission> without uid at "
+ parser.getPositionDescription());
XmlUtils.skipCurrentTag(parser);
continue;
}
int uid = Process.getUidForName(uidStr);
if (uid < 0) {
Log.w(TAG, "<assign-permission> with unknown uid \""
+ uidStr + "\" at "
+ parser.getPositionDescription());
XmlUtils.skipCurrentTag(parser);
continue;
}
perm = perm.intern();
HashSet<String> perms = mSystemPermissions.get(uid);
if (perms == null) {
perms = new HashSet<String>();
mSystemPermissions.put(uid, perms);
}
perms.add(perm);
XmlUtils.skipCurrentTag(parser);
} else if ("library".equals(name)) {
String lname = parser.getAttributeValue(null, "name");
String lfile = parser.getAttributeValue(null, "file");
if (lname == null) {
Log.w(TAG, "<library> without name at "
+ parser.getPositionDescription());
} else if (lfile == null) {
Log.w(TAG, "<library> without file at "
+ parser.getPositionDescription());
} else {
Log.i(TAG, "Got library " + lname + " in " + lfile);
this.mSharedLibraries.put(lname, lfile);
}
XmlUtils.skipCurrentTag(parser);
continue;
} else {
XmlUtils.skipCurrentTag(parser);
continue;
}
}
} catch (XmlPullParserException e) {
Log.w(TAG, "Got execption parsing permissions.", e);
} catch (IOException e) {
Log.w(TAG, "Got execption parsing permissions.", e);
}
| private void | removePackageDataLI(PackageParser.Package p, com.android.server.PackageManagerService$PackageRemovedInfo outInfo, int flags)
String packageName = p.packageName;
outInfo.removedPackage = packageName;
removePackageLI(p, true);
// Retrieve object to delete permissions for shared user later on
PackageSetting deletedPs;
synchronized (mPackages) {
deletedPs = mSettings.mPackages.get(packageName);
}
if ((flags&PackageManager.DONT_DELETE_DATA) == 0) {
if (mInstaller != null) {
int retCode = mInstaller.remove(packageName);
if (retCode < 0) {
Log.w(TAG, "Couldn't remove app data or cache directory for package: "
+ packageName + ", retcode=" + retCode);
// we don't consider this to be a failure of the core package deletion
}
} else {
//for emulator
PackageParser.Package pkg = mPackages.get(packageName);
File dataDir = new File(pkg.applicationInfo.dataDir);
dataDir.delete();
}
synchronized (mPackages) {
outInfo.removedUid = mSettings.removePackageLP(packageName);
}
}
synchronized (mPackages) {
if ( (deletedPs != null) && (deletedPs.sharedUser != null)) {
// remove permissions associated with package
mSettings.updateSharedUserPerms (deletedPs);
}
// Save settings now
mSettings.writeLP ();
}
| public void | removePackageFromPreferred(java.lang.String packageName)
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
if (p == null) {
return;
}
if (p.mPreferredOrder > 0) {
PackageSetting ps = (PackageSetting)p.mExtras;
if (ps != null) {
mSettings.mPreferredPackages.remove(ps);
p.mPreferredOrder = 0;
updatePreferredIndicesLP();
mSettings.writeLP();
}
}
}
| void | removePackageLI(PackageParser.Package pkg, boolean chatty)
if (chatty && Config.LOGD) Log.d(
TAG, "Removing package " + pkg.applicationInfo.packageName );
synchronized (mPackages) {
if (pkg.mPreferredOrder > 0) {
mSettings.mPreferredPackages.remove(pkg);
pkg.mPreferredOrder = 0;
updatePreferredIndicesLP();
}
clearPackagePreferredActivitiesLP(pkg.packageName);
mPackages.remove(pkg.applicationInfo.packageName);
if (pkg.mPath != null) {
mAppDirs.remove(pkg.mPath);
}
PackageSetting ps = (PackageSetting)pkg.mExtras;
if (ps != null && ps.sharedUser != null) {
// XXX don't do this until the data is removed.
if (false) {
ps.sharedUser.packages.remove(ps);
if (ps.sharedUser.packages.size() == 0) {
// Remove.
}
}
}
int N = pkg.providers.size();
StringBuilder r = null;
int i;
for (i=0; i<N; i++) {
PackageParser.Provider p = pkg.providers.get(i);
mProvidersByComponent.remove(new ComponentName(p.info.packageName,
p.info.name));
if (p.info.authority == null) {
/* The is 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 (mProviders.get(names[j]) == p) {
mProviders.remove(names[j]);
if (chatty && Config.LOGD) Log.d(
TAG, "Unregistered content provider: " + names[j] +
", className = " + p.info.name +
", isSyncable = " + p.info.isSyncable);
}
}
if (chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append(p.info.name);
}
}
if (r != null) {
if (Config.LOGD) 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 (Config.LOGD) 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 (chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append(a.info.name);
}
}
if (r != null) {
if (Config.LOGD) 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 (chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append(a.info.name);
}
}
if (r != null) {
if (Config.LOGD) Log.d(TAG, " Activities: " + r);
}
N = pkg.permissions.size();
r = null;
for (i=0; i<N; i++) {
PackageParser.Permission p = pkg.permissions.get(i);
boolean tree = false;
BasePermission bp = mSettings.mPermissions.get(p.info.name);
if (bp == null) {
tree = true;
bp = mSettings.mPermissionTrees.get(p.info.name);
}
if (bp != null && bp.perm == p) {
if (bp.type != BasePermission.TYPE_BUILTIN) {
if (tree) {
mSettings.mPermissionTrees.remove(p.info.name);
} else {
mSettings.mPermissions.remove(p.info.name);
}
} else {
bp.perm = null;
}
if (chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append(p.info.name);
}
}
}
if (r != null) {
if (Config.LOGD) 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.component);
if (chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append(a.info.name);
}
}
if (r != null) {
if (Config.LOGD) Log.d(TAG, " Instrumentation: " + r);
}
}
| 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.writeLP();
}
}
| private void | replaceNonSystemPackageLI(PackageParser.Package deletedPackage, java.io.File tmpPackageFile, java.lang.String destFilePath, java.io.File destPackageFile, java.io.File destResourceFile, PackageParser.Package pkg, boolean forwardLocked, boolean newInstall, com.android.server.PackageManagerService$PackageInstalledInfo res)
PackageParser.Package newPackage = null;
String pkgName = deletedPackage.packageName;
boolean deletedPkg = true;
boolean updatedSettings = false;
int parseFlags = PackageManager.REPLACE_EXISTING_PACKAGE;
// First delete the existing package while retaining the data directory
if (!deletePackageLI(pkgName, false, PackageManager.DONT_DELETE_DATA,
res.removedInfo)) {
// If the existing package was'nt successfully deleted
res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
deletedPkg = false;
} else {
// Successfully deleted the old package. Now proceed with re-installation
mLastScanError = PackageManager.INSTALL_SUCCEEDED;
newPackage = scanPackageLI(tmpPackageFile, destPackageFile,
destResourceFile, pkg, parseFlags,
SCAN_MONITOR | SCAN_FORCE_DEX
| SCAN_UPDATE_SIGNATURE
| (forwardLocked ? SCAN_FORWARD_LOCKED : 0)
| (newInstall ? SCAN_NEW_INSTALL : 0));
if (newPackage == null) {
Log.w(TAG, "Package couldn't be installed in " + destPackageFile);
if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
}
} else {
updateSettingsLI(pkgName, tmpPackageFile,
destFilePath, destPackageFile,
destResourceFile, pkg,
newPackage,
true,
forwardLocked,
res);
updatedSettings = true;
}
}
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
// If we deleted an exisiting package, the old source and resource files that we
// were keeping around in case we needed them (see below) can now be deleted
final ApplicationInfo deletedPackageAppInfo = deletedPackage.applicationInfo;
final ApplicationInfo installedPackageAppInfo =
newPackage.applicationInfo;
if (!deletedPackageAppInfo.sourceDir
.equals(installedPackageAppInfo.sourceDir)) {
new File(deletedPackageAppInfo.sourceDir).delete();
}
if (!deletedPackageAppInfo.publicSourceDir
.equals(installedPackageAppInfo.publicSourceDir)) {
new File(deletedPackageAppInfo.publicSourceDir).delete();
}
//update signature on the new package setting
//this should always succeed, since we checked the
//signature earlier.
synchronized(mPackages) {
verifySignaturesLP(mSettings.mPackages.get(pkgName), pkg,
parseFlags, true);
}
} else {
// 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) {
deletePackageLI(
pkgName, true,
PackageManager.DONT_DELETE_DATA,
res.removedInfo);
}
// Since we failed to install the new package we need to restore the old
// package that we deleted.
if(deletedPkg) {
installPackageLI(
Uri.fromFile(new File(deletedPackage.mPath)),
isForwardLocked(deletedPackage)
? PackageManager.FORWARD_LOCK_PACKAGE
: 0, false);
}
}
| private void | replacePackageLI(java.lang.String pkgName, java.io.File tmpPackageFile, java.lang.String destFilePath, java.io.File destPackageFile, java.io.File destResourceFile, PackageParser.Package pkg, boolean forwardLocked, boolean newInstall, com.android.server.PackageManagerService$PackageInstalledInfo res)
PackageParser.Package deletedPackage;
// First find the old package info and check signatures
synchronized(mPackages) {
deletedPackage = mPackages.get(pkgName);
if(checkSignaturesLP(pkg, deletedPackage) != PackageManager.SIGNATURE_MATCH) {
res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
return;
}
}
boolean sysPkg = ((deletedPackage.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0);
if(sysPkg) {
replaceSystemPackageLI(deletedPackage,
tmpPackageFile, destFilePath,
destPackageFile, destResourceFile, pkg, forwardLocked,
newInstall, res);
} else {
replaceNonSystemPackageLI(deletedPackage, tmpPackageFile, destFilePath,
destPackageFile, destResourceFile, pkg, forwardLocked,
newInstall, res);
}
| private void | replaceSystemPackageLI(PackageParser.Package deletedPackage, java.io.File tmpPackageFile, java.lang.String destFilePath, java.io.File destPackageFile, java.io.File destResourceFile, PackageParser.Package pkg, boolean forwardLocked, boolean newInstall, com.android.server.PackageManagerService$PackageInstalledInfo res)
PackageParser.Package newPackage = null;
boolean updatedSettings = false;
int parseFlags = PackageManager.REPLACE_EXISTING_PACKAGE |
PackageParser.PARSE_IS_SYSTEM;
String packageName = deletedPackage.packageName;
res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
if (packageName == null) {
Log.w(TAG, "Attempt to delete null packageName.");
return;
}
PackageParser.Package oldPkg;
PackageSetting oldPkgSetting;
synchronized (mPackages) {
oldPkg = mPackages.get(packageName);
oldPkgSetting = mSettings.mPackages.get(packageName);
if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
(oldPkgSetting == null)) {
Log.w(TAG, "Could'nt find package:"+packageName+" information");
return;
}
}
res.removedInfo.uid = oldPkg.applicationInfo.uid;
res.removedInfo.removedPackage = packageName;
// Remove existing system package
removePackageLI(oldPkg, true);
synchronized (mPackages) {
res.removedInfo.removedUid = mSettings.disableSystemPackageLP(packageName);
}
// Successfully disabled the old package. Now proceed with re-installation
mLastScanError = PackageManager.INSTALL_SUCCEEDED;
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
newPackage = scanPackageLI(tmpPackageFile, destPackageFile,
destResourceFile, pkg, parseFlags,
SCAN_MONITOR | SCAN_FORCE_DEX
| SCAN_UPDATE_SIGNATURE
| (forwardLocked ? SCAN_FORWARD_LOCKED : 0)
| (newInstall ? SCAN_NEW_INSTALL : 0));
if (newPackage == null) {
Log.w(TAG, "Package couldn't be installed in " + destPackageFile);
if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
}
} else {
updateSettingsLI(packageName, tmpPackageFile,
destFilePath, destPackageFile,
destResourceFile, pkg,
newPackage,
true,
forwardLocked,
res);
updatedSettings = true;
}
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
//update signature on the new package setting
//this should always succeed, since we checked the
//signature earlier.
synchronized(mPackages) {
verifySignaturesLP(mSettings.mPackages.get(packageName), pkg,
parseFlags, true);
}
} else {
// Re installation failed. Restore old information
// Remove new pkg information
removePackageLI(newPackage, true);
// Add back the old system package
scanPackageLI(oldPkgSetting.codePath, oldPkgSetting.codePath,
oldPkgSetting.resourcePath,
oldPkg, parseFlags,
SCAN_MONITOR
| SCAN_UPDATE_SIGNATURE);
// Restore the old system information in Settings
synchronized(mPackages) {
if(updatedSettings) {
mSettings.enableSystemPackageLP(packageName);
}
mSettings.writeLP();
}
}
| private static void | reportSettingsProblem(int priority, java.lang.String msg)
try {
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
File fname = new File(systemDir, "uiderrors.txt");
FileOutputStream out = new FileOutputStream(fname, true);
PrintWriter pw = new PrintWriter(out);
pw.println(msg);
pw.close();
FileUtils.setPermissions(
fname.toString(),
FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
-1, -1);
} catch (java.io.IOException e) {
}
Log.println(priority, TAG, msg);
| public android.content.pm.ProviderInfo | resolveContentProvider(java.lang.String name, int flags)
synchronized (mPackages) {
final PackageParser.Provider provider = mProviders.get(name);
return provider != null
&& mSettings.isEnabledLP(provider.info, flags)
&& (!mSafeMode || (provider.info.applicationInfo.flags
&ApplicationInfo.FLAG_SYSTEM) != 0)
? PackageParser.generateProviderInfo(provider, flags)
: null;
}
| public android.content.pm.ResolveInfo | resolveIntent(android.content.Intent intent, java.lang.String resolvedType, int flags)
List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags);
if (query != null) {
final int N = query.size();
if (N == 1) {
return query.get(0);
} else if (N > 1) {
// 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 (false) {
System.out.println(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);
if (ri != null) {
return ri;
}
return mResolveInfo;
}
}
return null;
| public android.content.pm.ResolveInfo | resolveService(android.content.Intent intent, java.lang.String resolvedType, int flags)
List<ResolveInfo> query = queryIntentServices(intent, resolvedType,
flags);
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;
| private void | scanDirLI(java.io.File dir, int flags, int scanMode)
Log.d(TAG, "Scanning app dir " + dir);
String[] files = dir.list();
int i;
for (i=0; i<files.length; i++) {
File file = new File(dir, files[i]);
PackageParser.Package pkg = scanPackageLI(file, file, file,
flags|PackageParser.PARSE_MUST_BE_APK, scanMode);
}
| private PackageParser.Package | scanPackageLI(java.io.File scanFile, java.io.File destCodeFile, java.io.File destResourceFile, int parseFlags, int scanMode)
mLastScanError = PackageManager.INSTALL_SUCCEEDED;
parseFlags |= mDefParseFlags;
PackageParser pp = new PackageParser(scanFile.getPath());
pp.setSeparateProcesses(mSeparateProcesses);
pp.setSdkVersion(mSdkVersion);
final PackageParser.Package pkg = pp.parsePackage(scanFile,
destCodeFile.getAbsolutePath(), mMetrics, parseFlags);
if (pkg == null) {
mLastScanError = pp.getParseError();
return null;
}
PackageSetting ps;
PackageSetting updatedPkg;
synchronized (mPackages) {
ps = mSettings.peekPackageLP(pkg.packageName,
scanFile.toString());
updatedPkg = mSettings.mDisabledSysPackages.get(pkg.packageName);
}
if (updatedPkg != null) {
// An updated system app will not have the PARSE_IS_SYSTEM flag set initially
parseFlags |= PackageParser.PARSE_IS_SYSTEM;
}
if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
// Check for updated system applications here
if ((updatedPkg != null) && (ps == null)) {
// The system package has been updated and the code path does not match
// Ignore entry. Just return
Log.w(TAG, "Package:" + pkg.packageName +
" has been updated. Ignoring the one from path:"+scanFile);
mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
return null;
}
}
if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) {
Log.i(TAG, "Failed verifying certificates for package:" + pkg.packageName);
return null;
}
// The apk is forward locked (not public) if its code and resources
// are kept in different files.
if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
scanMode |= SCAN_FORWARD_LOCKED;
}
// Note that we invoke the following method only if we are about to unpack an application
return scanPackageLI(scanFile, destCodeFile, destResourceFile,
pkg, parseFlags, scanMode | SCAN_UPDATE_SIGNATURE);
| private PackageParser.Package | scanPackageLI(java.io.File scanFile, java.io.File destCodeFile, java.io.File destResourceFile, PackageParser.Package pkg, int parseFlags, int scanMode)
mScanningPath = scanFile;
if (pkg == null) {
mLastScanError = PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
return null;
}
final String pkgName = pkg.applicationInfo.packageName;
if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
}
if (pkgName.equals("android")) {
synchronized (mPackages) {
if (mAndroidApplication != null) {
Log.w(TAG, "*************************************************");
Log.w(TAG, "Core android package being redefined. Skipping.");
Log.w(TAG, " file=" + mScanningPath);
Log.w(TAG, "*************************************************");
mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
return null;
}
// Set up information for our fall-back user intent resolution
// activity.
mPlatformPackage = pkg;
pkg.mVersionCode = mSdkVersion;
mAndroidApplication = pkg.applicationInfo;
mResolveActivity.applicationInfo = mAndroidApplication;
mResolveActivity.name = ResolverActivity.class.getName();
mResolveActivity.packageName = mAndroidApplication.packageName;
mResolveActivity.processName = mAndroidApplication.processName;
mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
mResolveActivity.theme = com.android.internal.R.style.Theme_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 ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGD) Log.d(
TAG, "Scanning package " + pkgName);
if (mPackages.containsKey(pkgName) || mSharedLibraries.containsKey(pkgName)) {
Log.w(TAG, "*************************************************");
Log.w(TAG, "Application package " + pkgName
+ " already installed. Skipping duplicate.");
Log.w(TAG, "*************************************************");
mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
return null;
}
SharedUserSetting suid = null;
PackageSetting pkgSetting = null;
boolean removeExisting = false;
synchronized (mPackages) {
// Check all shared libraries and map to their actual file path.
if (pkg.usesLibraryFiles != null) {
for (int i=0; i<pkg.usesLibraryFiles.length; i++) {
String file = mSharedLibraries.get(pkg.usesLibraryFiles[i]);
if (file == null) {
Log.e(TAG, "Package " + pkg.packageName
+ " requires unavailable shared library "
+ pkg.usesLibraryFiles[i] + "; ignoring!");
mLastScanError = PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
return null;
}
pkg.usesLibraryFiles[i] = file;
}
}
if (pkg.mSharedUserId != null) {
suid = mSettings.getSharedUserLP(pkg.mSharedUserId,
pkg.applicationInfo.flags, true);
if (suid == null) {
Log.w(TAG, "Creating application package " + pkgName
+ " for shared user failed");
mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
return null;
}
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGD) {
Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid="
+ suid.userId + "): packages=" + suid.packages);
}
}
// Just create the setting, don't add it yet
pkgSetting = mSettings.getPackageLP(pkg, suid, destCodeFile,
destResourceFile, pkg.applicationInfo.flags, true, false);
if (pkgSetting == null) {
Log.w(TAG, "Creating application package " + pkgName + " failed");
mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
return null;
}
if(mSettings.mDisabledSysPackages.get(pkg.packageName) != null) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
}
pkg.applicationInfo.uid = pkgSetting.userId;
pkg.mExtras = pkgSetting;
if (!verifySignaturesLP(pkgSetting, pkg, parseFlags,
(scanMode&SCAN_UPDATE_SIGNATURE) != 0)) {
if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) == 0) {
mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
return null;
}
// 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 (!pkgSetting.sharedUser.signatures.mergeSignatures(
pkg.mSignatures, false)) {
mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
return null;
}
}
removeExisting = true;
}
// 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 ((scanMode&SCAN_NEW_INSTALL) != 0) {
int N = pkg.providers.size();
int i;
for (i=0; i<N; i++) {
PackageParser.Provider p = pkg.providers.get(i);
String names[] = p.info.authority.split(";");
for (int j = 0; j < names.length; j++) {
if (mProviders.containsKey(names[j])) {
PackageParser.Provider other = mProviders.get(names[j]);
Log.w(TAG, "Can't install because provider name " + names[j] +
" (in package " + pkg.applicationInfo.packageName +
") is already used by "
+ ((other != null && other.component != null)
? other.component.getPackageName() : "?"));
mLastScanError = PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
return null;
}
}
}
}
}
if (removeExisting) {
if (mInstaller != null) {
int ret = mInstaller.remove(pkgName);
if (ret != 0) {
String msg = "System package " + pkg.packageName
+ " could not have data directory erased after signature change.";
reportSettingsProblem(Log.WARN, msg);
mLastScanError = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
return null;
}
}
Log.w(TAG, "System package " + pkg.packageName
+ " signature changed: existing data removed.");
mLastScanError = PackageManager.INSTALL_SUCCEEDED;
}
long scanFileTime = scanFile.lastModified();
final boolean forceDex = (scanMode&SCAN_FORCE_DEX) != 0;
final boolean scanFileNewer = forceDex || scanFileTime != pkgSetting.getTimeStamp();
pkg.applicationInfo.processName = fixProcessName(
pkg.applicationInfo.packageName,
pkg.applicationInfo.processName,
pkg.applicationInfo.uid);
pkg.applicationInfo.publicSourceDir = pkgSetting.resourcePathString;
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 = new File(mAppDataDir, pkgName);
if (dataPath.exists()) {
mOutPermissions[1] = 0;
FileUtils.getPermissions(dataPath.getPath(), mOutPermissions);
if (mOutPermissions[1] == pkg.applicationInfo.uid
|| !Process.supportsProcesses()) {
pkg.applicationInfo.dataDir = dataPath.getPath();
} else {
boolean recovered = false;
if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
// If this is a system app, we can at least delete its
// current data so the application will still work.
if (mInstaller != null) {
int ret = mInstaller.remove(pkgName);
if(ret >= 0) {
// Old data gone!
String msg = "System package " + pkg.packageName
+ " has changed from uid: "
+ mOutPermissions[1] + " to "
+ pkg.applicationInfo.uid + "; old data erased";
reportSettingsProblem(Log.WARN, msg);
recovered = true;
// And now re-install the app.
ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
pkg.applicationInfo.uid);
if (ret == -1) {
// Ack should not happen!
msg = "System package " + pkg.packageName
+ " could not have data directory re-created after delete.";
reportSettingsProblem(Log.WARN, msg);
mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
return null;
}
}
}
if (!recovered) {
mHasSystemUidErrors = true;
}
}
if (!recovered) {
pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
+ pkg.applicationInfo.uid + "/fs_"
+ mOutPermissions[1];
String msg = "Package " + pkg.packageName
+ " has mismatched uid: "
+ mOutPermissions[1] + " on disk, "
+ pkg.applicationInfo.uid + " in settings";
synchronized (mPackages) {
if (!mReportedUidError) {
mReportedUidError = true;
msg = msg + "; read messages:\n"
+ mSettings.getReadMessagesLP();
}
reportSettingsProblem(Log.ERROR, msg);
}
}
}
pkg.applicationInfo.dataDir = dataPath.getPath();
} else {
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGV)
Log.v(TAG, "Want this data dir: " + dataPath);
//invoke installer to do the actual installation
if (mInstaller != null) {
int ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
pkg.applicationInfo.uid);
if(ret < 0) {
// Error from installer
mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
return null;
}
} else {
dataPath.mkdirs();
if (dataPath.exists()) {
FileUtils.setPermissions(
dataPath.toString(),
FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
pkg.applicationInfo.uid, pkg.applicationInfo.uid);
}
}
if (dataPath.exists()) {
pkg.applicationInfo.dataDir = dataPath.getPath();
} else {
Log.w(TAG, "Unable to create data directory: " + dataPath);
pkg.applicationInfo.dataDir = null;
}
}
}
// Perform shared library installation and dex validation and
// optimization, if this is not a system app.
if (mInstaller != null) {
String path = scanFile.getPath();
if (scanFileNewer) {
Log.i(TAG, path + " changed; unpacking");
try {
cachePackageSharedLibsLI(pkg, dataPath, scanFile);
} catch (IOException e) {
Log.e(TAG, "Failure extracting shared libs", e);
if(mInstaller != null) {
mInstaller.remove(pkgName);
} else {
dataPath.delete();
}
mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
return null;
}
}
if ((scanMode&SCAN_NO_DEX) == 0
&& (pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
int ret = 0;
try {
if (forceDex || dalvik.system.DexFile.isDexOptNeeded(path)) {
ret = mInstaller.dexopt(path, pkg.applicationInfo.uid,
(scanMode&SCAN_FORWARD_LOCKED) == 0);
}
} catch (FileNotFoundException e) {
Log.w(TAG, "Apk not found for dexopt: " + path);
ret = -1;
} catch (IOException e) {
Log.w(TAG, "Exception reading apk: " + path, e);
ret = -1;
}
if (ret < 0) {
//error from installer
mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
return null;
}
}
}
if (mFactoryTest && pkg.requestedPermissions.contains(
android.Manifest.permission.FACTORY_TEST)) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
}
if ((scanMode&SCAN_MONITOR) != 0) {
pkg.mPath = destCodeFile.getAbsolutePath();
mAppDirs.put(pkg.mPath, pkg);
}
synchronized (mPackages) {
// We don't expect installation to fail beyond this point
// Add the new setting to mSettings
mSettings.insertPackageSettingLP(pkgSetting, pkg.packageName, suid);
// Add the new setting to mPackages
mPackages.put(pkg.applicationInfo.packageName, pkg);
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);
mProvidersByComponent.put(new ComponentName(p.info.packageName,
p.info.name), p);
p.syncable = p.info.isSyncable;
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 (!mProviders.containsKey(names[j])) {
mProviders.put(names[j], p);
if (p.info.authority == null) {
p.info.authority = names[j];
} else {
p.info.authority = p.info.authority + ";" + names[j];
}
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGD)
Log.d(TAG, "Registered content provider: " + names[j] +
", className = " + p.info.name +
", isSyncable = " + p.info.isSyncable);
} else {
PackageParser.Provider other = mProviders.get(names[j]);
Log.w(TAG, "Skipping provider name " + names[j] +
" (in package " + pkg.applicationInfo.packageName +
"): name already used by "
+ ((other != null && other.component != null)
? other.component.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 (Config.LOGD) 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 (Config.LOGD) 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 (Config.LOGD) 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 (Config.LOGD) 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 {
Log.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 (Config.LOGD) 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);
HashMap<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);
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.perm = p;
bp.uid = pkg.applicationInfo.uid;
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ");
}
r.append(p.info.name);
}
} else {
Log.w(TAG, "Permission " + p.info.name + " from package "
+ p.info.packageName + " ignored: base tree "
+ tree.name + " is from package "
+ tree.sourcePackage);
}
} else {
Log.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);
}
} else {
Log.w(TAG, "Permission " + p.info.name + " from package "
+ p.info.packageName + " ignored: no group "
+ p.group);
}
}
if (r != null) {
if (Config.LOGD) 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.dataDir = pkg.applicationInfo.dataDir;
mInstrumentation.put(a.component, 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 (Config.LOGD) Log.d(TAG, " Instrumentation: " + r);
}
pkgSetting.setTimeStamp(scanFileTime);
}
return pkg;
| private static final void | sendPackageBroadcast(java.lang.String action, java.lang.String pkg, android.os.Bundle extras)
IActivityManager am = ActivityManagerNative.getDefault();
if (am != null) {
try {
final Intent intent = new Intent(action,
pkg != null ? Uri.fromParts("package", pkg, null) : null);
if (extras != null) {
intent.putExtras(extras);
}
am.broadcastIntent(
null, intent,
null, null, 0, null, null, null, false, false);
} catch (RemoteException ex) {
}
}
| public void | setApplicationEnabledSetting(java.lang.String appPackageName, int newState, int flags)
setEnabledSetting(appPackageName, null, newState, flags);
| public void | setComponentEnabledSetting(android.content.ComponentName componentName, int newState, int flags)
setEnabledSetting(componentName.getPackageName(),
componentName.getClassName(), newState, flags);
| private void | setEnabledSetting(java.lang.String packageNameStr, java.lang.String classNameStr, int newState, int flags)
if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
|| newState == COMPONENT_ENABLED_STATE_ENABLED
|| newState == COMPONENT_ENABLED_STATE_DISABLED)) {
throw new IllegalArgumentException("Invalid new component state: "
+ newState);
}
PackageSetting pkgSetting;
final int uid = Binder.getCallingUid();
final int permission = mContext.checkCallingPermission(
android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
int packageUid = -1;
synchronized (mPackages) {
pkgSetting = mSettings.mPackages.get(packageNameStr);
if (pkgSetting == null) {
if (classNameStr == null) {
throw new IllegalArgumentException(
"Unknown package: " + packageNameStr);
}
throw new IllegalArgumentException(
"Unknown component: " + packageNameStr
+ "/" + classNameStr);
}
if (!allowedByPermission && (uid != pkgSetting.userId)) {
throw new SecurityException(
"Permission Denial: attempt to change component state from pid="
+ Binder.getCallingPid()
+ ", uid=" + uid + ", package uid=" + pkgSetting.userId);
}
packageUid = pkgSetting.userId;
if (classNameStr == null) {
// We're dealing with an application/package level state change
pkgSetting.enabled = newState;
} else {
// We're dealing with a component level state change
switch (newState) {
case COMPONENT_ENABLED_STATE_ENABLED:
pkgSetting.enableComponentLP(classNameStr);
break;
case COMPONENT_ENABLED_STATE_DISABLED:
pkgSetting.disableComponentLP(classNameStr);
break;
case COMPONENT_ENABLED_STATE_DEFAULT:
pkgSetting.restoreComponentLP(classNameStr);
break;
default:
Log.e(TAG, "Invalid new component state: " + newState);
}
}
mSettings.writeLP();
}
long callingId = Binder.clearCallingIdentity();
try {
Bundle extras = new Bundle(2);
extras.putBoolean(Intent.EXTRA_DONT_KILL_APP,
(flags&PackageManager.DONT_KILL_APP) != 0);
extras.putInt(Intent.EXTRA_UID, packageUid);
sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageNameStr, extras);
} finally {
Binder.restoreCallingIdentity(callingId);
}
| private int | setPermissionsLI(java.lang.String pkgName, PackageParser.Package newPackage, java.lang.String destFilePath, java.io.File destResourceFile, boolean forwardLocked)
int retCode;
if (forwardLocked) {
try {
extractPublicFiles(newPackage, destResourceFile);
} catch (IOException e) {
Log.e(TAG, "Couldn't create a new zip file for the public parts of a" +
" forward-locked app.");
return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
} finally {
//TODO clean up the extracted public files
}
if (mInstaller != null) {
retCode = mInstaller.setForwardLockPerm(pkgName,
newPackage.applicationInfo.uid);
} else {
final int filePermissions =
FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP;
retCode = FileUtils.setPermissions(destFilePath, filePermissions, -1,
newPackage.applicationInfo.uid);
}
} else {
final int filePermissions =
FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP
|FileUtils.S_IROTH;
retCode = FileUtils.setPermissions(destFilePath, filePermissions, -1, -1);
}
if (retCode != 0) {
Log.e(TAG, "Couldn't set new package file permissions for " + destFilePath
+ ". The return code was: " + retCode);
}
return PackageManager.INSTALL_SUCCEEDED;
| 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;
| public void | systemReady()
mSystemReady = true;
| private void | updatePermissionsLP()
// Make sure there are no dangling permission trees.
Iterator<BasePermission> it = mSettings.mPermissionTrees
.values().iterator();
while (it.hasNext()) {
BasePermission bp = it.next();
if (bp.perm == null) {
Log.w(TAG, "Removing dangling permission tree: " + bp.name
+ " from package " + bp.sourcePackage);
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()) {
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.perm == null && bp.pendingInfo != null) {
BasePermission tree = findPermissionTreeLP(bp.name);
if (tree != null) {
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.perm == null) {
Log.w(TAG, "Removing dangling permission: " + bp.name
+ " from package " + bp.sourcePackage);
it.remove();
}
}
// Now update the permissions for all packages, in particular
// replace the granted permissions of the system packages.
for (PackageParser.Package pkg : mPackages.values()) {
grantPermissionsLP(pkg, false);
}
| private void | updatePreferredIndicesLP()
final ArrayList<PackageSetting> pkgs
= mSettings.mPreferredPackages;
final int N = pkgs.size();
for (int i=0; i<N; i++) {
pkgs.get(i).pkg.mPreferredOrder = N - i;
}
| private void | updateSettingsLI(java.lang.String pkgName, java.io.File tmpPackageFile, java.lang.String destFilePath, java.io.File destPackageFile, java.io.File destResourceFile, PackageParser.Package pkg, PackageParser.Package newPackage, boolean replacingExistingPackage, boolean forwardLocked, com.android.server.PackageManagerService$PackageInstalledInfo res)
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, PKG_INSTALL_INCOMPLETE);
mSettings.writeLP();
}
int retCode = 0;
if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
retCode = mInstaller.movedex(tmpPackageFile.toString(),
destPackageFile.toString());
if (retCode != 0) {
Log.e(TAG, "Couldn't rename dex file: " + destPackageFile);
res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
return;
}
}
// XXX There are probably some big issues here: upon doing
// the rename, we have reached the point of no return (the
// original .apk is gone!), so we can't fail. Yet... we can.
if (!tmpPackageFile.renameTo(destPackageFile)) {
Log.e(TAG, "Couldn't move package file to: " + destPackageFile);
res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
} else {
res.returnCode = setPermissionsLI(pkgName, newPackage, destFilePath,
destResourceFile,
forwardLocked);
if(res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
return;
} else {
Log.d(TAG, "New package installed in " + destPackageFile);
}
}
if(res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
if (mInstaller != null) {
mInstaller.rmdex(tmpPackageFile.getPath());
}
}
synchronized (mPackages) {
grantPermissionsLP(newPackage, true);
res.name = pkgName;
res.uid = newPackage.applicationInfo.uid;
res.pkg = newPackage;
mSettings.setInstallStatus(pkgName, PKG_INSTALL_COMPLETE);
res.returnCode = PackageManager.INSTALL_SUCCEEDED;
//to update install status
mSettings.writeLP();
}
| private boolean | verifySignaturesLP(com.android.server.PackageManagerService$PackageSetting pkgSetting, PackageParser.Package pkg, int parseFlags, boolean updateSignature)
if (pkg.mSignatures != null) {
if (!pkgSetting.signatures.updateSignatures(pkg.mSignatures,
updateSignature)) {
Log.e(TAG, "Package " + pkg.packageName
+ " signatures do not match the previously installed version; ignoring!");
mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
return false;
}
if (pkgSetting.sharedUser != null) {
if (!pkgSetting.sharedUser.signatures.mergeSignatures(
pkg.mSignatures, updateSignature)) {
Log.e(TAG, "Package " + pkg.packageName
+ " has no signatures that match those in shared user "
+ pkgSetting.sharedUser.name + "; ignoring!");
mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
return false;
}
}
} else {
pkg.mSignatures = pkgSetting.signatures.mSignatures;
}
return true;
|
|