Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(678)

Side by Side Diff: build/android/incremental_install/java/org/chromium/incrementalinstall/BootstrapApplication.java

Issue 1469113004: GN(Android): Fix incremental install when manifest has short-hand app name. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 } 67 }
68 } 68 }
69 69
70 mClassLoaderPatcher.importNativeLibs(libDir); 70 mClassLoaderPatcher.importNativeLibs(libDir);
71 mClassLoaderPatcher.loadDexFiles(dexDir); 71 mClassLoaderPatcher.loadDexFiles(dexDir);
72 72
73 if (isFirstRun && mClassLoaderPatcher.mIsPrimaryProcess) { 73 if (isFirstRun && mClassLoaderPatcher.mIsPrimaryProcess) {
74 LockFile.clearInstallerLock(firstRunLockFile); 74 LockFile.clearInstallerLock(firstRunLockFile);
75 } 75 }
76 76
77 Bundle metadata = getManifestMetadata();
78 // mInstrumentationAppDir is one of a set of fields that is initiali zed only when 77 // mInstrumentationAppDir is one of a set of fields that is initiali zed only when
79 // instrumentation is active. 78 // instrumentation is active.
80 if (Reflect.getField(mActivityThread, "mInstrumentationAppDir") != n ull) { 79 if (Reflect.getField(mActivityThread, "mInstrumentationAppDir") != n ull) {
81 initInstrumentation(metadata.getString(REAL_INSTRUMENTATION_META _DATA_NAME)); 80 String realInstrumentationName =
81 getClassNameFromMetadata(REAL_INSTRUMENTATION_META_DATA_ NAME);
82 initInstrumentation(realInstrumentationName);
82 } else { 83 } else {
83 Log.i(TAG, "No instrumentation active."); 84 Log.i(TAG, "No instrumentation active.");
84 } 85 }
85 86
86 // Even when instrumentation is not enabled, ActivityThread uses a d efault 87 // Even when instrumentation is not enabled, ActivityThread uses a d efault
87 // Instrumentation instance internally. We hook it here in order to hook into the 88 // Instrumentation instance internally. We hook it here in order to hook into the
88 // call to Instrumentation.onCreate(). 89 // call to Instrumentation.onCreate().
89 Reflect.setField(mActivityThread, "mInstrumentation", 90 Reflect.setField(mActivityThread, "mInstrumentation",
90 new BootstrapInstrumentation(this)); 91 new BootstrapInstrumentation(this));
91 92
92 // attachBaseContext() is called from ActivityThread#handleBindAppli cation() and 93 // attachBaseContext() is called from ActivityThread#handleBindAppli cation() and
93 // Application#mApplication is changed right after we return. Thus, we cannot swap 94 // Application#mApplication is changed right after we return. Thus, we cannot swap
94 // the Application instances until onCreate() is called. 95 // the Application instances until onCreate() is called.
95 String realApplicationName = metadata.getString(REAL_APP_META_DATA_N AME); 96 String realApplicationName = getClassNameFromMetadata(REAL_APP_META_ DATA_NAME);
96 Log.i(TAG, "Instantiating " + realApplicationName); 97 Log.i(TAG, "Instantiating " + realApplicationName);
97 mRealApplication = 98 mRealApplication =
98 (Application) Reflect.newInstance(Class.forName(realApplicat ionName)); 99 (Application) Reflect.newInstance(Class.forName(realApplicat ionName));
99 Reflect.invokeMethod(mRealApplication, "attachBaseContext", context) ; 100 Reflect.invokeMethod(mRealApplication, "attachBaseContext", context) ;
100 101
101 // Between attachBaseContext() and onCreate(), ActivityThread tries to instantiate 102 // Between attachBaseContext() and onCreate(), ActivityThread tries to instantiate
102 // all ContentProviders. The ContentProviders break without the corr ect Application 103 // all ContentProviders. The ContentProviders break without the corr ect Application
103 // class being installed, so temporarily pretend there are no provid ers, and then 104 // class being installed, so temporarily pretend there are no provid ers, and then
104 // instantiate them explicitly within onCreate(). 105 // instantiate them explicitly within onCreate().
105 disableContentProviders(); 106 disableContentProviders();
106 Log.i(TAG, "Waiting for Instrumentation.onCreate"); 107 Log.i(TAG, "Waiting for Instrumentation.onCreate");
107 } catch (Exception e) { 108 } catch (Exception e) {
108 throw new RuntimeException("Incremental install failed.", e); 109 throw new RuntimeException("Incremental install failed.", e);
109 } 110 }
110 } 111 }
111 112
112 /** 113 /**
114 * Returns the fully-qualified class name for the given key, stored in a
115 * <meta> witin the manifest.
116 */
117 private String getClassNameFromMetadata(String key) throws NameNotFoundExcep tion {
118 ApplicationInfo appInfo = getPackageManager().getApplicationInfo(getPack ageName(),
119 PackageManager.GET_META_DATA);
120 String value = appInfo.metaData.getString(key);
121 if (!value.contains(".")) {
122 value = getPackageName() + "." + value;
123 }
124 return value;
125 }
126
127 /**
113 * Instantiates and initializes mRealInstrumentation (the real Instrumentati on class). 128 * Instantiates and initializes mRealInstrumentation (the real Instrumentati on class).
114 */ 129 */
115 private void initInstrumentation(String realInstrumentationName) 130 private void initInstrumentation(String realInstrumentationName)
116 throws ReflectiveOperationException { 131 throws ReflectiveOperationException {
117 Log.i(TAG, "Instantiating instrumentation " + realInstrumentationName); 132 Log.i(TAG, "Instantiating instrumentation " + realInstrumentationName);
118 mRealInstrumentation = (Instrumentation) Reflect.newInstance( 133 mRealInstrumentation = (Instrumentation) Reflect.newInstance(
119 Class.forName(realInstrumentationName)); 134 Class.forName(realInstrumentationName));
120 Instrumentation oldInstrumentation = 135 Instrumentation oldInstrumentation =
121 (Instrumentation) Reflect.getField(mActivityThread, "mInstrument ation"); 136 (Instrumentation) Reflect.getField(mActivityThread, "mInstrument ation");
122 137
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 super.onCreate(); 171 super.onCreate();
157 try { 172 try {
158 Log.i(TAG, "Application.onCreate() called."); 173 Log.i(TAG, "Application.onCreate() called.");
159 mRealApplication.onCreate(); 174 mRealApplication.onCreate();
160 } catch (Exception e) { 175 } catch (Exception e) {
161 throw new RuntimeException("Incremental install failed.", e); 176 throw new RuntimeException("Incremental install failed.", e);
162 } 177 }
163 } 178 }
164 179
165 /** 180 /**
166 * Returns the class name of the real Application class (recorded in the
167 * AndroidManifest.xml)
168 */
169 private Bundle getManifestMetadata() throws NameNotFoundException {
170 ApplicationInfo appInfo = getPackageManager().getApplicationInfo(getPack ageName(),
171 PackageManager.GET_META_DATA);
172 return appInfo.metaData;
173 }
174
175 /**
176 * Nulls out ActivityThread.mBoundApplication.providers. 181 * Nulls out ActivityThread.mBoundApplication.providers.
177 */ 182 */
178 private void disableContentProviders() throws ReflectiveOperationException { 183 private void disableContentProviders() throws ReflectiveOperationException {
179 Object data = Reflect.getField(mActivityThread, "mBoundApplication"); 184 Object data = Reflect.getField(mActivityThread, "mBoundApplication");
180 mStashedProviderList = Reflect.getField(data, "providers"); 185 mStashedProviderList = Reflect.getField(data, "providers");
181 Reflect.setField(data, "providers", null); 186 Reflect.setField(data, "providers", null);
182 } 187 }
183 188
184 /** 189 /**
185 * Restores the value of ActivityThread.mBoundApplication.providers, and inv okes 190 * Restores the value of ActivityThread.mBoundApplication.providers, and inv okes
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 for (Map.Entry<String, WeakReference<?>> entry : packageMap.entrySet ()) { 226 for (Map.Entry<String, WeakReference<?>> entry : packageMap.entrySet ()) {
222 Object loadedApk = entry.getValue().get(); 227 Object loadedApk = entry.getValue().get();
223 if (loadedApk != null && Reflect.getField(loadedApk, "mApplicati on") == this) { 228 if (loadedApk != null && Reflect.getField(loadedApk, "mApplicati on") == this) {
224 Reflect.setField(loadedApk, "mApplication", mRealApplication ); 229 Reflect.setField(loadedApk, "mApplication", mRealApplication );
225 Reflect.setField(mRealApplication, "mLoadedApk", loadedApk); 230 Reflect.setField(mRealApplication, "mLoadedApk", loadedApk);
226 } 231 }
227 } 232 }
228 } 233 }
229 } 234 }
230 } 235 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698