summaryrefslogtreecommitdiffstats
path: root/services/java/com/android/server/pm/PackageManagerService.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/java/com/android/server/pm/PackageManagerService.java')
-rw-r--r--services/java/com/android/server/pm/PackageManagerService.java206
1 files changed, 187 insertions, 19 deletions
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 83672c5..0cbfa6f 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006 The Android Open Source Project
+ * This code has been modified. Portions copyright (C) 2010, T-Mobile USA, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,6 +32,7 @@ import static libcore.io.OsConstants.S_IXGRP;
import static libcore.io.OsConstants.S_IROTH;
import static libcore.io.OsConstants.S_IXOTH;
+import com.android.internal.app.IAssetRedirectionManager;
import com.android.internal.app.IMediaContainerService;
import com.android.internal.app.ResolverActivity;
import com.android.internal.content.NativeLibraryHelper;
@@ -143,6 +145,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
+import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -150,6 +153,9 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
import libcore.io.ErrnoException;
import libcore.io.IoUtils;
@@ -201,6 +207,8 @@ public class PackageManagerService extends IPackageManager.Stub {
// package apks to install directory.
private static final String INSTALL_PACKAGE_SUFFIX = "-";
+ private static final int THEME_MAMANER_GUID = 1300;
+
static final int SCAN_MONITOR = 1<<0;
static final int SCAN_NO_DEX = 1<<1;
static final int SCAN_FORCE_DEX = 1<<2;
@@ -407,6 +415,8 @@ public class PackageManagerService extends IPackageManager.Stub {
ComponentName mResolveComponentName;
PackageParser.Package mPlatformPackage;
+ IAssetRedirectionManager mAssetRedirectionManager;
+
// Set of pending broadcasts for aggregating enable/disable of components.
final HashMap<String, ArrayList<String>> mPendingBroadcasts
= new HashMap<String, ArrayList<String>>();
@@ -706,7 +716,7 @@ public class PackageManagerService extends IPackageManager.Stub {
PackageInstalledInfo res = data.res;
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
- res.removedInfo.sendBroadcast(false, true, false);
+ res.removedInfo.sendBroadcast(false, true, false, false);
Bundle extras = new Bundle(1);
extras.putInt(Intent.EXTRA_UID, res.uid);
// Determine the set of users who are adding this
@@ -743,21 +753,25 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
- res.pkg.applicationInfo.packageName,
+ res.pkg.applicationInfo.packageName, null,
extras, null, null, firstUsers);
final boolean update = res.removedInfo.removedPackage != null;
if (update) {
extras.putBoolean(Intent.EXTRA_REPLACING, true);
}
+ String category = null;
+ if(res.pkg.mIsThemeApk) {
+ category = Intent.CATEGORY_THEME_PACKAGE_INSTALLED_STATE_CHANGE;
+ }
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
- res.pkg.applicationInfo.packageName,
+ res.pkg.applicationInfo.packageName, category,
extras, null, null, updateUsers);
if (update) {
sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
- res.pkg.applicationInfo.packageName,
+ res.pkg.applicationInfo.packageName, category,
extras, null, null, updateUsers);
sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
- null, null,
+ null, null, null,
res.pkg.applicationInfo.packageName, null, updateUsers);
}
if (res.removedInfo.args != null) {
@@ -975,6 +989,7 @@ public class PackageManagerService extends IPackageManager.Stub {
Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM);
mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, ApplicationInfo.FLAG_SYSTEM);
mSettings.addSharedUserLPw("android.uid.log", LOG_UID, ApplicationInfo.FLAG_SYSTEM);
+ mSettings.addSharedUserLPw("com.tmobile.thememanager", THEME_MAMANER_GUID, ApplicationInfo.FLAG_SYSTEM);
mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, ApplicationInfo.FLAG_SYSTEM);
mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, ApplicationInfo.FLAG_SYSTEM);
@@ -2938,6 +2953,20 @@ public class PackageManagerService extends IPackageManager.Stub {
return list;
}
+ public List<PackageInfo> getInstalledThemePackages() {
+ // Returns a list of theme APKs.
+ ArrayList<PackageInfo> finalList = new ArrayList<PackageInfo>();
+ List<PackageInfo> installedPackagesList = mContext.getPackageManager().getInstalledPackages(0);
+ Iterator<PackageInfo> i = installedPackagesList.iterator();
+ while (i.hasNext()) {
+ final PackageInfo pi = i.next();
+ if (pi != null && pi.isThemeApk) {
+ finalList.add(pi);
+ }
+ }
+ return finalList;
+ }
+
@Override
public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags,
String lastRead, int userId) {
@@ -4495,6 +4524,32 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ // NOTE: this method can return null if the SystemServer is still
+ // initializing
+ public IAssetRedirectionManager getAssetRedirectionManager() {
+ if (mAssetRedirectionManager != null) {
+ return mAssetRedirectionManager;
+ }
+ IBinder b = ServiceManager.getService("assetredirection");
+ mAssetRedirectionManager = IAssetRedirectionManager.Stub.asInterface(b);
+ return mAssetRedirectionManager;
+ }
+
+ private void cleanAssetRedirections(PackageParser.Package pkg) {
+ IAssetRedirectionManager rm = getAssetRedirectionManager();
+ if (rm == null) {
+ return;
+ }
+ try {
+ if (pkg.mIsThemeApk) {
+ rm.clearRedirectionMapsByTheme(pkg.packageName, null);
+ } else {
+ rm.clearPackageRedirectionMap(pkg.packageName);
+ }
+ } catch (RemoteException e) {
+ }
+ }
+
void removePackageLI(PackageSetting ps, boolean chatty) {
if (DEBUG_INSTALL) {
if (chatty)
@@ -4523,6 +4578,8 @@ public class PackageManagerService extends IPackageManager.Stub {
// writer
synchronized (mPackages) {
+ cleanAssetRedirections(pkg);
+
mPackages.remove(pkg.applicationInfo.packageName);
if (pkg.mPath != null) {
mAppDirs.remove(pkg.mPath);
@@ -5367,7 +5424,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
};
- static final void sendPackageBroadcast(String action, String pkg,
+ static final void sendPackageBroadcast(String action, String pkg, String intentCategory,
Bundle extras, String targetPkg, IIntentReceiver finishedReceiver,
int[] userIds) {
IActivityManager am = ActivityManagerNative.getDefault();
@@ -5400,6 +5457,9 @@ public class PackageManagerService extends IPackageManager.Stub {
+ intent.toShortString(false, true, false, false)
+ " " + intent.getExtras(), here);
}
+ if (intentCategory != null) {
+ intent.addCategory(intentCategory);
+ }
am.broadcastIntent(null, intent, null, finishedReceiver,
0, null, null, null, finishedReceiver != null, false, id);
}
@@ -5483,6 +5543,7 @@ public class PackageManagerService extends IPackageManager.Stub {
String addedPackage = null;
int addedAppId = -1;
int[] addedUsers = null;
+ String category = null;
// TODO post a message to the handler to obtain serial ordering
synchronized (mInstallLock) {
@@ -5513,6 +5574,9 @@ public class PackageManagerService extends IPackageManager.Stub {
synchronized (mPackages) {
p = mAppDirs.get(fullPathStr);
if (p != null) {
+ if (p.mIsThemeApk) {
+ category = Intent.CATEGORY_THEME_PACKAGE_INSTALLED_STATE_CHANGE;
+ }
ps = mSettings.mPackages.get(p.applicationInfo.packageName);
if (ps != null) {
removedUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
@@ -5554,6 +5618,9 @@ public class PackageManagerService extends IPackageManager.Stub {
addedAppId = UserHandle.getAppId(p.applicationInfo.uid);
}
}
+ if (p != null && p.mIsThemeApk) {
+ category = Intent.CATEGORY_THEME_PACKAGE_INSTALLED_STATE_CHANGE;
+ }
}
// reader
@@ -5566,13 +5633,13 @@ public class PackageManagerService extends IPackageManager.Stub {
Bundle extras = new Bundle(1);
extras.putInt(Intent.EXTRA_UID, removedAppId);
extras.putBoolean(Intent.EXTRA_DATA_REMOVED, false);
- sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, category,
extras, null, null, removedUsers);
}
if (addedPackage != null) {
Bundle extras = new Bundle(1);
extras.putInt(Intent.EXTRA_UID, addedAppId);
- sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage,
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage, category,
extras, null, null, addedUsers);
}
}
@@ -5669,7 +5736,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
if (sendAdded) {
- sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, null,
packageName, extras, null, null, new int[] {userId});
}
} finally {
@@ -7791,6 +7858,24 @@ public class PackageManagerService extends IPackageManager.Stub {
Log.d(TAG, "New package installed in " + newPackage.mPath);
+ cleanAssetRedirections(newPackage);
+
+ if (newPackage.mIsThemeApk) {
+ /* DBS-TODO
+ boolean isThemePackageDrmProtected = false;
+ int N = newPackage.mThemeInfos.size();
+ for (int i = 0; i < N; i++) {
+ if (newPackage.mThemeInfos.get(i).isDrmProtected) {
+ isThemePackageDrmProtected = true;
+ break;
+ }
+ }
+ if (isThemePackageDrmProtected) {
+ splitThemePackage(newPackage.mPath);
+ }
+ */
+ }
+
synchronized (mPackages) {
updatePermissionsLPw(newPackage.packageName, newPackage,
UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
@@ -7806,6 +7891,65 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ private void deleteLockedZipFileIfExists(String originalPackagePath) {
+ String lockedZipFilePath = PackageParser.getLockedZipFilePath(originalPackagePath);
+ File zipFile = new File(lockedZipFilePath);
+ if (zipFile.exists() && zipFile.isFile()) {
+ if (!zipFile.delete()) {
+ Log.w(TAG, "Couldn't delete locked zip file: " + originalPackagePath);
+ }
+ }
+ }
+ private void splitThemePackage(File originalFile) {
+ final String originalPackagePath = originalFile.getPath();
+ final String lockedZipFilePath = PackageParser.getLockedZipFilePath(originalPackagePath);
+
+ try {
+ final List<String> drmProtectedEntries = new ArrayList<String>();
+ final ZipFile privateZip = new ZipFile(originalFile.getPath());
+
+ final Enumeration<? extends ZipEntry> privateZipEntries = privateZip.entries();
+ while (privateZipEntries.hasMoreElements()) {
+ final ZipEntry zipEntry = privateZipEntries.nextElement();
+ final String zipEntryName = zipEntry.getName();
+ if (zipEntryName.startsWith("assets/") && zipEntryName.contains("/locked/")) {
+ drmProtectedEntries.add(zipEntryName);
+ }
+ }
+ privateZip.close();
+
+ String [] args = new String[0];
+ args = drmProtectedEntries.toArray(args);
+ int code = mContext.getAssets().splitDrmProtectedThemePackage(
+ originalPackagePath,
+ lockedZipFilePath,
+ args);
+ if (code != 0) {
+ Log.e("PackageManagerService",
+ "splitDrmProtectedThemePackage returned = " + code);
+ }
+ code = FileUtils.setPermissions(
+ lockedZipFilePath,
+ 0640,
+ -1,
+ THEME_MAMANER_GUID);
+ if (code != 0) {
+ Log.e("PackageManagerService",
+ "Set permissions for " + lockedZipFilePath + " returned = " + code);
+ }
+ code = FileUtils.setPermissions(
+ originalPackagePath,
+ 0644,
+ -1, -1);
+ if (code != 0) {
+ Log.e("PackageManagerService",
+ "Set permissions for " + originalPackagePath + " returned = " + code);
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Failure to generate new zip files for theme");
+ }
+ }
+
private void installPackageLI(InstallArgs args,
boolean newInstall, PackageInstalledInfo res) {
int pFlags = args.flags;
@@ -8066,6 +8210,18 @@ public class PackageManagerService extends IPackageManager.Stub {
boolean removedForAllUsers = false;
boolean systemUpdate = false;
+
+ synchronized (mPackages) {
+ PackageParser.Package p = mPackages.get(packageName);
+ if (p != null) {
+ info.isThemeApk = p.mIsThemeApk;
+ if (info.isThemeApk &&
+ !info.isRemovedPackageSystemUpdate) {
+ deleteLockedZipFileIfExists(p.mPath);
+ }
+ }
+ }
+
synchronized (mInstallLock) {
res = deletePackageLI(packageName,
(flags & PackageManager.DELETE_ALL_USERS) != 0
@@ -8078,7 +8234,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
if (res) {
- info.sendBroadcast(true, systemUpdate, removedForAllUsers);
+ info.sendBroadcast(true, systemUpdate, removedForAllUsers, true);
// If the removed package was a system update, the old system package
// was re-enabled; we need to broadcast this information
@@ -8088,11 +8244,16 @@ public class PackageManagerService extends IPackageManager.Stub {
? info.removedAppId : info.uid);
extras.putBoolean(Intent.EXTRA_REPLACING, true);
- sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
+ String category = null;
+ if (info.isThemeApk) {
+ category = Intent.CATEGORY_THEME_PACKAGE_INSTALLED_STATE_CHANGE;
+ }
+
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, category,
extras, null, null, null);
- sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName, category,
extras, null, null, null);
- sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
+ sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, null,
null, packageName, null, null);
}
}
@@ -8117,8 +8278,10 @@ public class PackageManagerService extends IPackageManager.Stub {
boolean isRemovedPackageSystemUpdate = false;
// Clean up resources deleted packages.
InstallArgs args = null;
+ boolean isThemeApk = false;
- void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) {
+ void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers,
+ boolean deleteLockedZipFileIfExists) {
Bundle extras = new Bundle(1);
extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
@@ -8127,15 +8290,19 @@ public class PackageManagerService extends IPackageManager.Stub {
}
extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
if (removedPackage != null) {
- sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
+ String category = null;
+ if (isThemeApk) {
+ category = Intent.CATEGORY_THEME_PACKAGE_INSTALLED_STATE_CHANGE;
+ }
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, category,
extras, null, null, removedUsers);
if (fullRemove && !replacing) {
- sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage, category,
extras, null, null, removedUsers);
}
}
if (removedAppId >= 0) {
- sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null,
+ sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, null, extras, null, null,
removedUsers);
}
}
@@ -8714,6 +8881,7 @@ public class PackageManagerService extends IPackageManager.Stub {
"replacePreferredActivity expects filter to have no data authorities, " +
"paths, schemes or types.");
}
+
synchronized (mPackages) {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
@@ -8989,7 +9157,7 @@ public class PackageManagerService extends IPackageManager.Stub {
extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
extras.putInt(Intent.EXTRA_UID, packageUid);
- sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null,
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, null, extras, null, null,
new int[] {UserHandle.getUserId(packageUid)});
}
@@ -9654,7 +9822,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
: Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
- sendPackageBroadcast(action, null, extras, null, finishedReceiver, null);
+ sendPackageBroadcast(action, null, null, extras, null, finishedReceiver, null);
}
}