1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.app; 18 19 import android.annotation.CallSuper; 20 import android.content.ComponentCallbacks; 21 import android.content.ComponentCallbacks2; 22 import android.content.Context; 23 import android.content.ContextWrapper; 24 import android.content.Intent; 25 import android.content.res.Configuration; 26 import android.os.Bundle; 27 import android.util.Log; 28 import android.view.autofill.AutofillManager; 29 30 import java.util.ArrayList; 31 32 /** 33 * Base class for maintaining global application state. You can provide your own 34 * implementation by creating a subclass and specifying the fully-qualified name 35 * of this subclass as the <code>"android:name"</code> attribute in your 36 * AndroidManifest.xml's <code><application></code> tag. The Application 37 * class, or your subclass of the Application class, is instantiated before any 38 * other class when the process for your application/package is created. 39 * 40 * <p class="note"><strong>Note: </strong>There is normally no need to subclass 41 * Application. In most situations, static singletons can provide the same 42 * functionality in a more modular way. If your singleton needs a global 43 * context (for example to register broadcast receivers), include 44 * {@link android.content.Context#getApplicationContext() Context.getApplicationContext()} 45 * as a {@link android.content.Context} argument when invoking your singleton's 46 * <code>getInstance()</code> method. 47 * </p> 48 */ 49 public class Application extends ContextWrapper implements ComponentCallbacks2 { 50 private static final String TAG = "Application"; 51 private ArrayList<ComponentCallbacks> mComponentCallbacks = 52 new ArrayList<ComponentCallbacks>(); 53 private ArrayList<ActivityLifecycleCallbacks> mActivityLifecycleCallbacks = 54 new ArrayList<ActivityLifecycleCallbacks>(); 55 private ArrayList<OnProvideAssistDataListener> mAssistCallbacks = null; 56 57 /** @hide */ 58 public LoadedApk mLoadedApk; 59 60 public interface ActivityLifecycleCallbacks { onActivityCreated(Activity activity, Bundle savedInstanceState)61 void onActivityCreated(Activity activity, Bundle savedInstanceState); onActivityStarted(Activity activity)62 void onActivityStarted(Activity activity); onActivityResumed(Activity activity)63 void onActivityResumed(Activity activity); onActivityPaused(Activity activity)64 void onActivityPaused(Activity activity); onActivityStopped(Activity activity)65 void onActivityStopped(Activity activity); onActivitySaveInstanceState(Activity activity, Bundle outState)66 void onActivitySaveInstanceState(Activity activity, Bundle outState); onActivityDestroyed(Activity activity)67 void onActivityDestroyed(Activity activity); 68 } 69 70 /** 71 * Callback interface for use with {@link Application#registerOnProvideAssistDataListener} 72 * and {@link Application#unregisterOnProvideAssistDataListener}. 73 */ 74 public interface OnProvideAssistDataListener { 75 /** 76 * This is called when the user is requesting an assist, to build a full 77 * {@link Intent#ACTION_ASSIST} Intent with all of the context of the current 78 * application. You can override this method to place into the bundle anything 79 * you would like to appear in the {@link Intent#EXTRA_ASSIST_CONTEXT} part 80 * of the assist Intent. 81 */ onProvideAssistData(Activity activity, Bundle data)82 public void onProvideAssistData(Activity activity, Bundle data); 83 } 84 Application()85 public Application() { 86 super(null); 87 } 88 89 /** 90 * Called when the application is starting, before any activity, service, 91 * or receiver objects (excluding content providers) have been created. 92 * 93 * <p>Implementations should be as quick as possible (for example using 94 * lazy initialization of state) since the time spent in this function 95 * directly impacts the performance of starting the first activity, 96 * service, or receiver in a process.</p> 97 * 98 * <p>If you override this method, be sure to call {@code super.onCreate()}.</p> 99 * 100 * <p class="note">Be aware that direct boot may also affect callback order on 101 * Android {@link android.os.Build.VERSION_CODES#N} and later devices. 102 * Until the user unlocks the device, only direct boot aware components are 103 * allowed to run. You should consider that all direct boot unaware 104 * components, including such {@link android.content.ContentProvider}, are 105 * disabled until user unlock happens, especially when component callback 106 * order matters.</p> 107 */ 108 @CallSuper onCreate()109 public void onCreate() { 110 } 111 112 /** 113 * This method is for use in emulated process environments. It will 114 * never be called on a production Android device, where processes are 115 * removed by simply killing them; no user code (including this callback) 116 * is executed when doing so. 117 */ 118 @CallSuper onTerminate()119 public void onTerminate() { 120 } 121 122 @CallSuper onConfigurationChanged(Configuration newConfig)123 public void onConfigurationChanged(Configuration newConfig) { 124 Object[] callbacks = collectComponentCallbacks(); 125 if (callbacks != null) { 126 for (int i=0; i<callbacks.length; i++) { 127 ((ComponentCallbacks)callbacks[i]).onConfigurationChanged(newConfig); 128 } 129 } 130 } 131 132 @CallSuper onLowMemory()133 public void onLowMemory() { 134 Object[] callbacks = collectComponentCallbacks(); 135 if (callbacks != null) { 136 for (int i=0; i<callbacks.length; i++) { 137 ((ComponentCallbacks)callbacks[i]).onLowMemory(); 138 } 139 } 140 } 141 142 @CallSuper onTrimMemory(int level)143 public void onTrimMemory(int level) { 144 Object[] callbacks = collectComponentCallbacks(); 145 if (callbacks != null) { 146 for (int i=0; i<callbacks.length; i++) { 147 Object c = callbacks[i]; 148 if (c instanceof ComponentCallbacks2) { 149 ((ComponentCallbacks2)c).onTrimMemory(level); 150 } 151 } 152 } 153 } 154 registerComponentCallbacks(ComponentCallbacks callback)155 public void registerComponentCallbacks(ComponentCallbacks callback) { 156 synchronized (mComponentCallbacks) { 157 mComponentCallbacks.add(callback); 158 } 159 } 160 unregisterComponentCallbacks(ComponentCallbacks callback)161 public void unregisterComponentCallbacks(ComponentCallbacks callback) { 162 synchronized (mComponentCallbacks) { 163 mComponentCallbacks.remove(callback); 164 } 165 } 166 registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback)167 public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) { 168 synchronized (mActivityLifecycleCallbacks) { 169 mActivityLifecycleCallbacks.add(callback); 170 } 171 } 172 unregisterActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback)173 public void unregisterActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) { 174 synchronized (mActivityLifecycleCallbacks) { 175 mActivityLifecycleCallbacks.remove(callback); 176 } 177 } 178 registerOnProvideAssistDataListener(OnProvideAssistDataListener callback)179 public void registerOnProvideAssistDataListener(OnProvideAssistDataListener callback) { 180 synchronized (this) { 181 if (mAssistCallbacks == null) { 182 mAssistCallbacks = new ArrayList<OnProvideAssistDataListener>(); 183 } 184 mAssistCallbacks.add(callback); 185 } 186 } 187 unregisterOnProvideAssistDataListener(OnProvideAssistDataListener callback)188 public void unregisterOnProvideAssistDataListener(OnProvideAssistDataListener callback) { 189 synchronized (this) { 190 if (mAssistCallbacks != null) { 191 mAssistCallbacks.remove(callback); 192 } 193 } 194 } 195 196 /** 197 * Returns the name of the current process. A package's default process name 198 * is the same as its package name. Non-default processes will look like 199 * "$PACKAGE_NAME:$NAME", where $NAME corresponds to an android:process 200 * attribute within AndroidManifest.xml. 201 */ getProcessName()202 public static String getProcessName() { 203 return ActivityThread.currentProcessName(); 204 } 205 206 // ------------------ Internal API ------------------ 207 208 /** 209 * @hide 210 */ attach(Context context)211 /* package */ final void attach(Context context) { 212 attachBaseContext(context); 213 mLoadedApk = ContextImpl.getImpl(context).mPackageInfo; 214 } 215 dispatchActivityCreated(Activity activity, Bundle savedInstanceState)216 /* package */ void dispatchActivityCreated(Activity activity, Bundle savedInstanceState) { 217 Object[] callbacks = collectActivityLifecycleCallbacks(); 218 if (callbacks != null) { 219 for (int i=0; i<callbacks.length; i++) { 220 ((ActivityLifecycleCallbacks)callbacks[i]).onActivityCreated(activity, 221 savedInstanceState); 222 } 223 } 224 } 225 dispatchActivityStarted(Activity activity)226 /* package */ void dispatchActivityStarted(Activity activity) { 227 Object[] callbacks = collectActivityLifecycleCallbacks(); 228 if (callbacks != null) { 229 for (int i=0; i<callbacks.length; i++) { 230 ((ActivityLifecycleCallbacks)callbacks[i]).onActivityStarted(activity); 231 } 232 } 233 } 234 dispatchActivityResumed(Activity activity)235 /* package */ void dispatchActivityResumed(Activity activity) { 236 Object[] callbacks = collectActivityLifecycleCallbacks(); 237 if (callbacks != null) { 238 for (int i=0; i<callbacks.length; i++) { 239 ((ActivityLifecycleCallbacks)callbacks[i]).onActivityResumed(activity); 240 } 241 } 242 } 243 dispatchActivityPaused(Activity activity)244 /* package */ void dispatchActivityPaused(Activity activity) { 245 Object[] callbacks = collectActivityLifecycleCallbacks(); 246 if (callbacks != null) { 247 for (int i=0; i<callbacks.length; i++) { 248 ((ActivityLifecycleCallbacks)callbacks[i]).onActivityPaused(activity); 249 } 250 } 251 } 252 dispatchActivityStopped(Activity activity)253 /* package */ void dispatchActivityStopped(Activity activity) { 254 Object[] callbacks = collectActivityLifecycleCallbacks(); 255 if (callbacks != null) { 256 for (int i=0; i<callbacks.length; i++) { 257 ((ActivityLifecycleCallbacks)callbacks[i]).onActivityStopped(activity); 258 } 259 } 260 } 261 dispatchActivitySaveInstanceState(Activity activity, Bundle outState)262 /* package */ void dispatchActivitySaveInstanceState(Activity activity, Bundle outState) { 263 Object[] callbacks = collectActivityLifecycleCallbacks(); 264 if (callbacks != null) { 265 for (int i=0; i<callbacks.length; i++) { 266 ((ActivityLifecycleCallbacks)callbacks[i]).onActivitySaveInstanceState(activity, 267 outState); 268 } 269 } 270 } 271 dispatchActivityDestroyed(Activity activity)272 /* package */ void dispatchActivityDestroyed(Activity activity) { 273 Object[] callbacks = collectActivityLifecycleCallbacks(); 274 if (callbacks != null) { 275 for (int i=0; i<callbacks.length; i++) { 276 ((ActivityLifecycleCallbacks)callbacks[i]).onActivityDestroyed(activity); 277 } 278 } 279 } 280 collectComponentCallbacks()281 private Object[] collectComponentCallbacks() { 282 Object[] callbacks = null; 283 synchronized (mComponentCallbacks) { 284 if (mComponentCallbacks.size() > 0) { 285 callbacks = mComponentCallbacks.toArray(); 286 } 287 } 288 return callbacks; 289 } 290 collectActivityLifecycleCallbacks()291 private Object[] collectActivityLifecycleCallbacks() { 292 Object[] callbacks = null; 293 synchronized (mActivityLifecycleCallbacks) { 294 if (mActivityLifecycleCallbacks.size() > 0) { 295 callbacks = mActivityLifecycleCallbacks.toArray(); 296 } 297 } 298 return callbacks; 299 } 300 dispatchOnProvideAssistData(Activity activity, Bundle data)301 /* package */ void dispatchOnProvideAssistData(Activity activity, Bundle data) { 302 Object[] callbacks; 303 synchronized (this) { 304 if (mAssistCallbacks == null) { 305 return; 306 } 307 callbacks = mAssistCallbacks.toArray(); 308 } 309 if (callbacks != null) { 310 for (int i=0; i<callbacks.length; i++) { 311 ((OnProvideAssistDataListener)callbacks[i]).onProvideAssistData(activity, data); 312 } 313 } 314 } 315 316 /** @hide */ 317 @Override getAutofillClient()318 public AutofillManager.AutofillClient getAutofillClient() { 319 final AutofillManager.AutofillClient client = super.getAutofillClient(); 320 if (client != null) { 321 return client; 322 } 323 if (android.view.autofill.Helper.sVerbose) { 324 Log.v(TAG, "getAutofillClient(): null on super, trying to find activity thread"); 325 } 326 // Okay, ppl use the application context when they should not. This breaks 327 // autofill among other things. We pick the focused activity since autofill 328 // interacts only with the currently focused activity and we need the fill 329 // client only if a call comes from the focused activity. Sigh... 330 final ActivityThread activityThread = ActivityThread.currentActivityThread(); 331 if (activityThread == null) { 332 return null; 333 } 334 final int activityCount = activityThread.mActivities.size(); 335 for (int i = 0; i < activityCount; i++) { 336 final ActivityThread.ActivityClientRecord record = 337 activityThread.mActivities.valueAt(i); 338 if (record == null) { 339 continue; 340 } 341 final Activity activity = record.activity; 342 if (activity == null) { 343 continue; 344 } 345 if (activity.getWindow().getDecorView().hasFocus()) { 346 if (android.view.autofill.Helper.sVerbose) { 347 Log.v(TAG, "getAutofillClient(): found activity for " + this + ": " + activity); 348 } 349 return activity; 350 } 351 } 352 if (android.view.autofill.Helper.sVerbose) { 353 Log.v(TAG, "getAutofillClient(): none of the " + activityCount + " activities on " 354 + this + " have focus"); 355 } 356 return null; 357 } 358 } 359