From d2509fd83597595914ef0627685e917380863eb6 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Mon, 12 Sep 2011 12:29:43 -0700 Subject: [PATCH] Add boot mode where only "core apps" are started. A core app is one that has coreApp="true" in its manifest tag. The system can successfully boot (though a little painfully) with only framework-res.apk, SettingsProvider.apk, SystemUI.apk, DefaultContainerService.apk, and Launcher2.apk set as core apps. Currently this boot mode is always turned off. Change-Id: Ieaa4a8031c2c391a12996aa8d8b1d65fc2b09d6b --- .../android/content/pm/PackageParser.java | 35 +++++++--- core/res/AndroidManifest.xml | 2 +- .../AndroidManifest.xml | 2 +- packages/SettingsProvider/AndroidManifest.xml | 1 + packages/SystemUI/AndroidManifest.xml | 1 + .../java/com/android/server/SystemServer.java | 3 +- .../server/pm/PackageManagerService.java | 67 +++++++++++-------- 7 files changed, 71 insertions(+), 40 deletions(-) diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index c61e32fc9c154..e7b844c4808ba 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -92,6 +92,7 @@ public class PackageParser { private String mArchiveSourcePath; private String[] mSeparateProcesses; + private boolean mOnlyCoreApps; private static final int SDK_VERSION = Build.VERSION.SDK_INT; private static final String SDK_CODENAME = "REL".equals(Build.VERSION.CODENAME) ? null : Build.VERSION.CODENAME; @@ -180,6 +181,10 @@ public class PackageParser { mSeparateProcesses = procs; } + public void setOnlyCoreApps(boolean onlyCoreApps) { + mOnlyCoreApps = onlyCoreApps; + } + private static final boolean isPackageFilename(String name) { return name.endsWith(".apk"); } @@ -433,18 +438,22 @@ public class PackageParser { if (pkg == null) { - if (errorException != null) { - Slog.w(TAG, mArchiveSourcePath, errorException); - } else { - Slog.w(TAG, mArchiveSourcePath + " (at " - + parser.getPositionDescription() - + "): " + errorText[0]); + // If we are only parsing core apps, then a null with INSTALL_SUCCEEDED + // just means to skip this app so don't make a fuss about it. + if (!mOnlyCoreApps || mParseError != PackageManager.INSTALL_SUCCEEDED) { + if (errorException != null) { + Slog.w(TAG, mArchiveSourcePath, errorException); + } else { + Slog.w(TAG, mArchiveSourcePath + " (at " + + parser.getPositionDescription() + + "): " + errorText[0]); + } + if (mParseError == PackageManager.INSTALL_SUCCEEDED) { + mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; + } } parser.close(); assmgr.close(); - if (mParseError == PackageManager.INSTALL_SUCCEEDED) { - mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; - } return null; } @@ -782,6 +791,14 @@ public class PackageParser { } int type; + if (mOnlyCoreApps) { + boolean core = attrs.getAttributeBooleanValue(null, "coreApp", false); + if (!core) { + mParseError = PackageManager.INSTALL_SUCCEEDED; + return null; + } + } + final Package pkg = new Package(pkgName); boolean foundApp = false; diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 72863a2c32cc8..9f2eef553eba4 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -18,7 +18,7 @@ */ --> diff --git a/packages/DefaultContainerService/AndroidManifest.xml b/packages/DefaultContainerService/AndroidManifest.xml index 0f47482e7e221..319eb8d5b6b75 100755 --- a/packages/DefaultContainerService/AndroidManifest.xml +++ b/packages/DefaultContainerService/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="com.android.defcontainer" coreApp="true"> diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml index dd0d064ceeef3..07194266017b2 100644 --- a/packages/SettingsProvider/AndroidManifest.xml +++ b/packages/SettingsProvider/AndroidManifest.xml @@ -1,5 +1,6 @@ diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 2714fc55377a3..7e28c4f1b26a5 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -148,7 +148,8 @@ class ServerThread extends Thread { Slog.i(TAG, "Package Manager"); pm = PackageManagerService.main(context, - factoryTest != SystemServer.FACTORY_TEST_OFF); + factoryTest != SystemServer.FACTORY_TEST_OFF, + false); ActivityManagerService.setSystemProcess(); diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index bfb244b931207..4e5ca8e886f6d 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -221,6 +221,7 @@ public class PackageManagerService extends IPackageManager.Stub { final Context mContext; final boolean mFactoryTest; + final boolean mOnlyCore; final boolean mNoDexOpt; final DisplayMetrics mMetrics; final int mDefParseFlags; @@ -809,8 +810,9 @@ public class PackageManagerService extends IPackageManager.Stub { return false; } - public static final IPackageManager main(Context context, boolean factoryTest) { - PackageManagerService m = new PackageManagerService(context, factoryTest); + public static final IPackageManager main(Context context, boolean factoryTest, + boolean onlyCore) { + PackageManagerService m = new PackageManagerService(context, factoryTest, onlyCore); ServiceManager.addService("package", m); return m; } @@ -837,7 +839,7 @@ public class PackageManagerService extends IPackageManager.Stub { return res; } - public PackageManagerService(Context context, boolean factoryTest) { + public PackageManagerService(Context context, boolean factoryTest, boolean onlyCore) { EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, SystemClock.uptimeMillis()); @@ -847,6 +849,7 @@ public class PackageManagerService extends IPackageManager.Stub { mContext = context; mFactoryTest = factoryTest; + mOnlyCore = onlyCore; mNoDexOpt = "eng".equals(SystemProperties.get("ro.build.type")); mMetrics = new DisplayMetrics(); mSettings = new Settings(); @@ -1051,18 +1054,20 @@ public class PackageManagerService extends IPackageManager.Stub { mInstaller.moveFiles(); // Prune any system packages that no longer exist. - Iterator psit = mSettings.mPackages.values().iterator(); - while (psit.hasNext()) { - PackageSetting ps = psit.next(); - if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0 - && !mPackages.containsKey(ps.name) - && !mSettings.mDisabledSysPackages.containsKey(ps.name)) { - psit.remove(); - String msg = "System package " + ps.name - + " no longer exists; wiping its data"; - reportSettingsProblem(Log.WARN, msg); - mInstaller.remove(ps.name, 0); - mUserManager.removePackageForAllUsers(ps.name); + if (!mOnlyCore) { + Iterator psit = mSettings.mPackages.values().iterator(); + while (psit.hasNext()) { + PackageSetting ps = psit.next(); + if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0 + && !mPackages.containsKey(ps.name) + && !mSettings.mDisabledSysPackages.containsKey(ps.name)) { + psit.remove(); + String msg = "System package " + ps.name + + " no longer exists; wiping its data"; + reportSettingsProblem(Log.WARN, msg); + mInstaller.remove(ps.name, 0); + mUserManager.removePackageForAllUsers(ps.name); + } } } @@ -1077,18 +1082,23 @@ public class PackageManagerService extends IPackageManager.Stub { //delete tmp files deleteTempPackageFiles(); - EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, - SystemClock.uptimeMillis()); - mAppInstallObserver = new AppDirObserver( - mAppInstallDir.getPath(), OBSERVER_EVENTS, false); - mAppInstallObserver.startWatching(); - scanDirLI(mAppInstallDir, 0, scanMode, 0); - - mDrmAppInstallObserver = new AppDirObserver( - mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false); - mDrmAppInstallObserver.startWatching(); - scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, - scanMode, 0); + if (!mOnlyCore) { + EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, + SystemClock.uptimeMillis()); + mAppInstallObserver = new AppDirObserver( + mAppInstallDir.getPath(), OBSERVER_EVENTS, false); + mAppInstallObserver.startWatching(); + scanDirLI(mAppInstallDir, 0, scanMode, 0); + + mDrmAppInstallObserver = new AppDirObserver( + mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false); + mDrmAppInstallObserver.startWatching(); + scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, + scanMode, 0); + } else { + mAppInstallObserver = null; + mDrmAppInstallObserver = null; + } EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, SystemClock.uptimeMillis()); @@ -2749,6 +2759,7 @@ public class PackageManagerService extends IPackageManager.Stub { parseFlags |= mDefParseFlags; PackageParser pp = new PackageParser(scanPath); pp.setSeparateProcesses(mSeparateProcesses); + pp.setOnlyCoreApps(mOnlyCore); final PackageParser.Package pkg = pp.parsePackage(scanFile, scanPath, mMetrics, parseFlags); if (pkg == null) { @@ -4044,7 +4055,7 @@ public class PackageManagerService extends IPackageManager.Stub { + " info=" + bp.pendingInfo); if (bp.packageSetting == null && bp.pendingInfo != null) { final BasePermission tree = findPermissionTreeLP(bp.name); - if (tree != null) { + if (tree != null && tree.perm != null) { bp.packageSetting = tree.packageSetting; bp.perm = new PackageParser.Permission(tree.perm.owner, new PermissionInfo(bp.pendingInfo));