| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.incrementalinstall; | 5 package org.chromium.incrementalinstall; |
| 6 | 6 |
| 7 import android.app.Application; | 7 import android.app.Application; |
| 8 import android.app.Instrumentation; | 8 import android.app.Instrumentation; |
| 9 import android.content.ComponentName; | 9 import android.content.ComponentName; |
| 10 import android.content.Context; | 10 import android.content.Context; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 * after side-loading its .so and .dex files from /data/local/tmp. | 25 * after side-loading its .so and .dex files from /data/local/tmp. |
| 26 * | 26 * |
| 27 * This class is highly dependent on the private implementation details of | 27 * This class is highly dependent on the private implementation details of |
| 28 * Android's ActivityThread.java. However, it has been tested to work with | 28 * Android's ActivityThread.java. However, it has been tested to work with |
| 29 * JellyBean through Marshmallow. | 29 * JellyBean through Marshmallow. |
| 30 */ | 30 */ |
| 31 public final class BootstrapApplication extends Application { | 31 public final class BootstrapApplication extends Application { |
| 32 private static final String TAG = "cr.incrementalinstall"; | 32 private static final String TAG = "cr.incrementalinstall"; |
| 33 private static final String MANAGED_DIR_PREFIX = "/data/local/tmp/incrementa
l-app-"; | 33 private static final String MANAGED_DIR_PREFIX = "/data/local/tmp/incrementa
l-app-"; |
| 34 private static final String REAL_APP_META_DATA_NAME = "incremental-install-r
eal-app"; | 34 private static final String REAL_APP_META_DATA_NAME = "incremental-install-r
eal-app"; |
| 35 private static final String REAL_INSTRUMENTATION_META_DATA_NAME = | 35 private static final String REAL_INSTRUMENTATION_META_DATA_NAME0 = |
| 36 "incremental-install-real-instrumentation"; | 36 "incremental-install-real-instrumentation-0"; |
| 37 private static final String REAL_INSTRUMENTATION_META_DATA_NAME1 = |
| 38 "incremental-install-real-instrumentation-1"; |
| 37 | 39 |
| 38 private ClassLoaderPatcher mClassLoaderPatcher; | 40 private ClassLoaderPatcher mClassLoaderPatcher; |
| 39 private Application mRealApplication; | 41 private Application mRealApplication; |
| 40 private Instrumentation mOrigInstrumentation; | 42 private Instrumentation mOrigInstrumentation; |
| 41 private Instrumentation mRealInstrumentation; | 43 private Instrumentation mRealInstrumentation; |
| 42 private Object mStashedProviderList; | 44 private Object mStashedProviderList; |
| 43 private Object mActivityThread; | 45 private Object mActivityThread; |
| 44 | 46 |
| 45 @Override | 47 @Override |
| 46 protected void attachBaseContext(Context context) { | 48 protected void attachBaseContext(Context context) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 if (isFirstRun && mClassLoaderPatcher.mIsPrimaryProcess) { | 108 if (isFirstRun && mClassLoaderPatcher.mIsPrimaryProcess) { |
| 107 LockFile.clearInstallerLock(appFirstRunLockFile); | 109 LockFile.clearInstallerLock(appFirstRunLockFile); |
| 108 if (instPackageNameDiffers) { | 110 if (instPackageNameDiffers) { |
| 109 LockFile.clearInstallerLock(instFirstRunLockFile); | 111 LockFile.clearInstallerLock(instFirstRunLockFile); |
| 110 } | 112 } |
| 111 } | 113 } |
| 112 | 114 |
| 113 // mInstrumentationAppDir is one of a set of fields that is initiali
zed only when | 115 // mInstrumentationAppDir is one of a set of fields that is initiali
zed only when |
| 114 // instrumentation is active. | 116 // instrumentation is active. |
| 115 if (Reflect.getField(mActivityThread, "mInstrumentationAppDir") != n
ull) { | 117 if (Reflect.getField(mActivityThread, "mInstrumentationAppDir") != n
ull) { |
| 116 String realInstrumentationName = | 118 String metaDataName = REAL_INSTRUMENTATION_META_DATA_NAME0; |
| 117 getClassNameFromMetadata(REAL_INSTRUMENTATION_META_DATA_
NAME, instContext); | 119 if (mOrigInstrumentation instanceof SecondInstrumentation) { |
| 118 initInstrumentation(realInstrumentationName); | 120 metaDataName = REAL_INSTRUMENTATION_META_DATA_NAME1; |
| 121 } |
| 122 initInstrumentation(getClassNameFromMetadata(metaDataName, instC
ontext)); |
| 119 } else { | 123 } else { |
| 120 Log.i(TAG, "No instrumentation active."); | 124 Log.i(TAG, "No instrumentation active."); |
| 121 } | 125 } |
| 122 | 126 |
| 123 // Even when instrumentation is not enabled, ActivityThread uses a d
efault | 127 // Even when instrumentation is not enabled, ActivityThread uses a d
efault |
| 124 // Instrumentation instance internally. We hook it here in order to
hook into the | 128 // Instrumentation instance internally. We hook it here in order to
hook into the |
| 125 // call to Instrumentation.onCreate(). | 129 // call to Instrumentation.onCreate(). |
| 126 Reflect.setField(mActivityThread, "mInstrumentation", | 130 Reflect.setField(mActivityThread, "mInstrumentation", |
| 127 new BootstrapInstrumentation(this)); | 131 new BootstrapInstrumentation(this)); |
| 128 | 132 |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 for (Map.Entry<String, WeakReference<?>> entry : packageMap.entrySet
()) { | 277 for (Map.Entry<String, WeakReference<?>> entry : packageMap.entrySet
()) { |
| 274 Object loadedApk = entry.getValue().get(); | 278 Object loadedApk = entry.getValue().get(); |
| 275 if (loadedApk != null && Reflect.getField(loadedApk, "mApplicati
on") == this) { | 279 if (loadedApk != null && Reflect.getField(loadedApk, "mApplicati
on") == this) { |
| 276 Reflect.setField(loadedApk, "mApplication", mRealApplication
); | 280 Reflect.setField(loadedApk, "mApplication", mRealApplication
); |
| 277 Reflect.setField(mRealApplication, "mLoadedApk", loadedApk); | 281 Reflect.setField(mRealApplication, "mLoadedApk", loadedApk); |
| 278 } | 282 } |
| 279 } | 283 } |
| 280 } | 284 } |
| 281 } | 285 } |
| 282 } | 286 } |
| OLD | NEW |