diff options
-rw-r--r-- | api/current.xml | 65 | ||||
-rw-r--r-- | core/java/android/app/ActivityThread.java | 6 | ||||
-rw-r--r-- | core/java/android/app/ApplicationContext.java | 8 | ||||
-rw-r--r-- | core/java/android/content/Context.java | 4 | ||||
-rw-r--r-- | core/java/android/content/ContextWrapper.java | 6 | ||||
-rw-r--r-- | core/java/android/content/pm/ApplicationInfo.java | 19 | ||||
-rw-r--r-- | core/java/android/content/pm/IPackageManager.aidl | 7 | ||||
-rw-r--r-- | core/java/android/content/pm/PackageManager.java | 6 | ||||
-rw-r--r-- | core/java/android/content/pm/PackageParser.java | 50 | ||||
-rw-r--r-- | core/java/android/content/res/CompatibilityInfo.java | 3 | ||||
-rw-r--r-- | services/java/com/android/server/PackageManagerService.java | 92 | ||||
-rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 62 | ||||
-rw-r--r-- | services/java/com/android/server/am/HistoryRecord.java | 6 | ||||
-rw-r--r-- | test-runner/android/test/mock/MockContext.java | 6 | ||||
-rw-r--r-- | tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java | 7 |
15 files changed, 263 insertions, 84 deletions
diff --git a/api/current.xml b/api/current.xml index 4efc71f..95c396f 100644 --- a/api/current.xml +++ b/api/current.xml @@ -27473,6 +27473,17 @@ visibility="public" > </method> +<method name="getApplicationInfo" + return="android.content.pm.ApplicationInfo" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="getAssets" return="android.content.res.AssetManager" abstract="true" @@ -28825,6 +28836,17 @@ visibility="public" > </method> +<method name="getApplicationInfo" + return="android.content.pm.ApplicationInfo" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="getAssets" return="android.content.res.AssetManager" abstract="false" @@ -35185,6 +35207,17 @@ visibility="public" > </field> +<field name="FLAG_SUPPORTS_LARGE_SCREENS" + type="int" + transient="false" + volatile="false" + value="512" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="FLAG_SYSTEM" type="int" transient="false" @@ -35258,16 +35291,6 @@ visibility="public" > </field> -<field name="expandable" - type="boolean" - transient="false" - volatile="false" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -</field> <field name="flags" type="int" transient="false" @@ -37127,17 +37150,6 @@ visibility="public" > </field> -<field name="GET_EXPANDABLE" - type="int" - transient="false" - volatile="false" - value="131072" - static="true" - final="true" - deprecated="not deprecated" - visibility="public" -> -</field> <field name="GET_GIDS" type="int" transient="false" @@ -114387,6 +114399,17 @@ visibility="public" > </method> +<method name="getApplicationInfo" + return="android.content.pm.ApplicationInfo" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="getAssets" return="android.content.res.AssetManager" abstract="false" diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 477badb..6873379 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -187,7 +187,7 @@ public final class ActivityThread { try { appInfo = getPackageManager().getApplicationInfo( pkgInfo.getPackageName(), - PackageManager.GET_SUPPORTS_DENSITIES | PackageManager.GET_EXPANDABLE); + PackageManager.GET_SUPPORTS_DENSITIES); } catch (RemoteException e) { throw new AssertionError(e); } @@ -287,6 +287,10 @@ public final class ActivityThread { return mPackageName; } + public ApplicationInfo getApplicationInfo() { + return mApplicationInfo; + } + public boolean isSecurityViolation() { return mSecurityViolation; } diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java index 23daf12..bbad8f4 100644 --- a/core/java/android/app/ApplicationContext.java +++ b/core/java/android/app/ApplicationContext.java @@ -283,6 +283,14 @@ class ApplicationContext extends Context { } @Override + public ApplicationInfo getApplicationInfo() { + if (mPackageInfo != null) { + return mPackageInfo.getApplicationInfo(); + } + throw new RuntimeException("Not supported in system context"); + } + + @Override public String getPackageResourcePath() { if (mPackageInfo != null) { return mPackageInfo.getResDir(); diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 925249e..b0396f6 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -16,6 +16,7 @@ package android.content; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.AssetManager; import android.content.res.Resources; @@ -233,6 +234,9 @@ public abstract class Context { /** Return the name of this application's package. */ public abstract String getPackageName(); + /** Return the full application info for this context's package. */ + public abstract ApplicationInfo getApplicationInfo(); + /** * {@hide} * Return the full path to this context's resource files. This is the ZIP files diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index 262204e..7513b3b 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -16,6 +16,7 @@ package android.content; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.AssetManager; import android.content.res.Resources; @@ -120,6 +121,11 @@ public class ContextWrapper extends Context { } @Override + public ApplicationInfo getApplicationInfo() { + return mBase.getApplicationInfo(); + } + + @Override public String getPackageResourcePath() { return mBase.getPackageResourcePath(); } diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index f10dd53..2a2cf93 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -137,6 +137,13 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { public static final int FLAG_TEST_ONLY = 1<<8; /** + * Value for {@link #flags}: true when the application's window can be + * expanded over default window size in target density (320x480 for + * 1.0 density, 480x720 for 1.5 density etc) + */ + public static final int FLAG_SUPPORTS_LARGE_SCREENS = 1<<9; + + /** * Value for {@link #flags}: this is false if the application has set * its android:allowBackup to false, true otherwise. * @@ -201,12 +208,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { public int[] supportsDensities; /** - * True when the application's window can be expanded over default window - * size in target density (320x480 for 1.0 density, 480x720 for 1.5 density etc) - */ - public boolean expandable = false; - - /** * The minimum SDK version this application targets. It may run on earilier * versions, but it knows how to work with any new behavior added at this * version. Will be {@link android.os.Build.VERSION_CODES#CUR_DEVELOPMENT} @@ -240,7 +241,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { pw.println(prefix + "manageSpaceActivityName="+manageSpaceActivityName); pw.println(prefix + "description=0x"+Integer.toHexString(descriptionRes)); pw.println(prefix + "supportsDensities=" + supportsDensities); - pw.println(prefix + "expandable=" + expandable); super.dumpBack(pw, prefix); } @@ -288,7 +288,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { manageSpaceActivityName = orig.manageSpaceActivityName; descriptionRes = orig.descriptionRes; supportsDensities = orig.supportsDensities; - expandable = orig.expandable; } @@ -321,7 +320,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { dest.writeString(backupAgentName); dest.writeInt(descriptionRes); dest.writeIntArray(supportsDensities); - dest.writeInt(expandable ? 1 : 0); } public static final Parcelable.Creator<ApplicationInfo> CREATOR @@ -353,7 +351,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { backupAgentName = source.readString(); descriptionRes = source.readInt(); supportsDensities = source.createIntArray(); - expandable = source.readInt() != 0; } /** @@ -383,7 +380,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { * @hide */ public void disableCompatibilityMode() { - expandable = true; + flags |= FLAG_SUPPORTS_LARGE_SCREENS; supportsDensities = ANY_DENSITIES_ARRAY; } } diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 5656b6b..b33a85b 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -301,4 +301,11 @@ interface IPackageManager { boolean isSafeMode(); void systemReady(); boolean hasSystemUidErrors(); + + /** + * Ask the package manager to perform dex-opt (if needed) on the given + * package, if it already hasn't done mode. Only does this if running + * in the special development "no pre-dexopt" mode. + */ + boolean performDexOpt(String packageName); } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index f746a40..e0cad39 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -181,12 +181,6 @@ public abstract class PackageManager { public static final int MATCH_DEFAULT_ONLY = 0x00010000; /** - * {@link ApplicationInfo} flag: return the - * {link ApplicationInfo#expandable} boolean flag of the package. - */ - public static final int GET_EXPANDABLE = 0x00020000; - - /** * Permission check result: this is returned by {@link #checkPermission} * if the permission has been granted to the given package. */ diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index ab8559c..ab9518e 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -777,7 +777,7 @@ public class PackageParser { targetCode = minCode = val.string.toString(); } else { // If it's not a string, it's an integer. - minVers = val.data; + targetVers = minVers = val.data; } } @@ -798,6 +798,25 @@ public class PackageParser { sa.recycle(); + if (minCode != null) { + if (!minCode.equals(mSdkCodename)) { + if (mSdkCodename != null) { + outError[0] = "Requires development platform " + minCode + + " (current platform is " + mSdkCodename + ")"; + } else { + outError[0] = "Requires development platform " + minCode + + " but this is a release platform."; + } + mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK; + return null; + } + } else if (minVers > mSdkVersion) { + outError[0] = "Requires newer sdk version #" + minVers + + " (current version is #" + mSdkVersion + ")"; + mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK; + return null; + } + if (targetCode != null) { if (!targetCode.equals(mSdkCodename)) { if (mSdkCodename != null) { @@ -817,13 +836,6 @@ public class PackageParser { pkg.applicationInfo.targetSdkVersion = targetVers; } - if (minVers > mSdkVersion) { - outError[0] = "Requires newer sdk version #" + minVers - + " (current version is #" + mSdkVersion + ")"; - mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK; - return null; - } - if (maxVers < mSdkVersion) { outError[0] = "Requires older sdk version #" + maxVers + " (current version is #" + mSdkVersion + ")"; @@ -865,7 +877,7 @@ public class PackageParser { XmlUtils.skipCurrentTag(parser); } else if (tagName.equals("expandable")) { - pkg.expandable = true; + pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS; XmlUtils.skipCurrentTag(parser); } else { Log.w(TAG, "Bad element under <manifest>: " @@ -2262,9 +2274,6 @@ public class PackageParser { public final ArrayList<Integer> supportsDensityList = new ArrayList<Integer>(); public int[] supportsDensities = null; - // If the application's window is expandable. - public boolean expandable; - // If this is a 3rd party app, this is the path of the zip file. public String mPath; @@ -2287,6 +2296,17 @@ public class PackageParser { // preferred up order. public int mPreferredOrder = 0; + // For use by package manager service to keep track of which apps + // have been installed with forward locking. + public boolean mForwardLocked; + + // For use by the package manager to keep track of the path to the + // file an app came from. + public String mScanPath; + + // For use by package manager to keep track of where it has done dexopt. + public boolean mDidDexOpt; + // Additional data supplied by callers. public Object mExtras; @@ -2439,9 +2459,6 @@ public class PackageParser { && p.supportsDensities != null) { return true; } - if ((flags & PackageManager.GET_EXPANDABLE) != 0) { - return true; - } return false; } @@ -2462,9 +2479,6 @@ public class PackageParser { if ((flags & PackageManager.GET_SUPPORTS_DENSITIES) != 0) { ai.supportsDensities = p.supportsDensities; } - if ((flags & PackageManager.GET_EXPANDABLE) != 0) { - ai.expandable = p.expandable; - } return ai; } diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java index 836de39..680fef8 100644 --- a/core/java/android/content/res/CompatibilityInfo.java +++ b/core/java/android/content/res/CompatibilityInfo.java @@ -69,7 +69,8 @@ public class CompatibilityInfo { public final boolean mScalingRequired; public CompatibilityInfo(ApplicationInfo appInfo) { - mExpandable = mConfiguredExpandable = appInfo.expandable; + mExpandable = mConfiguredExpandable = + (appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0; float packageDensityScale = -1.0f; if (appInfo.supportsDensities != null) { diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java index f51f3d0..f18d6e0 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -19,7 +19,6 @@ package com.android.server; import com.android.internal.app.ResolverActivity; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; -import com.android.server.PackageManagerService.PreferredActivity; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -30,7 +29,6 @@ import android.app.IActivityManager; import android.app.PendingIntent; import android.app.PendingIntent.CanceledException; import android.content.ComponentName; -import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -152,6 +150,7 @@ class PackageManagerService extends IPackageManager.Stub { final Context mContext; final boolean mFactoryTest; + final boolean mNoDexOpt; final DisplayMetrics mMetrics; final int mDefParseFlags; final String[] mSeparateProcesses; @@ -303,6 +302,7 @@ class PackageManagerService extends IPackageManager.Stub { mContext = context; mFactoryTest = factoryTest; + mNoDexOpt = "eng".equals(SystemProperties.get("ro.build.type")); mMetrics = new DisplayMetrics(); mSettings = new Settings(); mSettings.addSharedUserLP("android.uid.system", @@ -372,6 +372,10 @@ class PackageManagerService extends IPackageManager.Stub { startTime); int scanMode = SCAN_MONITOR; + if (mNoDexOpt) { + Log.w(TAG, "Running ENG build: no pre-dexopt!"); + scanMode |= SCAN_NO_DEX; + } final HashSet<String> libFiles = new HashSet<String>(); @@ -993,10 +997,11 @@ class PackageManagerService extends IPackageManager.Stub { if (Config.LOGV) Log.v(TAG, "getActivityInfo " + component + ": " + a); if (a != null && mSettings.isEnabledLP(a.info, flags)) { ActivityInfo ainfo = PackageParser.generateActivityInfo(a, flags); - if (ainfo != null && (flags & PackageManager.GET_EXPANDABLE) != 0) { + if (ainfo != null) { ApplicationInfo appInfo = getApplicationInfo(component.getPackageName(), - PackageManager.GET_EXPANDABLE | PackageManager.GET_SUPPORTS_DENSITIES); - if (appInfo != null && !appInfo.expandable) { + PackageManager.GET_SUPPORTS_DENSITIES); + if (appInfo != null && + (appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) == 0) { // Check if the screen size is same as what the application expect. CompatibilityInfo info = new CompatibilityInfo(appInfo); DisplayMetrics metrics = new DisplayMetrics(); @@ -1009,11 +1014,13 @@ class PackageManagerService extends IPackageManager.Stub { // Don't allow an app that cannot expand to handle rotation. ainfo.configChanges &= ~ ActivityInfo.CONFIG_ORIENTATION; } else { - appInfo.expandable = true; + appInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS; } if (DEBUG_SETTINGS) { Log.d(TAG, "component=" + component + - ", expandable:" + appInfo.expandable); + ", expandable:" + + ((appInfo.flags & + ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0)); } } } @@ -1943,7 +1950,56 @@ class PackageManagerService extends IPackageManager.Stub { } return true; } + + public boolean performDexOpt(String packageName) { + if (!mNoDexOpt) { + return false; + } + + PackageParser.Package p; + synchronized (mPackages) { + p = mPackages.get(packageName); + if (p == null || p.mDidDexOpt) { + return false; + } + } + synchronized (mInstallLock) { + return performDexOptLI(p, false) == DEX_OPT_PERFORMED; + } + } + + static final int DEX_OPT_SKIPPED = 0; + static final int DEX_OPT_PERFORMED = 1; + static final int DEX_OPT_FAILED = -1; + + private int performDexOptLI(PackageParser.Package pkg, boolean forceDex) { + boolean performed = false; + if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) { + String path = pkg.mScanPath; + int ret = 0; + try { + if (forceDex || dalvik.system.DexFile.isDexOptNeeded(path)) { + ret = mInstaller.dexopt(path, pkg.applicationInfo.uid, + !pkg.mForwardLocked); + pkg.mDidDexOpt = true; + performed = true; + } + } 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 + return DEX_OPT_FAILED; + } + } + return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED; + } + private PackageParser.Package scanPackageLI( File scanFile, File destCodeFile, File destResourceFile, PackageParser.Package pkg, int parseFlags, int scanMode) { @@ -2239,23 +2295,11 @@ class PackageManagerService extends IPackageManager.Stub { } } - 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 + pkg.mForwardLocked = (scanMode&SCAN_FORWARD_LOCKED) != 0; + pkg.mScanPath = path; + + if ((scanMode&SCAN_NO_DEX) == 0) { + if (performDexOptLI(pkg, forceDex) == DEX_OPT_FAILED) { mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT; return null; } diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 045e636..8cf1cc2 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -181,7 +181,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen // The flags that are set for all calls we make to the package manager. static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES - | PackageManager.GET_SUPPORTS_DENSITIES | PackageManager.GET_EXPANDABLE; + | PackageManager.GET_SUPPORTS_DENSITIES; private static final String SYSTEM_SECURE = "ro.secure"; @@ -809,6 +809,12 @@ public final class ActivityManagerService extends ActivityManagerNative implemen */ int[] mProcDeaths = new int[20]; + /** + * This is set if we had to do a delayed dexopt of an app before launching + * it, to increasing the ANR timeouts in that case. + */ + boolean mDidDexOpt; + String mDebugApp = null; boolean mWaitForDebugger = false; boolean mDebugTransient = false; @@ -1007,6 +1013,12 @@ public final class ActivityManagerService extends ActivityManagerNative implemen processNextBroadcast(true); } break; case BROADCAST_TIMEOUT_MSG: { + if (mDidDexOpt) { + mDidDexOpt = false; + Message nmsg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); + mHandler.sendMessageDelayed(nmsg, BROADCAST_TIMEOUT); + return; + } broadcastTimeout(); } break; case PAUSE_TIMEOUT_MSG: { @@ -1017,9 +1029,16 @@ public final class ActivityManagerService extends ActivityManagerNative implemen activityPaused(token, null, true); } break; case IDLE_TIMEOUT_MSG: { - IBinder token = (IBinder)msg.obj; + if (mDidDexOpt) { + mDidDexOpt = false; + Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); + nmsg.obj = msg.obj; + mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); + return; + } // We don't at this point know if the activity is fullscreen, // so we need to be conservative and assume it isn't. + IBinder token = (IBinder)msg.obj; Log.w(TAG, "Activity idle timeout for " + token); activityIdleInternal(token, true); } break; @@ -1035,6 +1054,13 @@ public final class ActivityManagerService extends ActivityManagerNative implemen activityIdle(token); } break; case SERVICE_TIMEOUT_MSG: { + if (mDidDexOpt) { + mDidDexOpt = false; + Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); + nmsg.obj = msg.obj; + mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT); + return; + } serviceTimeout((ProcessRecord)msg.obj); } break; case UPDATE_TIME_ZONE: { @@ -1071,6 +1097,12 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } } break; case LAUNCH_TIMEOUT_MSG: { + if (mDidDexOpt) { + mDidDexOpt = false; + Message nmsg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG); + mHandler.sendMessageDelayed(nmsg, LAUNCH_TIMEOUT); + return; + } synchronized (ActivityManagerService.this) { if (mLaunchingActivity.isHeld()) { Log.w(TAG, "Launch timeout has expired, giving up wake lock!"); @@ -1091,6 +1123,13 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } } case PROC_START_TIMEOUT_MSG: { + if (mDidDexOpt) { + mDidDexOpt = false; + Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); + nmsg.obj = msg.obj; + mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); + return; + } ProcessRecord app = (ProcessRecord)msg.obj; synchronized (ActivityManagerService.this) { processStartTimedOutLocked(app); @@ -1607,6 +1646,16 @@ public final class ActivityManagerService extends ActivityManagerNative implemen return proc; } + private void ensurePackageDexOpt(String packageName) { + IPackageManager pm = ActivityThread.getPackageManager(); + try { + if (pm.performDexOpt(packageName)) { + mDidDexOpt = true; + } + } catch (RemoteException e) { + } + } + private boolean isNextTransitionForward() { int transit = mWindowManager.getPendingAppTransition(); return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN @@ -1666,6 +1715,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (r.isHomeActivity) { mHomeProcess = app; } + ensurePackageDexOpt(r.intent.getComponent().getPackageName()); app.thread.scheduleLaunchActivity(new Intent(r.intent), r, r.info, r.icicle, results, newIntents, !andResume, isNextTransitionForward()); @@ -4819,6 +4869,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); } + ensurePackageDexOpt(app.info.packageName); + if (app.instrumentationInfo != null) { + ensurePackageDexOpt(app.instrumentationInfo.packageName); + } thread.bindApplication(processName, app.instrumentationInfo != null ? app.instrumentationInfo : app.info, providers, app.instrumentationClass, app.instrumentationProfileFile, @@ -4907,6 +4961,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen // Check whether the next backup agent is in this process... if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) { if (DEBUG_BACKUP) Log.v(TAG, "New app is backup target, launching agent for " + app); + ensurePackageDexOpt(mBackupTarget.appInfo.packageName); try { thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode); } catch (Exception e) { @@ -6918,6 +6973,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } app.pubProviders.put(cpi.name, cpr); app.addPackage(cpi.applicationInfo.packageName); + ensurePackageDexOpt(cpi.applicationInfo.packageName); } } return providers; @@ -9542,6 +9598,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen synchronized (r.stats.getBatteryStats()) { r.stats.startLaunchedLocked(); } + ensurePackageDexOpt(r.serviceInfo.packageName); app.thread.scheduleCreateService(r, r.serviceInfo); created = true; } finally { @@ -11098,6 +11155,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Delivering to component " + r.curComponent + ": " + r); + ensurePackageDexOpt(r.intent.getComponent().getPackageName()); app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver, r.resultCode, r.resultData, r.resultExtras, r.ordered); started = true; diff --git a/services/java/com/android/server/am/HistoryRecord.java b/services/java/com/android/server/am/HistoryRecord.java index 944ea02..b3fc313 100644 --- a/services/java/com/android/server/am/HistoryRecord.java +++ b/services/java/com/android/server/am/HistoryRecord.java @@ -463,6 +463,12 @@ class HistoryRecord extends IApplicationToken.Stub { return false; } + if (service.mDidDexOpt) { + // Give more time since we were dexopting. + service.mDidDexOpt = false; + return false; + } + if (r.app.instrumentationClass == null) { service.appNotRespondingLocked(r.app, r, "keyDispatchingTimedOut"); } else { diff --git a/test-runner/android/test/mock/MockContext.java b/test-runner/android/test/mock/MockContext.java index 9e0cf2c..efc4880 100644 --- a/test-runner/android/test/mock/MockContext.java +++ b/test-runner/android/test/mock/MockContext.java @@ -24,6 +24,7 @@ import android.content.IntentFilter; import android.content.BroadcastReceiver; import android.content.ServiceConnection; import android.content.SharedPreferences; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.AssetManager; import android.content.res.Resources; @@ -100,6 +101,11 @@ public class MockContext extends Context { } @Override + public ApplicationInfo getApplicationInfo() { + throw new UnsupportedOperationException(); + } + + @Override public String getPackageResourcePath() { throw new UnsupportedOperationException(); } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java index d0896b5..69f3d9c 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java @@ -29,6 +29,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.SharedPreferences; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.AssetManager; import android.content.res.Configuration; @@ -960,6 +961,12 @@ public final class BridgeContext extends Context { } @Override + public ApplicationInfo getApplicationInfo() { + // TODO Auto-generated method stub + return null; + } + + @Override public String getPackageResourcePath() { // TODO Auto-generated method stub return null; |