blob: 941467fad736cd05025803c8188e6b8860ba3b72 [file] [log] [blame]
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app;
import android.annotation.CallSuper;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentCallbacks;
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.autofill.AutofillManager;
import java.util.ArrayList;
/**
* Base class for maintaining global application state. You can provide your own
* implementation by creating a subclass and specifying the fully-qualified name
* of this subclass as the <code>"android:name"</code> attribute in your
* AndroidManifest.xml's <code>&lt;application&gt;</code> tag. The Application
* class, or your subclass of the Application class, is instantiated before any
* other class when the process for your application/package is created.
*
* <p class="note"><strong>Note: </strong>There is normally no need to subclass
* Application. In most situations, static singletons can provide the same
* functionality in a more modular way. If your singleton needs a global
* context (for example to register broadcast receivers), include
* {@link android.content.Context#getApplicationContext() Context.getApplicationContext()}
* as a {@link android.content.Context} argument when invoking your singleton's
* <code>getInstance()</code> method.
* </p>
*/
public class Application extends ContextWrapper implements ComponentCallbacks2 {
private static final String TAG = "Application";
@UnsupportedAppUsage
private ArrayList<ComponentCallbacks> mComponentCallbacks =
new ArrayList<ComponentCallbacks>();
@UnsupportedAppUsage
private ArrayList<ActivityLifecycleCallbacks> mActivityLifecycleCallbacks =
new ArrayList<ActivityLifecycleCallbacks>();
@UnsupportedAppUsage
private ArrayList<OnProvideAssistDataListener> mAssistCallbacks = null;
/** @hide */
@UnsupportedAppUsage
public LoadedApk mLoadedApk;
public interface ActivityLifecycleCallbacks {
/**
* Called as the first step of the Activity being created. This is always called before
* {@link Activity#onCreate}.
*/
default void onActivityPreCreated(@NonNull Activity activity,
@Nullable Bundle savedInstanceState) {
}
/**
* Called when the Activity calls {@link Activity#onCreate super.onCreate()}.
*/
void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState);
/**
* Called as the last step of the Activity being created. This is always called after
* {@link Activity#onCreate}.
*/
default void onActivityPostCreated(@NonNull Activity activity,
@Nullable Bundle savedInstanceState) {
}
/**
* Called as the first step of the Activity being started. This is always called before
* {@link Activity#onStart}.
*/
default void onActivityPreStarted(@NonNull Activity activity) {
}
/**
* Called when the Activity calls {@link Activity#onStart super.onStart()}.
*/
void onActivityStarted(@NonNull Activity activity);
/**
* Called as the last step of the Activity being started. This is always called after
* {@link Activity#onStart}.
*/
default void onActivityPostStarted(@NonNull Activity activity) {
}
/**
* Called as the first step of the Activity being resumed. This is always called before
* {@link Activity#onResume}.
*/
default void onActivityPreResumed(@NonNull Activity activity) {
}
/**
* Called when the Activity calls {@link Activity#onResume super.onResume()}.
*/
void onActivityResumed(@NonNull Activity activity);
/**
* Called as the last step of the Activity being resumed. This is always called after
* {@link Activity#onResume} and {@link Activity#onPostResume}.
*/
default void onActivityPostResumed(@NonNull Activity activity) {
}
/**
* Called as the first step of the Activity being paused. This is always called before
* {@link Activity#onPause}.
*/
default void onActivityPrePaused(@NonNull Activity activity) {
}
/**
* Called when the Activity calls {@link Activity#onPause super.onPause()}.
*/
void onActivityPaused(@NonNull Activity activity);
/**
* Called as the last step of the Activity being paused. This is always called after
* {@link Activity#onPause}.
*/
default void onActivityPostPaused(@NonNull Activity activity) {
}
/**
* Called as the first step of the Activity being stopped. This is always called before
* {@link Activity#onStop}.
*/
default void onActivityPreStopped(@NonNull Activity activity) {
}
/**
* Called when the Activity calls {@link Activity#onStop super.onStop()}.
*/
void onActivityStopped(@NonNull Activity activity);
/**
* Called as the last step of the Activity being stopped. This is always called after
* {@link Activity#onStop}.
*/
default void onActivityPostStopped(@NonNull Activity activity) {
}
/**
* Called as the first step of the Activity saving its instance state. This is always
* called before {@link Activity#onSaveInstanceState}.
*/
default void onActivityPreSaveInstanceState(@NonNull Activity activity,
@NonNull Bundle outState) {
}
/**
* Called when the Activity calls
* {@link Activity#onSaveInstanceState super.onSaveInstanceState()}.
*/
void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState);
/**
* Called as the last step of the Activity saving its instance state. This is always
* called after{@link Activity#onSaveInstanceState}.
*/
default void onActivityPostSaveInstanceState(@NonNull Activity activity,
@NonNull Bundle outState) {
}
/**
* Called as the first step of the Activity being destroyed. This is always called before
* {@link Activity#onDestroy}.
*/
default void onActivityPreDestroyed(@NonNull Activity activity) {
}
/**
* Called when the Activity calls {@link Activity#onDestroy super.onDestroy()}.
*/
void onActivityDestroyed(@NonNull Activity activity);
/**
* Called as the last step of the Activity being destroyed. This is always called after
* {@link Activity#onDestroy}.
*/
default void onActivityPostDestroyed(@NonNull Activity activity) {
}
}
/**
* Callback interface for use with {@link Application#registerOnProvideAssistDataListener}
* and {@link Application#unregisterOnProvideAssistDataListener}.
*/
public interface OnProvideAssistDataListener {
/**
* This is called when the user is requesting an assist, to build a full
* {@link Intent#ACTION_ASSIST} Intent with all of the context of the current
* application. You can override this method to place into the bundle anything
* you would like to appear in the {@link Intent#EXTRA_ASSIST_CONTEXT} part
* of the assist Intent.
*/
public void onProvideAssistData(Activity activity, Bundle data);
}
public Application() {
super(null);
}
/**
* Called when the application is starting, before any activity, service,
* or receiver objects (excluding content providers) have been created.
*
* <p>Implementations should be as quick as possible (for example using
* lazy initialization of state) since the time spent in this function
* directly impacts the performance of starting the first activity,
* service, or receiver in a process.</p>
*
* <p>If you override this method, be sure to call {@code super.onCreate()}.</p>
*
* <p class="note">Be aware that direct boot may also affect callback order on
* Android {@link android.os.Build.VERSION_CODES#N} and later devices.
* Until the user unlocks the device, only direct boot aware components are
* allowed to run. You should consider that all direct boot unaware
* components, including such {@link android.content.ContentProvider}, are
* disabled until user unlock happens, especially when component callback
* order matters.</p>
*/
@CallSuper
public void onCreate() {
}
/**
* This method is for use in emulated process environments. It will
* never be called on a production Android device, where processes are
* removed by simply killing them; no user code (including this callback)
* is executed when doing so.
*/
@CallSuper
public void onTerminate() {
}
@CallSuper
public void onConfigurationChanged(@NonNull Configuration newConfig) {
Object[] callbacks = collectComponentCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ComponentCallbacks)callbacks[i]).onConfigurationChanged(newConfig);
}
}
}
@CallSuper
public void onLowMemory() {
Object[] callbacks = collectComponentCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ComponentCallbacks)callbacks[i]).onLowMemory();
}
}
}
@CallSuper
public void onTrimMemory(int level) {
Object[] callbacks = collectComponentCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
Object c = callbacks[i];
if (c instanceof ComponentCallbacks2) {
((ComponentCallbacks2)c).onTrimMemory(level);
}
}
}
}
public void registerComponentCallbacks(ComponentCallbacks callback) {
synchronized (mComponentCallbacks) {
mComponentCallbacks.add(callback);
}
}
public void unregisterComponentCallbacks(ComponentCallbacks callback) {
synchronized (mComponentCallbacks) {
mComponentCallbacks.remove(callback);
}
}
public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {
synchronized (mActivityLifecycleCallbacks) {
mActivityLifecycleCallbacks.add(callback);
}
}
public void unregisterActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {
synchronized (mActivityLifecycleCallbacks) {
mActivityLifecycleCallbacks.remove(callback);
}
}
public void registerOnProvideAssistDataListener(OnProvideAssistDataListener callback) {
synchronized (this) {
if (mAssistCallbacks == null) {
mAssistCallbacks = new ArrayList<OnProvideAssistDataListener>();
}
mAssistCallbacks.add(callback);
}
}
public void unregisterOnProvideAssistDataListener(OnProvideAssistDataListener callback) {
synchronized (this) {
if (mAssistCallbacks != null) {
mAssistCallbacks.remove(callback);
}
}
}
/**
* Returns the name of the current process. A package's default process name
* is the same as its package name. Non-default processes will look like
* "$PACKAGE_NAME:$NAME", where $NAME corresponds to an android:process
* attribute within AndroidManifest.xml.
*/
public static String getProcessName() {
return ActivityThread.currentProcessName();
}
// ------------------ Internal API ------------------
/**
* @hide
*/
@UnsupportedAppUsage
/* package */ final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
@UnsupportedAppUsage
/* package */ void dispatchActivityPreCreated(@NonNull Activity activity,
@Nullable Bundle savedInstanceState) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((ActivityLifecycleCallbacks) callbacks[i]).onActivityPreCreated(activity,
savedInstanceState);
}
}
}
@UnsupportedAppUsage
/* package */ void dispatchActivityCreated(@NonNull Activity activity,
@Nullable Bundle savedInstanceState) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ActivityLifecycleCallbacks)callbacks[i]).onActivityCreated(activity,
savedInstanceState);
}
}
}
@UnsupportedAppUsage
/* package */ void dispatchActivityPostCreated(@NonNull Activity activity,
@Nullable Bundle savedInstanceState) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((ActivityLifecycleCallbacks) callbacks[i]).onActivityPostCreated(activity,
savedInstanceState);
}
}
}
@UnsupportedAppUsage
/* package */ void dispatchActivityPreStarted(@NonNull Activity activity) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((ActivityLifecycleCallbacks) callbacks[i]).onActivityPreStarted(activity);
}
}
}
@UnsupportedAppUsage
/* package */ void dispatchActivityStarted(@NonNull Activity activity) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ActivityLifecycleCallbacks)callbacks[i]).onActivityStarted(activity);
}
}
}
@UnsupportedAppUsage
/* package */ void dispatchActivityPostStarted(@NonNull Activity activity) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((ActivityLifecycleCallbacks) callbacks[i]).onActivityPostStarted(activity);
}
}
}
@UnsupportedAppUsage
/* package */ void dispatchActivityPreResumed(@NonNull Activity activity) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((ActivityLifecycleCallbacks) callbacks[i]).onActivityPreResumed(activity);
}
}
}
@UnsupportedAppUsage
/* package */ void dispatchActivityResumed(@NonNull Activity activity) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ActivityLifecycleCallbacks)callbacks[i]).onActivityResumed(activity);
}
}
}
@UnsupportedAppUsage
/* package */ void dispatchActivityPostResumed(@NonNull Activity activity) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((ActivityLifecycleCallbacks) callbacks[i]).onActivityPostResumed(activity);
}
}
}
@UnsupportedAppUsage
/* package */ void dispatchActivityPrePaused(@NonNull Activity activity) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((ActivityLifecycleCallbacks) callbacks[i]).onActivityPrePaused(activity);
}
}
}
@UnsupportedAppUsage
/* package */ void dispatchActivityPaused(@NonNull Activity activity) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ActivityLifecycleCallbacks)callbacks[i]).onActivityPaused(activity);
}
}
}
@UnsupportedAppUsage
/* package */ void dispatchActivityPostPaused(@NonNull Activity activity) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((ActivityLifecycleCallbacks) callbacks[i]).onActivityPostPaused(activity);
}
}
}
@UnsupportedAppUsage
/* package */ void dispatchActivityPreStopped(@NonNull Activity activity) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((ActivityLifecycleCallbacks) callbacks[i]).onActivityPreStopped(activity);
}
}
}
@UnsupportedAppUsage
/* package */ void dispatchActivityStopped(@NonNull Activity activity) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ActivityLifecycleCallbacks)callbacks[i]).onActivityStopped(activity);
}
}
}
@UnsupportedAppUsage
/* package */ void dispatchActivityPostStopped(@NonNull Activity activity) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((ActivityLifecycleCallbacks) callbacks[i]).onActivityPostStopped(activity);
}
}
}
@UnsupportedAppUsage
/* package */ void dispatchActivityPreSaveInstanceState(@NonNull Activity activity,
@NonNull Bundle outState) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((ActivityLifecycleCallbacks) callbacks[i]).onActivityPreSaveInstanceState(
activity, outState);
}
}
}
@UnsupportedAppUsage
/* package */ void dispatchActivitySaveInstanceState(@NonNull Activity activity,
@NonNull Bundle outState) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ActivityLifecycleCallbacks)callbacks[i]).onActivitySaveInstanceState(activity,
outState);
}
}
}
@UnsupportedAppUsage
/* package */ void dispatchActivityPostSaveInstanceState(@NonNull Activity activity,
@NonNull Bundle outState) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((ActivityLifecycleCallbacks) callbacks[i]).onActivityPostSaveInstanceState(
activity, outState);
}
}
}
@UnsupportedAppUsage
/* package */ void dispatchActivityPreDestroyed(@NonNull Activity activity) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((ActivityLifecycleCallbacks) callbacks[i]).onActivityPreDestroyed(activity);
}
}
}
@UnsupportedAppUsage
/* package */ void dispatchActivityDestroyed(@NonNull Activity activity) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ActivityLifecycleCallbacks)callbacks[i]).onActivityDestroyed(activity);
}
}
}
@UnsupportedAppUsage
/* package */ void dispatchActivityPostDestroyed(@NonNull Activity activity) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((ActivityLifecycleCallbacks) callbacks[i]).onActivityPostDestroyed(activity);
}
}
}
private Object[] collectComponentCallbacks() {
Object[] callbacks = null;
synchronized (mComponentCallbacks) {
if (mComponentCallbacks.size() > 0) {
callbacks = mComponentCallbacks.toArray();
}
}
return callbacks;
}
@UnsupportedAppUsage
private Object[] collectActivityLifecycleCallbacks() {
Object[] callbacks = null;
synchronized (mActivityLifecycleCallbacks) {
if (mActivityLifecycleCallbacks.size() > 0) {
callbacks = mActivityLifecycleCallbacks.toArray();
}
}
return callbacks;
}
/* package */ void dispatchOnProvideAssistData(Activity activity, Bundle data) {
Object[] callbacks;
synchronized (this) {
if (mAssistCallbacks == null) {
return;
}
callbacks = mAssistCallbacks.toArray();
}
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((OnProvideAssistDataListener)callbacks[i]).onProvideAssistData(activity, data);
}
}
}
/** @hide */
@Override
public AutofillManager.AutofillClient getAutofillClient() {
final AutofillManager.AutofillClient client = super.getAutofillClient();
if (client != null) {
return client;
}
if (android.view.autofill.Helper.sVerbose) {
Log.v(TAG, "getAutofillClient(): null on super, trying to find activity thread");
}
// Okay, ppl use the application context when they should not. This breaks
// autofill among other things. We pick the focused activity since autofill
// interacts only with the currently focused activity and we need the fill
// client only if a call comes from the focused activity. Sigh...
final ActivityThread activityThread = ActivityThread.currentActivityThread();
if (activityThread == null) {
return null;
}
final int activityCount = activityThread.mActivities.size();
for (int i = 0; i < activityCount; i++) {
final ActivityThread.ActivityClientRecord record =
activityThread.mActivities.valueAt(i);
if (record == null) {
continue;
}
final Activity activity = record.activity;
if (activity == null) {
continue;
}
if (activity.getWindow().getDecorView().hasFocus()) {
if (android.view.autofill.Helper.sVerbose) {
Log.v(TAG, "getAutofillClient(): found activity for " + this + ": " + activity);
}
return activity;
}
}
if (android.view.autofill.Helper.sVerbose) {
Log.v(TAG, "getAutofillClient(): none of the " + activityCount + " activities on "
+ this + " have focus");
}
return null;
}
}