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; | 
