blob: 4531f53bd86fe3f1b19e39b48ee5b889535c0942 [file] [log] [blame]
Justin Klaassen10d07c82017-09-15 17:58:39 -04001/*
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
17package android.app;
18
Justin Klaassen10d07c82017-09-15 17:58:39 -040019import android.annotation.CallSuper;
20import android.content.ComponentCallbacks;
21import android.content.ComponentCallbacks2;
22import android.content.Context;
23import android.content.ContextWrapper;
24import android.content.Intent;
25import android.content.res.Configuration;
26import android.os.Bundle;
Justin Klaassen4d01eea2018-04-03 23:21:57 -040027import android.util.Log;
28import android.view.autofill.AutofillManager;
29
30import java.util.ArrayList;
Justin Klaassen10d07c82017-09-15 17:58:39 -040031
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>&lt;application&gt;</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 */
49public class Application extends ContextWrapper implements ComponentCallbacks2 {
Justin Klaassen4d01eea2018-04-03 23:21:57 -040050 private static final String TAG = "Application";
Justin Klaassen10d07c82017-09-15 17:58:39 -040051 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 {
61 void onActivityCreated(Activity activity, Bundle savedInstanceState);
62 void onActivityStarted(Activity activity);
63 void onActivityResumed(Activity activity);
64 void onActivityPaused(Activity activity);
65 void onActivityStopped(Activity activity);
66 void onActivitySaveInstanceState(Activity activity, Bundle outState);
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 */
82 public void onProvideAssistData(Activity activity, Bundle data);
83 }
84
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.
Justin Klaassen4d01eea2018-04-03 23:21:57 -040092 *
93 * <p>Implementations should be as quick as possible (for example using
Justin Klaassen10d07c82017-09-15 17:58:39 -040094 * lazy initialization of state) since the time spent in this function
95 * directly impacts the performance of starting the first activity,
Justin Klaassen4d01eea2018-04-03 23:21:57 -040096 * 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>
Justin Klaassen10d07c82017-09-15 17:58:39 -0400107 */
108 @CallSuper
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
119 public void onTerminate() {
120 }
121
122 @CallSuper
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
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
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
155 public void registerComponentCallbacks(ComponentCallbacks callback) {
156 synchronized (mComponentCallbacks) {
157 mComponentCallbacks.add(callback);
158 }
159 }
160
161 public void unregisterComponentCallbacks(ComponentCallbacks callback) {
162 synchronized (mComponentCallbacks) {
163 mComponentCallbacks.remove(callback);
164 }
165 }
166
167 public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {
168 synchronized (mActivityLifecycleCallbacks) {
169 mActivityLifecycleCallbacks.add(callback);
170 }
171 }
172
173 public void unregisterActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {
174 synchronized (mActivityLifecycleCallbacks) {
175 mActivityLifecycleCallbacks.remove(callback);
176 }
177 }
178
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
188 public void unregisterOnProvideAssistDataListener(OnProvideAssistDataListener callback) {
189 synchronized (this) {
190 if (mAssistCallbacks != null) {
191 mAssistCallbacks.remove(callback);
192 }
193 }
194 }
195
Justin Klaassen4d01eea2018-04-03 23:21:57 -0400196 /**
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 */
202 public static String getProcessName() {
203 return ActivityThread.currentProcessName();
204 }
205
Justin Klaassen10d07c82017-09-15 17:58:39 -0400206 // ------------------ Internal API ------------------
207
208 /**
209 * @hide
210 */
211 /* package */ final void attach(Context context) {
212 attachBaseContext(context);
Justin Klaassen4d01eea2018-04-03 23:21:57 -0400213 mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
Justin Klaassen10d07c82017-09-15 17:58:39 -0400214 }
215
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
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
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
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
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
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
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
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
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
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 }
Justin Klaassen4d01eea2018-04-03 23:21:57 -0400315
316 /** @hide */
317 @Override
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}