Home | History | Annotate | Download | only in am
      1 /*
      2  * Copyright (C) 2006-2008 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 com.android.server.am;
     18 
     19 import com.android.internal.telephony.TelephonyIntents;
     20 import com.google.android.collect.Lists;
     21 import com.google.android.collect.Maps;
     22 import com.android.internal.R;
     23 import com.android.internal.annotations.GuardedBy;
     24 import com.android.internal.app.AssistUtils;
     25 import com.android.internal.app.DumpHeapActivity;
     26 import com.android.internal.app.IAppOpsCallback;
     27 import com.android.internal.app.IAppOpsService;
     28 import com.android.internal.app.IVoiceInteractor;
     29 import com.android.internal.app.ProcessMap;
     30 import com.android.internal.app.SystemUserHomeActivity;
     31 import com.android.internal.app.procstats.ProcessStats;
     32 import com.android.internal.os.BackgroundThread;
     33 import com.android.internal.os.BatteryStatsImpl;
     34 import com.android.internal.os.IResultReceiver;
     35 import com.android.internal.os.ProcessCpuTracker;
     36 import com.android.internal.os.TransferPipe;
     37 import com.android.internal.os.Zygote;
     38 import com.android.internal.os.InstallerConnection.InstallerException;
     39 import com.android.internal.util.ArrayUtils;
     40 import com.android.internal.util.FastPrintWriter;
     41 import com.android.internal.util.FastXmlSerializer;
     42 import com.android.internal.util.MemInfoReader;
     43 import com.android.internal.util.Preconditions;
     44 import com.android.server.AppOpsService;
     45 import com.android.server.AttributeCache;
     46 import com.android.server.DeviceIdleController;
     47 import com.android.server.IntentResolver;
     48 import com.android.server.LocalServices;
     49 import com.android.server.LockGuard;
     50 import com.android.server.ServiceThread;
     51 import com.android.server.SystemService;
     52 import com.android.server.SystemServiceManager;
     53 import com.android.server.Watchdog;
     54 import com.android.server.am.ActivityStack.ActivityState;
     55 import com.android.server.firewall.IntentFirewall;
     56 import com.android.server.pm.Installer;
     57 import com.android.server.statusbar.StatusBarManagerInternal;
     58 import com.android.server.vr.VrManagerInternal;
     59 import com.android.server.wm.WindowManagerService;
     60 
     61 import org.xmlpull.v1.XmlPullParser;
     62 import org.xmlpull.v1.XmlPullParserException;
     63 import org.xmlpull.v1.XmlSerializer;
     64 
     65 import android.Manifest;
     66 import android.annotation.UserIdInt;
     67 import android.app.Activity;
     68 import android.app.ActivityManager;
     69 import android.app.ActivityManager.RunningTaskInfo;
     70 import android.app.ActivityManager.StackId;
     71 import android.app.ActivityManager.StackInfo;
     72 import android.app.ActivityManager.TaskThumbnailInfo;
     73 import android.app.ActivityManagerInternal;
     74 import android.app.ActivityManagerInternal.SleepToken;
     75 import android.app.ActivityManagerNative;
     76 import android.app.ActivityOptions;
     77 import android.app.ActivityThread;
     78 import android.app.AlertDialog;
     79 import android.app.AppGlobals;
     80 import android.app.AppOpsManager;
     81 import android.app.ApplicationErrorReport;
     82 import android.app.ApplicationThreadNative;
     83 import android.app.BroadcastOptions;
     84 import android.app.Dialog;
     85 import android.app.IActivityContainer;
     86 import android.app.IActivityContainerCallback;
     87 import android.app.IActivityController;
     88 import android.app.IAppTask;
     89 import android.app.IApplicationThread;
     90 import android.app.IInstrumentationWatcher;
     91 import android.app.INotificationManager;
     92 import android.app.IProcessObserver;
     93 import android.app.IServiceConnection;
     94 import android.app.IStopUserCallback;
     95 import android.app.ITaskStackListener;
     96 import android.app.IUiAutomationConnection;
     97 import android.app.IUidObserver;
     98 import android.app.IUserSwitchObserver;
     99 import android.app.Instrumentation;
    100 import android.app.Notification;
    101 import android.app.NotificationManager;
    102 import android.app.PendingIntent;
    103 import android.app.ProfilerInfo;
    104 import android.app.admin.DevicePolicyManager;
    105 import android.app.assist.AssistContent;
    106 import android.app.assist.AssistStructure;
    107 import android.app.backup.IBackupManager;
    108 import android.app.usage.UsageEvents;
    109 import android.app.usage.UsageStatsManagerInternal;
    110 import android.appwidget.AppWidgetManager;
    111 import android.content.ActivityNotFoundException;
    112 import android.content.BroadcastReceiver;
    113 import android.content.ClipData;
    114 import android.content.ComponentCallbacks2;
    115 import android.content.ComponentName;
    116 import android.content.ContentProvider;
    117 import android.content.ContentResolver;
    118 import android.content.Context;
    119 import android.content.DialogInterface;
    120 import android.content.IContentProvider;
    121 import android.content.IIntentReceiver;
    122 import android.content.IIntentSender;
    123 import android.content.Intent;
    124 import android.content.IntentFilter;
    125 import android.content.IntentSender;
    126 import android.content.pm.ActivityInfo;
    127 import android.content.pm.ApplicationInfo;
    128 import android.content.pm.ConfigurationInfo;
    129 import android.content.pm.IPackageDataObserver;
    130 import android.content.pm.IPackageManager;
    131 import android.content.pm.InstrumentationInfo;
    132 import android.content.pm.PackageInfo;
    133 import android.content.pm.PackageManager;
    134 import android.content.pm.PackageManager.NameNotFoundException;
    135 import android.content.pm.PackageManagerInternal;
    136 import android.content.pm.ParceledListSlice;
    137 import android.content.pm.PathPermission;
    138 import android.content.pm.PermissionInfo;
    139 import android.content.pm.ProviderInfo;
    140 import android.content.pm.ResolveInfo;
    141 import android.content.pm.ServiceInfo;
    142 import android.content.pm.ShortcutServiceInternal;
    143 import android.content.pm.UserInfo;
    144 import android.content.res.CompatibilityInfo;
    145 import android.content.res.Configuration;
    146 import android.content.res.Resources;
    147 import android.database.ContentObserver;
    148 import android.graphics.Bitmap;
    149 import android.graphics.Point;
    150 import android.graphics.Rect;
    151 import android.location.LocationManager;
    152 import android.net.Proxy;
    153 import android.net.ProxyInfo;
    154 import android.net.Uri;
    155 import android.os.BatteryStats;
    156 import android.os.Binder;
    157 import android.os.Build;
    158 import android.os.Bundle;
    159 import android.os.Debug;
    160 import android.os.DropBoxManager;
    161 import android.os.Environment;
    162 import android.os.FactoryTest;
    163 import android.os.FileObserver;
    164 import android.os.FileUtils;
    165 import android.os.Handler;
    166 import android.os.IBinder;
    167 import android.os.IPermissionController;
    168 import android.os.IProcessInfoService;
    169 import android.os.IProgressListener;
    170 import android.os.LocaleList;
    171 import android.os.Looper;
    172 import android.os.Message;
    173 import android.os.Parcel;
    174 import android.os.ParcelFileDescriptor;
    175 import android.os.PersistableBundle;
    176 import android.os.PowerManager;
    177 import android.os.PowerManagerInternal;
    178 import android.os.Process;
    179 import android.os.RemoteCallbackList;
    180 import android.os.RemoteException;
    181 import android.os.ResultReceiver;
    182 import android.os.ServiceManager;
    183 import android.os.StrictMode;
    184 import android.os.SystemClock;
    185 import android.os.SystemProperties;
    186 import android.os.Trace;
    187 import android.os.TransactionTooLargeException;
    188 import android.os.UpdateLock;
    189 import android.os.UserHandle;
    190 import android.os.UserManager;
    191 import android.os.WorkSource;
    192 import android.os.storage.IMountService;
    193 import android.os.storage.MountServiceInternal;
    194 import android.os.storage.StorageManager;
    195 import android.provider.Settings;
    196 import android.service.voice.IVoiceInteractionSession;
    197 import android.service.voice.VoiceInteractionManagerInternal;
    198 import android.service.voice.VoiceInteractionSession;
    199 import android.telecom.TelecomManager;
    200 import android.text.format.DateUtils;
    201 import android.text.format.Time;
    202 import android.text.style.SuggestionSpan;
    203 import android.util.ArrayMap;
    204 import android.util.ArraySet;
    205 import android.util.AtomicFile;
    206 import android.util.DebugUtils;
    207 import android.util.DisplayMetrics;
    208 import android.util.EventLog;
    209 import android.util.Log;
    210 import android.util.Pair;
    211 import android.util.PrintWriterPrinter;
    212 import android.util.Slog;
    213 import android.util.SparseArray;
    214 import android.util.TimeUtils;
    215 import android.util.Xml;
    216 import android.view.Display;
    217 import android.view.Gravity;
    218 import android.view.LayoutInflater;
    219 import android.view.View;
    220 import android.view.WindowManager;
    221 
    222 import java.io.File;
    223 import java.io.FileDescriptor;
    224 import java.io.FileInputStream;
    225 import java.io.FileNotFoundException;
    226 import java.io.FileOutputStream;
    227 import java.io.IOException;
    228 import java.io.InputStreamReader;
    229 import java.io.PrintWriter;
    230 import java.io.StringWriter;
    231 import java.lang.ref.WeakReference;
    232 import java.nio.charset.StandardCharsets;
    233 import java.util.ArrayList;
    234 import java.util.Arrays;
    235 import java.util.Collections;
    236 import java.util.Comparator;
    237 import java.util.HashMap;
    238 import java.util.HashSet;
    239 import java.util.Iterator;
    240 import java.util.List;
    241 import java.util.Locale;
    242 import java.util.Map;
    243 import java.util.Objects;
    244 import java.util.Set;
    245 import java.util.concurrent.atomic.AtomicBoolean;
    246 import java.util.concurrent.atomic.AtomicLong;
    247 
    248 import dalvik.system.VMRuntime;
    249 
    250 import libcore.io.IoUtils;
    251 import libcore.util.EmptyArray;
    252 
    253 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
    254 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
    255 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
    256 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
    257 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
    258 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
    259 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
    260 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
    261 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
    262 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
    263 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
    264 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
    265 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
    266 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
    267 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
    268 import static android.content.pm.PackageManager.GET_PROVIDERS;
    269 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
    270 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
    271 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
    272 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
    273 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
    274 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
    275 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
    276 import static android.os.Process.PROC_CHAR;
    277 import static android.os.Process.PROC_OUT_LONG;
    278 import static android.os.Process.PROC_PARENS;
    279 import static android.os.Process.PROC_SPACE_TERM;
    280 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
    281 import static android.provider.Settings.Global.DEBUG_APP;
    282 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
    283 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
    284 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
    285 import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
    286 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
    287 import static android.provider.Settings.System.FONT_SCALE;
    288 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
    289 import static com.android.internal.util.XmlUtils.readIntAttribute;
    290 import static com.android.internal.util.XmlUtils.readLongAttribute;
    291 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
    292 import static com.android.internal.util.XmlUtils.writeIntAttribute;
    293 import static com.android.internal.util.XmlUtils.writeLongAttribute;
    294 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
    295 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
    296 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
    297 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
    298 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
    299 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
    300 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
    301 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
    302 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
    303 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
    304 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
    305 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
    306 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
    307 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
    308 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
    309 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
    310 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
    311 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
    312 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
    313 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
    314 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
    315 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
    316 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
    317 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
    318 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
    319 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
    320 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
    321 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
    322 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
    323 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
    324 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
    325 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
    326 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
    327 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
    328 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
    329 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
    330 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
    331 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
    332 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
    333 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
    334 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
    335 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
    336 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
    337 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
    338 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
    339 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
    340 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
    341 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
    342 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
    343 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
    344 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
    345 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
    346 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
    347 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
    348 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
    349 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
    350 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
    351 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
    352 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
    353 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
    354 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
    355 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
    356 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
    357 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
    358 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
    359 import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
    360 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
    361 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
    362 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
    363 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
    364 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
    365 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
    366 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
    367 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
    368 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
    369 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
    370 import static org.xmlpull.v1.XmlPullParser.START_TAG;
    371 
    372 public final class ActivityManagerService extends ActivityManagerNative
    373         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    374 
    375     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
    376     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
    377     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
    378     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
    379     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
    380     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
    381     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
    382     private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
    383     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
    384     private static final String TAG_LRU = TAG + POSTFIX_LRU;
    385     private static final String TAG_MU = TAG + POSTFIX_MU;
    386     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
    387     private static final String TAG_POWER = TAG + POSTFIX_POWER;
    388     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
    389     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
    390     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
    391     private static final String TAG_PSS = TAG + POSTFIX_PSS;
    392     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
    393     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
    394     private static final String TAG_STACK = TAG + POSTFIX_STACK;
    395     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
    396     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
    397     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
    398     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
    399     private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
    400 
    401     // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
    402     // here so that while the job scheduler can depend on AMS, the other way around
    403     // need not be the case.
    404     public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
    405 
    406     /** Control over CPU and battery monitoring */
    407     // write battery stats every 30 minutes.
    408     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
    409     static final boolean MONITOR_CPU_USAGE = true;
    410     // don't sample cpu less than every 5 seconds.
    411     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
    412     // wait possibly forever for next cpu sample.
    413     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
    414     static final boolean MONITOR_THREAD_CPU_USAGE = false;
    415 
    416     // The flags that are set for all calls we make to the package manager.
    417     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
    418 
    419     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
    420 
    421     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
    422 
    423     // Amount of time after a call to stopAppSwitches() during which we will
    424     // prevent further untrusted switches from happening.
    425     static final long APP_SWITCH_DELAY_TIME = 5*1000;
    426 
    427     // How long we wait for a launched process to attach to the activity manager
    428     // before we decide it's never going to come up for real.
    429     static final int PROC_START_TIMEOUT = 10*1000;
    430     // How long we wait for an attached process to publish its content providers
    431     // before we decide it must be hung.
    432     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
    433 
    434     // How long we will retain processes hosting content providers in the "last activity"
    435     // state before allowing them to drop down to the regular cached LRU list.  This is
    436     // to avoid thrashing of provider processes under low memory situations.
    437     static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
    438 
    439     // How long we wait for a launched process to attach to the activity manager
    440     // before we decide it's never going to come up for real, when the process was
    441     // started with a wrapper for instrumentation (such as Valgrind) because it
    442     // could take much longer than usual.
    443     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
    444 
    445     // How long to wait after going idle before forcing apps to GC.
    446     static final int GC_TIMEOUT = 5*1000;
    447 
    448     // The minimum amount of time between successive GC requests for a process.
    449     static final int GC_MIN_INTERVAL = 60*1000;
    450 
    451     // The minimum amount of time between successive PSS requests for a process.
    452     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
    453 
    454     // The minimum amount of time between successive PSS requests for a process
    455     // when the request is due to the memory state being lowered.
    456     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
    457 
    458     // The rate at which we check for apps using excessive power -- 15 mins.
    459     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
    460 
    461     // The minimum sample duration we will allow before deciding we have
    462     // enough data on wake locks to start killing things.
    463     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    464 
    465     // The minimum sample duration we will allow before deciding we have
    466     // enough data on CPU usage to start killing things.
    467     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    468 
    469     // How long we allow a receiver to run before giving up on it.
    470     static final int BROADCAST_FG_TIMEOUT = 10*1000;
    471     static final int BROADCAST_BG_TIMEOUT = 60*1000;
    472 
    473     // How long we wait until we timeout on key dispatching.
    474     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
    475 
    476     // How long we wait until we timeout on key dispatching during instrumentation.
    477     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
    478 
    479     // This is the amount of time an app needs to be running a foreground service before
    480     // we will consider it to be doing interaction for usage stats.
    481     static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
    482 
    483     // Maximum amount of time we will allow to elapse before re-reporting usage stats
    484     // interaction with foreground processes.
    485     static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
    486 
    487     // This is the amount of time we allow an app to settle after it goes into the background,
    488     // before we start restricting what it can do.
    489     static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
    490 
    491     // How long to wait in getAssistContextExtras for the activity and foreground services
    492     // to respond with the result.
    493     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
    494 
    495     // How long top wait when going through the modern assist (which doesn't need to block
    496     // on getting this result before starting to launch its UI).
    497     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
    498 
    499     // Maximum number of persisted Uri grants a package is allowed
    500     static final int MAX_PERSISTED_URI_GRANTS = 128;
    501 
    502     static final int MY_PID = Process.myPid();
    503 
    504     static final String[] EMPTY_STRING_ARRAY = new String[0];
    505 
    506     // How many bytes to write into the dropbox log before truncating
    507     static final int DROPBOX_MAX_SIZE = 192 * 1024;
    508     // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
    509     // as one line, but close enough for now.
    510     static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
    511 
    512     // Access modes for handleIncomingUser.
    513     static final int ALLOW_NON_FULL = 0;
    514     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
    515     static final int ALLOW_FULL_ONLY = 2;
    516 
    517     // Delay in notifying task stack change listeners (in millis)
    518     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
    519 
    520     // Necessary ApplicationInfo flags to mark an app as persistent
    521     private static final int PERSISTENT_MASK =
    522             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
    523 
    524     // Intent sent when remote bugreport collection has been completed
    525     private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
    526             "android.intent.action.REMOTE_BUGREPORT_FINISHED";
    527 
    528     // Delay to disable app launch boost
    529     static final int APP_BOOST_MESSAGE_DELAY = 3000;
    530     // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
    531     static final int APP_BOOST_TIMEOUT = 2500;
    532 
    533     // Used to indicate that a task is removed it should also be removed from recents.
    534     private static final boolean REMOVE_FROM_RECENTS = true;
    535     // Used to indicate that an app transition should be animated.
    536     static final boolean ANIMATE = true;
    537 
    538     // Determines whether to take full screen screenshots
    539     static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
    540     public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
    541 
    542     private static native int nativeMigrateToBoost();
    543     private static native int nativeMigrateFromBoost();
    544     private boolean mIsBoosted = false;
    545     private long mBoostStartTime = 0;
    546 
    547     /** All system services */
    548     SystemServiceManager mSystemServiceManager;
    549 
    550     private Installer mInstaller;
    551 
    552     /** Run all ActivityStacks through this */
    553     final ActivityStackSupervisor mStackSupervisor;
    554 
    555     final ActivityStarter mActivityStarter;
    556 
    557     /** Task stack change listeners. */
    558     private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
    559             new RemoteCallbackList<ITaskStackListener>();
    560 
    561     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
    562 
    563     public IntentFirewall mIntentFirewall;
    564 
    565     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
    566     // default actuion automatically.  Important for devices without direct input
    567     // devices.
    568     private boolean mShowDialogs = true;
    569     private boolean mInVrMode = false;
    570 
    571     BroadcastQueue mFgBroadcastQueue;
    572     BroadcastQueue mBgBroadcastQueue;
    573     // Convenient for easy iteration over the queues. Foreground is first
    574     // so that dispatch of foreground broadcasts gets precedence.
    575     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
    576 
    577     BroadcastStats mLastBroadcastStats;
    578     BroadcastStats mCurBroadcastStats;
    579 
    580     BroadcastQueue broadcastQueueForIntent(Intent intent) {
    581         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
    582         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
    583                 "Broadcast intent " + intent + " on "
    584                 + (isFg ? "foreground" : "background") + " queue");
    585         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
    586     }
    587 
    588     /**
    589      * Activity we have told the window manager to have key focus.
    590      */
    591     ActivityRecord mFocusedActivity = null;
    592 
    593     /**
    594      * User id of the last activity mFocusedActivity was set to.
    595      */
    596     private int mLastFocusedUserId;
    597 
    598     /**
    599      * If non-null, we are tracking the time the user spends in the currently focused app.
    600      */
    601     private AppTimeTracker mCurAppTimeTracker;
    602 
    603     /**
    604      * List of intents that were used to start the most recent tasks.
    605      */
    606     final RecentTasks mRecentTasks;
    607 
    608     /**
    609      * For addAppTask: cached of the last activity component that was added.
    610      */
    611     ComponentName mLastAddedTaskComponent;
    612 
    613     /**
    614      * For addAppTask: cached of the last activity uid that was added.
    615      */
    616     int mLastAddedTaskUid;
    617 
    618     /**
    619      * For addAppTask: cached of the last ActivityInfo that was added.
    620      */
    621     ActivityInfo mLastAddedTaskActivity;
    622 
    623     /**
    624      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
    625      */
    626     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
    627 
    628     /**
    629      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
    630      */
    631     String mDeviceOwnerName;
    632 
    633     final UserController mUserController;
    634 
    635     final AppErrors mAppErrors;
    636 
    637     boolean mDoingSetFocusedActivity;
    638 
    639     public boolean canShowErrorDialogs() {
    640         return mShowDialogs && !mSleeping && !mShuttingDown;
    641     }
    642 
    643     // it's a semaphore; boost when 0->1, reset when 1->0
    644     static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
    645         @Override protected Integer initialValue() {
    646             return 0;
    647         }
    648     };
    649 
    650     static void boostPriorityForLockedSection() {
    651         if (sIsBoosted.get() == 0) {
    652             // boost to prio 118 while holding a global lock
    653             Process.setThreadPriority(Process.myTid(), -2);
    654             //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
    655         }
    656         int cur = sIsBoosted.get();
    657         sIsBoosted.set(cur + 1);
    658     }
    659 
    660     static void resetPriorityAfterLockedSection() {
    661         sIsBoosted.set(sIsBoosted.get() - 1);
    662         if (sIsBoosted.get() == 0) {
    663             //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
    664             Process.setThreadPriority(Process.myTid(), 0);
    665         }
    666     }
    667     public class PendingAssistExtras extends Binder implements Runnable {
    668         public final ActivityRecord activity;
    669         public final Bundle extras;
    670         public final Intent intent;
    671         public final String hint;
    672         public final IResultReceiver receiver;
    673         public final int userHandle;
    674         public boolean haveResult = false;
    675         public Bundle result = null;
    676         public AssistStructure structure = null;
    677         public AssistContent content = null;
    678         public Bundle receiverExtras;
    679 
    680         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
    681                 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
    682             activity = _activity;
    683             extras = _extras;
    684             intent = _intent;
    685             hint = _hint;
    686             receiver = _receiver;
    687             receiverExtras = _receiverExtras;
    688             userHandle = _userHandle;
    689         }
    690         @Override
    691         public void run() {
    692             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
    693             synchronized (this) {
    694                 haveResult = true;
    695                 notifyAll();
    696             }
    697             pendingAssistExtrasTimedOut(this);
    698         }
    699     }
    700 
    701     final ArrayList<PendingAssistExtras> mPendingAssistExtras
    702             = new ArrayList<PendingAssistExtras>();
    703 
    704     /**
    705      * Process management.
    706      */
    707     final ProcessList mProcessList = new ProcessList();
    708 
    709     /**
    710      * All of the applications we currently have running organized by name.
    711      * The keys are strings of the application package name (as
    712      * returned by the package manager), and the keys are ApplicationRecord
    713      * objects.
    714      */
    715     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
    716 
    717     /**
    718      * Tracking long-term execution of processes to look for abuse and other
    719      * bad app behavior.
    720      */
    721     final ProcessStatsService mProcessStats;
    722 
    723     /**
    724      * The currently running isolated processes.
    725      */
    726     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
    727 
    728     /**
    729      * Counter for assigning isolated process uids, to avoid frequently reusing the
    730      * same ones.
    731      */
    732     int mNextIsolatedProcessUid = 0;
    733 
    734     /**
    735      * The currently running heavy-weight process, if any.
    736      */
    737     ProcessRecord mHeavyWeightProcess = null;
    738 
    739     /**
    740      * All of the processes we currently have running organized by pid.
    741      * The keys are the pid running the application.
    742      *
    743      * <p>NOTE: This object is protected by its own lock, NOT the global
    744      * activity manager lock!
    745      */
    746     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
    747 
    748     /**
    749      * All of the processes that have been forced to be foreground.  The key
    750      * is the pid of the caller who requested it (we hold a death
    751      * link on it).
    752      */
    753     abstract class ForegroundToken implements IBinder.DeathRecipient {
    754         int pid;
    755         IBinder token;
    756     }
    757     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
    758 
    759     /**
    760      * List of records for processes that someone had tried to start before the
    761      * system was ready.  We don't start them at that point, but ensure they
    762      * are started by the time booting is complete.
    763      */
    764     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
    765 
    766     /**
    767      * List of persistent applications that are in the process
    768      * of being started.
    769      */
    770     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
    771 
    772     /**
    773      * Processes that are being forcibly torn down.
    774      */
    775     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
    776 
    777     /**
    778      * List of running applications, sorted by recent usage.
    779      * The first entry in the list is the least recently used.
    780      */
    781     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
    782 
    783     /**
    784      * Where in mLruProcesses that the processes hosting activities start.
    785      */
    786     int mLruProcessActivityStart = 0;
    787 
    788     /**
    789      * Where in mLruProcesses that the processes hosting services start.
    790      * This is after (lower index) than mLruProcessesActivityStart.
    791      */
    792     int mLruProcessServiceStart = 0;
    793 
    794     /**
    795      * List of processes that should gc as soon as things are idle.
    796      */
    797     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
    798 
    799     /**
    800      * Processes we want to collect PSS data from.
    801      */
    802     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
    803 
    804     private boolean mBinderTransactionTrackingEnabled = false;
    805 
    806     /**
    807      * Last time we requested PSS data of all processes.
    808      */
    809     long mLastFullPssTime = SystemClock.uptimeMillis();
    810 
    811     /**
    812      * If set, the next time we collect PSS data we should do a full collection
    813      * with data from native processes and the kernel.
    814      */
    815     boolean mFullPssPending = false;
    816 
    817     /**
    818      * This is the process holding what we currently consider to be
    819      * the "home" activity.
    820      */
    821     ProcessRecord mHomeProcess;
    822 
    823     /**
    824      * This is the process holding the activity the user last visited that
    825      * is in a different process from the one they are currently in.
    826      */
    827     ProcessRecord mPreviousProcess;
    828 
    829     /**
    830      * The time at which the previous process was last visible.
    831      */
    832     long mPreviousProcessVisibleTime;
    833 
    834     /**
    835      * Track all uids that have actively running processes.
    836      */
    837     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
    838 
    839     /**
    840      * This is for verifying the UID report flow.
    841      */
    842     static final boolean VALIDATE_UID_STATES = true;
    843     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
    844 
    845     /**
    846      * Packages that the user has asked to have run in screen size
    847      * compatibility mode instead of filling the screen.
    848      */
    849     final CompatModePackages mCompatModePackages;
    850 
    851     /**
    852      * Set of IntentSenderRecord objects that are currently active.
    853      */
    854     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
    855             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
    856 
    857     /**
    858      * Fingerprints (hashCode()) of stack traces that we've
    859      * already logged DropBox entries for.  Guarded by itself.  If
    860      * something (rogue user app) forces this over
    861      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
    862      */
    863     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
    864     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
    865 
    866     /**
    867      * Strict Mode background batched logging state.
    868      *
    869      * The string buffer is guarded by itself, and its lock is also
    870      * used to determine if another batched write is already
    871      * in-flight.
    872      */
    873     private final StringBuilder mStrictModeBuffer = new StringBuilder();
    874 
    875     /**
    876      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
    877      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
    878      */
    879     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
    880 
    881     /**
    882      * Resolver for broadcast intents to registered receivers.
    883      * Holds BroadcastFilter (subclass of IntentFilter).
    884      */
    885     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
    886             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
    887         @Override
    888         protected boolean allowFilterResult(
    889                 BroadcastFilter filter, List<BroadcastFilter> dest) {
    890             IBinder target = filter.receiverList.receiver.asBinder();
    891             for (int i = dest.size() - 1; i >= 0; i--) {
    892                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
    893                     return false;
    894                 }
    895             }
    896             return true;
    897         }
    898 
    899         @Override
    900         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
    901             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
    902                     || userId == filter.owningUserId) {
    903                 return super.newResult(filter, match, userId);
    904             }
    905             return null;
    906         }
    907 
    908         @Override
    909         protected BroadcastFilter[] newArray(int size) {
    910             return new BroadcastFilter[size];
    911         }
    912 
    913         @Override
    914         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
    915             return packageName.equals(filter.packageName);
    916         }
    917     };
    918 
    919     /**
    920      * State of all active sticky broadcasts per user.  Keys are the action of the
    921      * sticky Intent, values are an ArrayList of all broadcasted intents with
    922      * that action (which should usually be one).  The SparseArray is keyed
    923      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
    924      * for stickies that are sent to all users.
    925      */
    926     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
    927             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
    928 
    929     final ActiveServices mServices;
    930 
    931     final static class Association {
    932         final int mSourceUid;
    933         final String mSourceProcess;
    934         final int mTargetUid;
    935         final ComponentName mTargetComponent;
    936         final String mTargetProcess;
    937 
    938         int mCount;
    939         long mTime;
    940 
    941         int mNesting;
    942         long mStartTime;
    943 
    944         // states of the source process when the bind occurred.
    945         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
    946         long mLastStateUptime;
    947         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
    948                 - ActivityManager.MIN_PROCESS_STATE+1];
    949 
    950         Association(int sourceUid, String sourceProcess, int targetUid,
    951                 ComponentName targetComponent, String targetProcess) {
    952             mSourceUid = sourceUid;
    953             mSourceProcess = sourceProcess;
    954             mTargetUid = targetUid;
    955             mTargetComponent = targetComponent;
    956             mTargetProcess = targetProcess;
    957         }
    958     }
    959 
    960     /**
    961      * When service association tracking is enabled, this is all of the associations we
    962      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
    963      * -> association data.
    964      */
    965     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
    966             mAssociations = new SparseArray<>();
    967     boolean mTrackingAssociations;
    968 
    969     /**
    970      * Backup/restore process management
    971      */
    972     String mBackupAppName = null;
    973     BackupRecord mBackupTarget = null;
    974 
    975     final ProviderMap mProviderMap;
    976 
    977     /**
    978      * List of content providers who have clients waiting for them.  The
    979      * application is currently being launched and the provider will be
    980      * removed from this list once it is published.
    981      */
    982     final ArrayList<ContentProviderRecord> mLaunchingProviders
    983             = new ArrayList<ContentProviderRecord>();
    984 
    985     /**
    986      * File storing persisted {@link #mGrantedUriPermissions}.
    987      */
    988     private final AtomicFile mGrantFile;
    989 
    990     /** XML constants used in {@link #mGrantFile} */
    991     private static final String TAG_URI_GRANTS = "uri-grants";
    992     private static final String TAG_URI_GRANT = "uri-grant";
    993     private static final String ATTR_USER_HANDLE = "userHandle";
    994     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
    995     private static final String ATTR_TARGET_USER_ID = "targetUserId";
    996     private static final String ATTR_SOURCE_PKG = "sourcePkg";
    997     private static final String ATTR_TARGET_PKG = "targetPkg";
    998     private static final String ATTR_URI = "uri";
    999     private static final String ATTR_MODE_FLAGS = "modeFlags";
   1000     private static final String ATTR_CREATED_TIME = "createdTime";
   1001     private static final String ATTR_PREFIX = "prefix";
   1002 
   1003     /**
   1004      * Global set of specific {@link Uri} permissions that have been granted.
   1005      * This optimized lookup structure maps from {@link UriPermission#targetUid}
   1006      * to {@link UriPermission#uri} to {@link UriPermission}.
   1007      */
   1008     @GuardedBy("this")
   1009     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
   1010             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
   1011 
   1012     public static class GrantUri {
   1013         public final int sourceUserId;
   1014         public final Uri uri;
   1015         public boolean prefix;
   1016 
   1017         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
   1018             this.sourceUserId = sourceUserId;
   1019             this.uri = uri;
   1020             this.prefix = prefix;
   1021         }
   1022 
   1023         @Override
   1024         public int hashCode() {
   1025             int hashCode = 1;
   1026             hashCode = 31 * hashCode + sourceUserId;
   1027             hashCode = 31 * hashCode + uri.hashCode();
   1028             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
   1029             return hashCode;
   1030         }
   1031 
   1032         @Override
   1033         public boolean equals(Object o) {
   1034             if (o instanceof GrantUri) {
   1035                 GrantUri other = (GrantUri) o;
   1036                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
   1037                         && prefix == other.prefix;
   1038             }
   1039             return false;
   1040         }
   1041 
   1042         @Override
   1043         public String toString() {
   1044             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
   1045             if (prefix) result += " [prefix]";
   1046             return result;
   1047         }
   1048 
   1049         public String toSafeString() {
   1050             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
   1051             if (prefix) result += " [prefix]";
   1052             return result;
   1053         }
   1054 
   1055         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
   1056             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
   1057                     ContentProvider.getUriWithoutUserId(uri), false);
   1058         }
   1059     }
   1060 
   1061     CoreSettingsObserver mCoreSettingsObserver;
   1062 
   1063     FontScaleSettingObserver mFontScaleSettingObserver;
   1064 
   1065     private final class FontScaleSettingObserver extends ContentObserver {
   1066         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
   1067 
   1068         public FontScaleSettingObserver() {
   1069             super(mHandler);
   1070             ContentResolver resolver = mContext.getContentResolver();
   1071             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
   1072         }
   1073 
   1074         @Override
   1075         public void onChange(boolean selfChange, Uri uri) {
   1076             if (mFontScaleUri.equals(uri)) {
   1077                 updateFontScaleIfNeeded();
   1078             }
   1079         }
   1080     }
   1081 
   1082     /**
   1083      * Thread-local storage used to carry caller permissions over through
   1084      * indirect content-provider access.
   1085      */
   1086     private class Identity {
   1087         public final IBinder token;
   1088         public final int pid;
   1089         public final int uid;
   1090 
   1091         Identity(IBinder _token, int _pid, int _uid) {
   1092             token = _token;
   1093             pid = _pid;
   1094             uid = _uid;
   1095         }
   1096     }
   1097 
   1098     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
   1099 
   1100     /**
   1101      * All information we have collected about the runtime performance of
   1102      * any user id that can impact battery performance.
   1103      */
   1104     final BatteryStatsService mBatteryStatsService;
   1105 
   1106     /**
   1107      * Information about component usage
   1108      */
   1109     UsageStatsManagerInternal mUsageStatsService;
   1110 
   1111     /**
   1112      * Access to DeviceIdleController service.
   1113      */
   1114     DeviceIdleController.LocalService mLocalDeviceIdleController;
   1115 
   1116     /**
   1117      * Information about and control over application operations
   1118      */
   1119     final AppOpsService mAppOpsService;
   1120 
   1121     /**
   1122      * Current configuration information.  HistoryRecord objects are given
   1123      * a reference to this object to indicate which configuration they are
   1124      * currently running in, so this object must be kept immutable.
   1125      */
   1126     Configuration mConfiguration = new Configuration();
   1127 
   1128     /**
   1129      * Current sequencing integer of the configuration, for skipping old
   1130      * configurations.
   1131      */
   1132     int mConfigurationSeq = 0;
   1133 
   1134     boolean mSuppressResizeConfigChanges = false;
   1135 
   1136     /**
   1137      * Hardware-reported OpenGLES version.
   1138      */
   1139     final int GL_ES_VERSION;
   1140 
   1141     /**
   1142      * List of initialization arguments to pass to all processes when binding applications to them.
   1143      * For example, references to the commonly used services.
   1144      */
   1145     HashMap<String, IBinder> mAppBindArgs;
   1146 
   1147     /**
   1148      * Temporary to avoid allocations.  Protected by main lock.
   1149      */
   1150     final StringBuilder mStringBuilder = new StringBuilder(256);
   1151 
   1152     /**
   1153      * Used to control how we initialize the service.
   1154      */
   1155     ComponentName mTopComponent;
   1156     String mTopAction = Intent.ACTION_MAIN;
   1157     String mTopData;
   1158 
   1159     volatile boolean mProcessesReady = false;
   1160     volatile boolean mSystemReady = false;
   1161     volatile boolean mOnBattery = false;
   1162     volatile int mFactoryTest;
   1163 
   1164     @GuardedBy("this") boolean mBooting = false;
   1165     @GuardedBy("this") boolean mCallFinishBooting = false;
   1166     @GuardedBy("this") boolean mBootAnimationComplete = false;
   1167     @GuardedBy("this") boolean mLaunchWarningShown = false;
   1168     @GuardedBy("this") boolean mCheckedForSetup = false;
   1169 
   1170     Context mContext;
   1171 
   1172     /**
   1173      * The time at which we will allow normal application switches again,
   1174      * after a call to {@link #stopAppSwitches()}.
   1175      */
   1176     long mAppSwitchesAllowedTime;
   1177 
   1178     /**
   1179      * This is set to true after the first switch after mAppSwitchesAllowedTime
   1180      * is set; any switches after that will clear the time.
   1181      */
   1182     boolean mDidAppSwitch;
   1183 
   1184     /**
   1185      * Last time (in realtime) at which we checked for power usage.
   1186      */
   1187     long mLastPowerCheckRealtime;
   1188 
   1189     /**
   1190      * Last time (in uptime) at which we checked for power usage.
   1191      */
   1192     long mLastPowerCheckUptime;
   1193 
   1194     /**
   1195      * Set while we are wanting to sleep, to prevent any
   1196      * activities from being started/resumed.
   1197      */
   1198     private boolean mSleeping = false;
   1199 
   1200     /**
   1201      * The process state used for processes that are running the top activities.
   1202      * This changes between TOP and TOP_SLEEPING to following mSleeping.
   1203      */
   1204     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
   1205 
   1206     /**
   1207      * Set while we are running a voice interaction.  This overrides
   1208      * sleeping while it is active.
   1209      */
   1210     private IVoiceInteractionSession mRunningVoice;
   1211 
   1212     /**
   1213      * For some direct access we need to power manager.
   1214      */
   1215     PowerManagerInternal mLocalPowerManager;
   1216 
   1217     /**
   1218      * We want to hold a wake lock while running a voice interaction session, since
   1219      * this may happen with the screen off and we need to keep the CPU running to
   1220      * be able to continue to interact with the user.
   1221      */
   1222     PowerManager.WakeLock mVoiceWakeLock;
   1223 
   1224     /**
   1225      * State of external calls telling us if the device is awake or asleep.
   1226      */
   1227     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
   1228 
   1229     /**
   1230      * A list of tokens that cause the top activity to be put to sleep.
   1231      * They are used by components that may hide and block interaction with underlying
   1232      * activities.
   1233      */
   1234     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
   1235 
   1236     static final int LOCK_SCREEN_HIDDEN = 0;
   1237     static final int LOCK_SCREEN_LEAVING = 1;
   1238     static final int LOCK_SCREEN_SHOWN = 2;
   1239     /**
   1240      * State of external call telling us if the lock screen is shown.
   1241      */
   1242     int mLockScreenShown = LOCK_SCREEN_HIDDEN;
   1243 
   1244     /**
   1245      * Set if we are shutting down the system, similar to sleeping.
   1246      */
   1247     boolean mShuttingDown = false;
   1248 
   1249     /**
   1250      * Current sequence id for oom_adj computation traversal.
   1251      */
   1252     int mAdjSeq = 0;
   1253 
   1254     /**
   1255      * Current sequence id for process LRU updating.
   1256      */
   1257     int mLruSeq = 0;
   1258 
   1259     /**
   1260      * Keep track of the non-cached/empty process we last found, to help
   1261      * determine how to distribute cached/empty processes next time.
   1262      */
   1263     int mNumNonCachedProcs = 0;
   1264 
   1265     /**
   1266      * Keep track of the number of cached hidden procs, to balance oom adj
   1267      * distribution between those and empty procs.
   1268      */
   1269     int mNumCachedHiddenProcs = 0;
   1270 
   1271     /**
   1272      * Keep track of the number of service processes we last found, to
   1273      * determine on the next iteration which should be B services.
   1274      */
   1275     int mNumServiceProcs = 0;
   1276     int mNewNumAServiceProcs = 0;
   1277     int mNewNumServiceProcs = 0;
   1278 
   1279     /**
   1280      * Allow the current computed overall memory level of the system to go down?
   1281      * This is set to false when we are killing processes for reasons other than
   1282      * memory management, so that the now smaller process list will not be taken as
   1283      * an indication that memory is tighter.
   1284      */
   1285     boolean mAllowLowerMemLevel = false;
   1286 
   1287     /**
   1288      * The last computed memory level, for holding when we are in a state that
   1289      * processes are going away for other reasons.
   1290      */
   1291     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
   1292 
   1293     /**
   1294      * The last total number of process we have, to determine if changes actually look
   1295      * like a shrinking number of process due to lower RAM.
   1296      */
   1297     int mLastNumProcesses;
   1298 
   1299     /**
   1300      * The uptime of the last time we performed idle maintenance.
   1301      */
   1302     long mLastIdleTime = SystemClock.uptimeMillis();
   1303 
   1304     /**
   1305      * Total time spent with RAM that has been added in the past since the last idle time.
   1306      */
   1307     long mLowRamTimeSinceLastIdle = 0;
   1308 
   1309     /**
   1310      * If RAM is currently low, when that horrible situation started.
   1311      */
   1312     long mLowRamStartTime = 0;
   1313 
   1314     /**
   1315      * For reporting to battery stats the current top application.
   1316      */
   1317     private String mCurResumedPackage = null;
   1318     private int mCurResumedUid = -1;
   1319 
   1320     /**
   1321      * For reporting to battery stats the apps currently running foreground
   1322      * service.  The ProcessMap is package/uid tuples; each of these contain
   1323      * an array of the currently foreground processes.
   1324      */
   1325     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
   1326             = new ProcessMap<ArrayList<ProcessRecord>>();
   1327 
   1328     /**
   1329      * This is set if we had to do a delayed dexopt of an app before launching
   1330      * it, to increase the ANR timeouts in that case.
   1331      */
   1332     boolean mDidDexOpt;
   1333 
   1334     /**
   1335      * Set if the systemServer made a call to enterSafeMode.
   1336      */
   1337     boolean mSafeMode;
   1338 
   1339     /**
   1340      * If true, we are running under a test environment so will sample PSS from processes
   1341      * much more rapidly to try to collect better data when the tests are rapidly
   1342      * running through apps.
   1343      */
   1344     boolean mTestPssMode = false;
   1345 
   1346     String mDebugApp = null;
   1347     boolean mWaitForDebugger = false;
   1348     boolean mDebugTransient = false;
   1349     String mOrigDebugApp = null;
   1350     boolean mOrigWaitForDebugger = false;
   1351     boolean mAlwaysFinishActivities = false;
   1352     boolean mLenientBackgroundCheck = false;
   1353     boolean mForceResizableActivities;
   1354     boolean mSupportsMultiWindow;
   1355     boolean mSupportsFreeformWindowManagement;
   1356     boolean mSupportsPictureInPicture;
   1357     boolean mSupportsLeanbackOnly;
   1358     Rect mDefaultPinnedStackBounds;
   1359     IActivityController mController = null;
   1360     boolean mControllerIsAMonkey = false;
   1361     String mProfileApp = null;
   1362     ProcessRecord mProfileProc = null;
   1363     String mProfileFile;
   1364     ParcelFileDescriptor mProfileFd;
   1365     int mSamplingInterval = 0;
   1366     boolean mAutoStopProfiler = false;
   1367     int mProfileType = 0;
   1368     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
   1369     String mMemWatchDumpProcName;
   1370     String mMemWatchDumpFile;
   1371     int mMemWatchDumpPid;
   1372     int mMemWatchDumpUid;
   1373     String mTrackAllocationApp = null;
   1374     String mNativeDebuggingApp = null;
   1375 
   1376     final long[] mTmpLong = new long[2];
   1377 
   1378     static final class ProcessChangeItem {
   1379         static final int CHANGE_ACTIVITIES = 1<<0;
   1380         static final int CHANGE_PROCESS_STATE = 1<<1;
   1381         int changes;
   1382         int uid;
   1383         int pid;
   1384         int processState;
   1385         boolean foregroundActivities;
   1386     }
   1387 
   1388     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
   1389     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
   1390 
   1391     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
   1392     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
   1393 
   1394     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
   1395     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
   1396 
   1397     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
   1398     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
   1399 
   1400     /**
   1401      * Runtime CPU use collection thread.  This object's lock is used to
   1402      * perform synchronization with the thread (notifying it to run).
   1403      */
   1404     final Thread mProcessCpuThread;
   1405 
   1406     /**
   1407      * Used to collect per-process CPU use for ANRs, battery stats, etc.
   1408      * Must acquire this object's lock when accessing it.
   1409      * NOTE: this lock will be held while doing long operations (trawling
   1410      * through all processes in /proc), so it should never be acquired by
   1411      * any critical paths such as when holding the main activity manager lock.
   1412      */
   1413     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
   1414             MONITOR_THREAD_CPU_USAGE);
   1415     final AtomicLong mLastCpuTime = new AtomicLong(0);
   1416     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
   1417 
   1418     long mLastWriteTime = 0;
   1419 
   1420     /**
   1421      * Used to retain an update lock when the foreground activity is in
   1422      * immersive mode.
   1423      */
   1424     final UpdateLock mUpdateLock = new UpdateLock("immersive");
   1425 
   1426     /**
   1427      * Set to true after the system has finished booting.
   1428      */
   1429     boolean mBooted = false;
   1430 
   1431     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
   1432     int mProcessLimitOverride = -1;
   1433 
   1434     WindowManagerService mWindowManager;
   1435     final ActivityThread mSystemThread;
   1436 
   1437     private final class AppDeathRecipient implements IBinder.DeathRecipient {
   1438         final ProcessRecord mApp;
   1439         final int mPid;
   1440         final IApplicationThread mAppThread;
   1441 
   1442         AppDeathRecipient(ProcessRecord app, int pid,
   1443                 IApplicationThread thread) {
   1444             if (DEBUG_ALL) Slog.v(
   1445                 TAG, "New death recipient " + this
   1446                 + " for thread " + thread.asBinder());
   1447             mApp = app;
   1448             mPid = pid;
   1449             mAppThread = thread;
   1450         }
   1451 
   1452         @Override
   1453         public void binderDied() {
   1454             if (DEBUG_ALL) Slog.v(
   1455                 TAG, "Death received in " + this
   1456                 + " for thread " + mAppThread.asBinder());
   1457             synchronized(ActivityManagerService.this) {
   1458                 appDiedLocked(mApp, mPid, mAppThread, true);
   1459             }
   1460         }
   1461     }
   1462 
   1463     static final int SHOW_ERROR_UI_MSG = 1;
   1464     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
   1465     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
   1466     static final int UPDATE_CONFIGURATION_MSG = 4;
   1467     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
   1468     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
   1469     static final int SERVICE_TIMEOUT_MSG = 12;
   1470     static final int UPDATE_TIME_ZONE = 13;
   1471     static final int SHOW_UID_ERROR_UI_MSG = 14;
   1472     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
   1473     static final int PROC_START_TIMEOUT_MSG = 20;
   1474     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
   1475     static final int KILL_APPLICATION_MSG = 22;
   1476     static final int FINALIZE_PENDING_INTENT_MSG = 23;
   1477     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
   1478     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
   1479     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
   1480     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
   1481     static final int CLEAR_DNS_CACHE_MSG = 28;
   1482     static final int UPDATE_HTTP_PROXY_MSG = 29;
   1483     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
   1484     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
   1485     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
   1486     static final int REPORT_MEM_USAGE_MSG = 33;
   1487     static final int REPORT_USER_SWITCH_MSG = 34;
   1488     static final int CONTINUE_USER_SWITCH_MSG = 35;
   1489     static final int USER_SWITCH_TIMEOUT_MSG = 36;
   1490     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
   1491     static final int PERSIST_URI_GRANTS_MSG = 38;
   1492     static final int REQUEST_ALL_PSS_MSG = 39;
   1493     static final int START_PROFILES_MSG = 40;
   1494     static final int UPDATE_TIME = 41;
   1495     static final int SYSTEM_USER_START_MSG = 42;
   1496     static final int SYSTEM_USER_CURRENT_MSG = 43;
   1497     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
   1498     static final int FINISH_BOOTING_MSG = 45;
   1499     static final int START_USER_SWITCH_UI_MSG = 46;
   1500     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
   1501     static final int DISMISS_DIALOG_UI_MSG = 48;
   1502     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
   1503     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
   1504     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
   1505     static final int DELETE_DUMPHEAP_MSG = 52;
   1506     static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
   1507     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
   1508     static final int REPORT_TIME_TRACKER_MSG = 55;
   1509     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
   1510     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
   1511     static final int APP_BOOST_DEACTIVATE_MSG = 58;
   1512     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
   1513     static final int IDLE_UIDS_MSG = 60;
   1514     static final int SYSTEM_USER_UNLOCK_MSG = 61;
   1515     static final int LOG_STACK_STATE = 62;
   1516     static final int VR_MODE_CHANGE_MSG = 63;
   1517     static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
   1518     static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
   1519     static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
   1520     static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
   1521     static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
   1522     static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
   1523     static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
   1524 
   1525     static final int FIRST_ACTIVITY_STACK_MSG = 100;
   1526     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
   1527     static final int FIRST_COMPAT_MODE_MSG = 300;
   1528     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
   1529 
   1530     static ServiceThread sKillThread = null;
   1531     static KillHandler sKillHandler = null;
   1532 
   1533     CompatModeDialog mCompatModeDialog;
   1534     UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
   1535     long mLastMemUsageReportTime = 0;
   1536 
   1537     /**
   1538      * Flag whether the current user is a "monkey", i.e. whether
   1539      * the UI is driven by a UI automation tool.
   1540      */
   1541     private boolean mUserIsMonkey;
   1542 
   1543     /** Flag whether the device has a Recents UI */
   1544     boolean mHasRecents;
   1545 
   1546     /** The dimensions of the thumbnails in the Recents UI. */
   1547     int mThumbnailWidth;
   1548     int mThumbnailHeight;
   1549     float mFullscreenThumbnailScale;
   1550 
   1551     final ServiceThread mHandlerThread;
   1552     final MainHandler mHandler;
   1553     final UiHandler mUiHandler;
   1554 
   1555     PackageManagerInternal mPackageManagerInt;
   1556 
   1557     // VoiceInteraction session ID that changes for each new request except when
   1558     // being called for multiwindow assist in a single session.
   1559     private int mViSessionId = 1000;
   1560 
   1561     final class KillHandler extends Handler {
   1562         static final int KILL_PROCESS_GROUP_MSG = 4000;
   1563 
   1564         public KillHandler(Looper looper) {
   1565             super(looper, null, true);
   1566         }
   1567 
   1568         @Override
   1569         public void handleMessage(Message msg) {
   1570             switch (msg.what) {
   1571                 case KILL_PROCESS_GROUP_MSG:
   1572                 {
   1573                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
   1574                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
   1575                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   1576                 }
   1577                 break;
   1578 
   1579                 default:
   1580                     super.handleMessage(msg);
   1581             }
   1582         }
   1583     }
   1584 
   1585     final class UiHandler extends Handler {
   1586         public UiHandler() {
   1587             super(com.android.server.UiThread.get().getLooper(), null, true);
   1588         }
   1589 
   1590         @Override
   1591         public void handleMessage(Message msg) {
   1592             switch (msg.what) {
   1593             case SHOW_ERROR_UI_MSG: {
   1594                 mAppErrors.handleShowAppErrorUi(msg);
   1595                 ensureBootCompleted();
   1596             } break;
   1597             case SHOW_NOT_RESPONDING_UI_MSG: {
   1598                 mAppErrors.handleShowAnrUi(msg);
   1599                 ensureBootCompleted();
   1600             } break;
   1601             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
   1602                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
   1603                 synchronized (ActivityManagerService.this) {
   1604                     ProcessRecord proc = (ProcessRecord) data.get("app");
   1605                     if (proc == null) {
   1606                         Slog.e(TAG, "App not found when showing strict mode dialog.");
   1607                         break;
   1608                     }
   1609                     if (proc.crashDialog != null) {
   1610                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
   1611                         return;
   1612                     }
   1613                     AppErrorResult res = (AppErrorResult) data.get("result");
   1614                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
   1615                         Dialog d = new StrictModeViolationDialog(mContext,
   1616                                 ActivityManagerService.this, res, proc);
   1617                         d.show();
   1618                         proc.crashDialog = d;
   1619                     } else {
   1620                         // The device is asleep, so just pretend that the user
   1621                         // saw a crash dialog and hit "force quit".
   1622                         res.set(0);
   1623                     }
   1624                 }
   1625                 ensureBootCompleted();
   1626             } break;
   1627             case SHOW_FACTORY_ERROR_UI_MSG: {
   1628                 Dialog d = new FactoryErrorDialog(
   1629                     mContext, msg.getData().getCharSequence("msg"));
   1630                 d.show();
   1631                 ensureBootCompleted();
   1632             } break;
   1633             case WAIT_FOR_DEBUGGER_UI_MSG: {
   1634                 synchronized (ActivityManagerService.this) {
   1635                     ProcessRecord app = (ProcessRecord)msg.obj;
   1636                     if (msg.arg1 != 0) {
   1637                         if (!app.waitedForDebugger) {
   1638                             Dialog d = new AppWaitingForDebuggerDialog(
   1639                                     ActivityManagerService.this,
   1640                                     mContext, app);
   1641                             app.waitDialog = d;
   1642                             app.waitedForDebugger = true;
   1643                             d.show();
   1644                         }
   1645                     } else {
   1646                         if (app.waitDialog != null) {
   1647                             app.waitDialog.dismiss();
   1648                             app.waitDialog = null;
   1649                         }
   1650                     }
   1651                 }
   1652             } break;
   1653             case SHOW_UID_ERROR_UI_MSG: {
   1654                 if (mShowDialogs) {
   1655                     AlertDialog d = new BaseErrorDialog(mContext);
   1656                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   1657                     d.setCancelable(false);
   1658                     d.setTitle(mContext.getText(R.string.android_system_label));
   1659                     d.setMessage(mContext.getText(R.string.system_error_wipe_data));
   1660                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
   1661                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
   1662                     d.show();
   1663                 }
   1664             } break;
   1665             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
   1666                 if (mShowDialogs) {
   1667                     AlertDialog d = new BaseErrorDialog(mContext);
   1668                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   1669                     d.setCancelable(false);
   1670                     d.setTitle(mContext.getText(R.string.android_system_label));
   1671                     d.setMessage(mContext.getText(R.string.system_error_manufacturer));
   1672                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
   1673                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
   1674                     d.show();
   1675                 }
   1676             } break;
   1677             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
   1678                 synchronized (ActivityManagerService.this) {
   1679                     ActivityRecord ar = (ActivityRecord) msg.obj;
   1680                     if (mCompatModeDialog != null) {
   1681                         if (mCompatModeDialog.mAppInfo.packageName.equals(
   1682                                 ar.info.applicationInfo.packageName)) {
   1683                             return;
   1684                         }
   1685                         mCompatModeDialog.dismiss();
   1686                         mCompatModeDialog = null;
   1687                     }
   1688                     if (ar != null && false) {
   1689                         if (mCompatModePackages.getPackageAskCompatModeLocked(
   1690                                 ar.packageName)) {
   1691                             int mode = mCompatModePackages.computeCompatModeLocked(
   1692                                     ar.info.applicationInfo);
   1693                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
   1694                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
   1695                                 mCompatModeDialog = new CompatModeDialog(
   1696                                         ActivityManagerService.this, mContext,
   1697                                         ar.info.applicationInfo);
   1698                                 mCompatModeDialog.show();
   1699                             }
   1700                         }
   1701                     }
   1702                 }
   1703                 break;
   1704             }
   1705             case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
   1706                 synchronized (ActivityManagerService.this) {
   1707                     final ActivityRecord ar = (ActivityRecord) msg.obj;
   1708                     if (mUnsupportedDisplaySizeDialog != null) {
   1709                         mUnsupportedDisplaySizeDialog.dismiss();
   1710                         mUnsupportedDisplaySizeDialog = null;
   1711                     }
   1712                     if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
   1713                             ar.packageName)) {
   1714                         mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
   1715                                 ActivityManagerService.this, mContext, ar.info.applicationInfo);
   1716                         mUnsupportedDisplaySizeDialog.show();
   1717                     }
   1718                 }
   1719                 break;
   1720             }
   1721             case START_USER_SWITCH_UI_MSG: {
   1722                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
   1723                 break;
   1724             }
   1725             case DISMISS_DIALOG_UI_MSG: {
   1726                 final Dialog d = (Dialog) msg.obj;
   1727                 d.dismiss();
   1728                 break;
   1729             }
   1730             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
   1731                 dispatchProcessesChanged();
   1732                 break;
   1733             }
   1734             case DISPATCH_PROCESS_DIED_UI_MSG: {
   1735                 final int pid = msg.arg1;
   1736                 final int uid = msg.arg2;
   1737                 dispatchProcessDied(pid, uid);
   1738                 break;
   1739             }
   1740             case DISPATCH_UIDS_CHANGED_UI_MSG: {
   1741                 dispatchUidsChanged();
   1742             } break;
   1743             }
   1744         }
   1745     }
   1746 
   1747     final class MainHandler extends Handler {
   1748         public MainHandler(Looper looper) {
   1749             super(looper, null, true);
   1750         }
   1751 
   1752         @Override
   1753         public void handleMessage(Message msg) {
   1754             switch (msg.what) {
   1755             case UPDATE_CONFIGURATION_MSG: {
   1756                 final ContentResolver resolver = mContext.getContentResolver();
   1757                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
   1758                         msg.arg1);
   1759             } break;
   1760             case GC_BACKGROUND_PROCESSES_MSG: {
   1761                 synchronized (ActivityManagerService.this) {
   1762                     performAppGcsIfAppropriateLocked();
   1763                 }
   1764             } break;
   1765             case SERVICE_TIMEOUT_MSG: {
   1766                 if (mDidDexOpt) {
   1767                     mDidDexOpt = false;
   1768                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   1769                     nmsg.obj = msg.obj;
   1770                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
   1771                     return;
   1772                 }
   1773                 mServices.serviceTimeout((ProcessRecord)msg.obj);
   1774             } break;
   1775             case UPDATE_TIME_ZONE: {
   1776                 synchronized (ActivityManagerService.this) {
   1777                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1778                         ProcessRecord r = mLruProcesses.get(i);
   1779                         if (r.thread != null) {
   1780                             try {
   1781                                 r.thread.updateTimeZone();
   1782                             } catch (RemoteException ex) {
   1783                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
   1784                             }
   1785                         }
   1786                     }
   1787                 }
   1788             } break;
   1789             case CLEAR_DNS_CACHE_MSG: {
   1790                 synchronized (ActivityManagerService.this) {
   1791                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1792                         ProcessRecord r = mLruProcesses.get(i);
   1793                         if (r.thread != null) {
   1794                             try {
   1795                                 r.thread.clearDnsCache();
   1796                             } catch (RemoteException ex) {
   1797                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
   1798                             }
   1799                         }
   1800                     }
   1801                 }
   1802             } break;
   1803             case UPDATE_HTTP_PROXY_MSG: {
   1804                 ProxyInfo proxy = (ProxyInfo)msg.obj;
   1805                 String host = "";
   1806                 String port = "";
   1807                 String exclList = "";
   1808                 Uri pacFileUrl = Uri.EMPTY;
   1809                 if (proxy != null) {
   1810                     host = proxy.getHost();
   1811                     port = Integer.toString(proxy.getPort());
   1812                     exclList = proxy.getExclusionListAsString();
   1813                     pacFileUrl = proxy.getPacFileUrl();
   1814                 }
   1815                 synchronized (ActivityManagerService.this) {
   1816                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1817                         ProcessRecord r = mLruProcesses.get(i);
   1818                         if (r.thread != null) {
   1819                             try {
   1820                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
   1821                             } catch (RemoteException ex) {
   1822                                 Slog.w(TAG, "Failed to update http proxy for: " +
   1823                                         r.info.processName);
   1824                             }
   1825                         }
   1826                     }
   1827                 }
   1828             } break;
   1829             case PROC_START_TIMEOUT_MSG: {
   1830                 if (mDidDexOpt) {
   1831                     mDidDexOpt = false;
   1832                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   1833                     nmsg.obj = msg.obj;
   1834                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
   1835                     return;
   1836                 }
   1837                 ProcessRecord app = (ProcessRecord)msg.obj;
   1838                 synchronized (ActivityManagerService.this) {
   1839                     processStartTimedOutLocked(app);
   1840                 }
   1841             } break;
   1842             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
   1843                 ProcessRecord app = (ProcessRecord)msg.obj;
   1844                 synchronized (ActivityManagerService.this) {
   1845                     processContentProviderPublishTimedOutLocked(app);
   1846                 }
   1847             } break;
   1848             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
   1849                 synchronized (ActivityManagerService.this) {
   1850                     mActivityStarter.doPendingActivityLaunchesLocked(true);
   1851                 }
   1852             } break;
   1853             case KILL_APPLICATION_MSG: {
   1854                 synchronized (ActivityManagerService.this) {
   1855                     final int appId = msg.arg1;
   1856                     final int userId = msg.arg2;
   1857                     Bundle bundle = (Bundle)msg.obj;
   1858                     String pkg = bundle.getString("pkg");
   1859                     String reason = bundle.getString("reason");
   1860                     forceStopPackageLocked(pkg, appId, false, false, true, false,
   1861                             false, userId, reason);
   1862                 }
   1863             } break;
   1864             case FINALIZE_PENDING_INTENT_MSG: {
   1865                 ((PendingIntentRecord)msg.obj).completeFinalize();
   1866             } break;
   1867             case POST_HEAVY_NOTIFICATION_MSG: {
   1868                 INotificationManager inm = NotificationManager.getService();
   1869                 if (inm == null) {
   1870                     return;
   1871                 }
   1872 
   1873                 ActivityRecord root = (ActivityRecord)msg.obj;
   1874                 ProcessRecord process = root.app;
   1875                 if (process == null) {
   1876                     return;
   1877                 }
   1878 
   1879                 try {
   1880                     Context context = mContext.createPackageContext(process.info.packageName, 0);
   1881                     String text = mContext.getString(R.string.heavy_weight_notification,
   1882                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
   1883                     Notification notification = new Notification.Builder(context)
   1884                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
   1885                             .setWhen(0)
   1886                             .setOngoing(true)
   1887                             .setTicker(text)
   1888                             .setColor(mContext.getColor(
   1889                                     com.android.internal.R.color.system_notification_accent_color))
   1890                             .setContentTitle(text)
   1891                             .setContentText(
   1892                                     mContext.getText(R.string.heavy_weight_notification_detail))
   1893                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
   1894                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
   1895                                     new UserHandle(root.userId)))
   1896                             .build();
   1897                     try {
   1898                         int[] outId = new int[1];
   1899                         inm.enqueueNotificationWithTag("android", "android", null,
   1900                                 R.string.heavy_weight_notification,
   1901                                 notification, outId, root.userId);
   1902                     } catch (RuntimeException e) {
   1903                         Slog.w(ActivityManagerService.TAG,
   1904                                 "Error showing notification for heavy-weight app", e);
   1905                     } catch (RemoteException e) {
   1906                     }
   1907                 } catch (NameNotFoundException e) {
   1908                     Slog.w(TAG, "Unable to create context for heavy notification", e);
   1909                 }
   1910             } break;
   1911             case CANCEL_HEAVY_NOTIFICATION_MSG: {
   1912                 INotificationManager inm = NotificationManager.getService();
   1913                 if (inm == null) {
   1914                     return;
   1915                 }
   1916                 try {
   1917                     inm.cancelNotificationWithTag("android", null,
   1918                             R.string.heavy_weight_notification,  msg.arg1);
   1919                 } catch (RuntimeException e) {
   1920                     Slog.w(ActivityManagerService.TAG,
   1921                             "Error canceling notification for service", e);
   1922                 } catch (RemoteException e) {
   1923                 }
   1924             } break;
   1925             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
   1926                 synchronized (ActivityManagerService.this) {
   1927                     checkExcessivePowerUsageLocked(true);
   1928                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1929                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1930                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   1931                 }
   1932             } break;
   1933             case REPORT_MEM_USAGE_MSG: {
   1934                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
   1935                 Thread thread = new Thread() {
   1936                     @Override public void run() {
   1937                         reportMemUsage(memInfos);
   1938                     }
   1939                 };
   1940                 thread.start();
   1941                 break;
   1942             }
   1943             case REPORT_USER_SWITCH_MSG: {
   1944                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
   1945                 break;
   1946             }
   1947             case CONTINUE_USER_SWITCH_MSG: {
   1948                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
   1949                 break;
   1950             }
   1951             case USER_SWITCH_TIMEOUT_MSG: {
   1952                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
   1953                 break;
   1954             }
   1955             case IMMERSIVE_MODE_LOCK_MSG: {
   1956                 final boolean nextState = (msg.arg1 != 0);
   1957                 if (mUpdateLock.isHeld() != nextState) {
   1958                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
   1959                             "Applying new update lock state '" + nextState
   1960                             + "' for " + (ActivityRecord)msg.obj);
   1961                     if (nextState) {
   1962                         mUpdateLock.acquire();
   1963                     } else {
   1964                         mUpdateLock.release();
   1965                     }
   1966                 }
   1967                 break;
   1968             }
   1969             case PERSIST_URI_GRANTS_MSG: {
   1970                 writeGrantedUriPermissions();
   1971                 break;
   1972             }
   1973             case REQUEST_ALL_PSS_MSG: {
   1974                 synchronized (ActivityManagerService.this) {
   1975                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
   1976                 }
   1977                 break;
   1978             }
   1979             case START_PROFILES_MSG: {
   1980                 synchronized (ActivityManagerService.this) {
   1981                     mUserController.startProfilesLocked();
   1982                 }
   1983                 break;
   1984             }
   1985             case UPDATE_TIME: {
   1986                 synchronized (ActivityManagerService.this) {
   1987                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1988                         ProcessRecord r = mLruProcesses.get(i);
   1989                         if (r.thread != null) {
   1990                             try {
   1991                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
   1992                             } catch (RemoteException ex) {
   1993                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
   1994                             }
   1995                         }
   1996                     }
   1997                 }
   1998                 break;
   1999             }
   2000             case SYSTEM_USER_START_MSG: {
   2001                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
   2002                         Integer.toString(msg.arg1), msg.arg1);
   2003                 mSystemServiceManager.startUser(msg.arg1);
   2004                 break;
   2005             }
   2006             case SYSTEM_USER_UNLOCK_MSG: {
   2007                 final int userId = msg.arg1;
   2008                 mSystemServiceManager.unlockUser(userId);
   2009                 synchronized (ActivityManagerService.this) {
   2010                     mRecentTasks.loadUserRecentsLocked(userId);
   2011                 }
   2012                 if (userId == UserHandle.USER_SYSTEM) {
   2013                     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
   2014                 }
   2015                 installEncryptionUnawareProviders(userId);
   2016                 mUserController.finishUserUnlocked((UserState) msg.obj);
   2017                 break;
   2018             }
   2019             case SYSTEM_USER_CURRENT_MSG: {
   2020                 mBatteryStatsService.noteEvent(
   2021                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
   2022                         Integer.toString(msg.arg2), msg.arg2);
   2023                 mBatteryStatsService.noteEvent(
   2024                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
   2025                         Integer.toString(msg.arg1), msg.arg1);
   2026                 mSystemServiceManager.switchUser(msg.arg1);
   2027                 break;
   2028             }
   2029             case ENTER_ANIMATION_COMPLETE_MSG: {
   2030                 synchronized (ActivityManagerService.this) {
   2031                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
   2032                     if (r != null && r.app != null && r.app.thread != null) {
   2033                         try {
   2034                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
   2035                         } catch (RemoteException e) {
   2036                         }
   2037                     }
   2038                 }
   2039                 break;
   2040             }
   2041             case FINISH_BOOTING_MSG: {
   2042                 if (msg.arg1 != 0) {
   2043                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
   2044                     finishBooting();
   2045                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   2046                 }
   2047                 if (msg.arg2 != 0) {
   2048                     enableScreenAfterBoot();
   2049                 }
   2050                 break;
   2051             }
   2052             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
   2053                 try {
   2054                     Locale l = (Locale) msg.obj;
   2055                     IBinder service = ServiceManager.getService("mount");
   2056                     IMountService mountService = IMountService.Stub.asInterface(service);
   2057                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
   2058                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
   2059                 } catch (RemoteException e) {
   2060                     Log.e(TAG, "Error storing locale for decryption UI", e);
   2061                 }
   2062                 break;
   2063             }
   2064             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
   2065                 synchronized (ActivityManagerService.this) {
   2066                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
   2067                         try {
   2068                             // Make a one-way callback to the listener
   2069                             mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
   2070                         } catch (RemoteException e){
   2071                             // Handled by the RemoteCallbackList
   2072                         }
   2073                     }
   2074                     mTaskStackListeners.finishBroadcast();
   2075                 }
   2076                 break;
   2077             }
   2078             case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
   2079                 synchronized (ActivityManagerService.this) {
   2080                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
   2081                         try {
   2082                             // Make a one-way callback to the listener
   2083                             mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
   2084                         } catch (RemoteException e){
   2085                             // Handled by the RemoteCallbackList
   2086                         }
   2087                     }
   2088                     mTaskStackListeners.finishBroadcast();
   2089                 }
   2090                 break;
   2091             }
   2092             case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
   2093                 synchronized (ActivityManagerService.this) {
   2094                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
   2095                         try {
   2096                             // Make a one-way callback to the listener
   2097                             mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
   2098                         } catch (RemoteException e){
   2099                             // Handled by the RemoteCallbackList
   2100                         }
   2101                     }
   2102                     mTaskStackListeners.finishBroadcast();
   2103                 }
   2104                 break;
   2105             }
   2106             case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
   2107                 synchronized (ActivityManagerService.this) {
   2108                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
   2109                         try {
   2110                             // Make a one-way callback to the listener
   2111                             mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
   2112                         } catch (RemoteException e){
   2113                             // Handled by the RemoteCallbackList
   2114                         }
   2115                     }
   2116                     mTaskStackListeners.finishBroadcast();
   2117                 }
   2118                 break;
   2119             }
   2120             case NOTIFY_FORCED_RESIZABLE_MSG: {
   2121                 synchronized (ActivityManagerService.this) {
   2122                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
   2123                         try {
   2124                             // Make a one-way callback to the listener
   2125                             mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
   2126                                     (String) msg.obj, msg.arg1);
   2127                         } catch (RemoteException e){
   2128                             // Handled by the RemoteCallbackList
   2129                         }
   2130                     }
   2131                     mTaskStackListeners.finishBroadcast();
   2132                 }
   2133                 break;
   2134             }
   2135                 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
   2136                     synchronized (ActivityManagerService.this) {
   2137                         for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
   2138                             try {
   2139                                 // Make a one-way callback to the listener
   2140                                 mTaskStackListeners.getBroadcastItem(i)
   2141                                         .onActivityDismissingDockedStack();
   2142                             } catch (RemoteException e){
   2143                                 // Handled by the RemoteCallbackList
   2144                             }
   2145                         }
   2146                         mTaskStackListeners.finishBroadcast();
   2147                     }
   2148                     break;
   2149                 }
   2150             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
   2151                 final int uid = msg.arg1;
   2152                 final byte[] firstPacket = (byte[]) msg.obj;
   2153 
   2154                 synchronized (mPidsSelfLocked) {
   2155                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
   2156                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
   2157                         if (p.uid == uid) {
   2158                             try {
   2159                                 p.thread.notifyCleartextNetwork(firstPacket);
   2160                             } catch (RemoteException ignored) {
   2161                             }
   2162                         }
   2163                     }
   2164                 }
   2165                 break;
   2166             }
   2167             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
   2168                 final String procName;
   2169                 final int uid;
   2170                 final long memLimit;
   2171                 final String reportPackage;
   2172                 synchronized (ActivityManagerService.this) {
   2173                     procName = mMemWatchDumpProcName;
   2174                     uid = mMemWatchDumpUid;
   2175                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
   2176                     if (val == null) {
   2177                         val = mMemWatchProcesses.get(procName, 0);
   2178                     }
   2179                     if (val != null) {
   2180                         memLimit = val.first;
   2181                         reportPackage = val.second;
   2182                     } else {
   2183                         memLimit = 0;
   2184                         reportPackage = null;
   2185                     }
   2186                 }
   2187                 if (procName == null) {
   2188                     return;
   2189                 }
   2190 
   2191                 if (DEBUG_PSS) Slog.d(TAG_PSS,
   2192                         "Showing dump heap notification from " + procName + "/" + uid);
   2193 
   2194                 INotificationManager inm = NotificationManager.getService();
   2195                 if (inm == null) {
   2196                     return;
   2197                 }
   2198 
   2199                 String text = mContext.getString(R.string.dump_heap_notification, procName);
   2200 
   2201 
   2202                 Intent deleteIntent = new Intent();
   2203                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
   2204                 Intent intent = new Intent();
   2205                 intent.setClassName("android", DumpHeapActivity.class.getName());
   2206                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
   2207                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
   2208                 if (reportPackage != null) {
   2209                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
   2210                 }
   2211                 int userId = UserHandle.getUserId(uid);
   2212                 Notification notification = new Notification.Builder(mContext)
   2213                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
   2214                         .setWhen(0)
   2215                         .setOngoing(true)
   2216                         .setAutoCancel(true)
   2217                         .setTicker(text)
   2218                         .setColor(mContext.getColor(
   2219                                 com.android.internal.R.color.system_notification_accent_color))
   2220                         .setContentTitle(text)
   2221                         .setContentText(
   2222                                 mContext.getText(R.string.dump_heap_notification_detail))
   2223                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
   2224                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
   2225                                 new UserHandle(userId)))
   2226                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
   2227                                 deleteIntent, 0, UserHandle.SYSTEM))
   2228                         .build();
   2229 
   2230                 try {
   2231                     int[] outId = new int[1];
   2232                     inm.enqueueNotificationWithTag("android", "android", null,
   2233                             R.string.dump_heap_notification,
   2234                             notification, outId, userId);
   2235                 } catch (RuntimeException e) {
   2236                     Slog.w(ActivityManagerService.TAG,
   2237                             "Error showing notification for dump heap", e);
   2238                 } catch (RemoteException e) {
   2239                 }
   2240             } break;
   2241             case DELETE_DUMPHEAP_MSG: {
   2242                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
   2243                         DumpHeapActivity.JAVA_URI,
   2244                         Intent.FLAG_GRANT_READ_URI_PERMISSION
   2245                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
   2246                         UserHandle.myUserId());
   2247                 synchronized (ActivityManagerService.this) {
   2248                     mMemWatchDumpFile = null;
   2249                     mMemWatchDumpProcName = null;
   2250                     mMemWatchDumpPid = -1;
   2251                     mMemWatchDumpUid = -1;
   2252                 }
   2253             } break;
   2254             case FOREGROUND_PROFILE_CHANGED_MSG: {
   2255                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
   2256             } break;
   2257             case REPORT_TIME_TRACKER_MSG: {
   2258                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
   2259                 tracker.deliverResult(mContext);
   2260             } break;
   2261             case REPORT_USER_SWITCH_COMPLETE_MSG: {
   2262                 mUserController.dispatchUserSwitchComplete(msg.arg1);
   2263             } break;
   2264             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
   2265                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
   2266                 try {
   2267                     connection.shutdown();
   2268                 } catch (RemoteException e) {
   2269                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
   2270                 }
   2271                 // Only a UiAutomation can set this flag and now that
   2272                 // it is finished we make sure it is reset to its default.
   2273                 mUserIsMonkey = false;
   2274             } break;
   2275             case APP_BOOST_DEACTIVATE_MSG: {
   2276                 synchronized(ActivityManagerService.this) {
   2277                     if (mIsBoosted) {
   2278                         if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
   2279                             nativeMigrateFromBoost();
   2280                             mIsBoosted = false;
   2281                             mBoostStartTime = 0;
   2282                         } else {
   2283                             Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
   2284                             mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
   2285                         }
   2286                     }
   2287                 }
   2288             } break;
   2289             case IDLE_UIDS_MSG: {
   2290                 idleUids();
   2291             } break;
   2292             case LOG_STACK_STATE: {
   2293                 synchronized (ActivityManagerService.this) {
   2294                     mStackSupervisor.logStackState();
   2295                 }
   2296             } break;
   2297             case VR_MODE_CHANGE_MSG: {
   2298                 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
   2299                 final ActivityRecord r = (ActivityRecord) msg.obj;
   2300                 boolean vrMode;
   2301                 ComponentName requestedPackage;
   2302                 ComponentName callingPackage;
   2303                 int userId;
   2304                 synchronized (ActivityManagerService.this) {
   2305                     vrMode = r.requestedVrComponent != null;
   2306                     requestedPackage = r.requestedVrComponent;
   2307                     userId = r.userId;
   2308                     callingPackage = r.info.getComponentName();
   2309                     if (mInVrMode != vrMode) {
   2310                         mInVrMode = vrMode;
   2311                         mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
   2312                     }
   2313                 }
   2314                 vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
   2315             } break;
   2316             case VR_MODE_APPLY_IF_NEEDED_MSG: {
   2317                 final ActivityRecord r = (ActivityRecord) msg.obj;
   2318                 final boolean needsVrMode = r != null && r.requestedVrComponent != null;
   2319                 if (needsVrMode) {
   2320                     applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
   2321                             r.info.getComponentName(), false);
   2322                 }
   2323             } break;
   2324             }
   2325         }
   2326     };
   2327 
   2328     static final int COLLECT_PSS_BG_MSG = 1;
   2329 
   2330     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
   2331         @Override
   2332         public void handleMessage(Message msg) {
   2333             switch (msg.what) {
   2334             case COLLECT_PSS_BG_MSG: {
   2335                 long start = SystemClock.uptimeMillis();
   2336                 MemInfoReader memInfo = null;
   2337                 synchronized (ActivityManagerService.this) {
   2338                     if (mFullPssPending) {
   2339                         mFullPssPending = false;
   2340                         memInfo = new MemInfoReader();
   2341                     }
   2342                 }
   2343                 if (memInfo != null) {
   2344                     updateCpuStatsNow();
   2345                     long nativeTotalPss = 0;
   2346                     synchronized (mProcessCpuTracker) {
   2347                         final int N = mProcessCpuTracker.countStats();
   2348                         for (int j=0; j<N; j++) {
   2349                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
   2350                             if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
   2351                                 // This is definitely an application process; skip it.
   2352                                 continue;
   2353                             }
   2354                             synchronized (mPidsSelfLocked) {
   2355                                 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
   2356                                     // This is one of our own processes; skip it.
   2357                                     continue;
   2358                                 }
   2359                             }
   2360                             nativeTotalPss += Debug.getPss(st.pid, null, null);
   2361                         }
   2362                     }
   2363                     memInfo.readMemInfo();
   2364                     synchronized (ActivityManagerService.this) {
   2365                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
   2366                                 + (SystemClock.uptimeMillis()-start) + "ms");
   2367                         final long cachedKb = memInfo.getCachedSizeKb();
   2368                         final long freeKb = memInfo.getFreeSizeKb();
   2369                         final long zramKb = memInfo.getZramTotalSizeKb();
   2370                         final long kernelKb = memInfo.getKernelUsedSizeKb();
   2371                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
   2372                                 kernelKb*1024, nativeTotalPss*1024);
   2373                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
   2374                                 nativeTotalPss);
   2375                     }
   2376                 }
   2377 
   2378                 int num = 0;
   2379                 long[] tmp = new long[2];
   2380                 do {
   2381                     ProcessRecord proc;
   2382                     int procState;
   2383                     int pid;
   2384                     long lastPssTime;
   2385                     synchronized (ActivityManagerService.this) {
   2386                         if (mPendingPssProcesses.size() <= 0) {
   2387                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
   2388                                     "Collected PSS of " + num + " processes in "
   2389                                     + (SystemClock.uptimeMillis() - start) + "ms");
   2390                             mPendingPssProcesses.clear();
   2391                             return;
   2392                         }
   2393                         proc = mPendingPssProcesses.remove(0);
   2394                         procState = proc.pssProcState;
   2395                         lastPssTime = proc.lastPssTime;
   2396                         if (proc.thread != null && procState == proc.setProcState
   2397                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
   2398                                         < SystemClock.uptimeMillis()) {
   2399                             pid = proc.pid;
   2400                         } else {
   2401                             proc = null;
   2402                             pid = 0;
   2403                         }
   2404                     }
   2405                     if (proc != null) {
   2406                         long pss = Debug.getPss(pid, tmp, null);
   2407                         synchronized (ActivityManagerService.this) {
   2408                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
   2409                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
   2410                                 num++;
   2411                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
   2412                                         SystemClock.uptimeMillis());
   2413                             }
   2414                         }
   2415                     }
   2416                 } while (true);
   2417             }
   2418             }
   2419         }
   2420     };
   2421 
   2422     public void setSystemProcess() {
   2423         try {
   2424             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
   2425             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
   2426             ServiceManager.addService("meminfo", new MemBinder(this));
   2427             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
   2428             ServiceManager.addService("dbinfo", new DbBinder(this));
   2429             if (MONITOR_CPU_USAGE) {
   2430                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
   2431             }
   2432             ServiceManager.addService("permission", new PermissionController(this));
   2433             ServiceManager.addService("processinfo", new ProcessInfoService(this));
   2434 
   2435             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
   2436                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
   2437             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
   2438 
   2439             synchronized (this) {
   2440                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
   2441                 app.persistent = true;
   2442                 app.pid = MY_PID;
   2443                 app.maxAdj = ProcessList.SYSTEM_ADJ;
   2444                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
   2445                 synchronized (mPidsSelfLocked) {
   2446                     mPidsSelfLocked.put(app.pid, app);
   2447                 }
   2448                 updateLruProcessLocked(app, false, null);
   2449                 updateOomAdjLocked();
   2450             }
   2451         } catch (PackageManager.NameNotFoundException e) {
   2452             throw new RuntimeException(
   2453                     "Unable to find android system package", e);
   2454         }
   2455     }
   2456 
   2457     public void setWindowManager(WindowManagerService wm) {
   2458         mWindowManager = wm;
   2459         mStackSupervisor.setWindowManager(wm);
   2460         mActivityStarter.setWindowManager(wm);
   2461     }
   2462 
   2463     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
   2464         mUsageStatsService = usageStatsManager;
   2465     }
   2466 
   2467     public void startObservingNativeCrashes() {
   2468         final NativeCrashListener ncl = new NativeCrashListener(this);
   2469         ncl.start();
   2470     }
   2471 
   2472     public IAppOpsService getAppOpsService() {
   2473         return mAppOpsService;
   2474     }
   2475 
   2476     static class MemBinder extends Binder {
   2477         ActivityManagerService mActivityManagerService;
   2478         MemBinder(ActivityManagerService activityManagerService) {
   2479             mActivityManagerService = activityManagerService;
   2480         }
   2481 
   2482         @Override
   2483         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2484             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   2485                     != PackageManager.PERMISSION_GRANTED) {
   2486                 pw.println("Permission Denial: can't dump meminfo from from pid="
   2487                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   2488                         + " without permission " + android.Manifest.permission.DUMP);
   2489                 return;
   2490             }
   2491 
   2492             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
   2493         }
   2494     }
   2495 
   2496     static class GraphicsBinder extends Binder {
   2497         ActivityManagerService mActivityManagerService;
   2498         GraphicsBinder(ActivityManagerService activityManagerService) {
   2499             mActivityManagerService = activityManagerService;
   2500         }
   2501 
   2502         @Override
   2503         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2504             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   2505                     != PackageManager.PERMISSION_GRANTED) {
   2506                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
   2507                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   2508                         + " without permission " + android.Manifest.permission.DUMP);
   2509                 return;
   2510             }
   2511 
   2512             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
   2513         }
   2514     }
   2515 
   2516     static class DbBinder extends Binder {
   2517         ActivityManagerService mActivityManagerService;
   2518         DbBinder(ActivityManagerService activityManagerService) {
   2519             mActivityManagerService = activityManagerService;
   2520         }
   2521 
   2522         @Override
   2523         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2524             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   2525                     != PackageManager.PERMISSION_GRANTED) {
   2526                 pw.println("Permission Denial: can't dump dbinfo from from pid="
   2527                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   2528                         + " without permission " + android.Manifest.permission.DUMP);
   2529                 return;
   2530             }
   2531 
   2532             mActivityManagerService.dumpDbInfo(fd, pw, args);
   2533         }
   2534     }
   2535 
   2536     static class CpuBinder extends Binder {
   2537         ActivityManagerService mActivityManagerService;
   2538         CpuBinder(ActivityManagerService activityManagerService) {
   2539             mActivityManagerService = activityManagerService;
   2540         }
   2541 
   2542         @Override
   2543         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2544             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   2545                     != PackageManager.PERMISSION_GRANTED) {
   2546                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
   2547                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   2548                         + " without permission " + android.Manifest.permission.DUMP);
   2549                 return;
   2550             }
   2551 
   2552             synchronized (mActivityManagerService.mProcessCpuTracker) {
   2553                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
   2554                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
   2555                         SystemClock.uptimeMillis()));
   2556             }
   2557         }
   2558     }
   2559 
   2560     public static final class Lifecycle extends SystemService {
   2561         private final ActivityManagerService mService;
   2562 
   2563         public Lifecycle(Context context) {
   2564             super(context);
   2565             mService = new ActivityManagerService(context);
   2566         }
   2567 
   2568         @Override
   2569         public void onStart() {
   2570             mService.start();
   2571         }
   2572 
   2573         public ActivityManagerService getService() {
   2574             return mService;
   2575         }
   2576     }
   2577 
   2578     // Note: This method is invoked on the main thread but may need to attach various
   2579     // handlers to other threads.  So take care to be explicit about the looper.
   2580     public ActivityManagerService(Context systemContext) {
   2581         mContext = systemContext;
   2582         mFactoryTest = FactoryTest.getMode();
   2583         mSystemThread = ActivityThread.currentActivityThread();
   2584 
   2585         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
   2586 
   2587         mHandlerThread = new ServiceThread(TAG,
   2588                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
   2589         mHandlerThread.start();
   2590         mHandler = new MainHandler(mHandlerThread.getLooper());
   2591         mUiHandler = new UiHandler();
   2592 
   2593         /* static; one-time init here */
   2594         if (sKillHandler == null) {
   2595             sKillThread = new ServiceThread(TAG + ":kill",
   2596                     android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
   2597             sKillThread.start();
   2598             sKillHandler = new KillHandler(sKillThread.getLooper());
   2599         }
   2600 
   2601         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
   2602                 "foreground", BROADCAST_FG_TIMEOUT, false);
   2603         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
   2604                 "background", BROADCAST_BG_TIMEOUT, true);
   2605         mBroadcastQueues[0] = mFgBroadcastQueue;
   2606         mBroadcastQueues[1] = mBgBroadcastQueue;
   2607 
   2608         mServices = new ActiveServices(this);
   2609         mProviderMap = new ProviderMap(this);
   2610         mAppErrors = new AppErrors(mContext, this);
   2611 
   2612         // TODO: Move creation of battery stats service outside of activity manager service.
   2613         File dataDir = Environment.getDataDirectory();
   2614         File systemDir = new File(dataDir, "system");
   2615         systemDir.mkdirs();
   2616         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
   2617         mBatteryStatsService.getActiveStatistics().readLocked();
   2618         mBatteryStatsService.scheduleWriteToDisk();
   2619         mOnBattery = DEBUG_POWER ? true
   2620                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
   2621         mBatteryStatsService.getActiveStatistics().setCallback(this);
   2622 
   2623         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
   2624 
   2625         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
   2626         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
   2627                 new IAppOpsCallback.Stub() {
   2628                     @Override public void opChanged(int op, int uid, String packageName) {
   2629                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
   2630                             if (mAppOpsService.checkOperation(op, uid, packageName)
   2631                                     != AppOpsManager.MODE_ALLOWED) {
   2632                                 runInBackgroundDisabled(uid);
   2633                             }
   2634                         }
   2635                     }
   2636                 });
   2637 
   2638         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
   2639 
   2640         mUserController = new UserController(this);
   2641 
   2642         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
   2643             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
   2644 
   2645         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
   2646 
   2647         mConfiguration.setToDefaults();
   2648         mConfiguration.setLocales(LocaleList.getDefault());
   2649 
   2650         mConfigurationSeq = mConfiguration.seq = 1;
   2651         mProcessCpuTracker.init();
   2652 
   2653         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
   2654         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
   2655         mStackSupervisor = new ActivityStackSupervisor(this);
   2656         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
   2657         mRecentTasks = new RecentTasks(this, mStackSupervisor);
   2658 
   2659         mProcessCpuThread = new Thread("CpuTracker") {
   2660             @Override
   2661             public void run() {
   2662                 while (true) {
   2663                     try {
   2664                         try {
   2665                             synchronized(this) {
   2666                                 final long now = SystemClock.uptimeMillis();
   2667                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
   2668                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
   2669                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
   2670                                 //        + ", write delay=" + nextWriteDelay);
   2671                                 if (nextWriteDelay < nextCpuDelay) {
   2672                                     nextCpuDelay = nextWriteDelay;
   2673                                 }
   2674                                 if (nextCpuDelay > 0) {
   2675                                     mProcessCpuMutexFree.set(true);
   2676                                     this.wait(nextCpuDelay);
   2677                                 }
   2678                             }
   2679                         } catch (InterruptedException e) {
   2680                         }
   2681                         updateCpuStatsNow();
   2682                     } catch (Exception e) {
   2683                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
   2684                     }
   2685                 }
   2686             }
   2687         };
   2688 
   2689         Watchdog.getInstance().addMonitor(this);
   2690         Watchdog.getInstance().addThread(mHandler);
   2691     }
   2692 
   2693     public void setSystemServiceManager(SystemServiceManager mgr) {
   2694         mSystemServiceManager = mgr;
   2695     }
   2696 
   2697     public void setInstaller(Installer installer) {
   2698         mInstaller = installer;
   2699     }
   2700 
   2701     private void start() {
   2702         Process.removeAllProcessGroups();
   2703         mProcessCpuThread.start();
   2704 
   2705         mBatteryStatsService.publish(mContext);
   2706         mAppOpsService.publish(mContext);
   2707         Slog.d("AppOps", "AppOpsService published");
   2708         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
   2709     }
   2710 
   2711     void onUserStoppedLocked(int userId) {
   2712         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
   2713     }
   2714 
   2715     public void initPowerManagement() {
   2716         mStackSupervisor.initPowerManagement();
   2717         mBatteryStatsService.initPowerManagement();
   2718         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
   2719         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
   2720         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
   2721         mVoiceWakeLock.setReferenceCounted(false);
   2722     }
   2723 
   2724     @Override
   2725     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   2726             throws RemoteException {
   2727         if (code == SYSPROPS_TRANSACTION) {
   2728             // We need to tell all apps about the system property change.
   2729             ArrayList<IBinder> procs = new ArrayList<IBinder>();
   2730             synchronized(this) {
   2731                 final int NP = mProcessNames.getMap().size();
   2732                 for (int ip=0; ip<NP; ip++) {
   2733                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   2734                     final int NA = apps.size();
   2735                     for (int ia=0; ia<NA; ia++) {
   2736                         ProcessRecord app = apps.valueAt(ia);
   2737                         if (app.thread != null) {
   2738                             procs.add(app.thread.asBinder());
   2739                         }
   2740                     }
   2741                 }
   2742             }
   2743 
   2744             int N = procs.size();
   2745             for (int i=0; i<N; i++) {
   2746                 Parcel data2 = Parcel.obtain();
   2747                 try {
   2748                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
   2749                 } catch (RemoteException e) {
   2750                 }
   2751                 data2.recycle();
   2752             }
   2753         }
   2754         try {
   2755             return super.onTransact(code, data, reply, flags);
   2756         } catch (RuntimeException e) {
   2757             // The activity manager only throws security exceptions, so let's
   2758             // log all others.
   2759             if (!(e instanceof SecurityException)) {
   2760                 Slog.wtf(TAG, "Activity Manager Crash", e);
   2761             }
   2762             throw e;
   2763         }
   2764     }
   2765 
   2766     void updateCpuStats() {
   2767         final long now = SystemClock.uptimeMillis();
   2768         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
   2769             return;
   2770         }
   2771         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
   2772             synchronized (mProcessCpuThread) {
   2773                 mProcessCpuThread.notify();
   2774             }
   2775         }
   2776     }
   2777 
   2778     void updateCpuStatsNow() {
   2779         synchronized (mProcessCpuTracker) {
   2780             mProcessCpuMutexFree.set(false);
   2781             final long now = SystemClock.uptimeMillis();
   2782             boolean haveNewCpuStats = false;
   2783 
   2784             if (MONITOR_CPU_USAGE &&
   2785                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
   2786                 mLastCpuTime.set(now);
   2787                 mProcessCpuTracker.update();
   2788                 if (mProcessCpuTracker.hasGoodLastStats()) {
   2789                     haveNewCpuStats = true;
   2790                     //Slog.i(TAG, mProcessCpu.printCurrentState());
   2791                     //Slog.i(TAG, "Total CPU usage: "
   2792                     //        + mProcessCpu.getTotalCpuPercent() + "%");
   2793 
   2794                     // Slog the cpu usage if the property is set.
   2795                     if ("true".equals(SystemProperties.get("events.cpu"))) {
   2796                         int user = mProcessCpuTracker.getLastUserTime();
   2797                         int system = mProcessCpuTracker.getLastSystemTime();
   2798                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
   2799                         int irq = mProcessCpuTracker.getLastIrqTime();
   2800                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
   2801                         int idle = mProcessCpuTracker.getLastIdleTime();
   2802 
   2803                         int total = user + system + iowait + irq + softIrq + idle;
   2804                         if (total == 0) total = 1;
   2805 
   2806                         EventLog.writeEvent(EventLogTags.CPU,
   2807                                 ((user+system+iowait+irq+softIrq) * 100) / total,
   2808                                 (user * 100) / total,
   2809                                 (system * 100) / total,
   2810                                 (iowait * 100) / total,
   2811                                 (irq * 100) / total,
   2812                                 (softIrq * 100) / total);
   2813                     }
   2814                 }
   2815             }
   2816 
   2817             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
   2818             synchronized(bstats) {
   2819                 synchronized(mPidsSelfLocked) {
   2820                     if (haveNewCpuStats) {
   2821                         if (bstats.startAddingCpuLocked()) {
   2822                             int totalUTime = 0;
   2823                             int totalSTime = 0;
   2824                             final int N = mProcessCpuTracker.countStats();
   2825                             for (int i=0; i<N; i++) {
   2826                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   2827                                 if (!st.working) {
   2828                                     continue;
   2829                                 }
   2830                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
   2831                                 totalUTime += st.rel_utime;
   2832                                 totalSTime += st.rel_stime;
   2833                                 if (pr != null) {
   2834                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
   2835                                     if (ps == null || !ps.isActive()) {
   2836                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
   2837                                                 pr.info.uid, pr.processName);
   2838                                     }
   2839                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
   2840                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
   2841                                 } else {
   2842                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
   2843                                     if (ps == null || !ps.isActive()) {
   2844                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
   2845                                                 bstats.mapUid(st.uid), st.name);
   2846                                     }
   2847                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
   2848                                 }
   2849                             }
   2850                             final int userTime = mProcessCpuTracker.getLastUserTime();
   2851                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
   2852                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
   2853                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
   2854                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
   2855                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
   2856                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
   2857                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
   2858                         }
   2859                     }
   2860                 }
   2861 
   2862                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
   2863                     mLastWriteTime = now;
   2864                     mBatteryStatsService.scheduleWriteToDisk();
   2865                 }
   2866             }
   2867         }
   2868     }
   2869 
   2870     @Override
   2871     public void batteryNeedsCpuUpdate() {
   2872         updateCpuStatsNow();
   2873     }
   2874 
   2875     @Override
   2876     public void batteryPowerChanged(boolean onBattery) {
   2877         // When plugging in, update the CPU stats first before changing
   2878         // the plug state.
   2879         updateCpuStatsNow();
   2880         synchronized (this) {
   2881             synchronized(mPidsSelfLocked) {
   2882                 mOnBattery = DEBUG_POWER ? true : onBattery;
   2883             }
   2884         }
   2885     }
   2886 
   2887     @Override
   2888     public void batterySendBroadcast(Intent intent) {
   2889         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
   2890                 AppOpsManager.OP_NONE, null, false, false,
   2891                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
   2892     }
   2893 
   2894     /**
   2895      * Initialize the application bind args. These are passed to each
   2896      * process when the bindApplication() IPC is sent to the process. They're
   2897      * lazily setup to make sure the services are running when they're asked for.
   2898      */
   2899     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
   2900         if (mAppBindArgs == null) {
   2901             mAppBindArgs = new HashMap<>();
   2902 
   2903             // Isolated processes won't get this optimization, so that we don't
   2904             // violate the rules about which services they have access to.
   2905             if (!isolated) {
   2906                 // Setup the application init args
   2907                 mAppBindArgs.put("package", ServiceManager.getService("package"));
   2908                 mAppBindArgs.put("window", ServiceManager.getService("window"));
   2909                 mAppBindArgs.put(Context.ALARM_SERVICE,
   2910                         ServiceManager.getService(Context.ALARM_SERVICE));
   2911             }
   2912         }
   2913         return mAppBindArgs;
   2914     }
   2915 
   2916     boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
   2917         if (r == null || mFocusedActivity == r) {
   2918             return false;
   2919         }
   2920 
   2921         if (!r.isFocusable()) {
   2922             if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
   2923             return false;
   2924         }
   2925 
   2926         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
   2927 
   2928         final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
   2929         if (wasDoingSetFocusedActivity) Slog.w(TAG,
   2930                 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
   2931         mDoingSetFocusedActivity = true;
   2932 
   2933         final ActivityRecord last = mFocusedActivity;
   2934         mFocusedActivity = r;
   2935         if (r.task.isApplicationTask()) {
   2936             if (mCurAppTimeTracker != r.appTimeTracker) {
   2937                 // We are switching app tracking.  Complete the current one.
   2938                 if (mCurAppTimeTracker != null) {
   2939                     mCurAppTimeTracker.stop();
   2940                     mHandler.obtainMessage(
   2941                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
   2942                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
   2943                     mCurAppTimeTracker = null;
   2944                 }
   2945                 if (r.appTimeTracker != null) {
   2946                     mCurAppTimeTracker = r.appTimeTracker;
   2947                     startTimeTrackingFocusedActivityLocked();
   2948                 }
   2949             } else {
   2950                 startTimeTrackingFocusedActivityLocked();
   2951             }
   2952         } else {
   2953             r.appTimeTracker = null;
   2954         }
   2955         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
   2956         // TODO: Probably not, because we don't want to resume voice on switching
   2957         // back to this activity
   2958         if (r.task.voiceInteractor != null) {
   2959             startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
   2960         } else {
   2961             finishRunningVoiceLocked();
   2962             IVoiceInteractionSession session;
   2963             if (last != null && ((session = last.task.voiceSession) != null
   2964                     || (session = last.voiceSession) != null)) {
   2965                 // We had been in a voice interaction session, but now focused has
   2966                 // move to something different.  Just finish the session, we can't
   2967                 // return to it and retain the proper state and synchronization with
   2968                 // the voice interaction service.
   2969                 finishVoiceTask(session);
   2970             }
   2971         }
   2972         if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
   2973             mWindowManager.setFocusedApp(r.appToken, true);
   2974         }
   2975         applyUpdateLockStateLocked(r);
   2976         applyUpdateVrModeLocked(r);
   2977         if (mFocusedActivity.userId != mLastFocusedUserId) {
   2978             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
   2979             mHandler.obtainMessage(
   2980                     FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
   2981             mLastFocusedUserId = mFocusedActivity.userId;
   2982         }
   2983 
   2984         // Log a warning if the focused app is changed during the process. This could
   2985         // indicate a problem of the focus setting logic!
   2986         if (mFocusedActivity != r) Slog.w(TAG,
   2987                 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
   2988         mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
   2989 
   2990         EventLogTags.writeAmFocusedActivity(
   2991                 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
   2992                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
   2993                 reason);
   2994         return true;
   2995     }
   2996 
   2997     final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
   2998         if (mFocusedActivity != goingAway) {
   2999             return;
   3000         }
   3001 
   3002         final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
   3003         if (focusedStack != null) {
   3004             final ActivityRecord top = focusedStack.topActivity();
   3005             if (top != null && top.userId != mLastFocusedUserId) {
   3006                 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
   3007                 mHandler.sendMessage(
   3008                         mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
   3009                 mLastFocusedUserId = top.userId;
   3010             }
   3011         }
   3012 
   3013         // Try to move focus to another activity if possible.
   3014         if (setFocusedActivityLocked(
   3015                 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
   3016             return;
   3017         }
   3018 
   3019         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
   3020                 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
   3021         mFocusedActivity = null;
   3022         EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
   3023     }
   3024 
   3025     @Override
   3026     public void setFocusedStack(int stackId) {
   3027         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
   3028         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
   3029         final long callingId = Binder.clearCallingIdentity();
   3030         try {
   3031             synchronized (this) {
   3032                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
   3033                 if (stack == null) {
   3034                     return;
   3035                 }
   3036                 final ActivityRecord r = stack.topRunningActivityLocked();
   3037                 if (setFocusedActivityLocked(r, "setFocusedStack")) {
   3038                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
   3039                 }
   3040             }
   3041         } finally {
   3042             Binder.restoreCallingIdentity(callingId);
   3043         }
   3044     }
   3045 
   3046     @Override
   3047     public void setFocusedTask(int taskId) {
   3048         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
   3049         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
   3050         final long callingId = Binder.clearCallingIdentity();
   3051         try {
   3052             synchronized (this) {
   3053                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   3054                 if (task == null) {
   3055                     return;
   3056                 }
   3057                 final ActivityRecord r = task.topRunningActivityLocked();
   3058                 if (setFocusedActivityLocked(r, "setFocusedTask")) {
   3059                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
   3060                 }
   3061             }
   3062         } finally {
   3063             Binder.restoreCallingIdentity(callingId);
   3064         }
   3065     }
   3066 
   3067     /** Sets the task stack listener that gets callbacks when a task stack changes. */
   3068     @Override
   3069     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
   3070         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
   3071         synchronized (this) {
   3072             if (listener != null) {
   3073                 mTaskStackListeners.register(listener);
   3074             }
   3075         }
   3076     }
   3077 
   3078     @Override
   3079     public void notifyActivityDrawn(IBinder token) {
   3080         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
   3081         synchronized (this) {
   3082             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
   3083             if (r != null) {
   3084                 r.task.stack.notifyActivityDrawnLocked(r);
   3085             }
   3086         }
   3087     }
   3088 
   3089     final void applyUpdateLockStateLocked(ActivityRecord r) {
   3090         // Modifications to the UpdateLock state are done on our handler, outside
   3091         // the activity manager's locks.  The new state is determined based on the
   3092         // state *now* of the relevant activity record.  The object is passed to
   3093         // the handler solely for logging detail, not to be consulted/modified.
   3094         final boolean nextState = r != null && r.immersive;
   3095         mHandler.sendMessage(
   3096                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
   3097     }
   3098 
   3099     final void applyUpdateVrModeLocked(ActivityRecord r) {
   3100         mHandler.sendMessage(
   3101                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
   3102     }
   3103 
   3104     private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
   3105         mHandler.sendMessage(
   3106                 mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
   3107     }
   3108 
   3109     private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
   3110             ComponentName callingPackage, boolean immediate) {
   3111         VrManagerInternal vrService =
   3112                 LocalServices.getService(VrManagerInternal.class);
   3113         if (immediate) {
   3114             vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
   3115         } else {
   3116             vrService.setVrMode(enabled, packageName, userId, callingPackage);
   3117         }
   3118     }
   3119 
   3120     final void showAskCompatModeDialogLocked(ActivityRecord r) {
   3121         Message msg = Message.obtain();
   3122         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
   3123         msg.obj = r.task.askedCompatMode ? null : r;
   3124         mUiHandler.sendMessage(msg);
   3125     }
   3126 
   3127     final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
   3128         if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
   3129                 && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
   3130             final Message msg = Message.obtain();
   3131             msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
   3132             msg.obj = r;
   3133             mUiHandler.sendMessage(msg);
   3134         }
   3135     }
   3136 
   3137     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
   3138             String what, Object obj, ProcessRecord srcApp) {
   3139         app.lastActivityTime = now;
   3140 
   3141         if (app.activities.size() > 0) {
   3142             // Don't want to touch dependent processes that are hosting activities.
   3143             return index;
   3144         }
   3145 
   3146         int lrui = mLruProcesses.lastIndexOf(app);
   3147         if (lrui < 0) {
   3148             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
   3149                     + what + " " + obj + " from " + srcApp);
   3150             return index;
   3151         }
   3152 
   3153         if (lrui >= index) {
   3154             // Don't want to cause this to move dependent processes *back* in the
   3155             // list as if they were less frequently used.
   3156             return index;
   3157         }
   3158 
   3159         if (lrui >= mLruProcessActivityStart) {
   3160             // Don't want to touch dependent processes that are hosting activities.
   3161             return index;
   3162         }
   3163 
   3164         mLruProcesses.remove(lrui);
   3165         if (index > 0) {
   3166             index--;
   3167         }
   3168         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
   3169                 + " in LRU list: " + app);
   3170         mLruProcesses.add(index, app);
   3171         return index;
   3172     }
   3173 
   3174     static void killProcessGroup(int uid, int pid) {
   3175         if (sKillHandler != null) {
   3176             sKillHandler.sendMessage(
   3177                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
   3178         } else {
   3179             Slog.w(TAG, "Asked to kill process group before system bringup!");
   3180             Process.killProcessGroup(uid, pid);
   3181         }
   3182     }
   3183 
   3184     final void removeLruProcessLocked(ProcessRecord app) {
   3185         int lrui = mLruProcesses.lastIndexOf(app);
   3186         if (lrui >= 0) {
   3187             if (!app.killed) {
   3188                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
   3189                 Process.killProcessQuiet(app.pid);
   3190                 killProcessGroup(app.uid, app.pid);
   3191             }
   3192             if (lrui <= mLruProcessActivityStart) {
   3193                 mLruProcessActivityStart--;
   3194             }
   3195             if (lrui <= mLruProcessServiceStart) {
   3196                 mLruProcessServiceStart--;
   3197             }
   3198             mLruProcesses.remove(lrui);
   3199         }
   3200     }
   3201 
   3202     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
   3203             ProcessRecord client) {
   3204         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
   3205                 || app.treatLikeActivity;
   3206         final boolean hasService = false; // not impl yet. app.services.size() > 0;
   3207         if (!activityChange && hasActivity) {
   3208             // The process has activities, so we are only allowing activity-based adjustments
   3209             // to move it.  It should be kept in the front of the list with other
   3210             // processes that have activities, and we don't want those to change their
   3211             // order except due to activity operations.
   3212             return;
   3213         }
   3214 
   3215         mLruSeq++;
   3216         final long now = SystemClock.uptimeMillis();
   3217         app.lastActivityTime = now;
   3218 
   3219         // First a quick reject: if the app is already at the position we will
   3220         // put it, then there is nothing to do.
   3221         if (hasActivity) {
   3222             final int N = mLruProcesses.size();
   3223             if (N > 0 && mLruProcesses.get(N-1) == app) {
   3224                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
   3225                 return;
   3226             }
   3227         } else {
   3228             if (mLruProcessServiceStart > 0
   3229                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
   3230                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
   3231                 return;
   3232             }
   3233         }
   3234 
   3235         int lrui = mLruProcesses.lastIndexOf(app);
   3236 
   3237         if (app.persistent && lrui >= 0) {
   3238             // We don't care about the position of persistent processes, as long as
   3239             // they are in the list.
   3240             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
   3241             return;
   3242         }
   3243 
   3244         /* In progress: compute new position first, so we can avoid doing work
   3245            if the process is not actually going to move.  Not yet working.
   3246         int addIndex;
   3247         int nextIndex;
   3248         boolean inActivity = false, inService = false;
   3249         if (hasActivity) {
   3250             // Process has activities, put it at the very tipsy-top.
   3251             addIndex = mLruProcesses.size();
   3252             nextIndex = mLruProcessServiceStart;
   3253             inActivity = true;
   3254         } else if (hasService) {
   3255             // Process has services, put it at the top of the service list.
   3256             addIndex = mLruProcessActivityStart;
   3257             nextIndex = mLruProcessServiceStart;
   3258             inActivity = true;
   3259             inService = true;
   3260         } else  {
   3261             // Process not otherwise of interest, it goes to the top of the non-service area.
   3262             addIndex = mLruProcessServiceStart;
   3263             if (client != null) {
   3264                 int clientIndex = mLruProcesses.lastIndexOf(client);
   3265                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
   3266                         + app);
   3267                 if (clientIndex >= 0 && addIndex > clientIndex) {
   3268                     addIndex = clientIndex;
   3269                 }
   3270             }
   3271             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
   3272         }
   3273 
   3274         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
   3275                 + mLruProcessActivityStart + "): " + app);
   3276         */
   3277 
   3278         if (lrui >= 0) {
   3279             if (lrui < mLruProcessActivityStart) {
   3280                 mLruProcessActivityStart--;
   3281             }
   3282             if (lrui < mLruProcessServiceStart) {
   3283                 mLruProcessServiceStart--;
   3284             }
   3285             /*
   3286             if (addIndex > lrui) {
   3287                 addIndex--;
   3288             }
   3289             if (nextIndex > lrui) {
   3290                 nextIndex--;
   3291             }
   3292             */
   3293             mLruProcesses.remove(lrui);
   3294         }
   3295 
   3296         /*
   3297         mLruProcesses.add(addIndex, app);
   3298         if (inActivity) {
   3299             mLruProcessActivityStart++;
   3300         }
   3301         if (inService) {
   3302             mLruProcessActivityStart++;
   3303         }
   3304         */
   3305 
   3306         int nextIndex;
   3307         if (hasActivity) {
   3308             final int N = mLruProcesses.size();
   3309             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
   3310                 // Process doesn't have activities, but has clients with
   3311                 // activities...  move it up, but one below the top (the top
   3312                 // should always have a real activity).
   3313                 if (DEBUG_LRU) Slog.d(TAG_LRU,
   3314                         "Adding to second-top of LRU activity list: " + app);
   3315                 mLruProcesses.add(N - 1, app);
   3316                 // To keep it from spamming the LRU list (by making a bunch of clients),
   3317                 // we will push down any other entries owned by the app.
   3318                 final int uid = app.info.uid;
   3319                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
   3320                     ProcessRecord subProc = mLruProcesses.get(i);
   3321                     if (subProc.info.uid == uid) {
   3322                         // We want to push this one down the list.  If the process after
   3323                         // it is for the same uid, however, don't do so, because we don't
   3324                         // want them internally to be re-ordered.
   3325                         if (mLruProcesses.get(i - 1).info.uid != uid) {
   3326                             if (DEBUG_LRU) Slog.d(TAG_LRU,
   3327                                     "Pushing uid " + uid + " swapping at " + i + ": "
   3328                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
   3329                             ProcessRecord tmp = mLruProcesses.get(i);
   3330                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
   3331                             mLruProcesses.set(i - 1, tmp);
   3332                             i--;
   3333                         }
   3334                     } else {
   3335                         // A gap, we can stop here.
   3336                         break;
   3337                     }
   3338                 }
   3339             } else {
   3340                 // Process has activities, put it at the very tipsy-top.
   3341                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
   3342                 mLruProcesses.add(app);
   3343             }
   3344             nextIndex = mLruProcessServiceStart;
   3345         } else if (hasService) {
   3346             // Process has services, put it at the top of the service list.
   3347             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
   3348             mLruProcesses.add(mLruProcessActivityStart, app);
   3349             nextIndex = mLruProcessServiceStart;
   3350             mLruProcessActivityStart++;
   3351         } else  {
   3352             // Process not otherwise of interest, it goes to the top of the non-service area.
   3353             int index = mLruProcessServiceStart;
   3354             if (client != null) {
   3355                 // If there is a client, don't allow the process to be moved up higher
   3356                 // in the list than that client.
   3357                 int clientIndex = mLruProcesses.lastIndexOf(client);
   3358                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
   3359                         + " when updating " + app);
   3360                 if (clientIndex <= lrui) {
   3361                     // Don't allow the client index restriction to push it down farther in the
   3362                     // list than it already is.
   3363                     clientIndex = lrui;
   3364                 }
   3365                 if (clientIndex >= 0 && index > clientIndex) {
   3366                     index = clientIndex;
   3367                 }
   3368             }
   3369             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
   3370             mLruProcesses.add(index, app);
   3371             nextIndex = index-1;
   3372             mLruProcessActivityStart++;
   3373             mLruProcessServiceStart++;
   3374         }
   3375 
   3376         // If the app is currently using a content provider or service,
   3377         // bump those processes as well.
   3378         for (int j=app.connections.size()-1; j>=0; j--) {
   3379             ConnectionRecord cr = app.connections.valueAt(j);
   3380             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
   3381                     && cr.binding.service.app != null
   3382                     && cr.binding.service.app.lruSeq != mLruSeq
   3383                     && !cr.binding.service.app.persistent) {
   3384                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
   3385                         "service connection", cr, app);
   3386             }
   3387         }
   3388         for (int j=app.conProviders.size()-1; j>=0; j--) {
   3389             ContentProviderRecord cpr = app.conProviders.get(j).provider;
   3390             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
   3391                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
   3392                         "provider reference", cpr, app);
   3393             }
   3394         }
   3395     }
   3396 
   3397     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
   3398         if (uid == Process.SYSTEM_UID) {
   3399             // The system gets to run in any process.  If there are multiple
   3400             // processes with the same uid, just pick the first (this
   3401             // should never happen).
   3402             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
   3403             if (procs == null) return null;
   3404             final int procCount = procs.size();
   3405             for (int i = 0; i < procCount; i++) {
   3406                 final int procUid = procs.keyAt(i);
   3407                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
   3408                     // Don't use an app process or different user process for system component.
   3409                     continue;
   3410                 }
   3411                 return procs.valueAt(i);
   3412             }
   3413         }
   3414         ProcessRecord proc = mProcessNames.get(processName, uid);
   3415         if (false && proc != null && !keepIfLarge
   3416                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
   3417                 && proc.lastCachedPss >= 4000) {
   3418             // Turn this condition on to cause killing to happen regularly, for testing.
   3419             if (proc.baseProcessTracker != null) {
   3420                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
   3421             }
   3422             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
   3423         } else if (proc != null && !keepIfLarge
   3424                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
   3425                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
   3426             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
   3427             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
   3428                 if (proc.baseProcessTracker != null) {
   3429                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
   3430                 }
   3431                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
   3432             }
   3433         }
   3434         return proc;
   3435     }
   3436 
   3437     void notifyPackageUse(String packageName, int reason) {
   3438         IPackageManager pm = AppGlobals.getPackageManager();
   3439         try {
   3440             pm.notifyPackageUse(packageName, reason);
   3441         } catch (RemoteException e) {
   3442         }
   3443     }
   3444 
   3445     boolean isNextTransitionForward() {
   3446         int transit = mWindowManager.getPendingAppTransition();
   3447         return transit == TRANSIT_ACTIVITY_OPEN
   3448                 || transit == TRANSIT_TASK_OPEN
   3449                 || transit == TRANSIT_TASK_TO_FRONT;
   3450     }
   3451 
   3452     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
   3453             String processName, String abiOverride, int uid, Runnable crashHandler) {
   3454         synchronized(this) {
   3455             ApplicationInfo info = new ApplicationInfo();
   3456             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
   3457             // For isolated processes, the former contains the parent's uid and the latter the
   3458             // actual uid of the isolated process.
   3459             // In the special case introduced by this method (which is, starting an isolated
   3460             // process directly from the SystemServer without an actual parent app process) the
   3461             // closest thing to a parent's uid is SYSTEM_UID.
   3462             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
   3463             // the |isolated| logic in the ProcessRecord constructor.
   3464             info.uid = Process.SYSTEM_UID;
   3465             info.processName = processName;
   3466             info.className = entryPoint;
   3467             info.packageName = "android";
   3468             ProcessRecord proc = startProcessLocked(processName, info /* info */,
   3469                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
   3470                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
   3471                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
   3472                     crashHandler);
   3473             return proc != null ? proc.pid : 0;
   3474         }
   3475     }
   3476 
   3477     final ProcessRecord startProcessLocked(String processName,
   3478             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
   3479             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
   3480             boolean isolated, boolean keepIfLarge) {
   3481         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
   3482                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
   3483                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
   3484                 null /* crashHandler */);
   3485     }
   3486 
   3487     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
   3488             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
   3489             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
   3490             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
   3491         long startTime = SystemClock.elapsedRealtime();
   3492         ProcessRecord app;
   3493         if (!isolated) {
   3494             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
   3495             checkTime(startTime, "startProcess: after getProcessRecord");
   3496 
   3497             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
   3498                 // If we are in the background, then check to see if this process
   3499                 // is bad.  If so, we will just silently fail.
   3500                 if (mAppErrors.isBadProcessLocked(info)) {
   3501                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
   3502                             + "/" + info.processName);
   3503                     return null;
   3504                 }
   3505             } else {
   3506                 // When the user is explicitly starting a process, then clear its
   3507                 // crash count so that we won't make it bad until they see at
   3508                 // least one crash dialog again, and make the process good again
   3509                 // if it had been bad.
   3510                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
   3511                         + "/" + info.processName);
   3512                 mAppErrors.resetProcessCrashTimeLocked(info);
   3513                 if (mAppErrors.isBadProcessLocked(info)) {
   3514                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
   3515                             UserHandle.getUserId(info.uid), info.uid,
   3516                             info.processName);
   3517                     mAppErrors.clearBadProcessLocked(info);
   3518                     if (app != null) {
   3519                         app.bad = false;
   3520                     }
   3521                 }
   3522             }
   3523         } else {
   3524             // If this is an isolated process, it can't re-use an existing process.
   3525             app = null;
   3526         }
   3527 
   3528         // app launch boost for big.little configurations
   3529         // use cpusets to migrate freshly launched tasks to big cores
   3530         nativeMigrateToBoost();
   3531         mIsBoosted = true;
   3532         mBoostStartTime = SystemClock.uptimeMillis();
   3533         Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
   3534         mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
   3535 
   3536         // We don't have to do anything more if:
   3537         // (1) There is an existing application record; and
   3538         // (2) The caller doesn't think it is dead, OR there is no thread
   3539         //     object attached to it so we know it couldn't have crashed; and
   3540         // (3) There is a pid assigned to it, so it is either starting or
   3541         //     already running.
   3542         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
   3543                 + " app=" + app + " knownToBeDead=" + knownToBeDead
   3544                 + " thread=" + (app != null ? app.thread : null)
   3545                 + " pid=" + (app != null ? app.pid : -1));
   3546         if (app != null && app.pid > 0) {
   3547             if ((!knownToBeDead && !app.killed) || app.thread == null) {
   3548                 // We already have the app running, or are waiting for it to
   3549                 // come up (we have a pid but not yet its thread), so keep it.
   3550                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
   3551                 // If this is a new package in the process, add the package to the list
   3552                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
   3553                 checkTime(startTime, "startProcess: done, added package to proc");
   3554                 return app;
   3555             }
   3556 
   3557             // An application record is attached to a previous process,
   3558             // clean it up now.
   3559             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
   3560             checkTime(startTime, "startProcess: bad proc running, killing");
   3561             killProcessGroup(app.uid, app.pid);
   3562             handleAppDiedLocked(app, true, true);
   3563             checkTime(startTime, "startProcess: done killing old proc");
   3564         }
   3565 
   3566         String hostingNameStr = hostingName != null
   3567                 ? hostingName.flattenToShortString() : null;
   3568 
   3569         if (app == null) {
   3570             checkTime(startTime, "startProcess: creating new process record");
   3571             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
   3572             if (app == null) {
   3573                 Slog.w(TAG, "Failed making new process record for "
   3574                         + processName + "/" + info.uid + " isolated=" + isolated);
   3575                 return null;
   3576             }
   3577             app.crashHandler = crashHandler;
   3578             checkTime(startTime, "startProcess: done creating new process record");
   3579         } else {
   3580             // If this is a new package in the process, add the package to the list
   3581             app.addPackage(info.packageName, info.versionCode, mProcessStats);
   3582             checkTime(startTime, "startProcess: added package to existing proc");
   3583         }
   3584 
   3585         // If the system is not ready yet, then hold off on starting this
   3586         // process until it is.
   3587         if (!mProcessesReady
   3588                 && !isAllowedWhileBooting(info)
   3589                 && !allowWhileBooting) {
   3590             if (!mProcessesOnHold.contains(app)) {
   3591                 mProcessesOnHold.add(app);
   3592             }
   3593             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
   3594                     "System not ready, putting on hold: " + app);
   3595             checkTime(startTime, "startProcess: returning with proc on hold");
   3596             return app;
   3597         }
   3598 
   3599         checkTime(startTime, "startProcess: stepping in to startProcess");
   3600         startProcessLocked(
   3601                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
   3602         checkTime(startTime, "startProcess: done starting proc!");
   3603         return (app.pid != 0) ? app : null;
   3604     }
   3605 
   3606     boolean isAllowedWhileBooting(ApplicationInfo ai) {
   3607         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
   3608     }
   3609 
   3610     private final void startProcessLocked(ProcessRecord app,
   3611             String hostingType, String hostingNameStr) {
   3612         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
   3613                 null /* entryPoint */, null /* entryPointArgs */);
   3614     }
   3615 
   3616     private final void startProcessLocked(ProcessRecord app, String hostingType,
   3617             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
   3618         long startTime = SystemClock.elapsedRealtime();
   3619         if (app.pid > 0 && app.pid != MY_PID) {
   3620             checkTime(startTime, "startProcess: removing from pids map");
   3621             synchronized (mPidsSelfLocked) {
   3622                 mPidsSelfLocked.remove(app.pid);
   3623                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   3624             }
   3625             checkTime(startTime, "startProcess: done removing from pids map");
   3626             app.setPid(0);
   3627         }
   3628 
   3629         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
   3630                 "startProcessLocked removing on hold: " + app);
   3631         mProcessesOnHold.remove(app);
   3632 
   3633         checkTime(startTime, "startProcess: starting to update cpu stats");
   3634         updateCpuStats();
   3635         checkTime(startTime, "startProcess: done updating cpu stats");
   3636 
   3637         try {
   3638             try {
   3639                 final int userId = UserHandle.getUserId(app.uid);
   3640                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
   3641             } catch (RemoteException e) {
   3642                 throw e.rethrowAsRuntimeException();
   3643             }
   3644 
   3645             int uid = app.uid;
   3646             int[] gids = null;
   3647             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
   3648             if (!app.isolated) {
   3649                 int[] permGids = null;
   3650                 try {
   3651                     checkTime(startTime, "startProcess: getting gids from package manager");
   3652                     final IPackageManager pm = AppGlobals.getPackageManager();
   3653                     permGids = pm.getPackageGids(app.info.packageName,
   3654                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
   3655                     MountServiceInternal mountServiceInternal = LocalServices.getService(
   3656                             MountServiceInternal.class);
   3657                     mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
   3658                             app.info.packageName);
   3659                 } catch (RemoteException e) {
   3660                     throw e.rethrowAsRuntimeException();
   3661                 }
   3662 
   3663                 /*
   3664                  * Add shared application and profile GIDs so applications can share some
   3665                  * resources like shared libraries and access user-wide resources
   3666                  */
   3667                 if (ArrayUtils.isEmpty(permGids)) {
   3668                     gids = new int[2];
   3669                 } else {
   3670                     gids = new int[permGids.length + 2];
   3671                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
   3672                 }
   3673                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
   3674                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
   3675             }
   3676             checkTime(startTime, "startProcess: building args");
   3677             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
   3678                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
   3679                         && mTopComponent != null
   3680                         && app.processName.equals(mTopComponent.getPackageName())) {
   3681                     uid = 0;
   3682                 }
   3683                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
   3684                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
   3685                     uid = 0;
   3686                 }
   3687             }
   3688             int debugFlags = 0;
   3689             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   3690                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
   3691                 // Also turn on CheckJNI for debuggable apps. It's quite
   3692                 // awkward to turn on otherwise.
   3693                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   3694             }
   3695             // Run the app in safe mode if its manifest requests so or the
   3696             // system is booted in safe mode.
   3697             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
   3698                 mSafeMode == true) {
   3699                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
   3700             }
   3701             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
   3702                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   3703             }
   3704             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
   3705             if ("true".equals(genDebugInfoProperty)) {
   3706                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
   3707             }
   3708             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
   3709                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
   3710             }
   3711             if ("1".equals(SystemProperties.get("debug.assert"))) {
   3712                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
   3713             }
   3714             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
   3715                 // Enable all debug flags required by the native debugger.
   3716                 debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
   3717                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
   3718                 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
   3719                 mNativeDebuggingApp = null;
   3720             }
   3721 
   3722             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
   3723             if (requiredAbi == null) {
   3724                 requiredAbi = Build.SUPPORTED_ABIS[0];
   3725             }
   3726 
   3727             String instructionSet = null;
   3728             if (app.info.primaryCpuAbi != null) {
   3729                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
   3730             }
   3731 
   3732             app.gids = gids;
   3733             app.requiredAbi = requiredAbi;
   3734             app.instructionSet = instructionSet;
   3735 
   3736             // Start the process.  It will either succeed and return a result containing
   3737             // the PID of the new process, or else throw a RuntimeException.
   3738             boolean isActivityProcess = (entryPoint == null);
   3739             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
   3740             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
   3741                     app.processName);
   3742             checkTime(startTime, "startProcess: asking zygote to start proc");
   3743             Process.ProcessStartResult startResult = Process.start(entryPoint,
   3744                     app.processName, uid, uid, gids, debugFlags, mountExternal,
   3745                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
   3746                     app.info.dataDir, entryPointArgs);
   3747             checkTime(startTime, "startProcess: returned from zygote!");
   3748             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   3749 
   3750             if (app.isolated) {
   3751                 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
   3752             }
   3753             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
   3754             checkTime(startTime, "startProcess: done updating battery stats");
   3755 
   3756             EventLog.writeEvent(EventLogTags.AM_PROC_START,
   3757                     UserHandle.getUserId(uid), startResult.pid, uid,
   3758                     app.processName, hostingType,
   3759                     hostingNameStr != null ? hostingNameStr : "");
   3760 
   3761             try {
   3762                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
   3763                         app.info.seinfo, app.info.sourceDir, startResult.pid);
   3764             } catch (RemoteException ex) {
   3765                 // Ignore
   3766             }
   3767 
   3768             if (app.persistent) {
   3769                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
   3770             }
   3771 
   3772             checkTime(startTime, "startProcess: building log message");
   3773             StringBuilder buf = mStringBuilder;
   3774             buf.setLength(0);
   3775             buf.append("Start proc ");
   3776             buf.append(startResult.pid);
   3777             buf.append(':');
   3778             buf.append(app.processName);
   3779             buf.append('/');
   3780             UserHandle.formatUid(buf, uid);
   3781             if (!isActivityProcess) {
   3782                 buf.append(" [");
   3783                 buf.append(entryPoint);
   3784                 buf.append("]");
   3785             }
   3786             buf.append(" for ");
   3787             buf.append(hostingType);
   3788             if (hostingNameStr != null) {
   3789                 buf.append(" ");
   3790                 buf.append(hostingNameStr);
   3791             }
   3792             Slog.i(TAG, buf.toString());
   3793             app.setPid(startResult.pid);
   3794             app.usingWrapper = startResult.usingWrapper;
   3795             app.removed = false;
   3796             app.killed = false;
   3797             app.killedByAm = false;
   3798             checkTime(startTime, "startProcess: starting to update pids map");
   3799             synchronized (mPidsSelfLocked) {
   3800                 this.mPidsSelfLocked.put(startResult.pid, app);
   3801                 if (isActivityProcess) {
   3802                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   3803                     msg.obj = app;
   3804                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
   3805                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
   3806                 }
   3807             }
   3808             checkTime(startTime, "startProcess: done updating pids map");
   3809         } catch (RuntimeException e) {
   3810             Slog.e(TAG, "Failure starting process " + app.processName, e);
   3811 
   3812             // Something went very wrong while trying to start this process; one
   3813             // common case is when the package is frozen due to an active
   3814             // upgrade. To recover, clean up any active bookkeeping related to
   3815             // starting this process. (We already invoked this method once when
   3816             // the package was initially frozen through KILL_APPLICATION_MSG, so
   3817             // it doesn't hurt to use it again.)
   3818             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
   3819                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
   3820         }
   3821     }
   3822 
   3823     void updateUsageStats(ActivityRecord component, boolean resumed) {
   3824         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
   3825                 "updateUsageStats: comp=" + component + "res=" + resumed);
   3826         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   3827         if (resumed) {
   3828             if (mUsageStatsService != null) {
   3829                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
   3830                         UsageEvents.Event.MOVE_TO_FOREGROUND);
   3831             }
   3832             synchronized (stats) {
   3833                 stats.noteActivityResumedLocked(component.app.uid);
   3834             }
   3835         } else {
   3836             if (mUsageStatsService != null) {
   3837                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
   3838                         UsageEvents.Event.MOVE_TO_BACKGROUND);
   3839             }
   3840             synchronized (stats) {
   3841                 stats.noteActivityPausedLocked(component.app.uid);
   3842             }
   3843         }
   3844     }
   3845 
   3846     Intent getHomeIntent() {
   3847         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
   3848         intent.setComponent(mTopComponent);
   3849         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
   3850         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   3851             intent.addCategory(Intent.CATEGORY_HOME);
   3852         }
   3853         return intent;
   3854     }
   3855 
   3856     boolean startHomeActivityLocked(int userId, String reason) {
   3857         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
   3858                 && mTopAction == null) {
   3859             // We are running in factory test mode, but unable to find
   3860             // the factory test app, so just sit around displaying the
   3861             // error message and don't try to start anything.
   3862             return false;
   3863         }
   3864         Intent intent = getHomeIntent();
   3865         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
   3866         if (aInfo != null) {
   3867             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
   3868             // Don't do this if the home app is currently being
   3869             // instrumented.
   3870             aInfo = new ActivityInfo(aInfo);
   3871             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
   3872             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
   3873                     aInfo.applicationInfo.uid, true);
   3874             if (app == null || app.instrumentationClass == null) {
   3875                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
   3876                 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
   3877             }
   3878         } else {
   3879             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
   3880         }
   3881 
   3882         return true;
   3883     }
   3884 
   3885     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
   3886         ActivityInfo ai = null;
   3887         ComponentName comp = intent.getComponent();
   3888         try {
   3889             if (comp != null) {
   3890                 // Factory test.
   3891                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
   3892             } else {
   3893                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
   3894                         intent,
   3895                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
   3896                         flags, userId);
   3897 
   3898                 if (info != null) {
   3899                     ai = info.activityInfo;
   3900                 }
   3901             }
   3902         } catch (RemoteException e) {
   3903             // ignore
   3904         }
   3905 
   3906         return ai;
   3907     }
   3908 
   3909     /**
   3910      * Starts the "new version setup screen" if appropriate.
   3911      */
   3912     void startSetupActivityLocked() {
   3913         // Only do this once per boot.
   3914         if (mCheckedForSetup) {
   3915             return;
   3916         }
   3917 
   3918         // We will show this screen if the current one is a different
   3919         // version than the last one shown, and we are not running in
   3920         // low-level factory test mode.
   3921         final ContentResolver resolver = mContext.getContentResolver();
   3922         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
   3923                 Settings.Global.getInt(resolver,
   3924                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
   3925             mCheckedForSetup = true;
   3926 
   3927             // See if we should be showing the platform update setup UI.
   3928             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
   3929             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
   3930                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
   3931             if (!ris.isEmpty()) {
   3932                 final ResolveInfo ri = ris.get(0);
   3933                 String vers = ri.activityInfo.metaData != null
   3934                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
   3935                         : null;
   3936                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
   3937                     vers = ri.activityInfo.applicationInfo.metaData.getString(
   3938                             Intent.METADATA_SETUP_VERSION);
   3939                 }
   3940                 String lastVers = Settings.Secure.getString(
   3941                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
   3942                 if (vers != null && !vers.equals(lastVers)) {
   3943                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   3944                     intent.setComponent(new ComponentName(
   3945                             ri.activityInfo.packageName, ri.activityInfo.name));
   3946                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
   3947                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
   3948                             null, 0, 0, 0, null, false, false, null, null, null);
   3949                 }
   3950             }
   3951         }
   3952     }
   3953 
   3954     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
   3955         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
   3956     }
   3957 
   3958     void enforceNotIsolatedCaller(String caller) {
   3959         if (UserHandle.isIsolated(Binder.getCallingUid())) {
   3960             throw new SecurityException("Isolated process not allowed to call " + caller);
   3961         }
   3962     }
   3963 
   3964     void enforceShellRestriction(String restriction, int userHandle) {
   3965         if (Binder.getCallingUid() == Process.SHELL_UID) {
   3966             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
   3967                 throw new SecurityException("Shell does not have permission to access user "
   3968                         + userHandle);
   3969             }
   3970         }
   3971     }
   3972 
   3973     @Override
   3974     public int getFrontActivityScreenCompatMode() {
   3975         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
   3976         synchronized (this) {
   3977             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
   3978         }
   3979     }
   3980 
   3981     @Override
   3982     public void setFrontActivityScreenCompatMode(int mode) {
   3983         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   3984                 "setFrontActivityScreenCompatMode");
   3985         synchronized (this) {
   3986             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
   3987         }
   3988     }
   3989 
   3990     @Override
   3991     public int getPackageScreenCompatMode(String packageName) {
   3992         enforceNotIsolatedCaller("getPackageScreenCompatMode");
   3993         synchronized (this) {
   3994             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
   3995         }
   3996     }
   3997 
   3998     @Override
   3999     public void setPackageScreenCompatMode(String packageName, int mode) {
   4000         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   4001                 "setPackageScreenCompatMode");
   4002         synchronized (this) {
   4003             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
   4004         }
   4005     }
   4006 
   4007     @Override
   4008     public boolean getPackageAskScreenCompat(String packageName) {
   4009         enforceNotIsolatedCaller("getPackageAskScreenCompat");
   4010         synchronized (this) {
   4011             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
   4012         }
   4013     }
   4014 
   4015     @Override
   4016     public void setPackageAskScreenCompat(String packageName, boolean ask) {
   4017         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   4018                 "setPackageAskScreenCompat");
   4019         synchronized (this) {
   4020             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
   4021         }
   4022     }
   4023 
   4024     private boolean hasUsageStatsPermission(String callingPackage) {
   4025         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
   4026                 Binder.getCallingUid(), callingPackage);
   4027         if (mode == AppOpsManager.MODE_DEFAULT) {
   4028             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
   4029                     == PackageManager.PERMISSION_GRANTED;
   4030         }
   4031         return mode == AppOpsManager.MODE_ALLOWED;
   4032     }
   4033 
   4034     @Override
   4035     public int getPackageProcessState(String packageName, String callingPackage) {
   4036         if (!hasUsageStatsPermission(callingPackage)) {
   4037             enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
   4038                     "getPackageProcessState");
   4039         }
   4040 
   4041         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
   4042         synchronized (this) {
   4043             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   4044                 final ProcessRecord proc = mLruProcesses.get(i);
   4045                 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
   4046                         || procState > proc.setProcState) {
   4047                     boolean found = false;
   4048                     for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
   4049                         if (proc.pkgList.keyAt(j).equals(packageName)) {
   4050                             procState = proc.setProcState;
   4051                             found = true;
   4052                         }
   4053                     }
   4054                     if (proc.pkgDeps != null && !found) {
   4055                         for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
   4056                             if (proc.pkgDeps.valueAt(j).equals(packageName)) {
   4057                                 procState = proc.setProcState;
   4058                                 break;
   4059                             }
   4060                         }
   4061                     }
   4062                 }
   4063             }
   4064         }
   4065         return procState;
   4066     }
   4067 
   4068     @Override
   4069     public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
   4070         synchronized (this) {
   4071             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
   4072             if (app == null) {
   4073                 return false;
   4074             }
   4075             if (app.trimMemoryLevel < level && app.thread != null &&
   4076                     (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
   4077                             app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
   4078                 try {
   4079                     app.thread.scheduleTrimMemory(level);
   4080                     app.trimMemoryLevel = level;
   4081                     return true;
   4082                 } catch (RemoteException e) {
   4083                     // Fallthrough to failure case.
   4084                 }
   4085             }
   4086         }
   4087         return false;
   4088     }
   4089 
   4090     private void dispatchProcessesChanged() {
   4091         int N;
   4092         synchronized (this) {
   4093             N = mPendingProcessChanges.size();
   4094             if (mActiveProcessChanges.length < N) {
   4095                 mActiveProcessChanges = new ProcessChangeItem[N];
   4096             }
   4097             mPendingProcessChanges.toArray(mActiveProcessChanges);
   4098             mPendingProcessChanges.clear();
   4099             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   4100                     "*** Delivering " + N + " process changes");
   4101         }
   4102 
   4103         int i = mProcessObservers.beginBroadcast();
   4104         while (i > 0) {
   4105             i--;
   4106             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   4107             if (observer != null) {
   4108                 try {
   4109                     for (int j=0; j<N; j++) {
   4110                         ProcessChangeItem item = mActiveProcessChanges[j];
   4111                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
   4112                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   4113                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
   4114                                     + item.uid + ": " + item.foregroundActivities);
   4115                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
   4116                                     item.foregroundActivities);
   4117                         }
   4118                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
   4119                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   4120                                     "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
   4121                                     + ": " + item.processState);
   4122                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
   4123                         }
   4124                     }
   4125                 } catch (RemoteException e) {
   4126                 }
   4127             }
   4128         }
   4129         mProcessObservers.finishBroadcast();
   4130 
   4131         synchronized (this) {
   4132             for (int j=0; j<N; j++) {
   4133                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
   4134             }
   4135         }
   4136     }
   4137 
   4138     private void dispatchProcessDied(int pid, int uid) {
   4139         int i = mProcessObservers.beginBroadcast();
   4140         while (i > 0) {
   4141             i--;
   4142             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   4143             if (observer != null) {
   4144                 try {
   4145                     observer.onProcessDied(pid, uid);
   4146                 } catch (RemoteException e) {
   4147                 }
   4148             }
   4149         }
   4150         mProcessObservers.finishBroadcast();
   4151     }
   4152 
   4153     private void dispatchUidsChanged() {
   4154         int N;
   4155         synchronized (this) {
   4156             N = mPendingUidChanges.size();
   4157             if (mActiveUidChanges.length < N) {
   4158                 mActiveUidChanges = new UidRecord.ChangeItem[N];
   4159             }
   4160             for (int i=0; i<N; i++) {
   4161                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
   4162                 mActiveUidChanges[i] = change;
   4163                 if (change.uidRecord != null) {
   4164                     change.uidRecord.pendingChange = null;
   4165                     change.uidRecord = null;
   4166                 }
   4167             }
   4168             mPendingUidChanges.clear();
   4169             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4170                     "*** Delivering " + N + " uid changes");
   4171         }
   4172 
   4173         if (mLocalPowerManager != null) {
   4174             for (int j=0; j<N; j++) {
   4175                 UidRecord.ChangeItem item = mActiveUidChanges[j];
   4176                 if (item.change == UidRecord.CHANGE_GONE
   4177                         || item.change == UidRecord.CHANGE_GONE_IDLE) {
   4178                     mLocalPowerManager.uidGone(item.uid);
   4179                 } else {
   4180                     mLocalPowerManager.updateUidProcState(item.uid, item.processState);
   4181                 }
   4182             }
   4183         }
   4184 
   4185         int i = mUidObservers.beginBroadcast();
   4186         while (i > 0) {
   4187             i--;
   4188             final IUidObserver observer = mUidObservers.getBroadcastItem(i);
   4189             final int which = (Integer)mUidObservers.getBroadcastCookie(i);
   4190             if (observer != null) {
   4191                 try {
   4192                     for (int j=0; j<N; j++) {
   4193                         UidRecord.ChangeItem item = mActiveUidChanges[j];
   4194                         final int change = item.change;
   4195                         UidRecord validateUid = null;
   4196                         if (VALIDATE_UID_STATES && i == 0) {
   4197                             validateUid = mValidateUids.get(item.uid);
   4198                             if (validateUid == null && change != UidRecord.CHANGE_GONE
   4199                                     && change != UidRecord.CHANGE_GONE_IDLE) {
   4200                                 validateUid = new UidRecord(item.uid);
   4201                                 mValidateUids.put(item.uid, validateUid);
   4202                             }
   4203                         }
   4204                         if (change == UidRecord.CHANGE_IDLE
   4205                                 || change == UidRecord.CHANGE_GONE_IDLE) {
   4206                             if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
   4207                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4208                                         "UID idle uid=" + item.uid);
   4209                                 observer.onUidIdle(item.uid);
   4210                             }
   4211                             if (VALIDATE_UID_STATES && i == 0) {
   4212                                 if (validateUid != null) {
   4213                                     validateUid.idle = true;
   4214                                 }
   4215                             }
   4216                         } else if (change == UidRecord.CHANGE_ACTIVE) {
   4217                             if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
   4218                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4219                                         "UID active uid=" + item.uid);
   4220                                 observer.onUidActive(item.uid);
   4221                             }
   4222                             if (VALIDATE_UID_STATES && i == 0) {
   4223                                 validateUid.idle = false;
   4224                             }
   4225                         }
   4226                         if (change == UidRecord.CHANGE_GONE
   4227                                 || change == UidRecord.CHANGE_GONE_IDLE) {
   4228                             if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
   4229                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4230                                         "UID gone uid=" + item.uid);
   4231                                 observer.onUidGone(item.uid);
   4232                             }
   4233                             if (VALIDATE_UID_STATES && i == 0) {
   4234                                 if (validateUid != null) {
   4235                                     mValidateUids.remove(item.uid);
   4236                                 }
   4237                             }
   4238                         } else {
   4239                             if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
   4240                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4241                                         "UID CHANGED uid=" + item.uid
   4242                                                 + ": " + item.processState);
   4243                                 observer.onUidStateChanged(item.uid, item.processState);
   4244                             }
   4245                             if (VALIDATE_UID_STATES && i == 0) {
   4246                                 validateUid.curProcState = validateUid.setProcState
   4247                                         = item.processState;
   4248                             }
   4249                         }
   4250                     }
   4251                 } catch (RemoteException e) {
   4252                 }
   4253             }
   4254         }
   4255         mUidObservers.finishBroadcast();
   4256 
   4257         synchronized (this) {
   4258             for (int j=0; j<N; j++) {
   4259                 mAvailUidChanges.add(mActiveUidChanges[j]);
   4260             }
   4261         }
   4262     }
   4263 
   4264     @Override
   4265     public final int startActivity(IApplicationThread caller, String callingPackage,
   4266             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   4267             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
   4268         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
   4269                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
   4270                 UserHandle.getCallingUserId());
   4271     }
   4272 
   4273     final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
   4274         enforceNotIsolatedCaller("ActivityContainer.startActivity");
   4275         final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
   4276                 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
   4277                 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
   4278 
   4279         // TODO: Switch to user app stacks here.
   4280         String mimeType = intent.getType();
   4281         final Uri data = intent.getData();
   4282         if (mimeType == null && data != null && "content".equals(data.getScheme())) {
   4283             mimeType = getProviderMimeType(data, userId);
   4284         }
   4285         container.checkEmbeddedAllowedInner(userId, intent, mimeType);
   4286 
   4287         intent.addFlags(FORCE_NEW_TASK_FLAGS);
   4288         return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
   4289                 null, 0, 0, null, null, null, null, false, userId, container, null);
   4290     }
   4291 
   4292     @Override
   4293     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
   4294             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   4295             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
   4296         enforceNotIsolatedCaller("startActivity");
   4297         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4298                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
   4299         // TODO: Switch to user app stacks here.
   4300         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
   4301                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
   4302                 profilerInfo, null, null, bOptions, false, userId, null, null);
   4303     }
   4304 
   4305     @Override
   4306     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
   4307             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   4308             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
   4309             int userId) {
   4310 
   4311         // This is very dangerous -- it allows you to perform a start activity (including
   4312         // permission grants) as any app that may launch one of your own activities.  So
   4313         // we will only allow this to be done from activities that are part of the core framework,
   4314         // and then only when they are running as the system.
   4315         final ActivityRecord sourceRecord;
   4316         final int targetUid;
   4317         final String targetPackage;
   4318         synchronized (this) {
   4319             if (resultTo == null) {
   4320                 throw new SecurityException("Must be called from an activity");
   4321             }
   4322             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
   4323             if (sourceRecord == null) {
   4324                 throw new SecurityException("Called with bad activity token: " + resultTo);
   4325             }
   4326             if (!sourceRecord.info.packageName.equals("android")) {
   4327                 throw new SecurityException(
   4328                         "Must be called from an activity that is declared in the android package");
   4329             }
   4330             if (sourceRecord.app == null) {
   4331                 throw new SecurityException("Called without a process attached to activity");
   4332             }
   4333             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
   4334                 // This is still okay, as long as this activity is running under the
   4335                 // uid of the original calling activity.
   4336                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
   4337                     throw new SecurityException(
   4338                             "Calling activity in uid " + sourceRecord.app.uid
   4339                                     + " must be system uid or original calling uid "
   4340                                     + sourceRecord.launchedFromUid);
   4341                 }
   4342             }
   4343             if (ignoreTargetSecurity) {
   4344                 if (intent.getComponent() == null) {
   4345                     throw new SecurityException(
   4346                             "Component must be specified with ignoreTargetSecurity");
   4347                 }
   4348                 if (intent.getSelector() != null) {
   4349                     throw new SecurityException(
   4350                             "Selector not allowed with ignoreTargetSecurity");
   4351                 }
   4352             }
   4353             targetUid = sourceRecord.launchedFromUid;
   4354             targetPackage = sourceRecord.launchedFromPackage;
   4355         }
   4356 
   4357         if (userId == UserHandle.USER_NULL) {
   4358             userId = UserHandle.getUserId(sourceRecord.app.uid);
   4359         }
   4360 
   4361         // TODO: Switch to user app stacks here.
   4362         try {
   4363             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
   4364                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
   4365                     null, null, bOptions, ignoreTargetSecurity, userId, null, null);
   4366             return ret;
   4367         } catch (SecurityException e) {
   4368             // XXX need to figure out how to propagate to original app.
   4369             // A SecurityException here is generally actually a fault of the original
   4370             // calling activity (such as a fairly granting permissions), so propagate it
   4371             // back to them.
   4372             /*
   4373             StringBuilder msg = new StringBuilder();
   4374             msg.append("While launching");
   4375             msg.append(intent.toString());
   4376             msg.append(": ");
   4377             msg.append(e.getMessage());
   4378             */
   4379             throw e;
   4380         }
   4381     }
   4382 
   4383     @Override
   4384     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
   4385             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   4386             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
   4387         enforceNotIsolatedCaller("startActivityAndWait");
   4388         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4389                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
   4390         WaitResult res = new WaitResult();
   4391         // TODO: Switch to user app stacks here.
   4392         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
   4393                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
   4394                 bOptions, false, userId, null, null);
   4395         return res;
   4396     }
   4397 
   4398     @Override
   4399     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
   4400             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   4401             int startFlags, Configuration config, Bundle bOptions, int userId) {
   4402         enforceNotIsolatedCaller("startActivityWithConfig");
   4403         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4404                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
   4405         // TODO: Switch to user app stacks here.
   4406         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
   4407                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
   4408                 null, null, config, bOptions, false, userId, null, null);
   4409         return ret;
   4410     }
   4411 
   4412     @Override
   4413     public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
   4414             Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
   4415             int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
   4416             throws TransactionTooLargeException {
   4417         enforceNotIsolatedCaller("startActivityIntentSender");
   4418         // Refuse possible leaked file descriptors
   4419         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
   4420             throw new IllegalArgumentException("File descriptors passed in Intent");
   4421         }
   4422 
   4423         IIntentSender sender = intent.getTarget();
   4424         if (!(sender instanceof PendingIntentRecord)) {
   4425             throw new IllegalArgumentException("Bad PendingIntent object");
   4426         }
   4427 
   4428         PendingIntentRecord pir = (PendingIntentRecord)sender;
   4429 
   4430         synchronized (this) {
   4431             // If this is coming from the currently resumed activity, it is
   4432             // effectively saying that app switches are allowed at this point.
   4433             final ActivityStack stack = getFocusedStack();
   4434             if (stack.mResumedActivity != null &&
   4435                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
   4436                 mAppSwitchesAllowedTime = 0;
   4437             }
   4438         }
   4439         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
   4440                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
   4441         return ret;
   4442     }
   4443 
   4444     @Override
   4445     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
   4446             Intent intent, String resolvedType, IVoiceInteractionSession session,
   4447             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
   4448             Bundle bOptions, int userId) {
   4449         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
   4450                 != PackageManager.PERMISSION_GRANTED) {
   4451             String msg = "Permission Denial: startVoiceActivity() from pid="
   4452                     + Binder.getCallingPid()
   4453                     + ", uid=" + Binder.getCallingUid()
   4454                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
   4455             Slog.w(TAG, msg);
   4456             throw new SecurityException(msg);
   4457         }
   4458         if (session == null || interactor == null) {
   4459             throw new NullPointerException("null session or interactor");
   4460         }
   4461         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
   4462                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
   4463         // TODO: Switch to user app stacks here.
   4464         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
   4465                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
   4466                 null, bOptions, false, userId, null, null);
   4467     }
   4468 
   4469     @Override
   4470     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
   4471             throws RemoteException {
   4472         Slog.i(TAG, "Activity tried to startVoiceInteraction");
   4473         synchronized (this) {
   4474             ActivityRecord activity = getFocusedStack().topActivity();
   4475             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
   4476                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
   4477             }
   4478             if (mRunningVoice != null || activity.task.voiceSession != null
   4479                     || activity.voiceSession != null) {
   4480                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
   4481                 return;
   4482             }
   4483             if (activity.pendingVoiceInteractionStart) {
   4484                 Slog.w(TAG, "Pending start of voice interaction already.");
   4485                 return;
   4486             }
   4487             activity.pendingVoiceInteractionStart = true;
   4488         }
   4489         LocalServices.getService(VoiceInteractionManagerInternal.class)
   4490                 .startLocalVoiceInteraction(callingActivity, options);
   4491     }
   4492 
   4493     @Override
   4494     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
   4495         LocalServices.getService(VoiceInteractionManagerInternal.class)
   4496                 .stopLocalVoiceInteraction(callingActivity);
   4497     }
   4498 
   4499     @Override
   4500     public boolean supportsLocalVoiceInteraction() throws RemoteException {
   4501         return LocalServices.getService(VoiceInteractionManagerInternal.class)
   4502                 .supportsLocalVoiceInteraction();
   4503     }
   4504 
   4505     void onLocalVoiceInteractionStartedLocked(IBinder activity,
   4506             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
   4507         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
   4508         if (activityToCallback == null) return;
   4509         activityToCallback.setVoiceSessionLocked(voiceSession);
   4510 
   4511         // Inform the activity
   4512         try {
   4513             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
   4514                     voiceInteractor);
   4515             long token = Binder.clearCallingIdentity();
   4516             try {
   4517                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
   4518             } finally {
   4519                 Binder.restoreCallingIdentity(token);
   4520             }
   4521             // TODO: VI Should we cache the activity so that it's easier to find later
   4522             // rather than scan through all the stacks and activities?
   4523         } catch (RemoteException re) {
   4524             activityToCallback.clearVoiceSessionLocked();
   4525             // TODO: VI Should this terminate the voice session?
   4526         }
   4527     }
   4528 
   4529     @Override
   4530     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
   4531         synchronized (this) {
   4532             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
   4533                 if (keepAwake) {
   4534                     mVoiceWakeLock.acquire();
   4535                 } else {
   4536                     mVoiceWakeLock.release();
   4537                 }
   4538             }
   4539         }
   4540     }
   4541 
   4542     @Override
   4543     public boolean startNextMatchingActivity(IBinder callingActivity,
   4544             Intent intent, Bundle bOptions) {
   4545         // Refuse possible leaked file descriptors
   4546         if (intent != null && intent.hasFileDescriptors() == true) {
   4547             throw new IllegalArgumentException("File descriptors passed in Intent");
   4548         }
   4549         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
   4550 
   4551         synchronized (this) {
   4552             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
   4553             if (r == null) {
   4554                 ActivityOptions.abort(options);
   4555                 return false;
   4556             }
   4557             if (r.app == null || r.app.thread == null) {
   4558                 // The caller is not running...  d'oh!
   4559                 ActivityOptions.abort(options);
   4560                 return false;
   4561             }
   4562             intent = new Intent(intent);
   4563             // The caller is not allowed to change the data.
   4564             intent.setDataAndType(r.intent.getData(), r.intent.getType());
   4565             // And we are resetting to find the next component...
   4566             intent.setComponent(null);
   4567 
   4568             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
   4569 
   4570             ActivityInfo aInfo = null;
   4571             try {
   4572                 List<ResolveInfo> resolves =
   4573                     AppGlobals.getPackageManager().queryIntentActivities(
   4574                             intent, r.resolvedType,
   4575                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
   4576                             UserHandle.getCallingUserId()).getList();
   4577 
   4578                 // Look for the original activity in the list...
   4579                 final int N = resolves != null ? resolves.size() : 0;
   4580                 for (int i=0; i<N; i++) {
   4581                     ResolveInfo rInfo = resolves.get(i);
   4582                     if (rInfo.activityInfo.packageName.equals(r.packageName)
   4583                             && rInfo.activityInfo.name.equals(r.info.name)) {
   4584                         // We found the current one...  the next matching is
   4585                         // after it.
   4586                         i++;
   4587                         if (i<N) {
   4588                             aInfo = resolves.get(i).activityInfo;
   4589                         }
   4590                         if (debug) {
   4591                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
   4592                                     + "/" + r.info.name);
   4593                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
   4594                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
   4595                         }
   4596                         break;
   4597                     }
   4598                 }
   4599             } catch (RemoteException e) {
   4600             }
   4601 
   4602             if (aInfo == null) {
   4603                 // Nobody who is next!
   4604                 ActivityOptions.abort(options);
   4605                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
   4606                 return false;
   4607             }
   4608 
   4609             intent.setComponent(new ComponentName(
   4610                     aInfo.applicationInfo.packageName, aInfo.name));
   4611             intent.setFlags(intent.getFlags()&~(
   4612                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
   4613                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
   4614                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
   4615                     Intent.FLAG_ACTIVITY_NEW_TASK));
   4616 
   4617             // Okay now we need to start the new activity, replacing the
   4618             // currently running activity.  This is a little tricky because
   4619             // we want to start the new one as if the current one is finished,
   4620             // but not finish the current one first so that there is no flicker.
   4621             // And thus...
   4622             final boolean wasFinishing = r.finishing;
   4623             r.finishing = true;
   4624 
   4625             // Propagate reply information over to the new activity.
   4626             final ActivityRecord resultTo = r.resultTo;
   4627             final String resultWho = r.resultWho;
   4628             final int requestCode = r.requestCode;
   4629             r.resultTo = null;
   4630             if (resultTo != null) {
   4631                 resultTo.removeResultsLocked(r, resultWho, requestCode);
   4632             }
   4633 
   4634             final long origId = Binder.clearCallingIdentity();
   4635             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
   4636                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
   4637                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
   4638                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
   4639                     false, false, null, null, null);
   4640             Binder.restoreCallingIdentity(origId);
   4641 
   4642             r.finishing = wasFinishing;
   4643             if (res != ActivityManager.START_SUCCESS) {
   4644                 return false;
   4645             }
   4646             return true;
   4647         }
   4648     }
   4649 
   4650     @Override
   4651     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
   4652         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
   4653             String msg = "Permission Denial: startActivityFromRecents called without " +
   4654                     START_TASKS_FROM_RECENTS;
   4655             Slog.w(TAG, msg);
   4656             throw new SecurityException(msg);
   4657         }
   4658         final long origId = Binder.clearCallingIdentity();
   4659         try {
   4660             synchronized (this) {
   4661                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
   4662             }
   4663         } finally {
   4664             Binder.restoreCallingIdentity(origId);
   4665         }
   4666     }
   4667 
   4668     final int startActivityInPackage(int uid, String callingPackage,
   4669             Intent intent, String resolvedType, IBinder resultTo,
   4670             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
   4671             IActivityContainer container, TaskRecord inTask) {
   4672 
   4673         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4674                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
   4675 
   4676         // TODO: Switch to user app stacks here.
   4677         int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
   4678                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
   4679                 null, null, null, bOptions, false, userId, container, inTask);
   4680         return ret;
   4681     }
   4682 
   4683     @Override
   4684     public final int startActivities(IApplicationThread caller, String callingPackage,
   4685             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
   4686             int userId) {
   4687         enforceNotIsolatedCaller("startActivities");
   4688         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4689                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
   4690         // TODO: Switch to user app stacks here.
   4691         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
   4692                 resolvedTypes, resultTo, bOptions, userId);
   4693         return ret;
   4694     }
   4695 
   4696     final int startActivitiesInPackage(int uid, String callingPackage,
   4697             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
   4698             Bundle bOptions, int userId) {
   4699 
   4700         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4701                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
   4702         // TODO: Switch to user app stacks here.
   4703         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
   4704                 resultTo, bOptions, userId);
   4705         return ret;
   4706     }
   4707 
   4708     @Override
   4709     public void reportActivityFullyDrawn(IBinder token) {
   4710         synchronized (this) {
   4711             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4712             if (r == null) {
   4713                 return;
   4714             }
   4715             r.reportFullyDrawnLocked();
   4716         }
   4717     }
   4718 
   4719     @Override
   4720     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
   4721         synchronized (this) {
   4722             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4723             if (r == null) {
   4724                 return;
   4725             }
   4726             TaskRecord task = r.task;
   4727             if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
   4728                 // Fixed screen orientation isn't supported when activities aren't in full screen
   4729                 // mode.
   4730                 return;
   4731             }
   4732             final long origId = Binder.clearCallingIdentity();
   4733             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
   4734             Configuration config = mWindowManager.updateOrientationFromAppTokens(
   4735                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
   4736             if (config != null) {
   4737                 r.frozenBeforeDestroy = true;
   4738                 if (!updateConfigurationLocked(config, r, false)) {
   4739                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
   4740                 }
   4741             }
   4742             Binder.restoreCallingIdentity(origId);
   4743         }
   4744     }
   4745 
   4746     @Override
   4747     public int getRequestedOrientation(IBinder token) {
   4748         synchronized (this) {
   4749             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4750             if (r == null) {
   4751                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
   4752             }
   4753             return mWindowManager.getAppOrientation(r.appToken);
   4754         }
   4755     }
   4756 
   4757     /**
   4758      * This is the internal entry point for handling Activity.finish().
   4759      *
   4760      * @param token The Binder token referencing the Activity we want to finish.
   4761      * @param resultCode Result code, if any, from this Activity.
   4762      * @param resultData Result data (Intent), if any, from this Activity.
   4763      * @param finishTask Whether to finish the task associated with this Activity.
   4764      *
   4765      * @return Returns true if the activity successfully finished, or false if it is still running.
   4766      */
   4767     @Override
   4768     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
   4769             int finishTask) {
   4770         // Refuse possible leaked file descriptors
   4771         if (resultData != null && resultData.hasFileDescriptors() == true) {
   4772             throw new IllegalArgumentException("File descriptors passed in Intent");
   4773         }
   4774 
   4775         synchronized(this) {
   4776             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4777             if (r == null) {
   4778                 return true;
   4779             }
   4780             // Keep track of the root activity of the task before we finish it
   4781             TaskRecord tr = r.task;
   4782             ActivityRecord rootR = tr.getRootActivity();
   4783             if (rootR == null) {
   4784                 Slog.w(TAG, "Finishing task with all activities already finished");
   4785             }
   4786             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
   4787             // finish.
   4788             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
   4789                     mStackSupervisor.isLastLockedTask(tr)) {
   4790                 Slog.i(TAG, "Not finishing task in lock task mode");
   4791                 mStackSupervisor.showLockTaskToast();
   4792                 return false;
   4793             }
   4794             if (mController != null) {
   4795                 // Find the first activity that is not finishing.
   4796                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
   4797                 if (next != null) {
   4798                     // ask watcher if this is allowed
   4799                     boolean resumeOK = true;
   4800                     try {
   4801                         resumeOK = mController.activityResuming(next.packageName);
   4802                     } catch (RemoteException e) {
   4803                         mController = null;
   4804                         Watchdog.getInstance().setActivityController(null);
   4805                     }
   4806 
   4807                     if (!resumeOK) {
   4808                         Slog.i(TAG, "Not finishing activity because controller resumed");
   4809                         return false;
   4810                     }
   4811                 }
   4812             }
   4813             final long origId = Binder.clearCallingIdentity();
   4814             try {
   4815                 boolean res;
   4816                 final boolean finishWithRootActivity =
   4817                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
   4818                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
   4819                         || (finishWithRootActivity && r == rootR)) {
   4820                     // If requested, remove the task that is associated to this activity only if it
   4821                     // was the root activity in the task. The result code and data is ignored
   4822                     // because we don't support returning them across task boundaries. Also, to
   4823                     // keep backwards compatibility we remove the task from recents when finishing
   4824                     // task with root activity.
   4825                     res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
   4826                     if (!res) {
   4827                         Slog.i(TAG, "Removing task failed to finish activity");
   4828                     }
   4829                 } else {
   4830                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
   4831                             resultData, "app-request", true);
   4832                     if (!res) {
   4833                         Slog.i(TAG, "Failed to finish by app-request");
   4834                     }
   4835                 }
   4836                 return res;
   4837             } finally {
   4838                 Binder.restoreCallingIdentity(origId);
   4839             }
   4840         }
   4841     }
   4842 
   4843     @Override
   4844     public final void finishHeavyWeightApp() {
   4845         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   4846                 != PackageManager.PERMISSION_GRANTED) {
   4847             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
   4848                     + Binder.getCallingPid()
   4849                     + ", uid=" + Binder.getCallingUid()
   4850                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   4851             Slog.w(TAG, msg);
   4852             throw new SecurityException(msg);
   4853         }
   4854 
   4855         synchronized(this) {
   4856             if (mHeavyWeightProcess == null) {
   4857                 return;
   4858             }
   4859 
   4860             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
   4861             for (int i = 0; i < activities.size(); i++) {
   4862                 ActivityRecord r = activities.get(i);
   4863                 if (!r.finishing && r.isInStackLocked()) {
   4864                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
   4865                             null, "finish-heavy", true);
   4866                 }
   4867             }
   4868 
   4869             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   4870                     mHeavyWeightProcess.userId, 0));
   4871             mHeavyWeightProcess = null;
   4872         }
   4873     }
   4874 
   4875     @Override
   4876     public void crashApplication(int uid, int initialPid, String packageName,
   4877             String message) {
   4878         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   4879                 != PackageManager.PERMISSION_GRANTED) {
   4880             String msg = "Permission Denial: crashApplication() from pid="
   4881                     + Binder.getCallingPid()
   4882                     + ", uid=" + Binder.getCallingUid()
   4883                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   4884             Slog.w(TAG, msg);
   4885             throw new SecurityException(msg);
   4886         }
   4887 
   4888         synchronized(this) {
   4889             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
   4890         }
   4891     }
   4892 
   4893     @Override
   4894     public final void finishSubActivity(IBinder token, String resultWho,
   4895             int requestCode) {
   4896         synchronized(this) {
   4897             final long origId = Binder.clearCallingIdentity();
   4898             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4899             if (r != null) {
   4900                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
   4901             }
   4902             Binder.restoreCallingIdentity(origId);
   4903         }
   4904     }
   4905 
   4906     @Override
   4907     public boolean finishActivityAffinity(IBinder token) {
   4908         synchronized(this) {
   4909             final long origId = Binder.clearCallingIdentity();
   4910             try {
   4911                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4912                 if (r == null) {
   4913                     return false;
   4914                 }
   4915 
   4916                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
   4917                 // can finish.
   4918                 final TaskRecord task = r.task;
   4919                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
   4920                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
   4921                     mStackSupervisor.showLockTaskToast();
   4922                     return false;
   4923                 }
   4924                 return task.stack.finishActivityAffinityLocked(r);
   4925             } finally {
   4926                 Binder.restoreCallingIdentity(origId);
   4927             }
   4928         }
   4929     }
   4930 
   4931     @Override
   4932     public void finishVoiceTask(IVoiceInteractionSession session) {
   4933         synchronized (this) {
   4934             final long origId = Binder.clearCallingIdentity();
   4935             try {
   4936                 // TODO: VI Consider treating local voice interactions and voice tasks
   4937                 // differently here
   4938                 mStackSupervisor.finishVoiceTask(session);
   4939             } finally {
   4940                 Binder.restoreCallingIdentity(origId);
   4941             }
   4942         }
   4943 
   4944     }
   4945 
   4946     @Override
   4947     public boolean releaseActivityInstance(IBinder token) {
   4948         synchronized(this) {
   4949             final long origId = Binder.clearCallingIdentity();
   4950             try {
   4951                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4952                 if (r == null) {
   4953                     return false;
   4954                 }
   4955                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
   4956             } finally {
   4957                 Binder.restoreCallingIdentity(origId);
   4958             }
   4959         }
   4960     }
   4961 
   4962     @Override
   4963     public void releaseSomeActivities(IApplicationThread appInt) {
   4964         synchronized(this) {
   4965             final long origId = Binder.clearCallingIdentity();
   4966             try {
   4967                 ProcessRecord app = getRecordForAppLocked(appInt);
   4968                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
   4969             } finally {
   4970                 Binder.restoreCallingIdentity(origId);
   4971             }
   4972         }
   4973     }
   4974 
   4975     @Override
   4976     public boolean willActivityBeVisible(IBinder token) {
   4977         synchronized(this) {
   4978             ActivityStack stack = ActivityRecord.getStackLocked(token);
   4979             if (stack != null) {
   4980                 return stack.willActivityBeVisibleLocked(token);
   4981             }
   4982             return false;
   4983         }
   4984     }
   4985 
   4986     @Override
   4987     public void overridePendingTransition(IBinder token, String packageName,
   4988             int enterAnim, int exitAnim) {
   4989         synchronized(this) {
   4990             ActivityRecord self = ActivityRecord.isInStackLocked(token);
   4991             if (self == null) {
   4992                 return;
   4993             }
   4994 
   4995             final long origId = Binder.clearCallingIdentity();
   4996 
   4997             if (self.state == ActivityState.RESUMED
   4998                     || self.state == ActivityState.PAUSING) {
   4999                 mWindowManager.overridePendingAppTransition(packageName,
   5000                         enterAnim, exitAnim, null);
   5001             }
   5002 
   5003             Binder.restoreCallingIdentity(origId);
   5004         }
   5005     }
   5006 
   5007     /**
   5008      * Main function for removing an existing process from the activity manager
   5009      * as a result of that process going away.  Clears out all connections
   5010      * to the process.
   5011      */
   5012     private final void handleAppDiedLocked(ProcessRecord app,
   5013             boolean restarting, boolean allowRestart) {
   5014         int pid = app.pid;
   5015         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
   5016         if (!kept && !restarting) {
   5017             removeLruProcessLocked(app);
   5018             if (pid > 0) {
   5019                 ProcessList.remove(pid);
   5020             }
   5021         }
   5022 
   5023         if (mProfileProc == app) {
   5024             clearProfilerLocked();
   5025         }
   5026 
   5027         // Remove this application's activities from active lists.
   5028         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
   5029 
   5030         app.activities.clear();
   5031 
   5032         if (app.instrumentationClass != null) {
   5033             Slog.w(TAG, "Crash of app " + app.processName
   5034                   + " running instrumentation " + app.instrumentationClass);
   5035             Bundle info = new Bundle();
   5036             info.putString("shortMsg", "Process crashed.");
   5037             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
   5038         }
   5039 
   5040         if (!restarting && hasVisibleActivities
   5041                 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
   5042             // If there was nothing to resume, and we are not already restarting this process, but
   5043             // there is a visible activity that is hosted by the process...  then make sure all
   5044             // visible activities are running, taking care of restarting this process.
   5045             mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   5046         }
   5047     }
   5048 
   5049     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
   5050         IBinder threadBinder = thread.asBinder();
   5051         // Find the application record.
   5052         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   5053             ProcessRecord rec = mLruProcesses.get(i);
   5054             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
   5055                 return i;
   5056             }
   5057         }
   5058         return -1;
   5059     }
   5060 
   5061     final ProcessRecord getRecordForAppLocked(
   5062             IApplicationThread thread) {
   5063         if (thread == null) {
   5064             return null;
   5065         }
   5066 
   5067         int appIndex = getLRURecordIndexForAppLocked(thread);
   5068         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
   5069     }
   5070 
   5071     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
   5072         // If there are no longer any background processes running,
   5073         // and the app that died was not running instrumentation,
   5074         // then tell everyone we are now low on memory.
   5075         boolean haveBg = false;
   5076         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   5077             ProcessRecord rec = mLruProcesses.get(i);
   5078             if (rec.thread != null
   5079                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   5080                 haveBg = true;
   5081                 break;
   5082             }
   5083         }
   5084 
   5085         if (!haveBg) {
   5086             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   5087             if (doReport) {
   5088                 long now = SystemClock.uptimeMillis();
   5089                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
   5090                     doReport = false;
   5091                 } else {
   5092                     mLastMemUsageReportTime = now;
   5093                 }
   5094             }
   5095             final ArrayList<ProcessMemInfo> memInfos
   5096                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
   5097             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
   5098             long now = SystemClock.uptimeMillis();
   5099             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   5100                 ProcessRecord rec = mLruProcesses.get(i);
   5101                 if (rec == dyingProc || rec.thread == null) {
   5102                     continue;
   5103                 }
   5104                 if (doReport) {
   5105                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
   5106                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
   5107                 }
   5108                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
   5109                     // The low memory report is overriding any current
   5110                     // state for a GC request.  Make sure to do
   5111                     // heavy/important/visible/foreground processes first.
   5112                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   5113                         rec.lastRequestedGc = 0;
   5114                     } else {
   5115                         rec.lastRequestedGc = rec.lastLowMemory;
   5116                     }
   5117                     rec.reportLowMemory = true;
   5118                     rec.lastLowMemory = now;
   5119                     mProcessesToGc.remove(rec);
   5120                     addProcessToGcListLocked(rec);
   5121                 }
   5122             }
   5123             if (doReport) {
   5124                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
   5125                 mHandler.sendMessage(msg);
   5126             }
   5127             scheduleAppGcsLocked();
   5128         }
   5129     }
   5130 
   5131     final void appDiedLocked(ProcessRecord app) {
   5132        appDiedLocked(app, app.pid, app.thread, false);
   5133     }
   5134 
   5135     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
   5136             boolean fromBinderDied) {
   5137         // First check if this ProcessRecord is actually active for the pid.
   5138         synchronized (mPidsSelfLocked) {
   5139             ProcessRecord curProc = mPidsSelfLocked.get(pid);
   5140             if (curProc != app) {
   5141                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
   5142                 return;
   5143             }
   5144         }
   5145 
   5146         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   5147         synchronized (stats) {
   5148             stats.noteProcessDiedLocked(app.info.uid, pid);
   5149         }
   5150 
   5151         if (!app.killed) {
   5152             if (!fromBinderDied) {
   5153                 Process.killProcessQuiet(pid);
   5154             }
   5155             killProcessGroup(app.uid, pid);
   5156             app.killed = true;
   5157         }
   5158 
   5159         // Clean up already done if the process has been re-started.
   5160         if (app.pid == pid && app.thread != null &&
   5161                 app.thread.asBinder() == thread.asBinder()) {
   5162             boolean doLowMem = app.instrumentationClass == null;
   5163             boolean doOomAdj = doLowMem;
   5164             if (!app.killedByAm) {
   5165                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   5166                         + ") has died");
   5167                 mAllowLowerMemLevel = true;
   5168             } else {
   5169                 // Note that we always want to do oom adj to update our state with the
   5170                 // new number of procs.
   5171                 mAllowLowerMemLevel = false;
   5172                 doLowMem = false;
   5173             }
   5174             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   5175             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
   5176                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
   5177             handleAppDiedLocked(app, false, true);
   5178 
   5179             if (doOomAdj) {
   5180                 updateOomAdjLocked();
   5181             }
   5182             if (doLowMem) {
   5183                 doLowMemReportIfNeededLocked(app);
   5184             }
   5185         } else if (app.pid != pid) {
   5186             // A new process has already been started.
   5187             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   5188                     + ") has died and restarted (pid " + app.pid + ").");
   5189             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   5190         } else if (DEBUG_PROCESSES) {
   5191             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
   5192                     + thread.asBinder());
   5193         }
   5194     }
   5195 
   5196     /**
   5197      * If a stack trace dump file is configured, dump process stack traces.
   5198      * @param clearTraces causes the dump file to be erased prior to the new
   5199      *    traces being written, if true; when false, the new traces will be
   5200      *    appended to any existing file content.
   5201      * @param firstPids of dalvik VM processes to dump stack traces for first
   5202      * @param lastPids of dalvik VM processes to dump stack traces for last
   5203      * @param nativeProcs optional list of native process names to dump stack crawls
   5204      * @return file containing stack traces, or null if no dump file is configured
   5205      */
   5206     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
   5207             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   5208         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   5209         if (tracesPath == null || tracesPath.length() == 0) {
   5210             return null;
   5211         }
   5212 
   5213         File tracesFile = new File(tracesPath);
   5214         try {
   5215             if (clearTraces && tracesFile.exists()) tracesFile.delete();
   5216             tracesFile.createNewFile();
   5217             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   5218         } catch (IOException e) {
   5219             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
   5220             return null;
   5221         }
   5222 
   5223         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
   5224         return tracesFile;
   5225     }
   5226 
   5227     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
   5228             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   5229         // Use a FileObserver to detect when traces finish writing.
   5230         // The order of traces is considered important to maintain for legibility.
   5231         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
   5232             @Override
   5233             public synchronized void onEvent(int event, String path) { notify(); }
   5234         };
   5235 
   5236         try {
   5237             observer.startWatching();
   5238 
   5239             // First collect all of the stacks of the most important pids.
   5240             if (firstPids != null) {
   5241                 try {
   5242                     int num = firstPids.size();
   5243                     for (int i = 0; i < num; i++) {
   5244                         synchronized (observer) {
   5245                             if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
   5246                                     + firstPids.get(i));
   5247                             final long sime = SystemClock.elapsedRealtime();
   5248                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
   5249                             observer.wait(1000);  // Wait for write-close, give up after 1 sec
   5250                             if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
   5251                                     + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
   5252                         }
   5253                     }
   5254                 } catch (InterruptedException e) {
   5255                     Slog.wtf(TAG, e);
   5256                 }
   5257             }
   5258 
   5259             // Next collect the stacks of the native pids
   5260             if (nativeProcs != null) {
   5261                 int[] pids = Process.getPidsForCommands(nativeProcs);
   5262                 if (pids != null) {
   5263                     for (int pid : pids) {
   5264                         if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
   5265                         final long sime = SystemClock.elapsedRealtime();
   5266                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
   5267                         if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
   5268                                 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
   5269                     }
   5270                 }
   5271             }
   5272 
   5273             // Lastly, measure CPU usage.
   5274             if (processCpuTracker != null) {
   5275                 processCpuTracker.init();
   5276                 System.gc();
   5277                 processCpuTracker.update();
   5278                 try {
   5279                     synchronized (processCpuTracker) {
   5280                         processCpuTracker.wait(500); // measure over 1/2 second.
   5281                     }
   5282                 } catch (InterruptedException e) {
   5283                 }
   5284                 processCpuTracker.update();
   5285 
   5286                 // We'll take the stack crawls of just the top apps using CPU.
   5287                 final int N = processCpuTracker.countWorkingStats();
   5288                 int numProcs = 0;
   5289                 for (int i=0; i<N && numProcs<5; i++) {
   5290                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
   5291                     if (lastPids.indexOfKey(stats.pid) >= 0) {
   5292                         numProcs++;
   5293                         try {
   5294                             synchronized (observer) {
   5295                                 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
   5296                                         + stats.pid);
   5297                                 final long stime = SystemClock.elapsedRealtime();
   5298                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
   5299                                 observer.wait(1000);  // Wait for write-close, give up after 1 sec
   5300                                 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
   5301                                         + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
   5302                             }
   5303                         } catch (InterruptedException e) {
   5304                             Slog.wtf(TAG, e);
   5305                         }
   5306                     } else if (DEBUG_ANR) {
   5307                         Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
   5308                                 + stats.pid);
   5309                     }
   5310                 }
   5311             }
   5312         } finally {
   5313             observer.stopWatching();
   5314         }
   5315     }
   5316 
   5317     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
   5318         if (true || IS_USER_BUILD) {
   5319             return;
   5320         }
   5321         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   5322         if (tracesPath == null || tracesPath.length() == 0) {
   5323             return;
   5324         }
   5325 
   5326         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
   5327         StrictMode.allowThreadDiskWrites();
   5328         try {
   5329             final File tracesFile = new File(tracesPath);
   5330             final File tracesDir = tracesFile.getParentFile();
   5331             final File tracesTmp = new File(tracesDir, "__tmp__");
   5332             try {
   5333                 if (tracesFile.exists()) {
   5334                     tracesTmp.delete();
   5335                     tracesFile.renameTo(tracesTmp);
   5336                 }
   5337                 StringBuilder sb = new StringBuilder();
   5338                 Time tobj = new Time();
   5339                 tobj.set(System.currentTimeMillis());
   5340                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
   5341                 sb.append(": ");
   5342                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
   5343                 sb.append(" since ");
   5344                 sb.append(msg);
   5345                 FileOutputStream fos = new FileOutputStream(tracesFile);
   5346                 fos.write(sb.toString().getBytes());
   5347                 if (app == null) {
   5348                     fos.write("\n*** No application process!".getBytes());
   5349                 }
   5350                 fos.close();
   5351                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   5352             } catch (IOException e) {
   5353                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
   5354                 return;
   5355             }
   5356 
   5357             if (app != null) {
   5358                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
   5359                 firstPids.add(app.pid);
   5360                 dumpStackTraces(tracesPath, firstPids, null, null, null);
   5361             }
   5362 
   5363             File lastTracesFile = null;
   5364             File curTracesFile = null;
   5365             for (int i=9; i>=0; i--) {
   5366                 String name = String.format(Locale.US, "slow%02d.txt", i);
   5367                 curTracesFile = new File(tracesDir, name);
   5368                 if (curTracesFile.exists()) {
   5369                     if (lastTracesFile != null) {
   5370                         curTracesFile.renameTo(lastTracesFile);
   5371                     } else {
   5372                         curTracesFile.delete();
   5373                     }
   5374                 }
   5375                 lastTracesFile = curTracesFile;
   5376             }
   5377             tracesFile.renameTo(curTracesFile);
   5378             if (tracesTmp.exists()) {
   5379                 tracesTmp.renameTo(tracesFile);
   5380             }
   5381         } finally {
   5382             StrictMode.setThreadPolicy(oldPolicy);
   5383         }
   5384     }
   5385 
   5386     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
   5387         if (!mLaunchWarningShown) {
   5388             mLaunchWarningShown = true;
   5389             mUiHandler.post(new Runnable() {
   5390                 @Override
   5391                 public void run() {
   5392                     synchronized (ActivityManagerService.this) {
   5393                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
   5394                         d.show();
   5395                         mUiHandler.postDelayed(new Runnable() {
   5396                             @Override
   5397                             public void run() {
   5398                                 synchronized (ActivityManagerService.this) {
   5399                                     d.dismiss();
   5400                                     mLaunchWarningShown = false;
   5401                                 }
   5402                             }
   5403                         }, 4000);
   5404                     }
   5405                 }
   5406             });
   5407         }
   5408     }
   5409 
   5410     @Override
   5411     public boolean clearApplicationUserData(final String packageName,
   5412             final IPackageDataObserver observer, int userId) {
   5413         enforceNotIsolatedCaller("clearApplicationUserData");
   5414         int uid = Binder.getCallingUid();
   5415         int pid = Binder.getCallingPid();
   5416         userId = mUserController.handleIncomingUser(pid, uid, userId, false,
   5417                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
   5418 
   5419 
   5420         long callingId = Binder.clearCallingIdentity();
   5421         try {
   5422             IPackageManager pm = AppGlobals.getPackageManager();
   5423             int pkgUid = -1;
   5424             synchronized(this) {
   5425                 if (getPackageManagerInternalLocked().canPackageBeWiped(
   5426                         userId, packageName)) {
   5427                     throw new SecurityException(
   5428                             "Cannot clear data for a device owner or a profile owner");
   5429                 }
   5430 
   5431                 try {
   5432                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
   5433                 } catch (RemoteException e) {
   5434                 }
   5435                 if (pkgUid == -1) {
   5436                     Slog.w(TAG, "Invalid packageName: " + packageName);
   5437                     if (observer != null) {
   5438                         try {
   5439                             observer.onRemoveCompleted(packageName, false);
   5440                         } catch (RemoteException e) {
   5441                             Slog.i(TAG, "Observer no longer exists.");
   5442                         }
   5443                     }
   5444                     return false;
   5445                 }
   5446                 if (uid == pkgUid || checkComponentPermission(
   5447                         android.Manifest.permission.CLEAR_APP_USER_DATA,
   5448                         pid, uid, -1, true)
   5449                         == PackageManager.PERMISSION_GRANTED) {
   5450                     forceStopPackageLocked(packageName, pkgUid, "clear data");
   5451                 } else {
   5452                     throw new SecurityException("PID " + pid + " does not have permission "
   5453                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
   5454                                     + " of package " + packageName);
   5455                 }
   5456 
   5457                 // Remove all tasks match the cleared application package and user
   5458                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
   5459                     final TaskRecord tr = mRecentTasks.get(i);
   5460                     final String taskPackageName =
   5461                             tr.getBaseIntent().getComponent().getPackageName();
   5462                     if (tr.userId != userId) continue;
   5463                     if (!taskPackageName.equals(packageName)) continue;
   5464                     removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
   5465                 }
   5466             }
   5467 
   5468             final int pkgUidF = pkgUid;
   5469             final int userIdF = userId;
   5470             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
   5471                 @Override
   5472                 public void onRemoveCompleted(String packageName, boolean succeeded)
   5473                         throws RemoteException {
   5474                     synchronized (ActivityManagerService.this) {
   5475                         finishForceStopPackageLocked(packageName, pkgUidF);
   5476                     }
   5477 
   5478                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
   5479                             Uri.fromParts("package", packageName, null));
   5480                     intent.putExtra(Intent.EXTRA_UID, pkgUidF);
   5481                     intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
   5482                     broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
   5483                             null, null, 0, null, null, null, null, false, false, userIdF);
   5484 
   5485                     if (observer != null) {
   5486                         observer.onRemoveCompleted(packageName, succeeded);
   5487                     }
   5488                 }
   5489             };
   5490 
   5491             try {
   5492                 // Clear application user data
   5493                 pm.clearApplicationUserData(packageName, localObserver, userId);
   5494 
   5495                 synchronized(this) {
   5496                     // Remove all permissions granted from/to this package
   5497                     removeUriPermissionsForPackageLocked(packageName, userId, true);
   5498                 }
   5499 
   5500                 // Remove all zen rules created by this package; revoke it's zen access.
   5501                 INotificationManager inm = NotificationManager.getService();
   5502                 inm.removeAutomaticZenRules(packageName);
   5503                 inm.setNotificationPolicyAccessGranted(packageName, false);
   5504 
   5505             } catch (RemoteException e) {
   5506             }
   5507         } finally {
   5508             Binder.restoreCallingIdentity(callingId);
   5509         }
   5510         return true;
   5511     }
   5512 
   5513     @Override
   5514     public void killBackgroundProcesses(final String packageName, int userId) {
   5515         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   5516                 != PackageManager.PERMISSION_GRANTED &&
   5517                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
   5518                         != PackageManager.PERMISSION_GRANTED) {
   5519             String msg = "Permission Denial: killBackgroundProcesses() from pid="
   5520                     + Binder.getCallingPid()
   5521                     + ", uid=" + Binder.getCallingUid()
   5522                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   5523             Slog.w(TAG, msg);
   5524             throw new SecurityException(msg);
   5525         }
   5526 
   5527         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   5528                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
   5529         long callingId = Binder.clearCallingIdentity();
   5530         try {
   5531             IPackageManager pm = AppGlobals.getPackageManager();
   5532             synchronized(this) {
   5533                 int appId = -1;
   5534                 try {
   5535                     appId = UserHandle.getAppId(
   5536                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
   5537                 } catch (RemoteException e) {
   5538                 }
   5539                 if (appId == -1) {
   5540                     Slog.w(TAG, "Invalid packageName: " + packageName);
   5541                     return;
   5542                 }
   5543                 killPackageProcessesLocked(packageName, appId, userId,
   5544                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
   5545             }
   5546         } finally {
   5547             Binder.restoreCallingIdentity(callingId);
   5548         }
   5549     }
   5550 
   5551     @Override
   5552     public void killAllBackgroundProcesses() {
   5553         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   5554                 != PackageManager.PERMISSION_GRANTED) {
   5555             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
   5556                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   5557                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   5558             Slog.w(TAG, msg);
   5559             throw new SecurityException(msg);
   5560         }
   5561 
   5562         final long callingId = Binder.clearCallingIdentity();
   5563         try {
   5564             synchronized (this) {
   5565                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
   5566                 final int NP = mProcessNames.getMap().size();
   5567                 for (int ip = 0; ip < NP; ip++) {
   5568                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   5569                     final int NA = apps.size();
   5570                     for (int ia = 0; ia < NA; ia++) {
   5571                         final ProcessRecord app = apps.valueAt(ia);
   5572                         if (app.persistent) {
   5573                             // We don't kill persistent processes.
   5574                             continue;
   5575                         }
   5576                         if (app.removed) {
   5577                             procs.add(app);
   5578                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   5579                             app.removed = true;
   5580                             procs.add(app);
   5581                         }
   5582                     }
   5583                 }
   5584 
   5585                 final int N = procs.size();
   5586                 for (int i = 0; i < N; i++) {
   5587                     removeProcessLocked(procs.get(i), false, true, "kill all background");
   5588                 }
   5589 
   5590                 mAllowLowerMemLevel = true;
   5591 
   5592                 updateOomAdjLocked();
   5593                 doLowMemReportIfNeededLocked(null);
   5594             }
   5595         } finally {
   5596             Binder.restoreCallingIdentity(callingId);
   5597         }
   5598     }
   5599 
   5600     /**
   5601      * Kills all background processes, except those matching any of the
   5602      * specified properties.
   5603      *
   5604      * @param minTargetSdk the target SDK version at or above which to preserve
   5605      *                     processes, or {@code -1} to ignore the target SDK
   5606      * @param maxProcState the process state at or below which to preserve
   5607      *                     processes, or {@code -1} to ignore the process state
   5608      */
   5609     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
   5610         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   5611                 != PackageManager.PERMISSION_GRANTED) {
   5612             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
   5613                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   5614                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   5615             Slog.w(TAG, msg);
   5616             throw new SecurityException(msg);
   5617         }
   5618 
   5619         final long callingId = Binder.clearCallingIdentity();
   5620         try {
   5621             synchronized (this) {
   5622                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
   5623                 final int NP = mProcessNames.getMap().size();
   5624                 for (int ip = 0; ip < NP; ip++) {
   5625                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   5626                     final int NA = apps.size();
   5627                     for (int ia = 0; ia < NA; ia++) {
   5628                         final ProcessRecord app = apps.valueAt(ia);
   5629                         if (app.removed) {
   5630                             procs.add(app);
   5631                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
   5632                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
   5633                             app.removed = true;
   5634                             procs.add(app);
   5635                         }
   5636                     }
   5637                 }
   5638 
   5639                 final int N = procs.size();
   5640                 for (int i = 0; i < N; i++) {
   5641                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
   5642                 }
   5643             }
   5644         } finally {
   5645             Binder.restoreCallingIdentity(callingId);
   5646         }
   5647     }
   5648 
   5649     @Override
   5650     public void forceStopPackage(final String packageName, int userId) {
   5651         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   5652                 != PackageManager.PERMISSION_GRANTED) {
   5653             String msg = "Permission Denial: forceStopPackage() from pid="
   5654                     + Binder.getCallingPid()
   5655                     + ", uid=" + Binder.getCallingUid()
   5656                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   5657             Slog.w(TAG, msg);
   5658             throw new SecurityException(msg);
   5659         }
   5660         final int callingPid = Binder.getCallingPid();
   5661         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
   5662                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
   5663         long callingId = Binder.clearCallingIdentity();
   5664         try {
   5665             IPackageManager pm = AppGlobals.getPackageManager();
   5666             synchronized(this) {
   5667                 int[] users = userId == UserHandle.USER_ALL
   5668                         ? mUserController.getUsers() : new int[] { userId };
   5669                 for (int user : users) {
   5670                     int pkgUid = -1;
   5671                     try {
   5672                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
   5673                                 user);
   5674                     } catch (RemoteException e) {
   5675                     }
   5676                     if (pkgUid == -1) {
   5677                         Slog.w(TAG, "Invalid packageName: " + packageName);
   5678                         continue;
   5679                     }
   5680                     try {
   5681                         pm.setPackageStoppedState(packageName, true, user);
   5682                     } catch (RemoteException e) {
   5683                     } catch (IllegalArgumentException e) {
   5684                         Slog.w(TAG, "Failed trying to unstop package "
   5685                                 + packageName + ": " + e);
   5686                     }
   5687                     if (mUserController.isUserRunningLocked(user, 0)) {
   5688                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
   5689                         finishForceStopPackageLocked(packageName, pkgUid);
   5690                     }
   5691                 }
   5692             }
   5693         } finally {
   5694             Binder.restoreCallingIdentity(callingId);
   5695         }
   5696     }
   5697 
   5698     @Override
   5699     public void addPackageDependency(String packageName) {
   5700         synchronized (this) {
   5701             int callingPid = Binder.getCallingPid();
   5702             if (callingPid == Process.myPid()) {
   5703                 //  Yeah, um, no.
   5704                 return;
   5705             }
   5706             ProcessRecord proc;
   5707             synchronized (mPidsSelfLocked) {
   5708                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   5709             }
   5710             if (proc != null) {
   5711                 if (proc.pkgDeps == null) {
   5712                     proc.pkgDeps = new ArraySet<String>(1);
   5713                 }
   5714                 proc.pkgDeps.add(packageName);
   5715             }
   5716         }
   5717     }
   5718 
   5719     /*
   5720      * The pkg name and app id have to be specified.
   5721      */
   5722     @Override
   5723     public void killApplication(String pkg, int appId, int userId, String reason) {
   5724         if (pkg == null) {
   5725             return;
   5726         }
   5727         // Make sure the uid is valid.
   5728         if (appId < 0) {
   5729             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
   5730             return;
   5731         }
   5732         int callerUid = Binder.getCallingUid();
   5733         // Only the system server can kill an application
   5734         if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
   5735             // Post an aysnc message to kill the application
   5736             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
   5737             msg.arg1 = appId;
   5738             msg.arg2 = userId;
   5739             Bundle bundle = new Bundle();
   5740             bundle.putString("pkg", pkg);
   5741             bundle.putString("reason", reason);
   5742             msg.obj = bundle;
   5743             mHandler.sendMessage(msg);
   5744         } else {
   5745             throw new SecurityException(callerUid + " cannot kill pkg: " +
   5746                     pkg);
   5747         }
   5748     }
   5749 
   5750     @Override
   5751     public void closeSystemDialogs(String reason) {
   5752         enforceNotIsolatedCaller("closeSystemDialogs");
   5753 
   5754         final int pid = Binder.getCallingPid();
   5755         final int uid = Binder.getCallingUid();
   5756         final long origId = Binder.clearCallingIdentity();
   5757         try {
   5758             synchronized (this) {
   5759                 // Only allow this from foreground processes, so that background
   5760                 // applications can't abuse it to prevent system UI from being shown.
   5761                 if (uid >= Process.FIRST_APPLICATION_UID) {
   5762                     ProcessRecord proc;
   5763                     synchronized (mPidsSelfLocked) {
   5764                         proc = mPidsSelfLocked.get(pid);
   5765                     }
   5766                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   5767                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
   5768                                 + " from background process " + proc);
   5769                         return;
   5770                     }
   5771                 }
   5772                 closeSystemDialogsLocked(reason);
   5773             }
   5774         } finally {
   5775             Binder.restoreCallingIdentity(origId);
   5776         }
   5777     }
   5778 
   5779     void closeSystemDialogsLocked(String reason) {
   5780         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
   5781         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   5782                 | Intent.FLAG_RECEIVER_FOREGROUND);
   5783         if (reason != null) {
   5784             intent.putExtra("reason", reason);
   5785         }
   5786         mWindowManager.closeSystemDialogs(reason);
   5787 
   5788         mStackSupervisor.closeSystemDialogsLocked();
   5789 
   5790         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
   5791                 AppOpsManager.OP_NONE, null, false, false,
   5792                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
   5793     }
   5794 
   5795     @Override
   5796     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
   5797         enforceNotIsolatedCaller("getProcessMemoryInfo");
   5798         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
   5799         for (int i=pids.length-1; i>=0; i--) {
   5800             ProcessRecord proc;
   5801             int oomAdj;
   5802             synchronized (this) {
   5803                 synchronized (mPidsSelfLocked) {
   5804                     proc = mPidsSelfLocked.get(pids[i]);
   5805                     oomAdj = proc != null ? proc.setAdj : 0;
   5806                 }
   5807             }
   5808             infos[i] = new Debug.MemoryInfo();
   5809             Debug.getMemoryInfo(pids[i], infos[i]);
   5810             if (proc != null) {
   5811                 synchronized (this) {
   5812                     if (proc.thread != null && proc.setAdj == oomAdj) {
   5813                         // Record this for posterity if the process has been stable.
   5814                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
   5815                                 infos[i].getTotalUss(), false, proc.pkgList);
   5816                     }
   5817                 }
   5818             }
   5819         }
   5820         return infos;
   5821     }
   5822 
   5823     @Override
   5824     public long[] getProcessPss(int[] pids) {
   5825         enforceNotIsolatedCaller("getProcessPss");
   5826         long[] pss = new long[pids.length];
   5827         for (int i=pids.length-1; i>=0; i--) {
   5828             ProcessRecord proc;
   5829             int oomAdj;
   5830             synchronized (this) {
   5831                 synchronized (mPidsSelfLocked) {
   5832                     proc = mPidsSelfLocked.get(pids[i]);
   5833                     oomAdj = proc != null ? proc.setAdj : 0;
   5834                 }
   5835             }
   5836             long[] tmpUss = new long[1];
   5837             pss[i] = Debug.getPss(pids[i], tmpUss, null);
   5838             if (proc != null) {
   5839                 synchronized (this) {
   5840                     if (proc.thread != null && proc.setAdj == oomAdj) {
   5841                         // Record this for posterity if the process has been stable.
   5842                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
   5843                     }
   5844                 }
   5845             }
   5846         }
   5847         return pss;
   5848     }
   5849 
   5850     @Override
   5851     public void killApplicationProcess(String processName, int uid) {
   5852         if (processName == null) {
   5853             return;
   5854         }
   5855 
   5856         int callerUid = Binder.getCallingUid();
   5857         // Only the system server can kill an application
   5858         if (callerUid == Process.SYSTEM_UID) {
   5859             synchronized (this) {
   5860                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
   5861                 if (app != null && app.thread != null) {
   5862                     try {
   5863                         app.thread.scheduleSuicide();
   5864                     } catch (RemoteException e) {
   5865                         // If the other end already died, then our work here is done.
   5866                     }
   5867                 } else {
   5868                     Slog.w(TAG, "Process/uid not found attempting kill of "
   5869                             + processName + " / " + uid);
   5870                 }
   5871             }
   5872         } else {
   5873             throw new SecurityException(callerUid + " cannot kill app process: " +
   5874                     processName);
   5875         }
   5876     }
   5877 
   5878     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
   5879         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
   5880                 false, true, false, false, UserHandle.getUserId(uid), reason);
   5881     }
   5882 
   5883     private void finishForceStopPackageLocked(final String packageName, int uid) {
   5884         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
   5885                 Uri.fromParts("package", packageName, null));
   5886         if (!mProcessesReady) {
   5887             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   5888                     | Intent.FLAG_RECEIVER_FOREGROUND);
   5889         }
   5890         intent.putExtra(Intent.EXTRA_UID, uid);
   5891         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
   5892         broadcastIntentLocked(null, null, intent,
   5893                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   5894                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
   5895     }
   5896 
   5897 
   5898     private final boolean killPackageProcessesLocked(String packageName, int appId,
   5899             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
   5900             boolean doit, boolean evenPersistent, String reason) {
   5901         ArrayList<ProcessRecord> procs = new ArrayList<>();
   5902 
   5903         // Remove all processes this package may have touched: all with the
   5904         // same UID (except for the system or root user), and all whose name
   5905         // matches the package name.
   5906         final int NP = mProcessNames.getMap().size();
   5907         for (int ip=0; ip<NP; ip++) {
   5908             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   5909             final int NA = apps.size();
   5910             for (int ia=0; ia<NA; ia++) {
   5911                 ProcessRecord app = apps.valueAt(ia);
   5912                 if (app.persistent && !evenPersistent) {
   5913                     // we don't kill persistent processes
   5914                     continue;
   5915                 }
   5916                 if (app.removed) {
   5917                     if (doit) {
   5918                         procs.add(app);
   5919                     }
   5920                     continue;
   5921                 }
   5922 
   5923                 // Skip process if it doesn't meet our oom adj requirement.
   5924                 if (app.setAdj < minOomAdj) {
   5925                     continue;
   5926                 }
   5927 
   5928                 // If no package is specified, we call all processes under the
   5929                 // give user id.
   5930                 if (packageName == null) {
   5931                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
   5932                         continue;
   5933                     }
   5934                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
   5935                         continue;
   5936                     }
   5937                 // Package has been specified, we want to hit all processes
   5938                 // that match it.  We need to qualify this by the processes
   5939                 // that are running under the specified app and user ID.
   5940                 } else {
   5941                     final boolean isDep = app.pkgDeps != null
   5942                             && app.pkgDeps.contains(packageName);
   5943                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
   5944                         continue;
   5945                     }
   5946                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
   5947                         continue;
   5948                     }
   5949                     if (!app.pkgList.containsKey(packageName) && !isDep) {
   5950                         continue;
   5951                     }
   5952                 }
   5953 
   5954                 // Process has passed all conditions, kill it!
   5955                 if (!doit) {
   5956                     return true;
   5957                 }
   5958                 app.removed = true;
   5959                 procs.add(app);
   5960             }
   5961         }
   5962 
   5963         int N = procs.size();
   5964         for (int i=0; i<N; i++) {
   5965             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
   5966         }
   5967         updateOomAdjLocked();
   5968         return N > 0;
   5969     }
   5970 
   5971     private void cleanupDisabledPackageComponentsLocked(
   5972             String packageName, int userId, boolean killProcess, String[] changedClasses) {
   5973 
   5974         Set<String> disabledClasses = null;
   5975         boolean packageDisabled = false;
   5976         IPackageManager pm = AppGlobals.getPackageManager();
   5977 
   5978         if (changedClasses == null) {
   5979             // Nothing changed...
   5980             return;
   5981         }
   5982 
   5983         // Determine enable/disable state of the package and its components.
   5984         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
   5985         for (int i = changedClasses.length - 1; i >= 0; i--) {
   5986             final String changedClass = changedClasses[i];
   5987 
   5988             if (changedClass.equals(packageName)) {
   5989                 try {
   5990                     // Entire package setting changed
   5991                     enabled = pm.getApplicationEnabledSetting(packageName,
   5992                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
   5993                 } catch (Exception e) {
   5994                     // No such package/component; probably racing with uninstall.  In any
   5995                     // event it means we have nothing further to do here.
   5996                     return;
   5997                 }
   5998                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
   5999                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
   6000                 if (packageDisabled) {
   6001                     // Entire package is disabled.
   6002                     // No need to continue to check component states.
   6003                     disabledClasses = null;
   6004                     break;
   6005                 }
   6006             } else {
   6007                 try {
   6008                     enabled = pm.getComponentEnabledSetting(
   6009                             new ComponentName(packageName, changedClass),
   6010                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
   6011                 } catch (Exception e) {
   6012                     // As above, probably racing with uninstall.
   6013                     return;
   6014                 }
   6015                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
   6016                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
   6017                     if (disabledClasses == null) {
   6018                         disabledClasses = new ArraySet<>(changedClasses.length);
   6019                     }
   6020                     disabledClasses.add(changedClass);
   6021                 }
   6022             }
   6023         }
   6024 
   6025         if (!packageDisabled && disabledClasses == null) {
   6026             // Nothing to do here...
   6027             return;
   6028         }
   6029 
   6030         // Clean-up disabled activities.
   6031         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
   6032                 packageName, disabledClasses, true, false, userId) && mBooted) {
   6033             mStackSupervisor.resumeFocusedStackTopActivityLocked();
   6034             mStackSupervisor.scheduleIdleLocked();
   6035         }
   6036 
   6037         // Clean-up disabled tasks
   6038         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
   6039 
   6040         // Clean-up disabled services.
   6041         mServices.bringDownDisabledPackageServicesLocked(
   6042                 packageName, disabledClasses, userId, false, killProcess, true);
   6043 
   6044         // Clean-up disabled providers.
   6045         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
   6046         mProviderMap.collectPackageProvidersLocked(
   6047                 packageName, disabledClasses, true, false, userId, providers);
   6048         for (int i = providers.size() - 1; i >= 0; i--) {
   6049             removeDyingProviderLocked(null, providers.get(i), true);
   6050         }
   6051 
   6052         // Clean-up disabled broadcast receivers.
   6053         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
   6054             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
   6055                     packageName, disabledClasses, userId, true);
   6056         }
   6057 
   6058     }
   6059 
   6060     final boolean clearBroadcastQueueForUserLocked(int userId) {
   6061         boolean didSomething = false;
   6062         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
   6063             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
   6064                     null, null, userId, true);
   6065         }
   6066         return didSomething;
   6067     }
   6068 
   6069     final boolean forceStopPackageLocked(String packageName, int appId,
   6070             boolean callerWillRestart, boolean purgeCache, boolean doit,
   6071             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
   6072         int i;
   6073 
   6074         if (userId == UserHandle.USER_ALL && packageName == null) {
   6075             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
   6076         }
   6077 
   6078         if (appId < 0 && packageName != null) {
   6079             try {
   6080                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
   6081                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
   6082             } catch (RemoteException e) {
   6083             }
   6084         }
   6085 
   6086         if (doit) {
   6087             if (packageName != null) {
   6088                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
   6089                         + " user=" + userId + ": " + reason);
   6090             } else {
   6091                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
   6092             }
   6093 
   6094             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
   6095         }
   6096 
   6097         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
   6098                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
   6099                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
   6100 
   6101         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
   6102                 packageName, null, doit, evenPersistent, userId)) {
   6103             if (!doit) {
   6104                 return true;
   6105             }
   6106             didSomething = true;
   6107         }
   6108 
   6109         if (mServices.bringDownDisabledPackageServicesLocked(
   6110                 packageName, null, userId, evenPersistent, true, doit)) {
   6111             if (!doit) {
   6112                 return true;
   6113             }
   6114             didSomething = true;
   6115         }
   6116 
   6117         if (packageName == null) {
   6118             // Remove all sticky broadcasts from this user.
   6119             mStickyBroadcasts.remove(userId);
   6120         }
   6121 
   6122         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
   6123         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
   6124                 userId, providers)) {
   6125             if (!doit) {
   6126                 return true;
   6127             }
   6128             didSomething = true;
   6129         }
   6130         for (i = providers.size() - 1; i >= 0; i--) {
   6131             removeDyingProviderLocked(null, providers.get(i), true);
   6132         }
   6133 
   6134         // Remove transient permissions granted from/to this package/user
   6135         removeUriPermissionsForPackageLocked(packageName, userId, false);
   6136 
   6137         if (doit) {
   6138             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
   6139                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
   6140                         packageName, null, userId, doit);
   6141             }
   6142         }
   6143 
   6144         if (packageName == null || uninstalling) {
   6145             // Remove pending intents.  For now we only do this when force
   6146             // stopping users, because we have some problems when doing this
   6147             // for packages -- app widgets are not currently cleaned up for
   6148             // such packages, so they can be left with bad pending intents.
   6149             if (mIntentSenderRecords.size() > 0) {
   6150                 Iterator<WeakReference<PendingIntentRecord>> it
   6151                         = mIntentSenderRecords.values().iterator();
   6152                 while (it.hasNext()) {
   6153                     WeakReference<PendingIntentRecord> wpir = it.next();
   6154                     if (wpir == null) {
   6155                         it.remove();
   6156                         continue;
   6157                     }
   6158                     PendingIntentRecord pir = wpir.get();
   6159                     if (pir == null) {
   6160                         it.remove();
   6161                         continue;
   6162                     }
   6163                     if (packageName == null) {
   6164                         // Stopping user, remove all objects for the user.
   6165                         if (pir.key.userId != userId) {
   6166                             // Not the same user, skip it.
   6167                             continue;
   6168                         }
   6169                     } else {
   6170                         if (UserHandle.getAppId(pir.uid) != appId) {
   6171                             // Different app id, skip it.
   6172                             continue;
   6173                         }
   6174                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
   6175                             // Different user, skip it.
   6176                             continue;
   6177                         }
   6178                         if (!pir.key.packageName.equals(packageName)) {
   6179                             // Different package, skip it.
   6180                             continue;
   6181                         }
   6182                     }
   6183                     if (!doit) {
   6184                         return true;
   6185                     }
   6186                     didSomething = true;
   6187                     it.remove();
   6188                     pir.canceled = true;
   6189                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
   6190                         pir.key.activity.pendingResults.remove(pir.ref);
   6191                     }
   6192                 }
   6193             }
   6194         }
   6195 
   6196         if (doit) {
   6197             if (purgeCache && packageName != null) {
   6198                 AttributeCache ac = AttributeCache.instance();
   6199                 if (ac != null) {
   6200                     ac.removePackage(packageName);
   6201                 }
   6202             }
   6203             if (mBooted) {
   6204                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
   6205                 mStackSupervisor.scheduleIdleLocked();
   6206             }
   6207         }
   6208 
   6209         return didSomething;
   6210     }
   6211 
   6212     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
   6213         ProcessRecord old = mProcessNames.remove(name, uid);
   6214         if (old != null) {
   6215             old.uidRecord.numProcs--;
   6216             if (old.uidRecord.numProcs == 0) {
   6217                 // No more processes using this uid, tell clients it is gone.
   6218                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   6219                         "No more processes in " + old.uidRecord);
   6220                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
   6221                 mActiveUids.remove(uid);
   6222                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
   6223             }
   6224             old.uidRecord = null;
   6225         }
   6226         mIsolatedProcesses.remove(uid);
   6227         return old;
   6228     }
   6229 
   6230     private final void addProcessNameLocked(ProcessRecord proc) {
   6231         // We shouldn't already have a process under this name, but just in case we
   6232         // need to clean up whatever may be there now.
   6233         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
   6234         if (old == proc && proc.persistent) {
   6235             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
   6236             Slog.w(TAG, "Re-adding persistent process " + proc);
   6237         } else if (old != null) {
   6238             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
   6239         }
   6240         UidRecord uidRec = mActiveUids.get(proc.uid);
   6241         if (uidRec == null) {
   6242             uidRec = new UidRecord(proc.uid);
   6243             // This is the first appearance of the uid, report it now!
   6244             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   6245                     "Creating new process uid: " + uidRec);
   6246             mActiveUids.put(proc.uid, uidRec);
   6247             noteUidProcessState(uidRec.uid, uidRec.curProcState);
   6248             enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
   6249         }
   6250         proc.uidRecord = uidRec;
   6251         uidRec.numProcs++;
   6252         mProcessNames.put(proc.processName, proc.uid, proc);
   6253         if (proc.isolated) {
   6254             mIsolatedProcesses.put(proc.uid, proc);
   6255         }
   6256     }
   6257 
   6258     boolean removeProcessLocked(ProcessRecord app,
   6259             boolean callerWillRestart, boolean allowRestart, String reason) {
   6260         final String name = app.processName;
   6261         final int uid = app.uid;
   6262         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
   6263             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
   6264 
   6265         ProcessRecord old = mProcessNames.get(name, uid);
   6266         if (old != app) {
   6267             // This process is no longer active, so nothing to do.
   6268             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
   6269             return false;
   6270         }
   6271         removeProcessNameLocked(name, uid);
   6272         if (mHeavyWeightProcess == app) {
   6273             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   6274                     mHeavyWeightProcess.userId, 0));
   6275             mHeavyWeightProcess = null;
   6276         }
   6277         boolean needRestart = false;
   6278         if (app.pid > 0 && app.pid != MY_PID) {
   6279             int pid = app.pid;
   6280             synchronized (mPidsSelfLocked) {
   6281                 mPidsSelfLocked.remove(pid);
   6282                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   6283             }
   6284             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   6285             if (app.isolated) {
   6286                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   6287             }
   6288             boolean willRestart = false;
   6289             if (app.persistent && !app.isolated) {
   6290                 if (!callerWillRestart) {
   6291                     willRestart = true;
   6292                 } else {
   6293                     needRestart = true;
   6294                 }
   6295             }
   6296             app.kill(reason, true);
   6297             handleAppDiedLocked(app, willRestart, allowRestart);
   6298             if (willRestart) {
   6299                 removeLruProcessLocked(app);
   6300                 addAppLocked(app.info, false, null /* ABI override */);
   6301             }
   6302         } else {
   6303             mRemovedProcesses.add(app);
   6304         }
   6305 
   6306         return needRestart;
   6307     }
   6308 
   6309     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
   6310         cleanupAppInLaunchingProvidersLocked(app, true);
   6311         removeProcessLocked(app, false, true, "timeout publishing content providers");
   6312     }
   6313 
   6314     private final void processStartTimedOutLocked(ProcessRecord app) {
   6315         final int pid = app.pid;
   6316         boolean gone = false;
   6317         synchronized (mPidsSelfLocked) {
   6318             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
   6319             if (knownApp != null && knownApp.thread == null) {
   6320                 mPidsSelfLocked.remove(pid);
   6321                 gone = true;
   6322             }
   6323         }
   6324 
   6325         if (gone) {
   6326             Slog.w(TAG, "Process " + app + " failed to attach");
   6327             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
   6328                     pid, app.uid, app.processName);
   6329             removeProcessNameLocked(app.processName, app.uid);
   6330             if (mHeavyWeightProcess == app) {
   6331                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   6332                         mHeavyWeightProcess.userId, 0));
   6333                 mHeavyWeightProcess = null;
   6334             }
   6335             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   6336             if (app.isolated) {
   6337                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   6338             }
   6339             // Take care of any launching providers waiting for this process.
   6340             cleanupAppInLaunchingProvidersLocked(app, true);
   6341             // Take care of any services that are waiting for the process.
   6342             mServices.processStartTimedOutLocked(app);
   6343             app.kill("start timeout", true);
   6344             removeLruProcessLocked(app);
   6345             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
   6346                 Slog.w(TAG, "Unattached app died before backup, skipping");
   6347                 try {
   6348                     IBackupManager bm = IBackupManager.Stub.asInterface(
   6349                             ServiceManager.getService(Context.BACKUP_SERVICE));
   6350                     bm.agentDisconnected(app.info.packageName);
   6351                 } catch (RemoteException e) {
   6352                     // Can't happen; the backup manager is local
   6353                 }
   6354             }
   6355             if (isPendingBroadcastProcessLocked(pid)) {
   6356                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   6357                 skipPendingBroadcastLocked(pid);
   6358             }
   6359         } else {
   6360             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
   6361         }
   6362     }
   6363 
   6364     private final boolean attachApplicationLocked(IApplicationThread thread,
   6365             int pid) {
   6366 
   6367         // Find the application record that is being attached...  either via
   6368         // the pid if we are running in multiple processes, or just pull the
   6369         // next app record if we are emulating process with anonymous threads.
   6370         ProcessRecord app;
   6371         if (pid != MY_PID && pid >= 0) {
   6372             synchronized (mPidsSelfLocked) {
   6373                 app = mPidsSelfLocked.get(pid);
   6374             }
   6375         } else {
   6376             app = null;
   6377         }
   6378 
   6379         if (app == null) {
   6380             Slog.w(TAG, "No pending application record for pid " + pid
   6381                     + " (IApplicationThread " + thread + "); dropping process");
   6382             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
   6383             if (pid > 0 && pid != MY_PID) {
   6384                 Process.killProcessQuiet(pid);
   6385                 //TODO: killProcessGroup(app.info.uid, pid);
   6386             } else {
   6387                 try {
   6388                     thread.scheduleExit();
   6389                 } catch (Exception e) {
   6390                     // Ignore exceptions.
   6391                 }
   6392             }
   6393             return false;
   6394         }
   6395 
   6396         // If this application record is still attached to a previous
   6397         // process, clean it up now.
   6398         if (app.thread != null) {
   6399             handleAppDiedLocked(app, true, true);
   6400         }
   6401 
   6402         // Tell the process all about itself.
   6403 
   6404         if (DEBUG_ALL) Slog.v(
   6405                 TAG, "Binding process pid " + pid + " to record " + app);
   6406 
   6407         final String processName = app.processName;
   6408         try {
   6409             AppDeathRecipient adr = new AppDeathRecipient(
   6410                     app, pid, thread);
   6411             thread.asBinder().linkToDeath(adr, 0);
   6412             app.deathRecipient = adr;
   6413         } catch (RemoteException e) {
   6414             app.resetPackageList(mProcessStats);
   6415             startProcessLocked(app, "link fail", processName);
   6416             return false;
   6417         }
   6418 
   6419         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
   6420 
   6421         app.makeActive(thread, mProcessStats);
   6422         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
   6423         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   6424         app.forcingToForeground = null;
   6425         updateProcessForegroundLocked(app, false, false);
   6426         app.hasShownUi = false;
   6427         app.debugging = false;
   6428         app.cached = false;
   6429         app.killedByAm = false;
   6430 
   6431         // We carefully use the same state that PackageManager uses for
   6432         // filtering, since we use this flag to decide if we need to install
   6433         // providers when user is unlocked later
   6434         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
   6435 
   6436         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   6437 
   6438         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
   6439         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
   6440 
   6441         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
   6442             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
   6443             msg.obj = app;
   6444             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
   6445         }
   6446 
   6447         if (!normalMode) {
   6448             Slog.i(TAG, "Launching preboot mode app: " + app);
   6449         }
   6450 
   6451         if (DEBUG_ALL) Slog.v(
   6452             TAG, "New app record " + app
   6453             + " thread=" + thread.asBinder() + " pid=" + pid);
   6454         try {
   6455             int testMode = IApplicationThread.DEBUG_OFF;
   6456             if (mDebugApp != null && mDebugApp.equals(processName)) {
   6457                 testMode = mWaitForDebugger
   6458                     ? IApplicationThread.DEBUG_WAIT
   6459                     : IApplicationThread.DEBUG_ON;
   6460                 app.debugging = true;
   6461                 if (mDebugTransient) {
   6462                     mDebugApp = mOrigDebugApp;
   6463                     mWaitForDebugger = mOrigWaitForDebugger;
   6464                 }
   6465             }
   6466             String profileFile = app.instrumentationProfileFile;
   6467             ParcelFileDescriptor profileFd = null;
   6468             int samplingInterval = 0;
   6469             boolean profileAutoStop = false;
   6470             if (mProfileApp != null && mProfileApp.equals(processName)) {
   6471                 mProfileProc = app;
   6472                 profileFile = mProfileFile;
   6473                 profileFd = mProfileFd;
   6474                 samplingInterval = mSamplingInterval;
   6475                 profileAutoStop = mAutoStopProfiler;
   6476             }
   6477             boolean enableTrackAllocation = false;
   6478             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
   6479                 enableTrackAllocation = true;
   6480                 mTrackAllocationApp = null;
   6481             }
   6482 
   6483             // If the app is being launched for restore or full backup, set it up specially
   6484             boolean isRestrictedBackupMode = false;
   6485             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
   6486                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
   6487                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
   6488                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
   6489                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
   6490             }
   6491 
   6492             if (app.instrumentationClass != null) {
   6493                 notifyPackageUse(app.instrumentationClass.getPackageName(),
   6494                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
   6495             }
   6496             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
   6497                     + processName + " with config " + mConfiguration);
   6498             ApplicationInfo appInfo = app.instrumentationInfo != null
   6499                     ? app.instrumentationInfo : app.info;
   6500             app.compat = compatibilityInfoForPackageLocked(appInfo);
   6501             if (profileFd != null) {
   6502                 profileFd = profileFd.dup();
   6503             }
   6504             ProfilerInfo profilerInfo = profileFile == null ? null
   6505                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
   6506             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
   6507                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
   6508                     app.instrumentationUiAutomationConnection, testMode,
   6509                     mBinderTransactionTrackingEnabled, enableTrackAllocation,
   6510                     isRestrictedBackupMode || !normalMode, app.persistent,
   6511                     new Configuration(mConfiguration), app.compat,
   6512                     getCommonServicesLocked(app.isolated),
   6513                     mCoreSettingsObserver.getCoreSettingsLocked());
   6514             updateLruProcessLocked(app, false, null);
   6515             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
   6516         } catch (Exception e) {
   6517             // todo: Yikes!  What should we do?  For now we will try to
   6518             // start another process, but that could easily get us in
   6519             // an infinite loop of restarting processes...
   6520             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
   6521 
   6522             app.resetPackageList(mProcessStats);
   6523             app.unlinkDeathRecipient();
   6524             startProcessLocked(app, "bind fail", processName);
   6525             return false;
   6526         }
   6527 
   6528         // Remove this record from the list of starting applications.
   6529         mPersistentStartingProcesses.remove(app);
   6530         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
   6531                 "Attach application locked removing on hold: " + app);
   6532         mProcessesOnHold.remove(app);
   6533 
   6534         boolean badApp = false;
   6535         boolean didSomething = false;
   6536 
   6537         // See if the top visible activity is waiting to run in this process...
   6538         if (normalMode) {
   6539             try {
   6540                 if (mStackSupervisor.attachApplicationLocked(app)) {
   6541                     didSomething = true;
   6542                 }
   6543             } catch (Exception e) {
   6544                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
   6545                 badApp = true;
   6546             }
   6547         }
   6548 
   6549         // Find any services that should be running in this process...
   6550         if (!badApp) {
   6551             try {
   6552                 didSomething |= mServices.attachApplicationLocked(app, processName);
   6553             } catch (Exception e) {
   6554                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
   6555                 badApp = true;
   6556             }
   6557         }
   6558 
   6559         // Check if a next-broadcast receiver is in this process...
   6560         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
   6561             try {
   6562                 didSomething |= sendPendingBroadcastsLocked(app);
   6563             } catch (Exception e) {
   6564                 // If the app died trying to launch the receiver we declare it 'bad'
   6565                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
   6566                 badApp = true;
   6567             }
   6568         }
   6569 
   6570         // Check whether the next backup agent is in this process...
   6571         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
   6572             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
   6573                     "New app is backup target, launching agent for " + app);
   6574             notifyPackageUse(mBackupTarget.appInfo.packageName,
   6575                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
   6576             try {
   6577                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
   6578                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
   6579                         mBackupTarget.backupMode);
   6580             } catch (Exception e) {
   6581                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
   6582                 badApp = true;
   6583             }
   6584         }
   6585 
   6586         if (badApp) {
   6587             app.kill("error during init", true);
   6588             handleAppDiedLocked(app, false, true);
   6589             return false;
   6590         }
   6591 
   6592         if (!didSomething) {
   6593             updateOomAdjLocked();
   6594         }
   6595 
   6596         return true;
   6597     }
   6598 
   6599     @Override
   6600     public final void attachApplication(IApplicationThread thread) {
   6601         synchronized (this) {
   6602             int callingPid = Binder.getCallingPid();
   6603             final long origId = Binder.clearCallingIdentity();
   6604             attachApplicationLocked(thread, callingPid);
   6605             Binder.restoreCallingIdentity(origId);
   6606         }
   6607     }
   6608 
   6609     @Override
   6610     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
   6611         final long origId = Binder.clearCallingIdentity();
   6612         synchronized (this) {
   6613             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6614             if (stack != null) {
   6615                 ActivityRecord r =
   6616                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
   6617                 if (stopProfiling) {
   6618                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
   6619                         try {
   6620                             mProfileFd.close();
   6621                         } catch (IOException e) {
   6622                         }
   6623                         clearProfilerLocked();
   6624                     }
   6625                 }
   6626             }
   6627         }
   6628         Binder.restoreCallingIdentity(origId);
   6629     }
   6630 
   6631     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
   6632         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
   6633                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
   6634     }
   6635 
   6636     void enableScreenAfterBoot() {
   6637         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
   6638                 SystemClock.uptimeMillis());
   6639         mWindowManager.enableScreenAfterBoot();
   6640 
   6641         synchronized (this) {
   6642             updateEventDispatchingLocked();
   6643         }
   6644     }
   6645 
   6646     @Override
   6647     public void showBootMessage(final CharSequence msg, final boolean always) {
   6648         if (Binder.getCallingUid() != Process.myUid()) {
   6649             // These days only the core system can call this, so apps can't get in
   6650             // the way of what we show about running them.
   6651         }
   6652         mWindowManager.showBootMessage(msg, always);
   6653     }
   6654 
   6655     @Override
   6656     public void keyguardWaitingForActivityDrawn() {
   6657         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
   6658         final long token = Binder.clearCallingIdentity();
   6659         try {
   6660             synchronized (this) {
   6661                 if (DEBUG_LOCKSCREEN) logLockScreen("");
   6662                 mWindowManager.keyguardWaitingForActivityDrawn();
   6663                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
   6664                     mLockScreenShown = LOCK_SCREEN_LEAVING;
   6665                     updateSleepIfNeededLocked();
   6666                 }
   6667             }
   6668         } finally {
   6669             Binder.restoreCallingIdentity(token);
   6670         }
   6671     }
   6672 
   6673     @Override
   6674     public void keyguardGoingAway(int flags) {
   6675         enforceNotIsolatedCaller("keyguardGoingAway");
   6676         final long token = Binder.clearCallingIdentity();
   6677         try {
   6678             synchronized (this) {
   6679                 if (DEBUG_LOCKSCREEN) logLockScreen("");
   6680                 mWindowManager.keyguardGoingAway(flags);
   6681                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
   6682                     mLockScreenShown = LOCK_SCREEN_HIDDEN;
   6683                     updateSleepIfNeededLocked();
   6684 
   6685                     // Some stack visibility might change (e.g. docked stack)
   6686                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   6687                     applyVrModeIfNeededLocked(mFocusedActivity, true);
   6688                 }
   6689             }
   6690         } finally {
   6691             Binder.restoreCallingIdentity(token);
   6692         }
   6693     }
   6694 
   6695     final void finishBooting() {
   6696         synchronized (this) {
   6697             if (!mBootAnimationComplete) {
   6698                 mCallFinishBooting = true;
   6699                 return;
   6700             }
   6701             mCallFinishBooting = false;
   6702         }
   6703 
   6704         ArraySet<String> completedIsas = new ArraySet<String>();
   6705         for (String abi : Build.SUPPORTED_ABIS) {
   6706             Process.establishZygoteConnectionForAbi(abi);
   6707             final String instructionSet = VMRuntime.getInstructionSet(abi);
   6708             if (!completedIsas.contains(instructionSet)) {
   6709                 try {
   6710                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
   6711                 } catch (InstallerException e) {
   6712                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
   6713                             e.getMessage() +")");
   6714                 }
   6715                 completedIsas.add(instructionSet);
   6716             }
   6717         }
   6718 
   6719         IntentFilter pkgFilter = new IntentFilter();
   6720         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
   6721         pkgFilter.addDataScheme("package");
   6722         mContext.registerReceiver(new BroadcastReceiver() {
   6723             @Override
   6724             public void onReceive(Context context, Intent intent) {
   6725                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
   6726                 if (pkgs != null) {
   6727                     for (String pkg : pkgs) {
   6728                         synchronized (ActivityManagerService.this) {
   6729                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
   6730                                     0, "query restart")) {
   6731                                 setResultCode(Activity.RESULT_OK);
   6732                                 return;
   6733                             }
   6734                         }
   6735                     }
   6736                 }
   6737             }
   6738         }, pkgFilter);
   6739 
   6740         IntentFilter dumpheapFilter = new IntentFilter();
   6741         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
   6742         mContext.registerReceiver(new BroadcastReceiver() {
   6743             @Override
   6744             public void onReceive(Context context, Intent intent) {
   6745                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
   6746                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
   6747                 } else {
   6748                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
   6749                 }
   6750             }
   6751         }, dumpheapFilter);
   6752 
   6753         // Let system services know.
   6754         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
   6755 
   6756         synchronized (this) {
   6757             // Ensure that any processes we had put on hold are now started
   6758             // up.
   6759             final int NP = mProcessesOnHold.size();
   6760             if (NP > 0) {
   6761                 ArrayList<ProcessRecord> procs =
   6762                     new ArrayList<ProcessRecord>(mProcessesOnHold);
   6763                 for (int ip=0; ip<NP; ip++) {
   6764                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
   6765                             + procs.get(ip));
   6766                     startProcessLocked(procs.get(ip), "on-hold", null);
   6767                 }
   6768             }
   6769 
   6770             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   6771                 // Start looking for apps that are abusing wake locks.
   6772                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   6773                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   6774                 // Tell anyone interested that we are done booting!
   6775                 SystemProperties.set("sys.boot_completed", "1");
   6776 
   6777                 // And trigger dev.bootcomplete if we are not showing encryption progress
   6778                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
   6779                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
   6780                     SystemProperties.set("dev.bootcomplete", "1");
   6781                 }
   6782                 mUserController.sendBootCompletedLocked(
   6783                         new IIntentReceiver.Stub() {
   6784                             @Override
   6785                             public void performReceive(Intent intent, int resultCode,
   6786                                     String data, Bundle extras, boolean ordered,
   6787                                     boolean sticky, int sendingUser) {
   6788                                 synchronized (ActivityManagerService.this) {
   6789                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
   6790                                             true, false);
   6791                                 }
   6792                             }
   6793                         });
   6794                 scheduleStartProfilesLocked();
   6795             }
   6796         }
   6797     }
   6798 
   6799     @Override
   6800     public void bootAnimationComplete() {
   6801         final boolean callFinishBooting;
   6802         synchronized (this) {
   6803             callFinishBooting = mCallFinishBooting;
   6804             mBootAnimationComplete = true;
   6805         }
   6806         if (callFinishBooting) {
   6807             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
   6808             finishBooting();
   6809             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   6810         }
   6811     }
   6812 
   6813     final void ensureBootCompleted() {
   6814         boolean booting;
   6815         boolean enableScreen;
   6816         synchronized (this) {
   6817             booting = mBooting;
   6818             mBooting = false;
   6819             enableScreen = !mBooted;
   6820             mBooted = true;
   6821         }
   6822 
   6823         if (booting) {
   6824             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
   6825             finishBooting();
   6826             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   6827         }
   6828 
   6829         if (enableScreen) {
   6830             enableScreenAfterBoot();
   6831         }
   6832     }
   6833 
   6834     @Override
   6835     public final void activityResumed(IBinder token) {
   6836         final long origId = Binder.clearCallingIdentity();
   6837         synchronized(this) {
   6838             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6839             if (stack != null) {
   6840                 stack.activityResumedLocked(token);
   6841             }
   6842         }
   6843         Binder.restoreCallingIdentity(origId);
   6844     }
   6845 
   6846     @Override
   6847     public final void activityPaused(IBinder token) {
   6848         final long origId = Binder.clearCallingIdentity();
   6849         synchronized(this) {
   6850             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6851             if (stack != null) {
   6852                 stack.activityPausedLocked(token, false);
   6853             }
   6854         }
   6855         Binder.restoreCallingIdentity(origId);
   6856     }
   6857 
   6858     @Override
   6859     public final void activityStopped(IBinder token, Bundle icicle,
   6860             PersistableBundle persistentState, CharSequence description) {
   6861         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
   6862 
   6863         // Refuse possible leaked file descriptors
   6864         if (icicle != null && icicle.hasFileDescriptors()) {
   6865             throw new IllegalArgumentException("File descriptors passed in Bundle");
   6866         }
   6867 
   6868         final long origId = Binder.clearCallingIdentity();
   6869 
   6870         synchronized (this) {
   6871             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   6872             if (r != null) {
   6873                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
   6874             }
   6875         }
   6876 
   6877         trimApplications();
   6878 
   6879         Binder.restoreCallingIdentity(origId);
   6880     }
   6881 
   6882     @Override
   6883     public final void activityDestroyed(IBinder token) {
   6884         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
   6885         synchronized (this) {
   6886             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6887             if (stack != null) {
   6888                 stack.activityDestroyedLocked(token, "activityDestroyed");
   6889             }
   6890         }
   6891     }
   6892 
   6893     @Override
   6894     public final void activityRelaunched(IBinder token) {
   6895         final long origId = Binder.clearCallingIdentity();
   6896         synchronized (this) {
   6897             mStackSupervisor.activityRelaunchedLocked(token);
   6898         }
   6899         Binder.restoreCallingIdentity(origId);
   6900     }
   6901 
   6902     @Override
   6903     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
   6904             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
   6905         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
   6906                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
   6907         synchronized (this) {
   6908             ActivityRecord record = ActivityRecord.isInStackLocked(token);
   6909             if (record == null) {
   6910                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
   6911                         + "found for: " + token);
   6912             }
   6913             record.setSizeConfigurations(horizontalSizeConfiguration,
   6914                     verticalSizeConfigurations, smallestSizeConfigurations);
   6915         }
   6916     }
   6917 
   6918     @Override
   6919     public final void backgroundResourcesReleased(IBinder token) {
   6920         final long origId = Binder.clearCallingIdentity();
   6921         try {
   6922             synchronized (this) {
   6923                 ActivityStack stack = ActivityRecord.getStackLocked(token);
   6924                 if (stack != null) {
   6925                     stack.backgroundResourcesReleased();
   6926                 }
   6927             }
   6928         } finally {
   6929             Binder.restoreCallingIdentity(origId);
   6930         }
   6931     }
   6932 
   6933     @Override
   6934     public final void notifyLaunchTaskBehindComplete(IBinder token) {
   6935         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
   6936     }
   6937 
   6938     @Override
   6939     public final void notifyEnterAnimationComplete(IBinder token) {
   6940         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
   6941     }
   6942 
   6943     @Override
   6944     public String getCallingPackage(IBinder token) {
   6945         synchronized (this) {
   6946             ActivityRecord r = getCallingRecordLocked(token);
   6947             return r != null ? r.info.packageName : null;
   6948         }
   6949     }
   6950 
   6951     @Override
   6952     public ComponentName getCallingActivity(IBinder token) {
   6953         synchronized (this) {
   6954             ActivityRecord r = getCallingRecordLocked(token);
   6955             return r != null ? r.intent.getComponent() : null;
   6956         }
   6957     }
   6958 
   6959     private ActivityRecord getCallingRecordLocked(IBinder token) {
   6960         ActivityRecord r = ActivityRecord.isInStackLocked(token);
   6961         if (r == null) {
   6962             return null;
   6963         }
   6964         return r.resultTo;
   6965     }
   6966 
   6967     @Override
   6968     public ComponentName getActivityClassForToken(IBinder token) {
   6969         synchronized(this) {
   6970             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   6971             if (r == null) {
   6972                 return null;
   6973             }
   6974             return r.intent.getComponent();
   6975         }
   6976     }
   6977 
   6978     @Override
   6979     public String getPackageForToken(IBinder token) {
   6980         synchronized(this) {
   6981             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   6982             if (r == null) {
   6983                 return null;
   6984             }
   6985             return r.packageName;
   6986         }
   6987     }
   6988 
   6989     @Override
   6990     public boolean isRootVoiceInteraction(IBinder token) {
   6991         synchronized(this) {
   6992             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   6993             if (r == null) {
   6994                 return false;
   6995             }
   6996             return r.rootVoiceInteraction;
   6997         }
   6998     }
   6999 
   7000     @Override
   7001     public IIntentSender getIntentSender(int type,
   7002             String packageName, IBinder token, String resultWho,
   7003             int requestCode, Intent[] intents, String[] resolvedTypes,
   7004             int flags, Bundle bOptions, int userId) {
   7005         enforceNotIsolatedCaller("getIntentSender");
   7006         // Refuse possible leaked file descriptors
   7007         if (intents != null) {
   7008             if (intents.length < 1) {
   7009                 throw new IllegalArgumentException("Intents array length must be >= 1");
   7010             }
   7011             for (int i=0; i<intents.length; i++) {
   7012                 Intent intent = intents[i];
   7013                 if (intent != null) {
   7014                     if (intent.hasFileDescriptors()) {
   7015                         throw new IllegalArgumentException("File descriptors passed in Intent");
   7016                     }
   7017                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
   7018                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   7019                         throw new IllegalArgumentException(
   7020                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   7021                     }
   7022                     intents[i] = new Intent(intent);
   7023                 }
   7024             }
   7025             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
   7026                 throw new IllegalArgumentException(
   7027                         "Intent array length does not match resolvedTypes length");
   7028             }
   7029         }
   7030         if (bOptions != null) {
   7031             if (bOptions.hasFileDescriptors()) {
   7032                 throw new IllegalArgumentException("File descriptors passed in options");
   7033             }
   7034         }
   7035 
   7036         synchronized(this) {
   7037             int callingUid = Binder.getCallingUid();
   7038             int origUserId = userId;
   7039             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
   7040                     type == ActivityManager.INTENT_SENDER_BROADCAST,
   7041                     ALLOW_NON_FULL, "getIntentSender", null);
   7042             if (origUserId == UserHandle.USER_CURRENT) {
   7043                 // We don't want to evaluate this until the pending intent is
   7044                 // actually executed.  However, we do want to always do the
   7045                 // security checking for it above.
   7046                 userId = UserHandle.USER_CURRENT;
   7047             }
   7048             try {
   7049                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   7050                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
   7051                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
   7052                     if (!UserHandle.isSameApp(callingUid, uid)) {
   7053                         String msg = "Permission Denial: getIntentSender() from pid="
   7054                             + Binder.getCallingPid()
   7055                             + ", uid=" + Binder.getCallingUid()
   7056                             + ", (need uid=" + uid + ")"
   7057                             + " is not allowed to send as package " + packageName;
   7058                         Slog.w(TAG, msg);
   7059                         throw new SecurityException(msg);
   7060                     }
   7061                 }
   7062 
   7063                 return getIntentSenderLocked(type, packageName, callingUid, userId,
   7064                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
   7065 
   7066             } catch (RemoteException e) {
   7067                 throw new SecurityException(e);
   7068             }
   7069         }
   7070     }
   7071 
   7072     IIntentSender getIntentSenderLocked(int type, String packageName,
   7073             int callingUid, int userId, IBinder token, String resultWho,
   7074             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
   7075             Bundle bOptions) {
   7076         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
   7077         ActivityRecord activity = null;
   7078         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   7079             activity = ActivityRecord.isInStackLocked(token);
   7080             if (activity == null) {
   7081                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
   7082                 return null;
   7083             }
   7084             if (activity.finishing) {
   7085                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
   7086                 return null;
   7087             }
   7088         }
   7089 
   7090         // We're going to be splicing together extras before sending, so we're
   7091         // okay poking into any contained extras.
   7092         if (intents != null) {
   7093             for (int i = 0; i < intents.length; i++) {
   7094                 intents[i].setDefusable(true);
   7095             }
   7096         }
   7097         Bundle.setDefusable(bOptions, true);
   7098 
   7099         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
   7100         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
   7101         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
   7102         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
   7103                 |PendingIntent.FLAG_UPDATE_CURRENT);
   7104 
   7105         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
   7106                 type, packageName, activity, resultWho,
   7107                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
   7108         WeakReference<PendingIntentRecord> ref;
   7109         ref = mIntentSenderRecords.get(key);
   7110         PendingIntentRecord rec = ref != null ? ref.get() : null;
   7111         if (rec != null) {
   7112             if (!cancelCurrent) {
   7113                 if (updateCurrent) {
   7114                     if (rec.key.requestIntent != null) {
   7115                         rec.key.requestIntent.replaceExtras(intents != null ?
   7116                                 intents[intents.length - 1] : null);
   7117                     }
   7118                     if (intents != null) {
   7119                         intents[intents.length-1] = rec.key.requestIntent;
   7120                         rec.key.allIntents = intents;
   7121                         rec.key.allResolvedTypes = resolvedTypes;
   7122                     } else {
   7123                         rec.key.allIntents = null;
   7124                         rec.key.allResolvedTypes = null;
   7125                     }
   7126                 }
   7127                 return rec;
   7128             }
   7129             rec.canceled = true;
   7130             mIntentSenderRecords.remove(key);
   7131         }
   7132         if (noCreate) {
   7133             return rec;
   7134         }
   7135         rec = new PendingIntentRecord(this, key, callingUid);
   7136         mIntentSenderRecords.put(key, rec.ref);
   7137         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   7138             if (activity.pendingResults == null) {
   7139                 activity.pendingResults
   7140                         = new HashSet<WeakReference<PendingIntentRecord>>();
   7141             }
   7142             activity.pendingResults.add(rec.ref);
   7143         }
   7144         return rec;
   7145     }
   7146 
   7147     @Override
   7148     public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
   7149             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
   7150         if (target instanceof PendingIntentRecord) {
   7151             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
   7152                     finishedReceiver, requiredPermission, options);
   7153         } else {
   7154             if (intent == null) {
   7155                 // Weird case: someone has given us their own custom IIntentSender, and now
   7156                 // they have someone else trying to send to it but of course this isn't
   7157                 // really a PendingIntent, so there is no base Intent, and the caller isn't
   7158                 // supplying an Intent... but we never want to dispatch a null Intent to
   7159                 // a receiver, so um...  let's make something up.
   7160                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
   7161                 intent = new Intent(Intent.ACTION_MAIN);
   7162             }
   7163             try {
   7164                 target.send(code, intent, resolvedType, null, requiredPermission, options);
   7165             } catch (RemoteException e) {
   7166             }
   7167             // Platform code can rely on getting a result back when the send is done, but if
   7168             // this intent sender is from outside of the system we can't rely on it doing that.
   7169             // So instead we don't give it the result receiver, and instead just directly
   7170             // report the finish immediately.
   7171             if (finishedReceiver != null) {
   7172                 try {
   7173                     finishedReceiver.performReceive(intent, 0,
   7174                             null, null, false, false, UserHandle.getCallingUserId());
   7175                 } catch (RemoteException e) {
   7176                 }
   7177             }
   7178             return 0;
   7179         }
   7180     }
   7181 
   7182     /**
   7183      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
   7184      *
   7185      * <p>{@code callerUid} must be allowed to request such whitelist by calling
   7186      * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
   7187      */
   7188     void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
   7189         if (DEBUG_WHITELISTS) {
   7190             Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
   7191                     + targetUid + ", " + duration + ")");
   7192         }
   7193         synchronized (mPidsSelfLocked) {
   7194             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
   7195             if (pr == null) {
   7196                 Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
   7197                 return;
   7198             }
   7199             if (!pr.whitelistManager) {
   7200                 if (DEBUG_WHITELISTS) {
   7201                     Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
   7202                             + callerPid + " is not allowed");
   7203                 }
   7204                 return;
   7205             }
   7206         }
   7207 
   7208         final long token = Binder.clearCallingIdentity();
   7209         try {
   7210             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
   7211                     true, "pe from uid:" + callerUid);
   7212         } finally {
   7213             Binder.restoreCallingIdentity(token);
   7214         }
   7215     }
   7216 
   7217     @Override
   7218     public void cancelIntentSender(IIntentSender sender) {
   7219         if (!(sender instanceof PendingIntentRecord)) {
   7220             return;
   7221         }
   7222         synchronized(this) {
   7223             PendingIntentRecord rec = (PendingIntentRecord)sender;
   7224             try {
   7225                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
   7226                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
   7227                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
   7228                     String msg = "Permission Denial: cancelIntentSender() from pid="
   7229                         + Binder.getCallingPid()
   7230                         + ", uid=" + Binder.getCallingUid()
   7231                         + " is not allowed to cancel packges "
   7232                         + rec.key.packageName;
   7233                     Slog.w(TAG, msg);
   7234                     throw new SecurityException(msg);
   7235                 }
   7236             } catch (RemoteException e) {
   7237                 throw new SecurityException(e);
   7238             }
   7239             cancelIntentSenderLocked(rec, true);
   7240         }
   7241     }
   7242 
   7243     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
   7244         rec.canceled = true;
   7245         mIntentSenderRecords.remove(rec.key);
   7246         if (cleanActivity && rec.key.activity != null) {
   7247             rec.key.activity.pendingResults.remove(rec.ref);
   7248         }
   7249     }
   7250 
   7251     @Override
   7252     public String getPackageForIntentSender(IIntentSender pendingResult) {
   7253         if (!(pendingResult instanceof PendingIntentRecord)) {
   7254             return null;
   7255         }
   7256         try {
   7257             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   7258             return res.key.packageName;
   7259         } catch (ClassCastException e) {
   7260         }
   7261         return null;
   7262     }
   7263 
   7264     @Override
   7265     public int getUidForIntentSender(IIntentSender sender) {
   7266         if (sender instanceof PendingIntentRecord) {
   7267             try {
   7268                 PendingIntentRecord res = (PendingIntentRecord)sender;
   7269                 return res.uid;
   7270             } catch (ClassCastException e) {
   7271             }
   7272         }
   7273         return -1;
   7274     }
   7275 
   7276     @Override
   7277     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
   7278         if (!(pendingResult instanceof PendingIntentRecord)) {
   7279             return false;
   7280         }
   7281         try {
   7282             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   7283             if (res.key.allIntents == null) {
   7284                 return false;
   7285             }
   7286             for (int i=0; i<res.key.allIntents.length; i++) {
   7287                 Intent intent = res.key.allIntents[i];
   7288                 if (intent.getPackage() != null && intent.getComponent() != null) {
   7289                     return false;
   7290                 }
   7291             }
   7292             return true;
   7293         } catch (ClassCastException e) {
   7294         }
   7295         return false;
   7296     }
   7297 
   7298     @Override
   7299     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
   7300         if (!(pendingResult instanceof PendingIntentRecord)) {
   7301             return false;
   7302         }
   7303         try {
   7304             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   7305             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
   7306                 return true;
   7307             }
   7308             return false;
   7309         } catch (ClassCastException e) {
   7310         }
   7311         return false;
   7312     }
   7313 
   7314     @Override
   7315     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
   7316         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
   7317                 "getIntentForIntentSender()");
   7318         if (!(pendingResult instanceof PendingIntentRecord)) {
   7319             return null;
   7320         }
   7321         try {
   7322             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   7323             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
   7324         } catch (ClassCastException e) {
   7325         }
   7326         return null;
   7327     }
   7328 
   7329     @Override
   7330     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
   7331         if (!(pendingResult instanceof PendingIntentRecord)) {
   7332             return null;
   7333         }
   7334         try {
   7335             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   7336             synchronized (this) {
   7337                 return getTagForIntentSenderLocked(res, prefix);
   7338             }
   7339         } catch (ClassCastException e) {
   7340         }
   7341         return null;
   7342     }
   7343 
   7344     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
   7345         final Intent intent = res.key.requestIntent;
   7346         if (intent != null) {
   7347             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
   7348                     || res.lastTagPrefix.equals(prefix))) {
   7349                 return res.lastTag;
   7350             }
   7351             res.lastTagPrefix = prefix;
   7352             final StringBuilder sb = new StringBuilder(128);
   7353             if (prefix != null) {
   7354                 sb.append(prefix);
   7355             }
   7356             if (intent.getAction() != null) {
   7357                 sb.append(intent.getAction());
   7358             } else if (intent.getComponent() != null) {
   7359                 intent.getComponent().appendShortString(sb);
   7360             } else {
   7361                 sb.append("?");
   7362             }
   7363             return res.lastTag = sb.toString();
   7364         }
   7365         return null;
   7366     }
   7367 
   7368     @Override
   7369     public void setProcessLimit(int max) {
   7370         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   7371                 "setProcessLimit()");
   7372         synchronized (this) {
   7373             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
   7374             mProcessLimitOverride = max;
   7375         }
   7376         trimApplications();
   7377     }
   7378 
   7379     @Override
   7380     public int getProcessLimit() {
   7381         synchronized (this) {
   7382             return mProcessLimitOverride;
   7383         }
   7384     }
   7385 
   7386     void foregroundTokenDied(ForegroundToken token) {
   7387         synchronized (ActivityManagerService.this) {
   7388             synchronized (mPidsSelfLocked) {
   7389                 ForegroundToken cur
   7390                     = mForegroundProcesses.get(token.pid);
   7391                 if (cur != token) {
   7392                     return;
   7393                 }
   7394                 mForegroundProcesses.remove(token.pid);
   7395                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
   7396                 if (pr == null) {
   7397                     return;
   7398                 }
   7399                 pr.forcingToForeground = null;
   7400                 updateProcessForegroundLocked(pr, false, false);
   7401             }
   7402             updateOomAdjLocked();
   7403         }
   7404     }
   7405 
   7406     @Override
   7407     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
   7408         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   7409                 "setProcessForeground()");
   7410         synchronized(this) {
   7411             boolean changed = false;
   7412 
   7413             synchronized (mPidsSelfLocked) {
   7414                 ProcessRecord pr = mPidsSelfLocked.get(pid);
   7415                 if (pr == null && isForeground) {
   7416                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
   7417                     return;
   7418                 }
   7419                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
   7420                 if (oldToken != null) {
   7421                     oldToken.token.unlinkToDeath(oldToken, 0);
   7422                     mForegroundProcesses.remove(pid);
   7423                     if (pr != null) {
   7424                         pr.forcingToForeground = null;
   7425                     }
   7426                     changed = true;
   7427                 }
   7428                 if (isForeground && token != null) {
   7429                     ForegroundToken newToken = new ForegroundToken() {
   7430                         @Override
   7431                         public void binderDied() {
   7432                             foregroundTokenDied(this);
   7433                         }
   7434                     };
   7435                     newToken.pid = pid;
   7436                     newToken.token = token;
   7437                     try {
   7438                         token.linkToDeath(newToken, 0);
   7439                         mForegroundProcesses.put(pid, newToken);
   7440                         pr.forcingToForeground = token;
   7441                         changed = true;
   7442                     } catch (RemoteException e) {
   7443                         // If the process died while doing this, we will later
   7444                         // do the cleanup with the process death link.
   7445                     }
   7446                 }
   7447             }
   7448 
   7449             if (changed) {
   7450                 updateOomAdjLocked();
   7451             }
   7452         }
   7453     }
   7454 
   7455     @Override
   7456     public boolean isAppForeground(int uid) throws RemoteException {
   7457         synchronized (this) {
   7458             UidRecord uidRec = mActiveUids.get(uid);
   7459             if (uidRec == null || uidRec.idle) {
   7460                 return false;
   7461             }
   7462             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   7463         }
   7464     }
   7465 
   7466     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
   7467     // be guarded by permission checking.
   7468     int getUidState(int uid) {
   7469         synchronized (this) {
   7470             UidRecord uidRec = mActiveUids.get(uid);
   7471             return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
   7472         }
   7473     }
   7474 
   7475     @Override
   7476     public boolean isInMultiWindowMode(IBinder token) {
   7477         final long origId = Binder.clearCallingIdentity();
   7478         try {
   7479             synchronized(this) {
   7480                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   7481                 if (r == null) {
   7482                     return false;
   7483                 }
   7484                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
   7485                 return !r.task.mFullscreen;
   7486             }
   7487         } finally {
   7488             Binder.restoreCallingIdentity(origId);
   7489         }
   7490     }
   7491 
   7492     @Override
   7493     public boolean isInPictureInPictureMode(IBinder token) {
   7494         final long origId = Binder.clearCallingIdentity();
   7495         try {
   7496             synchronized(this) {
   7497                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
   7498                 if (stack == null) {
   7499                     return false;
   7500                 }
   7501                 return stack.mStackId == PINNED_STACK_ID;
   7502             }
   7503         } finally {
   7504             Binder.restoreCallingIdentity(origId);
   7505         }
   7506     }
   7507 
   7508     @Override
   7509     public void enterPictureInPictureMode(IBinder token) {
   7510         final long origId = Binder.clearCallingIdentity();
   7511         try {
   7512             synchronized(this) {
   7513                 if (!mSupportsPictureInPicture) {
   7514                     throw new IllegalStateException("enterPictureInPictureMode: "
   7515                             + "Device doesn't support picture-in-picture mode.");
   7516                 }
   7517 
   7518                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   7519 
   7520                 if (r == null) {
   7521                     throw new IllegalStateException("enterPictureInPictureMode: "
   7522                             + "Can't find activity for token=" + token);
   7523                 }
   7524 
   7525                 if (!r.supportsPictureInPicture()) {
   7526                     throw new IllegalArgumentException("enterPictureInPictureMode: "
   7527                             + "Picture-In-Picture not supported for r=" + r);
   7528                 }
   7529 
   7530                 // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
   7531                 // current bounds.
   7532                 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
   7533                 final Rect bounds = (pinnedStack != null)
   7534                         ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
   7535 
   7536                 mStackSupervisor.moveActivityToPinnedStackLocked(
   7537                         r, "enterPictureInPictureMode", bounds);
   7538             }
   7539         } finally {
   7540             Binder.restoreCallingIdentity(origId);
   7541         }
   7542     }
   7543 
   7544     // =========================================================
   7545     // PROCESS INFO
   7546     // =========================================================
   7547 
   7548     static class ProcessInfoService extends IProcessInfoService.Stub {
   7549         final ActivityManagerService mActivityManagerService;
   7550         ProcessInfoService(ActivityManagerService activityManagerService) {
   7551             mActivityManagerService = activityManagerService;
   7552         }
   7553 
   7554         @Override
   7555         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
   7556             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
   7557                     /*in*/ pids, /*out*/ states, null);
   7558         }
   7559 
   7560         @Override
   7561         public void getProcessStatesAndOomScoresFromPids(
   7562                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
   7563             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
   7564                     /*in*/ pids, /*out*/ states, /*out*/ scores);
   7565         }
   7566     }
   7567 
   7568     /**
   7569      * For each PID in the given input array, write the current process state
   7570      * for that process into the states array, or -1 to indicate that no
   7571      * process with the given PID exists. If scores array is provided, write
   7572      * the oom score for the process into the scores array, with INVALID_ADJ
   7573      * indicating the PID doesn't exist.
   7574      */
   7575     public void getProcessStatesAndOomScoresForPIDs(
   7576             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
   7577         if (scores != null) {
   7578             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
   7579                     "getProcessStatesAndOomScoresForPIDs()");
   7580         }
   7581 
   7582         if (pids == null) {
   7583             throw new NullPointerException("pids");
   7584         } else if (states == null) {
   7585             throw new NullPointerException("states");
   7586         } else if (pids.length != states.length) {
   7587             throw new IllegalArgumentException("pids and states arrays have different lengths!");
   7588         } else if (scores != null && pids.length != scores.length) {
   7589             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
   7590         }
   7591 
   7592         synchronized (mPidsSelfLocked) {
   7593             for (int i = 0; i < pids.length; i++) {
   7594                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
   7595                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
   7596                         pr.curProcState;
   7597                 if (scores != null) {
   7598                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
   7599                 }
   7600             }
   7601         }
   7602     }
   7603 
   7604     // =========================================================
   7605     // PERMISSIONS
   7606     // =========================================================
   7607 
   7608     static class PermissionController extends IPermissionController.Stub {
   7609         ActivityManagerService mActivityManagerService;
   7610         PermissionController(ActivityManagerService activityManagerService) {
   7611             mActivityManagerService = activityManagerService;
   7612         }
   7613 
   7614         @Override
   7615         public boolean checkPermission(String permission, int pid, int uid) {
   7616             return mActivityManagerService.checkPermission(permission, pid,
   7617                     uid) == PackageManager.PERMISSION_GRANTED;
   7618         }
   7619 
   7620         @Override
   7621         public String[] getPackagesForUid(int uid) {
   7622             return mActivityManagerService.mContext.getPackageManager()
   7623                     .getPackagesForUid(uid);
   7624         }
   7625 
   7626         @Override
   7627         public boolean isRuntimePermission(String permission) {
   7628             try {
   7629                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
   7630                         .getPermissionInfo(permission, 0);
   7631                 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
   7632             } catch (NameNotFoundException nnfe) {
   7633                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
   7634             }
   7635             return false;
   7636         }
   7637     }
   7638 
   7639     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
   7640         @Override
   7641         public int checkComponentPermission(String permission, int pid, int uid,
   7642                 int owningUid, boolean exported) {
   7643             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
   7644                     owningUid, exported);
   7645         }
   7646 
   7647         @Override
   7648         public Object getAMSLock() {
   7649             return ActivityManagerService.this;
   7650         }
   7651     }
   7652 
   7653     /**
   7654      * This can be called with or without the global lock held.
   7655      */
   7656     int checkComponentPermission(String permission, int pid, int uid,
   7657             int owningUid, boolean exported) {
   7658         if (pid == MY_PID) {
   7659             return PackageManager.PERMISSION_GRANTED;
   7660         }
   7661         return ActivityManager.checkComponentPermission(permission, uid,
   7662                 owningUid, exported);
   7663     }
   7664 
   7665     /**
   7666      * As the only public entry point for permissions checking, this method
   7667      * can enforce the semantic that requesting a check on a null global
   7668      * permission is automatically denied.  (Internally a null permission
   7669      * string is used when calling {@link #checkComponentPermission} in cases
   7670      * when only uid-based security is needed.)
   7671      *
   7672      * This can be called with or without the global lock held.
   7673      */
   7674     @Override
   7675     public int checkPermission(String permission, int pid, int uid) {
   7676         if (permission == null) {
   7677             return PackageManager.PERMISSION_DENIED;
   7678         }
   7679         return checkComponentPermission(permission, pid, uid, -1, true);
   7680     }
   7681 
   7682     @Override
   7683     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
   7684         if (permission == null) {
   7685             return PackageManager.PERMISSION_DENIED;
   7686         }
   7687 
   7688         // We might be performing an operation on behalf of an indirect binder
   7689         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
   7690         // client identity accordingly before proceeding.
   7691         Identity tlsIdentity = sCallerIdentity.get();
   7692         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
   7693             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
   7694                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
   7695             uid = tlsIdentity.uid;
   7696             pid = tlsIdentity.pid;
   7697         }
   7698 
   7699         return checkComponentPermission(permission, pid, uid, -1, true);
   7700     }
   7701 
   7702     /**
   7703      * Binder IPC calls go through the public entry point.
   7704      * This can be called with or without the global lock held.
   7705      */
   7706     int checkCallingPermission(String permission) {
   7707         return checkPermission(permission,
   7708                 Binder.getCallingPid(),
   7709                 UserHandle.getAppId(Binder.getCallingUid()));
   7710     }
   7711 
   7712     /**
   7713      * This can be called with or without the global lock held.
   7714      */
   7715     void enforceCallingPermission(String permission, String func) {
   7716         if (checkCallingPermission(permission)
   7717                 == PackageManager.PERMISSION_GRANTED) {
   7718             return;
   7719         }
   7720 
   7721         String msg = "Permission Denial: " + func + " from pid="
   7722                 + Binder.getCallingPid()
   7723                 + ", uid=" + Binder.getCallingUid()
   7724                 + " requires " + permission;
   7725         Slog.w(TAG, msg);
   7726         throw new SecurityException(msg);
   7727     }
   7728 
   7729     /**
   7730      * Determine if UID is holding permissions required to access {@link Uri} in
   7731      * the given {@link ProviderInfo}. Final permission checking is always done
   7732      * in {@link ContentProvider}.
   7733      */
   7734     private final boolean checkHoldingPermissionsLocked(
   7735             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
   7736         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   7737                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
   7738         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
   7739             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
   7740                     != PERMISSION_GRANTED) {
   7741                 return false;
   7742             }
   7743         }
   7744         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
   7745     }
   7746 
   7747     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
   7748             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
   7749         if (pi.applicationInfo.uid == uid) {
   7750             return true;
   7751         } else if (!pi.exported) {
   7752             return false;
   7753         }
   7754 
   7755         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
   7756         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
   7757         try {
   7758             // check if target holds top-level <provider> permissions
   7759             if (!readMet && pi.readPermission != null && considerUidPermissions
   7760                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
   7761                 readMet = true;
   7762             }
   7763             if (!writeMet && pi.writePermission != null && considerUidPermissions
   7764                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
   7765                 writeMet = true;
   7766             }
   7767 
   7768             // track if unprotected read/write is allowed; any denied
   7769             // <path-permission> below removes this ability
   7770             boolean allowDefaultRead = pi.readPermission == null;
   7771             boolean allowDefaultWrite = pi.writePermission == null;
   7772 
   7773             // check if target holds any <path-permission> that match uri
   7774             final PathPermission[] pps = pi.pathPermissions;
   7775             if (pps != null) {
   7776                 final String path = grantUri.uri.getPath();
   7777                 int i = pps.length;
   7778                 while (i > 0 && (!readMet || !writeMet)) {
   7779                     i--;
   7780                     PathPermission pp = pps[i];
   7781                     if (pp.match(path)) {
   7782                         if (!readMet) {
   7783                             final String pprperm = pp.getReadPermission();
   7784                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   7785                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
   7786                                     + ": match=" + pp.match(path)
   7787                                     + " check=" + pm.checkUidPermission(pprperm, uid));
   7788                             if (pprperm != null) {
   7789                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
   7790                                         == PERMISSION_GRANTED) {
   7791                                     readMet = true;
   7792                                 } else {
   7793                                     allowDefaultRead = false;
   7794                                 }
   7795                             }
   7796                         }
   7797                         if (!writeMet) {
   7798                             final String ppwperm = pp.getWritePermission();
   7799                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   7800                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
   7801                                     + ": match=" + pp.match(path)
   7802                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
   7803                             if (ppwperm != null) {
   7804                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
   7805                                         == PERMISSION_GRANTED) {
   7806                                     writeMet = true;
   7807                                 } else {
   7808                                     allowDefaultWrite = false;
   7809                                 }
   7810                             }
   7811                         }
   7812                     }
   7813                 }
   7814             }
   7815 
   7816             // grant unprotected <provider> read/write, if not blocked by
   7817             // <path-permission> above
   7818             if (allowDefaultRead) readMet = true;
   7819             if (allowDefaultWrite) writeMet = true;
   7820 
   7821         } catch (RemoteException e) {
   7822             return false;
   7823         }
   7824 
   7825         return readMet && writeMet;
   7826     }
   7827 
   7828     public int getAppStartMode(int uid, String packageName) {
   7829         synchronized (this) {
   7830             return checkAllowBackgroundLocked(uid, packageName, -1, true);
   7831         }
   7832     }
   7833 
   7834     int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
   7835             boolean allowWhenForeground) {
   7836         UidRecord uidRec = mActiveUids.get(uid);
   7837         if (!mLenientBackgroundCheck) {
   7838             if (!allowWhenForeground || uidRec == null
   7839                     || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   7840                 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
   7841                         packageName) != AppOpsManager.MODE_ALLOWED) {
   7842                     return ActivityManager.APP_START_MODE_DELAYED;
   7843                 }
   7844             }
   7845 
   7846         } else if (uidRec == null || uidRec.idle) {
   7847             if (callingPid >= 0) {
   7848                 ProcessRecord proc;
   7849                 synchronized (mPidsSelfLocked) {
   7850                     proc = mPidsSelfLocked.get(callingPid);
   7851                 }
   7852                 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
   7853                     // Whoever is instigating this is in the foreground, so we will allow it
   7854                     // to go through.
   7855                     return ActivityManager.APP_START_MODE_NORMAL;
   7856                 }
   7857             }
   7858             if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
   7859                     != AppOpsManager.MODE_ALLOWED) {
   7860                 return ActivityManager.APP_START_MODE_DELAYED;
   7861             }
   7862         }
   7863         return ActivityManager.APP_START_MODE_NORMAL;
   7864     }
   7865 
   7866     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
   7867         ProviderInfo pi = null;
   7868         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
   7869         if (cpr != null) {
   7870             pi = cpr.info;
   7871         } else {
   7872             try {
   7873                 pi = AppGlobals.getPackageManager().resolveContentProvider(
   7874                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
   7875                         userHandle);
   7876             } catch (RemoteException ex) {
   7877             }
   7878         }
   7879         return pi;
   7880     }
   7881 
   7882     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
   7883         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
   7884         if (targetUris != null) {
   7885             return targetUris.get(grantUri);
   7886         }
   7887         return null;
   7888     }
   7889 
   7890     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
   7891             String targetPkg, int targetUid, GrantUri grantUri) {
   7892         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
   7893         if (targetUris == null) {
   7894             targetUris = Maps.newArrayMap();
   7895             mGrantedUriPermissions.put(targetUid, targetUris);
   7896         }
   7897 
   7898         UriPermission perm = targetUris.get(grantUri);
   7899         if (perm == null) {
   7900             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
   7901             targetUris.put(grantUri, perm);
   7902         }
   7903 
   7904         return perm;
   7905     }
   7906 
   7907     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
   7908             final int modeFlags) {
   7909         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
   7910         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
   7911                 : UriPermission.STRENGTH_OWNED;
   7912 
   7913         // Root gets to do everything.
   7914         if (uid == 0) {
   7915             return true;
   7916         }
   7917 
   7918         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   7919         if (perms == null) return false;
   7920 
   7921         // First look for exact match
   7922         final UriPermission exactPerm = perms.get(grantUri);
   7923         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
   7924             return true;
   7925         }
   7926 
   7927         // No exact match, look for prefixes
   7928         final int N = perms.size();
   7929         for (int i = 0; i < N; i++) {
   7930             final UriPermission perm = perms.valueAt(i);
   7931             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
   7932                     && perm.getStrength(modeFlags) >= minStrength) {
   7933                 return true;
   7934             }
   7935         }
   7936 
   7937         return false;
   7938     }
   7939 
   7940     /**
   7941      * @param uri This uri must NOT contain an embedded userId.
   7942      * @param userId The userId in which the uri is to be resolved.
   7943      */
   7944     @Override
   7945     public int checkUriPermission(Uri uri, int pid, int uid,
   7946             final int modeFlags, int userId, IBinder callerToken) {
   7947         enforceNotIsolatedCaller("checkUriPermission");
   7948 
   7949         // Another redirected-binder-call permissions check as in
   7950         // {@link checkPermissionWithToken}.
   7951         Identity tlsIdentity = sCallerIdentity.get();
   7952         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
   7953             uid = tlsIdentity.uid;
   7954             pid = tlsIdentity.pid;
   7955         }
   7956 
   7957         // Our own process gets to do everything.
   7958         if (pid == MY_PID) {
   7959             return PackageManager.PERMISSION_GRANTED;
   7960         }
   7961         synchronized (this) {
   7962             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
   7963                     ? PackageManager.PERMISSION_GRANTED
   7964                     : PackageManager.PERMISSION_DENIED;
   7965         }
   7966     }
   7967 
   7968     /**
   7969      * Check if the targetPkg can be granted permission to access uri by
   7970      * the callingUid using the given modeFlags.  Throws a security exception
   7971      * if callingUid is not allowed to do this.  Returns the uid of the target
   7972      * if the URI permission grant should be performed; returns -1 if it is not
   7973      * needed (for example targetPkg already has permission to access the URI).
   7974      * If you already know the uid of the target, you can supply it in
   7975      * lastTargetUid else set that to -1.
   7976      */
   7977     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
   7978             final int modeFlags, int lastTargetUid) {
   7979         if (!Intent.isAccessUriMode(modeFlags)) {
   7980             return -1;
   7981         }
   7982 
   7983         if (targetPkg != null) {
   7984             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   7985                     "Checking grant " + targetPkg + " permission to " + grantUri);
   7986         }
   7987 
   7988         final IPackageManager pm = AppGlobals.getPackageManager();
   7989 
   7990         // If this is not a content: uri, we can't do anything with it.
   7991         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
   7992             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   7993                     "Can't grant URI permission for non-content URI: " + grantUri);
   7994             return -1;
   7995         }
   7996 
   7997         final String authority = grantUri.uri.getAuthority();
   7998         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
   7999                 MATCH_DEBUG_TRIAGED_MISSING);
   8000         if (pi == null) {
   8001             Slog.w(TAG, "No content provider found for permission check: " +
   8002                     grantUri.uri.toSafeString());
   8003             return -1;
   8004         }
   8005 
   8006         int targetUid = lastTargetUid;
   8007         if (targetUid < 0 && targetPkg != null) {
   8008             try {
   8009                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
   8010                         UserHandle.getUserId(callingUid));
   8011                 if (targetUid < 0) {
   8012                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8013                             "Can't grant URI permission no uid for: " + targetPkg);
   8014                     return -1;
   8015                 }
   8016             } catch (RemoteException ex) {
   8017                 return -1;
   8018             }
   8019         }
   8020 
   8021         if (targetUid >= 0) {
   8022             // First...  does the target actually need this permission?
   8023             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
   8024                 // No need to grant the target this permission.
   8025                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8026                         "Target " + targetPkg + " already has full permission to " + grantUri);
   8027                 return -1;
   8028             }
   8029         } else {
   8030             // First...  there is no target package, so can anyone access it?
   8031             boolean allowed = pi.exported;
   8032             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   8033                 if (pi.readPermission != null) {
   8034                     allowed = false;
   8035                 }
   8036             }
   8037             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   8038                 if (pi.writePermission != null) {
   8039                     allowed = false;
   8040                 }
   8041             }
   8042             if (allowed) {
   8043                 return -1;
   8044             }
   8045         }
   8046 
   8047         /* There is a special cross user grant if:
   8048          * - The target is on another user.
   8049          * - Apps on the current user can access the uri without any uid permissions.
   8050          * In this case, we grant a uri permission, even if the ContentProvider does not normally
   8051          * grant uri permissions.
   8052          */
   8053         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
   8054                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
   8055                 modeFlags, false /*without considering the uid permissions*/);
   8056 
   8057         // Second...  is the provider allowing granting of URI permissions?
   8058         if (!specialCrossUserGrant) {
   8059             if (!pi.grantUriPermissions) {
   8060                 throw new SecurityException("Provider " + pi.packageName
   8061                         + "/" + pi.name
   8062                         + " does not allow granting of Uri permissions (uri "
   8063                         + grantUri + ")");
   8064             }
   8065             if (pi.uriPermissionPatterns != null) {
   8066                 final int N = pi.uriPermissionPatterns.length;
   8067                 boolean allowed = false;
   8068                 for (int i=0; i<N; i++) {
   8069                     if (pi.uriPermissionPatterns[i] != null
   8070                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
   8071                         allowed = true;
   8072                         break;
   8073                     }
   8074                 }
   8075                 if (!allowed) {
   8076                     throw new SecurityException("Provider " + pi.packageName
   8077                             + "/" + pi.name
   8078                             + " does not allow granting of permission to path of Uri "
   8079                             + grantUri);
   8080                 }
   8081             }
   8082         }
   8083 
   8084         // Third...  does the caller itself have permission to access
   8085         // this uri?
   8086         if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
   8087             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
   8088                 // Require they hold a strong enough Uri permission
   8089                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
   8090                     throw new SecurityException("Uid " + callingUid
   8091                             + " does not have permission to uri " + grantUri);
   8092                 }
   8093             }
   8094         }
   8095         return targetUid;
   8096     }
   8097 
   8098     /**
   8099      * @param uri This uri must NOT contain an embedded userId.
   8100      * @param userId The userId in which the uri is to be resolved.
   8101      */
   8102     @Override
   8103     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
   8104             final int modeFlags, int userId) {
   8105         enforceNotIsolatedCaller("checkGrantUriPermission");
   8106         synchronized(this) {
   8107             return checkGrantUriPermissionLocked(callingUid, targetPkg,
   8108                     new GrantUri(userId, uri, false), modeFlags, -1);
   8109         }
   8110     }
   8111 
   8112     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
   8113             final int modeFlags, UriPermissionOwner owner) {
   8114         if (!Intent.isAccessUriMode(modeFlags)) {
   8115             return;
   8116         }
   8117 
   8118         // So here we are: the caller has the assumed permission
   8119         // to the uri, and the target doesn't.  Let's now give this to
   8120         // the target.
   8121 
   8122         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8123                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
   8124 
   8125         final String authority = grantUri.uri.getAuthority();
   8126         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
   8127                 MATCH_DEBUG_TRIAGED_MISSING);
   8128         if (pi == null) {
   8129             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
   8130             return;
   8131         }
   8132 
   8133         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
   8134             grantUri.prefix = true;
   8135         }
   8136         final UriPermission perm = findOrCreateUriPermissionLocked(
   8137                 pi.packageName, targetPkg, targetUid, grantUri);
   8138         perm.grantModes(modeFlags, owner);
   8139     }
   8140 
   8141     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
   8142             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
   8143         if (targetPkg == null) {
   8144             throw new NullPointerException("targetPkg");
   8145         }
   8146         int targetUid;
   8147         final IPackageManager pm = AppGlobals.getPackageManager();
   8148         try {
   8149             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
   8150         } catch (RemoteException ex) {
   8151             return;
   8152         }
   8153 
   8154         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
   8155                 targetUid);
   8156         if (targetUid < 0) {
   8157             return;
   8158         }
   8159 
   8160         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
   8161                 owner);
   8162     }
   8163 
   8164     static class NeededUriGrants extends ArrayList<GrantUri> {
   8165         final String targetPkg;
   8166         final int targetUid;
   8167         final int flags;
   8168 
   8169         NeededUriGrants(String targetPkg, int targetUid, int flags) {
   8170             this.targetPkg = targetPkg;
   8171             this.targetUid = targetUid;
   8172             this.flags = flags;
   8173         }
   8174     }
   8175 
   8176     /**
   8177      * Like checkGrantUriPermissionLocked, but takes an Intent.
   8178      */
   8179     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
   8180             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
   8181         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8182                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
   8183                 + " clip=" + (intent != null ? intent.getClipData() : null)
   8184                 + " from " + intent + "; flags=0x"
   8185                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
   8186 
   8187         if (targetPkg == null) {
   8188             throw new NullPointerException("targetPkg");
   8189         }
   8190 
   8191         if (intent == null) {
   8192             return null;
   8193         }
   8194         Uri data = intent.getData();
   8195         ClipData clip = intent.getClipData();
   8196         if (data == null && clip == null) {
   8197             return null;
   8198         }
   8199         // Default userId for uris in the intent (if they don't specify it themselves)
   8200         int contentUserHint = intent.getContentUserHint();
   8201         if (contentUserHint == UserHandle.USER_CURRENT) {
   8202             contentUserHint = UserHandle.getUserId(callingUid);
   8203         }
   8204         final IPackageManager pm = AppGlobals.getPackageManager();
   8205         int targetUid;
   8206         if (needed != null) {
   8207             targetUid = needed.targetUid;
   8208         } else {
   8209             try {
   8210                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
   8211                         targetUserId);
   8212             } catch (RemoteException ex) {
   8213                 return null;
   8214             }
   8215             if (targetUid < 0) {
   8216                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8217                         "Can't grant URI permission no uid for: " + targetPkg
   8218                         + " on user " + targetUserId);
   8219                 return null;
   8220             }
   8221         }
   8222         if (data != null) {
   8223             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
   8224             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
   8225                     targetUid);
   8226             if (targetUid > 0) {
   8227                 if (needed == null) {
   8228                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
   8229                 }
   8230                 needed.add(grantUri);
   8231             }
   8232         }
   8233         if (clip != null) {
   8234             for (int i=0; i<clip.getItemCount(); i++) {
   8235                 Uri uri = clip.getItemAt(i).getUri();
   8236                 if (uri != null) {
   8237                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
   8238                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
   8239                             targetUid);
   8240                     if (targetUid > 0) {
   8241                         if (needed == null) {
   8242                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
   8243                         }
   8244                         needed.add(grantUri);
   8245                     }
   8246                 } else {
   8247                     Intent clipIntent = clip.getItemAt(i).getIntent();
   8248                     if (clipIntent != null) {
   8249                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
   8250                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
   8251                         if (newNeeded != null) {
   8252                             needed = newNeeded;
   8253                         }
   8254                     }
   8255                 }
   8256             }
   8257         }
   8258 
   8259         return needed;
   8260     }
   8261 
   8262     /**
   8263      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
   8264      */
   8265     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
   8266             UriPermissionOwner owner) {
   8267         if (needed != null) {
   8268             for (int i=0; i<needed.size(); i++) {
   8269                 GrantUri grantUri = needed.get(i);
   8270                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
   8271                         grantUri, needed.flags, owner);
   8272             }
   8273         }
   8274     }
   8275 
   8276     void grantUriPermissionFromIntentLocked(int callingUid,
   8277             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
   8278         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
   8279                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
   8280         if (needed == null) {
   8281             return;
   8282         }
   8283 
   8284         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
   8285     }
   8286 
   8287     /**
   8288      * @param uri This uri must NOT contain an embedded userId.
   8289      * @param userId The userId in which the uri is to be resolved.
   8290      */
   8291     @Override
   8292     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
   8293             final int modeFlags, int userId) {
   8294         enforceNotIsolatedCaller("grantUriPermission");
   8295         GrantUri grantUri = new GrantUri(userId, uri, false);
   8296         synchronized(this) {
   8297             final ProcessRecord r = getRecordForAppLocked(caller);
   8298             if (r == null) {
   8299                 throw new SecurityException("Unable to find app for caller "
   8300                         + caller
   8301                         + " when granting permission to uri " + grantUri);
   8302             }
   8303             if (targetPkg == null) {
   8304                 throw new IllegalArgumentException("null target");
   8305             }
   8306             if (grantUri == null) {
   8307                 throw new IllegalArgumentException("null uri");
   8308             }
   8309 
   8310             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
   8311                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
   8312                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
   8313                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
   8314 
   8315             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
   8316                     UserHandle.getUserId(r.uid));
   8317         }
   8318     }
   8319 
   8320     void removeUriPermissionIfNeededLocked(UriPermission perm) {
   8321         if (perm.modeFlags == 0) {
   8322             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
   8323                     perm.targetUid);
   8324             if (perms != null) {
   8325                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8326                         "Removing " + perm.targetUid + " permission to " + perm.uri);
   8327 
   8328                 perms.remove(perm.uri);
   8329                 if (perms.isEmpty()) {
   8330                     mGrantedUriPermissions.remove(perm.targetUid);
   8331                 }
   8332             }
   8333         }
   8334     }
   8335 
   8336     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
   8337         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8338                 "Revoking all granted permissions to " + grantUri);
   8339 
   8340         final IPackageManager pm = AppGlobals.getPackageManager();
   8341         final String authority = grantUri.uri.getAuthority();
   8342         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
   8343                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
   8344         if (pi == null) {
   8345             Slog.w(TAG, "No content provider found for permission revoke: "
   8346                     + grantUri.toSafeString());
   8347             return;
   8348         }
   8349 
   8350         // Does the caller have this permission on the URI?
   8351         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
   8352             // If they don't have direct access to the URI, then revoke any
   8353             // ownerless URI permissions that have been granted to them.
   8354             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   8355             if (perms != null) {
   8356                 boolean persistChanged = false;
   8357                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
   8358                     final UriPermission perm = it.next();
   8359                     if (perm.uri.sourceUserId == grantUri.sourceUserId
   8360                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
   8361                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8362                                 "Revoking non-owned " + perm.targetUid
   8363                                 + " permission to " + perm.uri);
   8364                         persistChanged |= perm.revokeModes(
   8365                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
   8366                         if (perm.modeFlags == 0) {
   8367                             it.remove();
   8368                         }
   8369                     }
   8370                 }
   8371                 if (perms.isEmpty()) {
   8372                     mGrantedUriPermissions.remove(callingUid);
   8373                 }
   8374                 if (persistChanged) {
   8375                     schedulePersistUriGrants();
   8376                 }
   8377             }
   8378             return;
   8379         }
   8380 
   8381         boolean persistChanged = false;
   8382 
   8383         // Go through all of the permissions and remove any that match.
   8384         int N = mGrantedUriPermissions.size();
   8385         for (int i = 0; i < N; i++) {
   8386             final int targetUid = mGrantedUriPermissions.keyAt(i);
   8387             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   8388 
   8389             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
   8390                 final UriPermission perm = it.next();
   8391                 if (perm.uri.sourceUserId == grantUri.sourceUserId
   8392                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
   8393                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8394                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
   8395                     persistChanged |= perm.revokeModes(
   8396                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
   8397                     if (perm.modeFlags == 0) {
   8398                         it.remove();
   8399                     }
   8400                 }
   8401             }
   8402 
   8403             if (perms.isEmpty()) {
   8404                 mGrantedUriPermissions.remove(targetUid);
   8405                 N--;
   8406                 i--;
   8407             }
   8408         }
   8409 
   8410         if (persistChanged) {
   8411             schedulePersistUriGrants();
   8412         }
   8413     }
   8414 
   8415     /**
   8416      * @param uri This uri must NOT contain an embedded userId.
   8417      * @param userId The userId in which the uri is to be resolved.
   8418      */
   8419     @Override
   8420     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
   8421             int userId) {
   8422         enforceNotIsolatedCaller("revokeUriPermission");
   8423         synchronized(this) {
   8424             final ProcessRecord r = getRecordForAppLocked(caller);
   8425             if (r == null) {
   8426                 throw new SecurityException("Unable to find app for caller "
   8427                         + caller
   8428                         + " when revoking permission to uri " + uri);
   8429             }
   8430             if (uri == null) {
   8431                 Slog.w(TAG, "revokeUriPermission: null uri");
   8432                 return;
   8433             }
   8434 
   8435             if (!Intent.isAccessUriMode(modeFlags)) {
   8436                 return;
   8437             }
   8438 
   8439             final String authority = uri.getAuthority();
   8440             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
   8441                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
   8442             if (pi == null) {
   8443                 Slog.w(TAG, "No content provider found for permission revoke: "
   8444                         + uri.toSafeString());
   8445                 return;
   8446             }
   8447 
   8448             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
   8449         }
   8450     }
   8451 
   8452     /**
   8453      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
   8454      * given package.
   8455      *
   8456      * @param packageName Package name to match, or {@code null} to apply to all
   8457      *            packages.
   8458      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
   8459      *            to all users.
   8460      * @param persistable If persistable grants should be removed.
   8461      */
   8462     private void removeUriPermissionsForPackageLocked(
   8463             String packageName, int userHandle, boolean persistable) {
   8464         if (userHandle == UserHandle.USER_ALL && packageName == null) {
   8465             throw new IllegalArgumentException("Must narrow by either package or user");
   8466         }
   8467 
   8468         boolean persistChanged = false;
   8469 
   8470         int N = mGrantedUriPermissions.size();
   8471         for (int i = 0; i < N; i++) {
   8472             final int targetUid = mGrantedUriPermissions.keyAt(i);
   8473             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   8474 
   8475             // Only inspect grants matching user
   8476             if (userHandle == UserHandle.USER_ALL
   8477                     || userHandle == UserHandle.getUserId(targetUid)) {
   8478                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
   8479                     final UriPermission perm = it.next();
   8480 
   8481                     // Only inspect grants matching package
   8482                     if (packageName == null || perm.sourcePkg.equals(packageName)
   8483                             || perm.targetPkg.equals(packageName)) {
   8484                         persistChanged |= perm.revokeModes(persistable
   8485                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
   8486 
   8487                         // Only remove when no modes remain; any persisted grants
   8488                         // will keep this alive.
   8489                         if (perm.modeFlags == 0) {
   8490                             it.remove();
   8491                         }
   8492                     }
   8493                 }
   8494 
   8495                 if (perms.isEmpty()) {
   8496                     mGrantedUriPermissions.remove(targetUid);
   8497                     N--;
   8498                     i--;
   8499                 }
   8500             }
   8501         }
   8502 
   8503         if (persistChanged) {
   8504             schedulePersistUriGrants();
   8505         }
   8506     }
   8507 
   8508     @Override
   8509     public IBinder newUriPermissionOwner(String name) {
   8510         enforceNotIsolatedCaller("newUriPermissionOwner");
   8511         synchronized(this) {
   8512             UriPermissionOwner owner = new UriPermissionOwner(this, name);
   8513             return owner.getExternalTokenLocked();
   8514         }
   8515     }
   8516 
   8517     @Override
   8518     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
   8519         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
   8520         synchronized(this) {
   8521             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
   8522             if (r == null) {
   8523                 throw new IllegalArgumentException("Activity does not exist; token="
   8524                         + activityToken);
   8525             }
   8526             return r.getUriPermissionsLocked().getExternalTokenLocked();
   8527         }
   8528     }
   8529     /**
   8530      * @param uri This uri must NOT contain an embedded userId.
   8531      * @param sourceUserId The userId in which the uri is to be resolved.
   8532      * @param targetUserId The userId of the app that receives the grant.
   8533      */
   8534     @Override
   8535     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
   8536             final int modeFlags, int sourceUserId, int targetUserId) {
   8537         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
   8538                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
   8539                 "grantUriPermissionFromOwner", null);
   8540         synchronized(this) {
   8541             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   8542             if (owner == null) {
   8543                 throw new IllegalArgumentException("Unknown owner: " + token);
   8544             }
   8545             if (fromUid != Binder.getCallingUid()) {
   8546                 if (Binder.getCallingUid() != Process.myUid()) {
   8547                     // Only system code can grant URI permissions on behalf
   8548                     // of other users.
   8549                     throw new SecurityException("nice try");
   8550                 }
   8551             }
   8552             if (targetPkg == null) {
   8553                 throw new IllegalArgumentException("null target");
   8554             }
   8555             if (uri == null) {
   8556                 throw new IllegalArgumentException("null uri");
   8557             }
   8558 
   8559             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
   8560                     modeFlags, owner, targetUserId);
   8561         }
   8562     }
   8563 
   8564     /**
   8565      * @param uri This uri must NOT contain an embedded userId.
   8566      * @param userId The userId in which the uri is to be resolved.
   8567      */
   8568     @Override
   8569     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
   8570         synchronized(this) {
   8571             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   8572             if (owner == null) {
   8573                 throw new IllegalArgumentException("Unknown owner: " + token);
   8574             }
   8575 
   8576             if (uri == null) {
   8577                 owner.removeUriPermissionsLocked(mode);
   8578             } else {
   8579                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
   8580             }
   8581         }
   8582     }
   8583 
   8584     private void schedulePersistUriGrants() {
   8585         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
   8586             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
   8587                     10 * DateUtils.SECOND_IN_MILLIS);
   8588         }
   8589     }
   8590 
   8591     private void writeGrantedUriPermissions() {
   8592         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
   8593 
   8594         // Snapshot permissions so we can persist without lock
   8595         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
   8596         synchronized (this) {
   8597             final int size = mGrantedUriPermissions.size();
   8598             for (int i = 0; i < size; i++) {
   8599                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   8600                 for (UriPermission perm : perms.values()) {
   8601                     if (perm.persistedModeFlags != 0) {
   8602                         persist.add(perm.snapshot());
   8603                     }
   8604                 }
   8605             }
   8606         }
   8607 
   8608         FileOutputStream fos = null;
   8609         try {
   8610             fos = mGrantFile.startWrite();
   8611 
   8612             XmlSerializer out = new FastXmlSerializer();
   8613             out.setOutput(fos, StandardCharsets.UTF_8.name());
   8614             out.startDocument(null, true);
   8615             out.startTag(null, TAG_URI_GRANTS);
   8616             for (UriPermission.Snapshot perm : persist) {
   8617                 out.startTag(null, TAG_URI_GRANT);
   8618                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
   8619                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
   8620                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
   8621                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
   8622                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
   8623                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
   8624                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
   8625                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
   8626                 out.endTag(null, TAG_URI_GRANT);
   8627             }
   8628             out.endTag(null, TAG_URI_GRANTS);
   8629             out.endDocument();
   8630 
   8631             mGrantFile.finishWrite(fos);
   8632         } catch (IOException e) {
   8633             if (fos != null) {
   8634                 mGrantFile.failWrite(fos);
   8635             }
   8636         }
   8637     }
   8638 
   8639     private void readGrantedUriPermissionsLocked() {
   8640         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
   8641 
   8642         final long now = System.currentTimeMillis();
   8643 
   8644         FileInputStream fis = null;
   8645         try {
   8646             fis = mGrantFile.openRead();
   8647             final XmlPullParser in = Xml.newPullParser();
   8648             in.setInput(fis, StandardCharsets.UTF_8.name());
   8649 
   8650             int type;
   8651             while ((type = in.next()) != END_DOCUMENT) {
   8652                 final String tag = in.getName();
   8653                 if (type == START_TAG) {
   8654                     if (TAG_URI_GRANT.equals(tag)) {
   8655                         final int sourceUserId;
   8656                         final int targetUserId;
   8657                         final int userHandle = readIntAttribute(in,
   8658                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
   8659                         if (userHandle != UserHandle.USER_NULL) {
   8660                             // For backwards compatibility.
   8661                             sourceUserId = userHandle;
   8662                             targetUserId = userHandle;
   8663                         } else {
   8664                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
   8665                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
   8666                         }
   8667                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
   8668                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
   8669                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
   8670                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
   8671                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
   8672                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
   8673 
   8674                         // Sanity check that provider still belongs to source package
   8675                         // Both direct boot aware and unaware packages are fine as we
   8676                         // will do filtering at query time to avoid multiple parsing.
   8677                         final ProviderInfo pi = getProviderInfoLocked(
   8678                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
   8679                                         | MATCH_DIRECT_BOOT_UNAWARE);
   8680                         if (pi != null && sourcePkg.equals(pi.packageName)) {
   8681                             int targetUid = -1;
   8682                             try {
   8683                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
   8684                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
   8685                             } catch (RemoteException e) {
   8686                             }
   8687                             if (targetUid != -1) {
   8688                                 final UriPermission perm = findOrCreateUriPermissionLocked(
   8689                                         sourcePkg, targetPkg, targetUid,
   8690                                         new GrantUri(sourceUserId, uri, prefix));
   8691                                 perm.initPersistedModes(modeFlags, createdTime);
   8692                             }
   8693                         } else {
   8694                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
   8695                                     + " but instead found " + pi);
   8696                         }
   8697                     }
   8698                 }
   8699             }
   8700         } catch (FileNotFoundException e) {
   8701             // Missing grants is okay
   8702         } catch (IOException e) {
   8703             Slog.wtf(TAG, "Failed reading Uri grants", e);
   8704         } catch (XmlPullParserException e) {
   8705             Slog.wtf(TAG, "Failed reading Uri grants", e);
   8706         } finally {
   8707             IoUtils.closeQuietly(fis);
   8708         }
   8709     }
   8710 
   8711     /**
   8712      * @param uri This uri must NOT contain an embedded userId.
   8713      * @param userId The userId in which the uri is to be resolved.
   8714      */
   8715     @Override
   8716     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
   8717         enforceNotIsolatedCaller("takePersistableUriPermission");
   8718 
   8719         Preconditions.checkFlagsArgument(modeFlags,
   8720                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   8721 
   8722         synchronized (this) {
   8723             final int callingUid = Binder.getCallingUid();
   8724             boolean persistChanged = false;
   8725             GrantUri grantUri = new GrantUri(userId, uri, false);
   8726 
   8727             UriPermission exactPerm = findUriPermissionLocked(callingUid,
   8728                     new GrantUri(userId, uri, false));
   8729             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
   8730                     new GrantUri(userId, uri, true));
   8731 
   8732             final boolean exactValid = (exactPerm != null)
   8733                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
   8734             final boolean prefixValid = (prefixPerm != null)
   8735                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
   8736 
   8737             if (!(exactValid || prefixValid)) {
   8738                 throw new SecurityException("No persistable permission grants found for UID "
   8739                         + callingUid + " and Uri " + grantUri.toSafeString());
   8740             }
   8741 
   8742             if (exactValid) {
   8743                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
   8744             }
   8745             if (prefixValid) {
   8746                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
   8747             }
   8748 
   8749             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
   8750 
   8751             if (persistChanged) {
   8752                 schedulePersistUriGrants();
   8753             }
   8754         }
   8755     }
   8756 
   8757     /**
   8758      * @param uri This uri must NOT contain an embedded userId.
   8759      * @param userId The userId in which the uri is to be resolved.
   8760      */
   8761     @Override
   8762     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
   8763         enforceNotIsolatedCaller("releasePersistableUriPermission");
   8764 
   8765         Preconditions.checkFlagsArgument(modeFlags,
   8766                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   8767 
   8768         synchronized (this) {
   8769             final int callingUid = Binder.getCallingUid();
   8770             boolean persistChanged = false;
   8771 
   8772             UriPermission exactPerm = findUriPermissionLocked(callingUid,
   8773                     new GrantUri(userId, uri, false));
   8774             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
   8775                     new GrantUri(userId, uri, true));
   8776             if (exactPerm == null && prefixPerm == null) {
   8777                 throw new SecurityException("No permission grants found for UID " + callingUid
   8778                         + " and Uri " + uri.toSafeString());
   8779             }
   8780 
   8781             if (exactPerm != null) {
   8782                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
   8783                 removeUriPermissionIfNeededLocked(exactPerm);
   8784             }
   8785             if (prefixPerm != null) {
   8786                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
   8787                 removeUriPermissionIfNeededLocked(prefixPerm);
   8788             }
   8789 
   8790             if (persistChanged) {
   8791                 schedulePersistUriGrants();
   8792             }
   8793         }
   8794     }
   8795 
   8796     /**
   8797      * Prune any older {@link UriPermission} for the given UID until outstanding
   8798      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
   8799      *
   8800      * @return if any mutations occured that require persisting.
   8801      */
   8802     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
   8803         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   8804         if (perms == null) return false;
   8805         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
   8806 
   8807         final ArrayList<UriPermission> persisted = Lists.newArrayList();
   8808         for (UriPermission perm : perms.values()) {
   8809             if (perm.persistedModeFlags != 0) {
   8810                 persisted.add(perm);
   8811             }
   8812         }
   8813 
   8814         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
   8815         if (trimCount <= 0) return false;
   8816 
   8817         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
   8818         for (int i = 0; i < trimCount; i++) {
   8819             final UriPermission perm = persisted.get(i);
   8820 
   8821             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8822                     "Trimming grant created at " + perm.persistedCreateTime);
   8823 
   8824             perm.releasePersistableModes(~0);
   8825             removeUriPermissionIfNeededLocked(perm);
   8826         }
   8827 
   8828         return true;
   8829     }
   8830 
   8831     @Override
   8832     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
   8833             String packageName, boolean incoming) {
   8834         enforceNotIsolatedCaller("getPersistedUriPermissions");
   8835         Preconditions.checkNotNull(packageName, "packageName");
   8836 
   8837         final int callingUid = Binder.getCallingUid();
   8838         final int callingUserId = UserHandle.getUserId(callingUid);
   8839         final IPackageManager pm = AppGlobals.getPackageManager();
   8840         try {
   8841             final int packageUid = pm.getPackageUid(packageName,
   8842                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
   8843             if (packageUid != callingUid) {
   8844                 throw new SecurityException(
   8845                         "Package " + packageName + " does not belong to calling UID " + callingUid);
   8846             }
   8847         } catch (RemoteException e) {
   8848             throw new SecurityException("Failed to verify package name ownership");
   8849         }
   8850 
   8851         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
   8852         synchronized (this) {
   8853             if (incoming) {
   8854                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
   8855                         callingUid);
   8856                 if (perms == null) {
   8857                     Slog.w(TAG, "No permission grants found for " + packageName);
   8858                 } else {
   8859                     for (UriPermission perm : perms.values()) {
   8860                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
   8861                             result.add(perm.buildPersistedPublicApiObject());
   8862                         }
   8863                     }
   8864                 }
   8865             } else {
   8866                 final int size = mGrantedUriPermissions.size();
   8867                 for (int i = 0; i < size; i++) {
   8868                     final ArrayMap<GrantUri, UriPermission> perms =
   8869                             mGrantedUriPermissions.valueAt(i);
   8870                     for (UriPermission perm : perms.values()) {
   8871                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
   8872                             result.add(perm.buildPersistedPublicApiObject());
   8873                         }
   8874                     }
   8875                 }
   8876             }
   8877         }
   8878         return new ParceledListSlice<android.content.UriPermission>(result);
   8879     }
   8880 
   8881     @Override
   8882     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
   8883             String packageName, int userId) {
   8884         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
   8885                 "getGrantedUriPermissions");
   8886 
   8887         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
   8888         synchronized (this) {
   8889             final int size = mGrantedUriPermissions.size();
   8890             for (int i = 0; i < size; i++) {
   8891                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   8892                 for (UriPermission perm : perms.values()) {
   8893                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
   8894                             && perm.persistedModeFlags != 0) {
   8895                         result.add(perm.buildPersistedPublicApiObject());
   8896                     }
   8897                 }
   8898             }
   8899         }
   8900         return new ParceledListSlice<android.content.UriPermission>(result);
   8901     }
   8902 
   8903     @Override
   8904     public void clearGrantedUriPermissions(String packageName, int userId) {
   8905         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
   8906                 "clearGrantedUriPermissions");
   8907         removeUriPermissionsForPackageLocked(packageName, userId, true);
   8908     }
   8909 
   8910     @Override
   8911     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
   8912         synchronized (this) {
   8913             ProcessRecord app =
   8914                 who != null ? getRecordForAppLocked(who) : null;
   8915             if (app == null) return;
   8916 
   8917             Message msg = Message.obtain();
   8918             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
   8919             msg.obj = app;
   8920             msg.arg1 = waiting ? 1 : 0;
   8921             mUiHandler.sendMessage(msg);
   8922         }
   8923     }
   8924 
   8925     @Override
   8926     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
   8927         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
   8928         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
   8929         outInfo.availMem = Process.getFreeMemory();
   8930         outInfo.totalMem = Process.getTotalMemory();
   8931         outInfo.threshold = homeAppMem;
   8932         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
   8933         outInfo.hiddenAppThreshold = cachedAppMem;
   8934         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
   8935                 ProcessList.SERVICE_ADJ);
   8936         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
   8937                 ProcessList.VISIBLE_APP_ADJ);
   8938         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
   8939                 ProcessList.FOREGROUND_APP_ADJ);
   8940     }
   8941 
   8942     // =========================================================
   8943     // TASK MANAGEMENT
   8944     // =========================================================
   8945 
   8946     @Override
   8947     public List<IAppTask> getAppTasks(String callingPackage) {
   8948         int callingUid = Binder.getCallingUid();
   8949         long ident = Binder.clearCallingIdentity();
   8950 
   8951         synchronized(this) {
   8952             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
   8953             try {
   8954                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
   8955 
   8956                 final int N = mRecentTasks.size();
   8957                 for (int i = 0; i < N; i++) {
   8958                     TaskRecord tr = mRecentTasks.get(i);
   8959                     // Skip tasks that do not match the caller.  We don't need to verify
   8960                     // callingPackage, because we are also limiting to callingUid and know
   8961                     // that will limit to the correct security sandbox.
   8962                     if (tr.effectiveUid != callingUid) {
   8963                         continue;
   8964                     }
   8965                     Intent intent = tr.getBaseIntent();
   8966                     if (intent == null ||
   8967                             !callingPackage.equals(intent.getComponent().getPackageName())) {
   8968                         continue;
   8969                     }
   8970                     ActivityManager.RecentTaskInfo taskInfo =
   8971                             createRecentTaskInfoFromTaskRecord(tr);
   8972                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
   8973                     list.add(taskImpl);
   8974                 }
   8975             } finally {
   8976                 Binder.restoreCallingIdentity(ident);
   8977             }
   8978             return list;
   8979         }
   8980     }
   8981 
   8982     @Override
   8983     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
   8984         final int callingUid = Binder.getCallingUid();
   8985         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
   8986 
   8987         synchronized(this) {
   8988             if (DEBUG_ALL) Slog.v(
   8989                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
   8990 
   8991             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
   8992                     callingUid);
   8993 
   8994             // TODO: Improve with MRU list from all ActivityStacks.
   8995             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
   8996         }
   8997 
   8998         return list;
   8999     }
   9000 
   9001     /**
   9002      * Creates a new RecentTaskInfo from a TaskRecord.
   9003      */
   9004     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
   9005         // Update the task description to reflect any changes in the task stack
   9006         tr.updateTaskDescription();
   9007 
   9008         // Compose the recent task info
   9009         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
   9010         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
   9011         rti.persistentId = tr.taskId;
   9012         rti.baseIntent = new Intent(tr.getBaseIntent());
   9013         rti.origActivity = tr.origActivity;
   9014         rti.realActivity = tr.realActivity;
   9015         rti.description = tr.lastDescription;
   9016         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
   9017         rti.userId = tr.userId;
   9018         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
   9019         rti.firstActiveTime = tr.firstActiveTime;
   9020         rti.lastActiveTime = tr.lastActiveTime;
   9021         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
   9022         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
   9023         rti.numActivities = 0;
   9024         if (tr.mBounds != null) {
   9025             rti.bounds = new Rect(tr.mBounds);
   9026         }
   9027         rti.isDockable = tr.canGoInDockedStack();
   9028         rti.resizeMode = tr.mResizeMode;
   9029 
   9030         ActivityRecord base = null;
   9031         ActivityRecord top = null;
   9032         ActivityRecord tmp;
   9033 
   9034         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
   9035             tmp = tr.mActivities.get(i);
   9036             if (tmp.finishing) {
   9037                 continue;
   9038             }
   9039             base = tmp;
   9040             if (top == null || (top.state == ActivityState.INITIALIZING)) {
   9041                 top = base;
   9042             }
   9043             rti.numActivities++;
   9044         }
   9045 
   9046         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
   9047         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
   9048 
   9049         return rti;
   9050     }
   9051 
   9052     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
   9053         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
   9054                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
   9055         if (!allowed) {
   9056             if (checkPermission(android.Manifest.permission.GET_TASKS,
   9057                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
   9058                 // Temporary compatibility: some existing apps on the system image may
   9059                 // still be requesting the old permission and not switched to the new
   9060                 // one; if so, we'll still allow them full access.  This means we need
   9061                 // to see if they are holding the old permission and are a system app.
   9062                 try {
   9063                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
   9064                         allowed = true;
   9065                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
   9066                                 + " is using old GET_TASKS but privileged; allowing");
   9067                     }
   9068                 } catch (RemoteException e) {
   9069                 }
   9070             }
   9071         }
   9072         if (!allowed) {
   9073             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
   9074                     + " does not hold REAL_GET_TASKS; limiting output");
   9075         }
   9076         return allowed;
   9077     }
   9078 
   9079     @Override
   9080     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
   9081             int userId) {
   9082         final int callingUid = Binder.getCallingUid();
   9083         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
   9084                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
   9085 
   9086         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
   9087         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
   9088         synchronized (this) {
   9089             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
   9090                     callingUid);
   9091             final boolean detailed = checkCallingPermission(
   9092                     android.Manifest.permission.GET_DETAILED_TASKS)
   9093                     == PackageManager.PERMISSION_GRANTED;
   9094 
   9095             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
   9096                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
   9097                 return ParceledListSlice.emptyList();
   9098             }
   9099             mRecentTasks.loadUserRecentsLocked(userId);
   9100 
   9101             final int recentsCount = mRecentTasks.size();
   9102             ArrayList<ActivityManager.RecentTaskInfo> res =
   9103                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
   9104 
   9105             final Set<Integer> includedUsers;
   9106             if (includeProfiles) {
   9107                 includedUsers = mUserController.getProfileIds(userId);
   9108             } else {
   9109                 includedUsers = new HashSet<>();
   9110             }
   9111             includedUsers.add(Integer.valueOf(userId));
   9112 
   9113             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
   9114                 TaskRecord tr = mRecentTasks.get(i);
   9115                 // Only add calling user or related users recent tasks
   9116                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
   9117                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
   9118                     continue;
   9119                 }
   9120 
   9121                 if (tr.realActivitySuspended) {
   9122                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
   9123                     continue;
   9124                 }
   9125 
   9126                 // Return the entry if desired by the caller.  We always return
   9127                 // the first entry, because callers always expect this to be the
   9128                 // foreground app.  We may filter others if the caller has
   9129                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
   9130                 // we should exclude the entry.
   9131 
   9132                 if (i == 0
   9133                         || withExcluded
   9134                         || (tr.intent == null)
   9135                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
   9136                                 == 0)) {
   9137                     if (!allowed) {
   9138                         // If the caller doesn't have the GET_TASKS permission, then only
   9139                         // allow them to see a small subset of tasks -- their own and home.
   9140                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
   9141                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
   9142                             continue;
   9143                         }
   9144                     }
   9145                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
   9146                         if (tr.stack != null && tr.stack.isHomeStack()) {
   9147                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9148                                     "Skipping, home stack task: " + tr);
   9149                             continue;
   9150                         }
   9151                     }
   9152                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
   9153                         final ActivityStack stack = tr.stack;
   9154                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
   9155                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9156                                     "Skipping, top task in docked stack: " + tr);
   9157                             continue;
   9158                         }
   9159                     }
   9160                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
   9161                         if (tr.stack != null && tr.stack.isPinnedStack()) {
   9162                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9163                                     "Skipping, pinned stack task: " + tr);
   9164                             continue;
   9165                         }
   9166                     }
   9167                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
   9168                         // Don't include auto remove tasks that are finished or finishing.
   9169                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9170                                 "Skipping, auto-remove without activity: " + tr);
   9171                         continue;
   9172                     }
   9173                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
   9174                             && !tr.isAvailable) {
   9175                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9176                                 "Skipping, unavail real act: " + tr);
   9177                         continue;
   9178                     }
   9179 
   9180                     if (!tr.mUserSetupComplete) {
   9181                         // Don't include task launched while user is not done setting-up.
   9182                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9183                                 "Skipping, user setup not complete: " + tr);
   9184                         continue;
   9185                     }
   9186 
   9187                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
   9188                     if (!detailed) {
   9189                         rti.baseIntent.replaceExtras((Bundle)null);
   9190                     }
   9191 
   9192                     res.add(rti);
   9193                     maxNum--;
   9194                 }
   9195             }
   9196             return new ParceledListSlice<>(res);
   9197         }
   9198     }
   9199 
   9200     @Override
   9201     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
   9202         synchronized (this) {
   9203             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
   9204                     "getTaskThumbnail()");
   9205             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
   9206                     id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
   9207             if (tr != null) {
   9208                 return tr.getTaskThumbnailLocked();
   9209             }
   9210         }
   9211         return null;
   9212     }
   9213 
   9214     @Override
   9215     public int addAppTask(IBinder activityToken, Intent intent,
   9216             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
   9217         final int callingUid = Binder.getCallingUid();
   9218         final long callingIdent = Binder.clearCallingIdentity();
   9219 
   9220         try {
   9221             synchronized (this) {
   9222                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
   9223                 if (r == null) {
   9224                     throw new IllegalArgumentException("Activity does not exist; token="
   9225                             + activityToken);
   9226                 }
   9227                 ComponentName comp = intent.getComponent();
   9228                 if (comp == null) {
   9229                     throw new IllegalArgumentException("Intent " + intent
   9230                             + " must specify explicit component");
   9231                 }
   9232                 if (thumbnail.getWidth() != mThumbnailWidth
   9233                         || thumbnail.getHeight() != mThumbnailHeight) {
   9234                     throw new IllegalArgumentException("Bad thumbnail size: got "
   9235                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
   9236                             + mThumbnailWidth + "x" + mThumbnailHeight);
   9237                 }
   9238                 if (intent.getSelector() != null) {
   9239                     intent.setSelector(null);
   9240                 }
   9241                 if (intent.getSourceBounds() != null) {
   9242                     intent.setSourceBounds(null);
   9243                 }
   9244                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
   9245                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
   9246                         // The caller has added this as an auto-remove task...  that makes no
   9247                         // sense, so turn off auto-remove.
   9248                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
   9249                     }
   9250                 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
   9251                     // Must be a new task.
   9252                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   9253                 }
   9254                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
   9255                     mLastAddedTaskActivity = null;
   9256                 }
   9257                 ActivityInfo ainfo = mLastAddedTaskActivity;
   9258                 if (ainfo == null) {
   9259                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
   9260                             comp, 0, UserHandle.getUserId(callingUid));
   9261                     if (ainfo.applicationInfo.uid != callingUid) {
   9262                         throw new SecurityException(
   9263                                 "Can't add task for another application: target uid="
   9264                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
   9265                     }
   9266                 }
   9267 
   9268                 // Use the full screen as the context for the task thumbnail
   9269                 final Point displaySize = new Point();
   9270                 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
   9271                 r.task.stack.getDisplaySize(displaySize);
   9272                 thumbnailInfo.taskWidth = displaySize.x;
   9273                 thumbnailInfo.taskHeight = displaySize.y;
   9274                 thumbnailInfo.screenOrientation = mConfiguration.orientation;
   9275 
   9276                 TaskRecord task = new TaskRecord(this,
   9277                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
   9278                         ainfo, intent, description, thumbnailInfo);
   9279 
   9280                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
   9281                 if (trimIdx >= 0) {
   9282                     // If this would have caused a trim, then we'll abort because that
   9283                     // means it would be added at the end of the list but then just removed.
   9284                     return INVALID_TASK_ID;
   9285                 }
   9286 
   9287                 final int N = mRecentTasks.size();
   9288                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
   9289                     final TaskRecord tr = mRecentTasks.remove(N - 1);
   9290                     tr.removedFromRecents();
   9291                 }
   9292 
   9293                 task.inRecents = true;
   9294                 mRecentTasks.add(task);
   9295                 r.task.stack.addTask(task, false, "addAppTask");
   9296 
   9297                 task.setLastThumbnailLocked(thumbnail);
   9298                 task.freeLastThumbnail();
   9299 
   9300                 return task.taskId;
   9301             }
   9302         } finally {
   9303             Binder.restoreCallingIdentity(callingIdent);
   9304         }
   9305     }
   9306 
   9307     @Override
   9308     public Point getAppTaskThumbnailSize() {
   9309         synchronized (this) {
   9310             return new Point(mThumbnailWidth,  mThumbnailHeight);
   9311         }
   9312     }
   9313 
   9314     @Override
   9315     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
   9316         synchronized (this) {
   9317             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   9318             if (r != null) {
   9319                 r.setTaskDescription(td);
   9320                 r.task.updateTaskDescription();
   9321             }
   9322         }
   9323     }
   9324 
   9325     @Override
   9326     public void setTaskResizeable(int taskId, int resizeableMode) {
   9327         synchronized (this) {
   9328             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
   9329                     taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
   9330             if (task == null) {
   9331                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
   9332                 return;
   9333             }
   9334             if (task.mResizeMode != resizeableMode) {
   9335                 task.mResizeMode = resizeableMode;
   9336                 mWindowManager.setTaskResizeable(taskId, resizeableMode);
   9337                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   9338                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
   9339             }
   9340         }
   9341     }
   9342 
   9343     @Override
   9344     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
   9345         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
   9346         long ident = Binder.clearCallingIdentity();
   9347         try {
   9348             synchronized (this) {
   9349                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   9350                 if (task == null) {
   9351                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
   9352                     return;
   9353                 }
   9354                 int stackId = task.stack.mStackId;
   9355                 // We allow the task to scroll instead of resizing if this is a non-resizeable task
   9356                 // in crop windows resize mode or if the task size is affected by the docked stack
   9357                 // changing size. No need to update configuration.
   9358                 if (bounds != null && task.inCropWindowsResizeMode()
   9359                         && mStackSupervisor.isStackDockedInEffect(stackId)) {
   9360                     mWindowManager.scrollTask(task.taskId, bounds);
   9361                     return;
   9362                 }
   9363 
   9364                 // Place the task in the right stack if it isn't there already based on
   9365                 // the requested bounds.
   9366                 // The stack transition logic is:
   9367                 // - a null bounds on a freeform task moves that task to fullscreen
   9368                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
   9369                 //   that task to freeform
   9370                 // - otherwise the task is not moved
   9371                 if (!StackId.isTaskResizeAllowed(stackId)) {
   9372                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
   9373                 }
   9374                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
   9375                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
   9376                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
   9377                     stackId = FREEFORM_WORKSPACE_STACK_ID;
   9378                 }
   9379                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
   9380                 if (stackId != task.stack.mStackId) {
   9381                     mStackSupervisor.moveTaskToStackUncheckedLocked(
   9382                             task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
   9383                     preserveWindow = false;
   9384                 }
   9385 
   9386                 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
   9387                         false /* deferResume */);
   9388             }
   9389         } finally {
   9390             Binder.restoreCallingIdentity(ident);
   9391         }
   9392     }
   9393 
   9394     @Override
   9395     public Rect getTaskBounds(int taskId) {
   9396         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
   9397         long ident = Binder.clearCallingIdentity();
   9398         Rect rect = new Rect();
   9399         try {
   9400             synchronized (this) {
   9401                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
   9402                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
   9403                 if (task == null) {
   9404                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
   9405                     return rect;
   9406                 }
   9407                 if (task.stack != null) {
   9408                     // Return the bounds from window manager since it will be adjusted for various
   9409                     // things like the presense of a docked stack for tasks that aren't resizeable.
   9410                     mWindowManager.getTaskBounds(task.taskId, rect);
   9411                 } else {
   9412                     // Task isn't in window manager yet since it isn't associated with a stack.
   9413                     // Return the persist value from activity manager
   9414                     if (task.mBounds != null) {
   9415                         rect.set(task.mBounds);
   9416                     } else if (task.mLastNonFullscreenBounds != null) {
   9417                         rect.set(task.mLastNonFullscreenBounds);
   9418                     }
   9419                 }
   9420             }
   9421         } finally {
   9422             Binder.restoreCallingIdentity(ident);
   9423         }
   9424         return rect;
   9425     }
   9426 
   9427     @Override
   9428     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
   9429         if (userId != UserHandle.getCallingUserId()) {
   9430             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   9431                     "getTaskDescriptionIcon");
   9432         }
   9433         final File passedIconFile = new File(filePath);
   9434         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
   9435                 passedIconFile.getName());
   9436         if (!legitIconFile.getPath().equals(filePath)
   9437                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
   9438             throw new IllegalArgumentException("Bad file path: " + filePath
   9439                     + " passed for userId " + userId);
   9440         }
   9441         return mRecentTasks.getTaskDescriptionIcon(filePath);
   9442     }
   9443 
   9444     @Override
   9445     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
   9446             throws RemoteException {
   9447         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
   9448                 opts.getCustomInPlaceResId() == 0) {
   9449             throw new IllegalArgumentException("Expected in-place ActivityOption " +
   9450                     "with valid animation");
   9451         }
   9452         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
   9453         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
   9454                 opts.getCustomInPlaceResId());
   9455         mWindowManager.executeAppTransition();
   9456     }
   9457 
   9458     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
   9459             boolean removeFromRecents) {
   9460         if (removeFromRecents) {
   9461             mRecentTasks.remove(tr);
   9462             tr.removedFromRecents();
   9463         }
   9464         ComponentName component = tr.getBaseIntent().getComponent();
   9465         if (component == null) {
   9466             Slog.w(TAG, "No component for base intent of task: " + tr);
   9467             return;
   9468         }
   9469 
   9470         // Find any running services associated with this app and stop if needed.
   9471         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
   9472 
   9473         if (!killProcess) {
   9474             return;
   9475         }
   9476 
   9477         // Determine if the process(es) for this task should be killed.
   9478         final String pkg = component.getPackageName();
   9479         ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
   9480         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
   9481         for (int i = 0; i < pmap.size(); i++) {
   9482 
   9483             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
   9484             for (int j = 0; j < uids.size(); j++) {
   9485                 ProcessRecord proc = uids.valueAt(j);
   9486                 if (proc.userId != tr.userId) {
   9487                     // Don't kill process for a different user.
   9488                     continue;
   9489                 }
   9490                 if (proc == mHomeProcess) {
   9491                     // Don't kill the home process along with tasks from the same package.
   9492                     continue;
   9493                 }
   9494                 if (!proc.pkgList.containsKey(pkg)) {
   9495                     // Don't kill process that is not associated with this task.
   9496                     continue;
   9497                 }
   9498 
   9499                 for (int k = 0; k < proc.activities.size(); k++) {
   9500                     TaskRecord otherTask = proc.activities.get(k).task;
   9501                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
   9502                         // Don't kill process(es) that has an activity in a different task that is
   9503                         // also in recents.
   9504                         return;
   9505                     }
   9506                 }
   9507 
   9508                 if (proc.foregroundServices) {
   9509                     // Don't kill process(es) with foreground service.
   9510                     return;
   9511                 }
   9512 
   9513                 // Add process to kill list.
   9514                 procsToKill.add(proc);
   9515             }
   9516         }
   9517 
   9518         // Kill the running processes.
   9519         for (int i = 0; i < procsToKill.size(); i++) {
   9520             ProcessRecord pr = procsToKill.get(i);
   9521             if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   9522                     && pr.curReceiver == null) {
   9523                 pr.kill("remove task", true);
   9524             } else {
   9525                 // We delay killing processes that are not in the background or running a receiver.
   9526                 pr.waitingToKill = "remove task";
   9527             }
   9528         }
   9529     }
   9530 
   9531     private void removeTasksByPackageNameLocked(String packageName, int userId) {
   9532         // Remove all tasks with activities in the specified package from the list of recent tasks
   9533         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
   9534             TaskRecord tr = mRecentTasks.get(i);
   9535             if (tr.userId != userId) continue;
   9536 
   9537             ComponentName cn = tr.intent.getComponent();
   9538             if (cn != null && cn.getPackageName().equals(packageName)) {
   9539                 // If the package name matches, remove the task.
   9540                 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
   9541             }
   9542         }
   9543     }
   9544 
   9545     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
   9546             int userId) {
   9547 
   9548         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
   9549             TaskRecord tr = mRecentTasks.get(i);
   9550             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
   9551                 continue;
   9552             }
   9553 
   9554             ComponentName cn = tr.intent.getComponent();
   9555             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
   9556                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
   9557             if (sameComponent) {
   9558                 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
   9559             }
   9560         }
   9561     }
   9562 
   9563     /**
   9564      * Removes the task with the specified task id.
   9565      *
   9566      * @param taskId Identifier of the task to be removed.
   9567      * @param killProcess Kill any process associated with the task if possible.
   9568      * @param removeFromRecents Whether to also remove the task from recents.
   9569      * @return Returns true if the given task was found and removed.
   9570      */
   9571     private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
   9572             boolean removeFromRecents) {
   9573         final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
   9574                 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
   9575         if (tr != null) {
   9576             tr.removeTaskActivitiesLocked();
   9577             cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
   9578             if (tr.isPersistable) {
   9579                 notifyTaskPersisterLocked(null, true);
   9580             }
   9581             return true;
   9582         }
   9583         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
   9584         return false;
   9585     }
   9586 
   9587     @Override
   9588     public void removeStack(int stackId) {
   9589         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
   9590         if (stackId == HOME_STACK_ID) {
   9591             throw new IllegalArgumentException("Removing home stack is not allowed.");
   9592         }
   9593 
   9594         synchronized (this) {
   9595             final long ident = Binder.clearCallingIdentity();
   9596             try {
   9597                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
   9598                 if (stack == null) {
   9599                     return;
   9600                 }
   9601                 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
   9602                 for (int i = tasks.size() - 1; i >= 0; i--) {
   9603                     removeTaskByIdLocked(
   9604                             tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
   9605                 }
   9606             } finally {
   9607                 Binder.restoreCallingIdentity(ident);
   9608             }
   9609         }
   9610     }
   9611 
   9612     @Override
   9613     public boolean removeTask(int taskId) {
   9614         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
   9615         synchronized (this) {
   9616             final long ident = Binder.clearCallingIdentity();
   9617             try {
   9618                 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
   9619             } finally {
   9620                 Binder.restoreCallingIdentity(ident);
   9621             }
   9622         }
   9623     }
   9624 
   9625     /**
   9626      * TODO: Add mController hook
   9627      */
   9628     @Override
   9629     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
   9630         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
   9631 
   9632         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
   9633         synchronized(this) {
   9634             moveTaskToFrontLocked(taskId, flags, bOptions);
   9635         }
   9636     }
   9637 
   9638     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
   9639         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
   9640 
   9641         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   9642                 Binder.getCallingUid(), -1, -1, "Task to front")) {
   9643             ActivityOptions.abort(options);
   9644             return;
   9645         }
   9646         final long origId = Binder.clearCallingIdentity();
   9647         try {
   9648             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   9649             if (task == null) {
   9650                 Slog.d(TAG, "Could not find task for id: "+ taskId);
   9651                 return;
   9652             }
   9653             if (mStackSupervisor.isLockTaskModeViolation(task)) {
   9654                 mStackSupervisor.showLockTaskToast();
   9655                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
   9656                 return;
   9657             }
   9658             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
   9659             if (prev != null && prev.isRecentsActivity()) {
   9660                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
   9661             }
   9662             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
   9663                     false /* forceNonResizable */);
   9664         } finally {
   9665             Binder.restoreCallingIdentity(origId);
   9666         }
   9667         ActivityOptions.abort(options);
   9668     }
   9669 
   9670     /**
   9671      * Moves an activity, and all of the other activities within the same task, to the bottom
   9672      * of the history stack.  The activity's order within the task is unchanged.
   9673      *
   9674      * @param token A reference to the activity we wish to move
   9675      * @param nonRoot If false then this only works if the activity is the root
   9676      *                of a task; if true it will work for any activity in a task.
   9677      * @return Returns true if the move completed, false if not.
   9678      */
   9679     @Override
   9680     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
   9681         enforceNotIsolatedCaller("moveActivityTaskToBack");
   9682         synchronized(this) {
   9683             final long origId = Binder.clearCallingIdentity();
   9684             try {
   9685                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
   9686                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   9687                 if (task != null) {
   9688                     if (mStackSupervisor.isLockedTask(task)) {
   9689                         mStackSupervisor.showLockTaskToast();
   9690                         return false;
   9691                     }
   9692                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
   9693                 }
   9694             } finally {
   9695                 Binder.restoreCallingIdentity(origId);
   9696             }
   9697         }
   9698         return false;
   9699     }
   9700 
   9701     @Override
   9702     public void moveTaskBackwards(int task) {
   9703         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   9704                 "moveTaskBackwards()");
   9705 
   9706         synchronized(this) {
   9707             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   9708                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
   9709                 return;
   9710             }
   9711             final long origId = Binder.clearCallingIdentity();
   9712             moveTaskBackwardsLocked(task);
   9713             Binder.restoreCallingIdentity(origId);
   9714         }
   9715     }
   9716 
   9717     private final void moveTaskBackwardsLocked(int task) {
   9718         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
   9719     }
   9720 
   9721     @Override
   9722     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
   9723             IActivityContainerCallback callback) throws RemoteException {
   9724         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
   9725         synchronized (this) {
   9726             if (parentActivityToken == null) {
   9727                 throw new IllegalArgumentException("parent token must not be null");
   9728             }
   9729             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
   9730             if (r == null) {
   9731                 return null;
   9732             }
   9733             if (callback == null) {
   9734                 throw new IllegalArgumentException("callback must not be null");
   9735             }
   9736             return mStackSupervisor.createVirtualActivityContainer(r, callback);
   9737         }
   9738     }
   9739 
   9740     @Override
   9741     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
   9742         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
   9743         synchronized (this) {
   9744             mStackSupervisor.deleteActivityContainer(container);
   9745         }
   9746     }
   9747 
   9748     @Override
   9749     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
   9750         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
   9751         synchronized (this) {
   9752             final int stackId = mStackSupervisor.getNextStackId();
   9753             final ActivityStack stack =
   9754                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
   9755             if (stack == null) {
   9756                 return null;
   9757             }
   9758             return stack.mActivityContainer;
   9759         }
   9760     }
   9761 
   9762     @Override
   9763     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
   9764         synchronized (this) {
   9765             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
   9766             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
   9767                 return stack.mActivityContainer.getDisplayId();
   9768             }
   9769             return Display.DEFAULT_DISPLAY;
   9770         }
   9771     }
   9772 
   9773     @Override
   9774     public int getActivityStackId(IBinder token) throws RemoteException {
   9775         synchronized (this) {
   9776             ActivityStack stack = ActivityRecord.getStackLocked(token);
   9777             if (stack == null) {
   9778                 return INVALID_STACK_ID;
   9779             }
   9780             return stack.mStackId;
   9781         }
   9782     }
   9783 
   9784     @Override
   9785     public void exitFreeformMode(IBinder token) throws RemoteException {
   9786         synchronized (this) {
   9787             long ident = Binder.clearCallingIdentity();
   9788             try {
   9789                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   9790                 if (r == null) {
   9791                     throw new IllegalArgumentException(
   9792                             "exitFreeformMode: No activity record matching token=" + token);
   9793                 }
   9794                 final ActivityStack stack = r.getStackLocked(token);
   9795                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
   9796                     throw new IllegalStateException(
   9797                             "exitFreeformMode: You can only go fullscreen from freeform.");
   9798                 }
   9799                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
   9800                 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
   9801                         ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
   9802             } finally {
   9803                 Binder.restoreCallingIdentity(ident);
   9804             }
   9805         }
   9806     }
   9807 
   9808     @Override
   9809     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
   9810         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
   9811         if (stackId == HOME_STACK_ID) {
   9812             throw new IllegalArgumentException(
   9813                     "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
   9814         }
   9815         synchronized (this) {
   9816             long ident = Binder.clearCallingIdentity();
   9817             try {
   9818                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
   9819                         + " to stackId=" + stackId + " toTop=" + toTop);
   9820                 if (stackId == DOCKED_STACK_ID) {
   9821                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
   9822                             null /* initialBounds */);
   9823                 }
   9824                 boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
   9825                         !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
   9826                 if (result && stackId == DOCKED_STACK_ID) {
   9827                     // If task moved to docked stack - show recents if needed.
   9828                     mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
   9829                             "moveTaskToDockedStack");
   9830                 }
   9831             } finally {
   9832                 Binder.restoreCallingIdentity(ident);
   9833             }
   9834         }
   9835     }
   9836 
   9837     @Override
   9838     public void swapDockedAndFullscreenStack() throws RemoteException {
   9839         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
   9840         synchronized (this) {
   9841             long ident = Binder.clearCallingIdentity();
   9842             try {
   9843                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
   9844                         FULLSCREEN_WORKSPACE_STACK_ID);
   9845                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
   9846                         : null;
   9847                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
   9848                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
   9849                         : null;
   9850                 if (topTask == null || tasks == null || tasks.size() == 0) {
   9851                     Slog.w(TAG,
   9852                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
   9853                     return;
   9854                 }
   9855 
   9856                 // TODO: App transition
   9857                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
   9858 
   9859                 // Defer the resume so resume/pausing while moving stacks is dangerous.
   9860                 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
   9861                         false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
   9862                         ANIMATE, true /* deferResume */);
   9863                 final int size = tasks.size();
   9864                 for (int i = 0; i < size; i++) {
   9865                     final int id = tasks.get(i).taskId;
   9866                     if (id == topTask.taskId) {
   9867                         continue;
   9868                     }
   9869                     mStackSupervisor.moveTaskToStackLocked(id,
   9870                             FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
   9871                             "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
   9872                 }
   9873 
   9874                 // Because we deferred the resume, to avoid conflicts with stack switches while
   9875                 // resuming, we need to do it after all the tasks are moved.
   9876                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   9877                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
   9878 
   9879                 mWindowManager.executeAppTransition();
   9880             } finally {
   9881                 Binder.restoreCallingIdentity(ident);
   9882             }
   9883         }
   9884     }
   9885 
   9886     /**
   9887      * Moves the input task to the docked stack.
   9888      *
   9889      * @param taskId Id of task to move.
   9890      * @param createMode The mode the docked stack should be created in if it doesn't exist
   9891      *                   already. See
   9892      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
   9893      *                   and
   9894      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
   9895      * @param toTop If the task and stack should be moved to the top.
   9896      * @param animate Whether we should play an animation for the moving the task
   9897      * @param initialBounds If the docked stack gets created, it will use these bounds for the
   9898      *                      docked stack. Pass {@code null} to use default bounds.
   9899      */
   9900     @Override
   9901     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
   9902             Rect initialBounds, boolean moveHomeStackFront) {
   9903         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
   9904         synchronized (this) {
   9905             long ident = Binder.clearCallingIdentity();
   9906             try {
   9907                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
   9908                         + " to createMode=" + createMode + " toTop=" + toTop);
   9909                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
   9910                 final boolean moved = mStackSupervisor.moveTaskToStackLocked(
   9911                         taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
   9912                         animate, DEFER_RESUME);
   9913                 if (moved) {
   9914                     if (moveHomeStackFront) {
   9915                         mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
   9916                     }
   9917                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   9918                 }
   9919                 return moved;
   9920             } finally {
   9921                 Binder.restoreCallingIdentity(ident);
   9922             }
   9923         }
   9924     }
   9925 
   9926     /**
   9927      * Moves the top activity in the input stackId to the pinned stack.
   9928      *
   9929      * @param stackId Id of stack to move the top activity to pinned stack.
   9930      * @param bounds Bounds to use for pinned stack.
   9931      *
   9932      * @return True if the top activity of the input stack was successfully moved to the pinned
   9933      *          stack.
   9934      */
   9935     @Override
   9936     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
   9937         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
   9938         synchronized (this) {
   9939             if (!mSupportsPictureInPicture) {
   9940                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
   9941                         + "Device doesn't support picture-in-pciture mode");
   9942             }
   9943 
   9944             long ident = Binder.clearCallingIdentity();
   9945             try {
   9946                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
   9947             } finally {
   9948                 Binder.restoreCallingIdentity(ident);
   9949             }
   9950         }
   9951     }
   9952 
   9953     @Override
   9954     public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
   9955             boolean preserveWindows, boolean animate, int animationDuration) {
   9956         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
   9957         long ident = Binder.clearCallingIdentity();
   9958         try {
   9959             synchronized (this) {
   9960                 if (animate) {
   9961                     if (stackId == PINNED_STACK_ID) {
   9962                         mWindowManager.animateResizePinnedStack(bounds, animationDuration);
   9963                     } else {
   9964                         throw new IllegalArgumentException("Stack: " + stackId
   9965                                 + " doesn't support animated resize.");
   9966                     }
   9967                 } else {
   9968                     mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
   9969                             null /* tempTaskInsetBounds */, preserveWindows,
   9970                             allowResizeInDockedMode, !DEFER_RESUME);
   9971                 }
   9972             }
   9973         } finally {
   9974             Binder.restoreCallingIdentity(ident);
   9975         }
   9976     }
   9977 
   9978     @Override
   9979     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
   9980             Rect tempDockedTaskInsetBounds,
   9981             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
   9982         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   9983                 "resizeDockedStack()");
   9984         long ident = Binder.clearCallingIdentity();
   9985         try {
   9986             synchronized (this) {
   9987                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
   9988                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
   9989                         PRESERVE_WINDOWS);
   9990             }
   9991         } finally {
   9992             Binder.restoreCallingIdentity(ident);
   9993         }
   9994     }
   9995 
   9996     @Override
   9997     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
   9998         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   9999                 "resizePinnedStack()");
   10000         final long ident = Binder.clearCallingIdentity();
   10001         try {
   10002             synchronized (this) {
   10003                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
   10004             }
   10005         } finally {
   10006             Binder.restoreCallingIdentity(ident);
   10007         }
   10008     }
   10009 
   10010     @Override
   10011     public void positionTaskInStack(int taskId, int stackId, int position) {
   10012         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
   10013         if (stackId == HOME_STACK_ID) {
   10014             throw new IllegalArgumentException(
   10015                     "positionTaskInStack: Attempt to change the position of task "
   10016                     + taskId + " in/to home stack");
   10017         }
   10018         synchronized (this) {
   10019             long ident = Binder.clearCallingIdentity();
   10020             try {
   10021                 if (DEBUG_STACK) Slog.d(TAG_STACK,
   10022                         "positionTaskInStack: positioning task=" + taskId
   10023                         + " in stackId=" + stackId + " at position=" + position);
   10024                 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
   10025             } finally {
   10026                 Binder.restoreCallingIdentity(ident);
   10027             }
   10028         }
   10029     }
   10030 
   10031     @Override
   10032     public List<StackInfo> getAllStackInfos() {
   10033         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
   10034         long ident = Binder.clearCallingIdentity();
   10035         try {
   10036             synchronized (this) {
   10037                 return mStackSupervisor.getAllStackInfosLocked();
   10038             }
   10039         } finally {
   10040             Binder.restoreCallingIdentity(ident);
   10041         }
   10042     }
   10043 
   10044     @Override
   10045     public StackInfo getStackInfo(int stackId) {
   10046         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
   10047         long ident = Binder.clearCallingIdentity();
   10048         try {
   10049             synchronized (this) {
   10050                 return mStackSupervisor.getStackInfoLocked(stackId);
   10051             }
   10052         } finally {
   10053             Binder.restoreCallingIdentity(ident);
   10054         }
   10055     }
   10056 
   10057     @Override
   10058     public boolean isInHomeStack(int taskId) {
   10059         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
   10060         long ident = Binder.clearCallingIdentity();
   10061         try {
   10062             synchronized (this) {
   10063                 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
   10064                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
   10065                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
   10066             }
   10067         } finally {
   10068             Binder.restoreCallingIdentity(ident);
   10069         }
   10070     }
   10071 
   10072     @Override
   10073     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
   10074         synchronized(this) {
   10075             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
   10076         }
   10077     }
   10078 
   10079     @Override
   10080     public void updateDeviceOwner(String packageName) {
   10081         final int callingUid = Binder.getCallingUid();
   10082         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   10083             throw new SecurityException("updateDeviceOwner called from non-system process");
   10084         }
   10085         synchronized (this) {
   10086             mDeviceOwnerName = packageName;
   10087         }
   10088     }
   10089 
   10090     @Override
   10091     public void updateLockTaskPackages(int userId, String[] packages) {
   10092         final int callingUid = Binder.getCallingUid();
   10093         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   10094             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
   10095                     "updateLockTaskPackages()");
   10096         }
   10097         synchronized (this) {
   10098             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
   10099                     Arrays.toString(packages));
   10100             mLockTaskPackages.put(userId, packages);
   10101             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
   10102         }
   10103     }
   10104 
   10105 
   10106     void startLockTaskModeLocked(TaskRecord task) {
   10107         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
   10108         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
   10109             return;
   10110         }
   10111 
   10112         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
   10113         // is initiated by system after the pinning request was shown and locked mode is initiated
   10114         // by an authorized app directly
   10115         final int callingUid = Binder.getCallingUid();
   10116         boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
   10117         long ident = Binder.clearCallingIdentity();
   10118         try {
   10119             if (!isSystemInitiated) {
   10120                 task.mLockTaskUid = callingUid;
   10121                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
   10122                     // startLockTask() called by app and task mode is lockTaskModeDefault.
   10123                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
   10124                     StatusBarManagerInternal statusBarManager =
   10125                             LocalServices.getService(StatusBarManagerInternal.class);
   10126                     if (statusBarManager != null) {
   10127                         statusBarManager.showScreenPinningRequest(task.taskId);
   10128                     }
   10129                     return;
   10130                 }
   10131 
   10132                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
   10133                 if (stack == null || task != stack.topTask()) {
   10134                     throw new IllegalArgumentException("Invalid task, not in foreground");
   10135                 }
   10136             }
   10137             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
   10138                     "Locking fully");
   10139             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
   10140                     ActivityManager.LOCK_TASK_MODE_PINNED :
   10141                     ActivityManager.LOCK_TASK_MODE_LOCKED,
   10142                     "startLockTask", true);
   10143         } finally {
   10144             Binder.restoreCallingIdentity(ident);
   10145         }
   10146     }
   10147 
   10148     @Override
   10149     public void startLockTaskMode(int taskId) {
   10150         synchronized (this) {
   10151             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   10152             if (task != null) {
   10153                 startLockTaskModeLocked(task);
   10154             }
   10155         }
   10156     }
   10157 
   10158     @Override
   10159     public void startLockTaskMode(IBinder token) {
   10160         synchronized (this) {
   10161             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   10162             if (r == null) {
   10163                 return;
   10164             }
   10165             final TaskRecord task = r.task;
   10166             if (task != null) {
   10167                 startLockTaskModeLocked(task);
   10168             }
   10169         }
   10170     }
   10171 
   10172     @Override
   10173     public void startSystemLockTaskMode(int taskId) throws RemoteException {
   10174         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
   10175         // This makes inner call to look as if it was initiated by system.
   10176         long ident = Binder.clearCallingIdentity();
   10177         try {
   10178             synchronized (this) {
   10179                 startLockTaskMode(taskId);
   10180             }
   10181         } finally {
   10182             Binder.restoreCallingIdentity(ident);
   10183         }
   10184     }
   10185 
   10186     @Override
   10187     public void stopLockTaskMode() {
   10188         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
   10189         if (lockTask == null) {
   10190             // Our work here is done.
   10191             return;
   10192         }
   10193 
   10194         final int callingUid = Binder.getCallingUid();
   10195         final int lockTaskUid = lockTask.mLockTaskUid;
   10196         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
   10197         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
   10198             // Done.
   10199             return;
   10200         } else {
   10201             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
   10202             // It is possible lockTaskMode was started by the system process because
   10203             // android:lockTaskMode is set to a locking value in the application manifest
   10204             // instead of the app calling startLockTaskMode. In this case
   10205             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
   10206             // {@link TaskRecord.effectiveUid} instead. Also caller with
   10207             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
   10208             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
   10209                     && callingUid != lockTaskUid
   10210                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
   10211                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
   10212                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
   10213             }
   10214         }
   10215         long ident = Binder.clearCallingIdentity();
   10216         try {
   10217             Log.d(TAG, "stopLockTaskMode");
   10218             // Stop lock task
   10219             synchronized (this) {
   10220                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
   10221                         "stopLockTask", true);
   10222             }
   10223             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
   10224             if (tm != null) {
   10225                 tm.showInCallScreen(false);
   10226             }
   10227         } finally {
   10228             Binder.restoreCallingIdentity(ident);
   10229         }
   10230     }
   10231 
   10232     /**
   10233      * This API should be called by SystemUI only when user perform certain action to dismiss
   10234      * lock task mode. We should only dismiss pinned lock task mode in this case.
   10235      */
   10236     @Override
   10237     public void stopSystemLockTaskMode() throws RemoteException {
   10238         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
   10239             stopLockTaskMode();
   10240         } else {
   10241             mStackSupervisor.showLockTaskToast();
   10242         }
   10243     }
   10244 
   10245     @Override
   10246     public boolean isInLockTaskMode() {
   10247         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
   10248     }
   10249 
   10250     @Override
   10251     public int getLockTaskModeState() {
   10252         synchronized (this) {
   10253             return mStackSupervisor.getLockTaskModeState();
   10254         }
   10255     }
   10256 
   10257     @Override
   10258     public void showLockTaskEscapeMessage(IBinder token) {
   10259         synchronized (this) {
   10260             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   10261             if (r == null) {
   10262                 return;
   10263             }
   10264             mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
   10265         }
   10266     }
   10267 
   10268     // =========================================================
   10269     // CONTENT PROVIDERS
   10270     // =========================================================
   10271 
   10272     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
   10273         List<ProviderInfo> providers = null;
   10274         try {
   10275             providers = AppGlobals.getPackageManager()
   10276                     .queryContentProviders(app.processName, app.uid,
   10277                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
   10278                                     | MATCH_DEBUG_TRIAGED_MISSING)
   10279                     .getList();
   10280         } catch (RemoteException ex) {
   10281         }
   10282         if (DEBUG_MU) Slog.v(TAG_MU,
   10283                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
   10284         int userId = app.userId;
   10285         if (providers != null) {
   10286             int N = providers.size();
   10287             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
   10288             for (int i=0; i<N; i++) {
   10289                 // TODO: keep logic in sync with installEncryptionUnawareProviders
   10290                 ProviderInfo cpi =
   10291                     (ProviderInfo)providers.get(i);
   10292                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   10293                         cpi.name, cpi.flags);
   10294                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
   10295                     // This is a singleton provider, but a user besides the
   10296                     // default user is asking to initialize a process it runs
   10297                     // in...  well, no, it doesn't actually run in this process,
   10298                     // it runs in the process of the default user.  Get rid of it.
   10299                     providers.remove(i);
   10300                     N--;
   10301                     i--;
   10302                     continue;
   10303                 }
   10304 
   10305                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   10306                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
   10307                 if (cpr == null) {
   10308                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
   10309                     mProviderMap.putProviderByClass(comp, cpr);
   10310                 }
   10311                 if (DEBUG_MU) Slog.v(TAG_MU,
   10312                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
   10313                 app.pubProviders.put(cpi.name, cpr);
   10314                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
   10315                     // Don't add this if it is a platform component that is marked
   10316                     // to run in multiple processes, because this is actually
   10317                     // part of the framework so doesn't make sense to track as a
   10318                     // separate apk in the process.
   10319                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
   10320                             mProcessStats);
   10321                 }
   10322                 notifyPackageUse(cpi.applicationInfo.packageName,
   10323                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
   10324             }
   10325         }
   10326         return providers;
   10327     }
   10328 
   10329     /**
   10330      * Check if {@link ProcessRecord} has a possible chance at accessing the
   10331      * given {@link ProviderInfo}. Final permission checking is always done
   10332      * in {@link ContentProvider}.
   10333      */
   10334     private final String checkContentProviderPermissionLocked(
   10335             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
   10336         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
   10337         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
   10338         boolean checkedGrants = false;
   10339         if (checkUser) {
   10340             // Looking for cross-user grants before enforcing the typical cross-users permissions
   10341             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
   10342             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
   10343                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
   10344                     return null;
   10345                 }
   10346                 checkedGrants = true;
   10347             }
   10348             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
   10349                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
   10350             if (userId != tmpTargetUserId) {
   10351                 // When we actually went to determine the final targer user ID, this ended
   10352                 // up different than our initial check for the authority.  This is because
   10353                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
   10354                 // SELF.  So we need to re-check the grants again.
   10355                 checkedGrants = false;
   10356             }
   10357         }
   10358         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
   10359                 cpi.applicationInfo.uid, cpi.exported)
   10360                 == PackageManager.PERMISSION_GRANTED) {
   10361             return null;
   10362         }
   10363         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
   10364                 cpi.applicationInfo.uid, cpi.exported)
   10365                 == PackageManager.PERMISSION_GRANTED) {
   10366             return null;
   10367         }
   10368 
   10369         PathPermission[] pps = cpi.pathPermissions;
   10370         if (pps != null) {
   10371             int i = pps.length;
   10372             while (i > 0) {
   10373                 i--;
   10374                 PathPermission pp = pps[i];
   10375                 String pprperm = pp.getReadPermission();
   10376                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
   10377                         cpi.applicationInfo.uid, cpi.exported)
   10378                         == PackageManager.PERMISSION_GRANTED) {
   10379                     return null;
   10380                 }
   10381                 String ppwperm = pp.getWritePermission();
   10382                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
   10383                         cpi.applicationInfo.uid, cpi.exported)
   10384                         == PackageManager.PERMISSION_GRANTED) {
   10385                     return null;
   10386                 }
   10387             }
   10388         }
   10389         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
   10390             return null;
   10391         }
   10392 
   10393         String msg;
   10394         if (!cpi.exported) {
   10395             msg = "Permission Denial: opening provider " + cpi.name
   10396                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   10397                     + ", uid=" + callingUid + ") that is not exported from uid "
   10398                     + cpi.applicationInfo.uid;
   10399         } else {
   10400             msg = "Permission Denial: opening provider " + cpi.name
   10401                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   10402                     + ", uid=" + callingUid + ") requires "
   10403                     + cpi.readPermission + " or " + cpi.writePermission;
   10404         }
   10405         Slog.w(TAG, msg);
   10406         return msg;
   10407     }
   10408 
   10409     /**
   10410      * Returns if the ContentProvider has granted a uri to callingUid
   10411      */
   10412     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
   10413         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   10414         if (perms != null) {
   10415             for (int i=perms.size()-1; i>=0; i--) {
   10416                 GrantUri grantUri = perms.keyAt(i);
   10417                 if (grantUri.sourceUserId == userId || !checkUser) {
   10418                     if (matchesProvider(grantUri.uri, cpi)) {
   10419                         return true;
   10420                     }
   10421                 }
   10422             }
   10423         }
   10424         return false;
   10425     }
   10426 
   10427     /**
   10428      * Returns true if the uri authority is one of the authorities specified in the provider.
   10429      */
   10430     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
   10431         String uriAuth = uri.getAuthority();
   10432         String cpiAuth = cpi.authority;
   10433         if (cpiAuth.indexOf(';') == -1) {
   10434             return cpiAuth.equals(uriAuth);
   10435         }
   10436         String[] cpiAuths = cpiAuth.split(";");
   10437         int length = cpiAuths.length;
   10438         for (int i = 0; i < length; i++) {
   10439             if (cpiAuths[i].equals(uriAuth)) return true;
   10440         }
   10441         return false;
   10442     }
   10443 
   10444     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
   10445             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   10446         if (r != null) {
   10447             for (int i=0; i<r.conProviders.size(); i++) {
   10448                 ContentProviderConnection conn = r.conProviders.get(i);
   10449                 if (conn.provider == cpr) {
   10450                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
   10451                             "Adding provider requested by "
   10452                             + r.processName + " from process "
   10453                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   10454                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   10455                     if (stable) {
   10456                         conn.stableCount++;
   10457                         conn.numStableIncs++;
   10458                     } else {
   10459                         conn.unstableCount++;
   10460                         conn.numUnstableIncs++;
   10461                     }
   10462                     return conn;
   10463                 }
   10464             }
   10465             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
   10466             if (stable) {
   10467                 conn.stableCount = 1;
   10468                 conn.numStableIncs = 1;
   10469             } else {
   10470                 conn.unstableCount = 1;
   10471                 conn.numUnstableIncs = 1;
   10472             }
   10473             cpr.connections.add(conn);
   10474             r.conProviders.add(conn);
   10475             startAssociationLocked(r.uid, r.processName, r.curProcState,
   10476                     cpr.uid, cpr.name, cpr.info.processName);
   10477             return conn;
   10478         }
   10479         cpr.addExternalProcessHandleLocked(externalProcessToken);
   10480         return null;
   10481     }
   10482 
   10483     boolean decProviderCountLocked(ContentProviderConnection conn,
   10484             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   10485         if (conn != null) {
   10486             cpr = conn.provider;
   10487             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
   10488                     "Removing provider requested by "
   10489                     + conn.client.processName + " from process "
   10490                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   10491                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   10492             if (stable) {
   10493                 conn.stableCount--;
   10494             } else {
   10495                 conn.unstableCount--;
   10496             }
   10497             if (conn.stableCount == 0 && conn.unstableCount == 0) {
   10498                 cpr.connections.remove(conn);
   10499                 conn.client.conProviders.remove(conn);
   10500                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   10501                     // The client is more important than last activity -- note the time this
   10502                     // is happening, so we keep the old provider process around a bit as last
   10503                     // activity to avoid thrashing it.
   10504                     if (cpr.proc != null) {
   10505                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
   10506                     }
   10507                 }
   10508                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
   10509                 return true;
   10510             }
   10511             return false;
   10512         }
   10513         cpr.removeExternalProcessHandleLocked(externalProcessToken);
   10514         return false;
   10515     }
   10516 
   10517     private void checkTime(long startTime, String where) {
   10518         long now = SystemClock.uptimeMillis();
   10519         if ((now-startTime) > 50) {
   10520             // If we are taking more than 50ms, log about it.
   10521             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
   10522         }
   10523     }
   10524 
   10525     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
   10526             PROC_SPACE_TERM,
   10527             PROC_SPACE_TERM|PROC_PARENS,
   10528             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
   10529     };
   10530 
   10531     private final long[] mProcessStateStatsLongs = new long[1];
   10532 
   10533     boolean isProcessAliveLocked(ProcessRecord proc) {
   10534         if (proc.procStatFile == null) {
   10535             proc.procStatFile = "/proc/" + proc.pid + "/stat";
   10536         }
   10537         mProcessStateStatsLongs[0] = 0;
   10538         if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
   10539                 mProcessStateStatsLongs, null)) {
   10540             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
   10541             return false;
   10542         }
   10543         final long state = mProcessStateStatsLongs[0];
   10544         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
   10545                 + (char)state);
   10546         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
   10547     }
   10548 
   10549     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
   10550             String name, IBinder token, boolean stable, int userId) {
   10551         ContentProviderRecord cpr;
   10552         ContentProviderConnection conn = null;
   10553         ProviderInfo cpi = null;
   10554 
   10555         synchronized(this) {
   10556             long startTime = SystemClock.uptimeMillis();
   10557 
   10558             ProcessRecord r = null;
   10559             if (caller != null) {
   10560                 r = getRecordForAppLocked(caller);
   10561                 if (r == null) {
   10562                     throw new SecurityException(
   10563                             "Unable to find app for caller " + caller
   10564                           + " (pid=" + Binder.getCallingPid()
   10565                           + ") when getting content provider " + name);
   10566                 }
   10567             }
   10568 
   10569             boolean checkCrossUser = true;
   10570 
   10571             checkTime(startTime, "getContentProviderImpl: getProviderByName");
   10572 
   10573             // First check if this content provider has been published...
   10574             cpr = mProviderMap.getProviderByName(name, userId);
   10575             // If that didn't work, check if it exists for user 0 and then
   10576             // verify that it's a singleton provider before using it.
   10577             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
   10578                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
   10579                 if (cpr != null) {
   10580                     cpi = cpr.info;
   10581                     if (isSingleton(cpi.processName, cpi.applicationInfo,
   10582                             cpi.name, cpi.flags)
   10583                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
   10584                         userId = UserHandle.USER_SYSTEM;
   10585                         checkCrossUser = false;
   10586                     } else {
   10587                         cpr = null;
   10588                         cpi = null;
   10589                     }
   10590                 }
   10591             }
   10592 
   10593             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
   10594             if (providerRunning) {
   10595                 cpi = cpr.info;
   10596                 String msg;
   10597                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
   10598                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
   10599                         != null) {
   10600                     throw new SecurityException(msg);
   10601                 }
   10602                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
   10603 
   10604                 if (r != null && cpr.canRunHere(r)) {
   10605                     // This provider has been published or is in the process
   10606                     // of being published...  but it is also allowed to run
   10607                     // in the caller's process, so don't make a connection
   10608                     // and just let the caller instantiate its own instance.
   10609                     ContentProviderHolder holder = cpr.newHolder(null);
   10610                     // don't give caller the provider object, it needs
   10611                     // to make its own.
   10612                     holder.provider = null;
   10613                     return holder;
   10614                 }
   10615 
   10616                 final long origId = Binder.clearCallingIdentity();
   10617 
   10618                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
   10619 
   10620                 // In this case the provider instance already exists, so we can
   10621                 // return it right away.
   10622                 conn = incProviderCountLocked(r, cpr, token, stable);
   10623                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
   10624                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   10625                         // If this is a perceptible app accessing the provider,
   10626                         // make sure to count it as being accessed and thus
   10627                         // back up on the LRU list.  This is good because
   10628                         // content providers are often expensive to start.
   10629                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
   10630                         updateLruProcessLocked(cpr.proc, false, null);
   10631                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
   10632                     }
   10633                 }
   10634 
   10635                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
   10636                 final int verifiedAdj = cpr.proc.verifiedAdj;
   10637                 boolean success = updateOomAdjLocked(cpr.proc);
   10638                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
   10639                 // if the process has been successfully adjusted.  So to reduce races with
   10640                 // it, we will check whether the process still exists.  Note that this doesn't
   10641                 // completely get rid of races with LMK killing the process, but should make
   10642                 // them much smaller.
   10643                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
   10644                     success = false;
   10645                 }
   10646                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
   10647                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
   10648                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
   10649                 // NOTE: there is still a race here where a signal could be
   10650                 // pending on the process even though we managed to update its
   10651                 // adj level.  Not sure what to do about this, but at least
   10652                 // the race is now smaller.
   10653                 if (!success) {
   10654                     // Uh oh...  it looks like the provider's process
   10655                     // has been killed on us.  We need to wait for a new
   10656                     // process to be started, and make sure its death
   10657                     // doesn't kill our process.
   10658                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
   10659                             + " is crashing; detaching " + r);
   10660                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
   10661                     checkTime(startTime, "getContentProviderImpl: before appDied");
   10662                     appDiedLocked(cpr.proc);
   10663                     checkTime(startTime, "getContentProviderImpl: after appDied");
   10664                     if (!lastRef) {
   10665                         // This wasn't the last ref our process had on
   10666                         // the provider...  we have now been killed, bail.
   10667                         return null;
   10668                     }
   10669                     providerRunning = false;
   10670                     conn = null;
   10671                 } else {
   10672                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
   10673                 }
   10674 
   10675                 Binder.restoreCallingIdentity(origId);
   10676             }
   10677 
   10678             if (!providerRunning) {
   10679                 try {
   10680                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
   10681                     cpi = AppGlobals.getPackageManager().
   10682                         resolveContentProvider(name,
   10683                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
   10684                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
   10685                 } catch (RemoteException ex) {
   10686                 }
   10687                 if (cpi == null) {
   10688                     return null;
   10689                 }
   10690                 // If the provider is a singleton AND
   10691                 // (it's a call within the same user || the provider is a
   10692                 // privileged app)
   10693                 // Then allow connecting to the singleton provider
   10694                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   10695                         cpi.name, cpi.flags)
   10696                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
   10697                 if (singleton) {
   10698                     userId = UserHandle.USER_SYSTEM;
   10699                 }
   10700                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
   10701                 checkTime(startTime, "getContentProviderImpl: got app info for user");
   10702 
   10703                 String msg;
   10704                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
   10705                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
   10706                         != null) {
   10707                     throw new SecurityException(msg);
   10708                 }
   10709                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
   10710 
   10711                 if (!mProcessesReady
   10712                         && !cpi.processName.equals("system")) {
   10713                     // If this content provider does not run in the system
   10714                     // process, and the system is not yet ready to run other
   10715                     // processes, then fail fast instead of hanging.
   10716                     throw new IllegalArgumentException(
   10717                             "Attempt to launch content provider before system ready");
   10718                 }
   10719 
   10720                 // Make sure that the user who owns this provider is running.  If not,
   10721                 // we don't want to allow it to run.
   10722                 if (!mUserController.isUserRunningLocked(userId, 0)) {
   10723                     Slog.w(TAG, "Unable to launch app "
   10724                             + cpi.applicationInfo.packageName + "/"
   10725                             + cpi.applicationInfo.uid + " for provider "
   10726                             + name + ": user " + userId + " is stopped");
   10727                     return null;
   10728                 }
   10729 
   10730                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   10731                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
   10732                 cpr = mProviderMap.getProviderByClass(comp, userId);
   10733                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
   10734                 final boolean firstClass = cpr == null;
   10735                 if (firstClass) {
   10736                     final long ident = Binder.clearCallingIdentity();
   10737 
   10738                     // If permissions need a review before any of the app components can run,
   10739                     // we return no provider and launch a review activity if the calling app
   10740                     // is in the foreground.
   10741                     if (Build.PERMISSIONS_REVIEW_REQUIRED) {
   10742                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
   10743                             return null;
   10744                         }
   10745                     }
   10746 
   10747                     try {
   10748                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
   10749                         ApplicationInfo ai =
   10750                             AppGlobals.getPackageManager().
   10751                                 getApplicationInfo(
   10752                                         cpi.applicationInfo.packageName,
   10753                                         STOCK_PM_FLAGS, userId);
   10754                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
   10755                         if (ai == null) {
   10756                             Slog.w(TAG, "No package info for content provider "
   10757                                     + cpi.name);
   10758                             return null;
   10759                         }
   10760                         ai = getAppInfoForUser(ai, userId);
   10761                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
   10762                     } catch (RemoteException ex) {
   10763                         // pm is in same process, this will never happen.
   10764                     } finally {
   10765                         Binder.restoreCallingIdentity(ident);
   10766                     }
   10767                 }
   10768 
   10769                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
   10770 
   10771                 if (r != null && cpr.canRunHere(r)) {
   10772                     // If this is a multiprocess provider, then just return its
   10773                     // info and allow the caller to instantiate it.  Only do
   10774                     // this if the provider is the same user as the caller's
   10775                     // process, or can run as root (so can be in any process).
   10776                     return cpr.newHolder(null);
   10777                 }
   10778 
   10779                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
   10780                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
   10781                             + cpr.info.name + " callers=" + Debug.getCallers(6));
   10782 
   10783                 // This is single process, and our app is now connecting to it.
   10784                 // See if we are already in the process of launching this
   10785                 // provider.
   10786                 final int N = mLaunchingProviders.size();
   10787                 int i;
   10788                 for (i = 0; i < N; i++) {
   10789                     if (mLaunchingProviders.get(i) == cpr) {
   10790                         break;
   10791                     }
   10792                 }
   10793 
   10794                 // If the provider is not already being launched, then get it
   10795                 // started.
   10796                 if (i >= N) {
   10797                     final long origId = Binder.clearCallingIdentity();
   10798 
   10799                     try {
   10800                         // Content provider is now in use, its package can't be stopped.
   10801                         try {
   10802                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
   10803                             AppGlobals.getPackageManager().setPackageStoppedState(
   10804                                     cpr.appInfo.packageName, false, userId);
   10805                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
   10806                         } catch (RemoteException e) {
   10807                         } catch (IllegalArgumentException e) {
   10808                             Slog.w(TAG, "Failed trying to unstop package "
   10809                                     + cpr.appInfo.packageName + ": " + e);
   10810                         }
   10811 
   10812                         // Use existing process if already started
   10813                         checkTime(startTime, "getContentProviderImpl: looking for process record");
   10814                         ProcessRecord proc = getProcessRecordLocked(
   10815                                 cpi.processName, cpr.appInfo.uid, false);
   10816                         if (proc != null && proc.thread != null && !proc.killed) {
   10817                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
   10818                                     "Installing in existing process " + proc);
   10819                             if (!proc.pubProviders.containsKey(cpi.name)) {
   10820                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
   10821                                 proc.pubProviders.put(cpi.name, cpr);
   10822                                 try {
   10823                                     proc.thread.scheduleInstallProvider(cpi);
   10824                                 } catch (RemoteException e) {
   10825                                 }
   10826                             }
   10827                         } else {
   10828                             checkTime(startTime, "getContentProviderImpl: before start process");
   10829                             proc = startProcessLocked(cpi.processName,
   10830                                     cpr.appInfo, false, 0, "content provider",
   10831                                     new ComponentName(cpi.applicationInfo.packageName,
   10832                                             cpi.name), false, false, false);
   10833                             checkTime(startTime, "getContentProviderImpl: after start process");
   10834                             if (proc == null) {
   10835                                 Slog.w(TAG, "Unable to launch app "
   10836                                         + cpi.applicationInfo.packageName + "/"
   10837                                         + cpi.applicationInfo.uid + " for provider "
   10838                                         + name + ": process is bad");
   10839                                 return null;
   10840                             }
   10841                         }
   10842                         cpr.launchingApp = proc;
   10843                         mLaunchingProviders.add(cpr);
   10844                     } finally {
   10845                         Binder.restoreCallingIdentity(origId);
   10846                     }
   10847                 }
   10848 
   10849                 checkTime(startTime, "getContentProviderImpl: updating data structures");
   10850 
   10851                 // Make sure the provider is published (the same provider class
   10852                 // may be published under multiple names).
   10853                 if (firstClass) {
   10854                     mProviderMap.putProviderByClass(comp, cpr);
   10855                 }
   10856 
   10857                 mProviderMap.putProviderByName(name, cpr);
   10858                 conn = incProviderCountLocked(r, cpr, token, stable);
   10859                 if (conn != null) {
   10860                     conn.waiting = true;
   10861                 }
   10862             }
   10863             checkTime(startTime, "getContentProviderImpl: done!");
   10864         }
   10865 
   10866         // Wait for the provider to be published...
   10867         synchronized (cpr) {
   10868             while (cpr.provider == null) {
   10869                 if (cpr.launchingApp == null) {
   10870                     Slog.w(TAG, "Unable to launch app "
   10871                             + cpi.applicationInfo.packageName + "/"
   10872                             + cpi.applicationInfo.uid + " for provider "
   10873                             + name + ": launching app became null");
   10874                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
   10875                             UserHandle.getUserId(cpi.applicationInfo.uid),
   10876                             cpi.applicationInfo.packageName,
   10877                             cpi.applicationInfo.uid, name);
   10878                     return null;
   10879                 }
   10880                 try {
   10881                     if (DEBUG_MU) Slog.v(TAG_MU,
   10882                             "Waiting to start provider " + cpr
   10883                             + " launchingApp=" + cpr.launchingApp);
   10884                     if (conn != null) {
   10885                         conn.waiting = true;
   10886                     }
   10887                     cpr.wait();
   10888                 } catch (InterruptedException ex) {
   10889                 } finally {
   10890                     if (conn != null) {
   10891                         conn.waiting = false;
   10892                     }
   10893                 }
   10894             }
   10895         }
   10896         return cpr != null ? cpr.newHolder(conn) : null;
   10897     }
   10898 
   10899     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
   10900             ProcessRecord r, final int userId) {
   10901         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
   10902                 cpi.packageName, userId)) {
   10903 
   10904             final boolean callerForeground = r == null || r.setSchedGroup
   10905                     != ProcessList.SCHED_GROUP_BACKGROUND;
   10906 
   10907             // Show a permission review UI only for starting from a foreground app
   10908             if (!callerForeground) {
   10909                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
   10910                         + cpi.packageName + " requires a permissions review");
   10911                 return false;
   10912             }
   10913 
   10914             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
   10915             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
   10916                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
   10917             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
   10918 
   10919             if (DEBUG_PERMISSIONS_REVIEW) {
   10920                 Slog.i(TAG, "u" + userId + " Launching permission review "
   10921                         + "for package " + cpi.packageName);
   10922             }
   10923 
   10924             final UserHandle userHandle = new UserHandle(userId);
   10925             mHandler.post(new Runnable() {
   10926                 @Override
   10927                 public void run() {
   10928                     mContext.startActivityAsUser(intent, userHandle);
   10929                 }
   10930             });
   10931 
   10932             return false;
   10933         }
   10934 
   10935         return true;
   10936     }
   10937 
   10938     PackageManagerInternal getPackageManagerInternalLocked() {
   10939         if (mPackageManagerInt == null) {
   10940             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
   10941         }
   10942         return mPackageManagerInt;
   10943     }
   10944 
   10945     @Override
   10946     public final ContentProviderHolder getContentProvider(
   10947             IApplicationThread caller, String name, int userId, boolean stable) {
   10948         enforceNotIsolatedCaller("getContentProvider");
   10949         if (caller == null) {
   10950             String msg = "null IApplicationThread when getting content provider "
   10951                     + name;
   10952             Slog.w(TAG, msg);
   10953             throw new SecurityException(msg);
   10954         }
   10955         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
   10956         // with cross-user grant.
   10957         return getContentProviderImpl(caller, name, null, stable, userId);
   10958     }
   10959 
   10960     public ContentProviderHolder getContentProviderExternal(
   10961             String name, int userId, IBinder token) {
   10962         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   10963             "Do not have permission in call getContentProviderExternal()");
   10964         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   10965                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
   10966         return getContentProviderExternalUnchecked(name, token, userId);
   10967     }
   10968 
   10969     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
   10970             IBinder token, int userId) {
   10971         return getContentProviderImpl(null, name, token, true, userId);
   10972     }
   10973 
   10974     /**
   10975      * Drop a content provider from a ProcessRecord's bookkeeping
   10976      */
   10977     public void removeContentProvider(IBinder connection, boolean stable) {
   10978         enforceNotIsolatedCaller("removeContentProvider");
   10979         long ident = Binder.clearCallingIdentity();
   10980         try {
   10981             synchronized (this) {
   10982                 ContentProviderConnection conn;
   10983                 try {
   10984                     conn = (ContentProviderConnection)connection;
   10985                 } catch (ClassCastException e) {
   10986                     String msg ="removeContentProvider: " + connection
   10987                             + " not a ContentProviderConnection";
   10988                     Slog.w(TAG, msg);
   10989                     throw new IllegalArgumentException(msg);
   10990                 }
   10991                 if (conn == null) {
   10992                     throw new NullPointerException("connection is null");
   10993                 }
   10994                 if (decProviderCountLocked(conn, null, null, stable)) {
   10995                     updateOomAdjLocked();
   10996                 }
   10997             }
   10998         } finally {
   10999             Binder.restoreCallingIdentity(ident);
   11000         }
   11001     }
   11002 
   11003     public void removeContentProviderExternal(String name, IBinder token) {
   11004         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   11005             "Do not have permission in call removeContentProviderExternal()");
   11006         int userId = UserHandle.getCallingUserId();
   11007         long ident = Binder.clearCallingIdentity();
   11008         try {
   11009             removeContentProviderExternalUnchecked(name, token, userId);
   11010         } finally {
   11011             Binder.restoreCallingIdentity(ident);
   11012         }
   11013     }
   11014 
   11015     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
   11016         synchronized (this) {
   11017             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
   11018             if(cpr == null) {
   11019                 //remove from mProvidersByClass
   11020                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
   11021                 return;
   11022             }
   11023 
   11024             //update content provider record entry info
   11025             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
   11026             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
   11027             if (localCpr.hasExternalProcessHandles()) {
   11028                 if (localCpr.removeExternalProcessHandleLocked(token)) {
   11029                     updateOomAdjLocked();
   11030                 } else {
   11031                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
   11032                             + " with no external reference for token: "
   11033                             + token + ".");
   11034                 }
   11035             } else {
   11036                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
   11037                         + " with no external references.");
   11038             }
   11039         }
   11040     }
   11041 
   11042     public final void publishContentProviders(IApplicationThread caller,
   11043             List<ContentProviderHolder> providers) {
   11044         if (providers == null) {
   11045             return;
   11046         }
   11047 
   11048         enforceNotIsolatedCaller("publishContentProviders");
   11049         synchronized (this) {
   11050             final ProcessRecord r = getRecordForAppLocked(caller);
   11051             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
   11052             if (r == null) {
   11053                 throw new SecurityException(
   11054                         "Unable to find app for caller " + caller
   11055                       + " (pid=" + Binder.getCallingPid()
   11056                       + ") when publishing content providers");
   11057             }
   11058 
   11059             final long origId = Binder.clearCallingIdentity();
   11060 
   11061             final int N = providers.size();
   11062             for (int i = 0; i < N; i++) {
   11063                 ContentProviderHolder src = providers.get(i);
   11064                 if (src == null || src.info == null || src.provider == null) {
   11065                     continue;
   11066                 }
   11067                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
   11068                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
   11069                 if (dst != null) {
   11070                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
   11071                     mProviderMap.putProviderByClass(comp, dst);
   11072                     String names[] = dst.info.authority.split(";");
   11073                     for (int j = 0; j < names.length; j++) {
   11074                         mProviderMap.putProviderByName(names[j], dst);
   11075                     }
   11076 
   11077                     int launchingCount = mLaunchingProviders.size();
   11078                     int j;
   11079                     boolean wasInLaunchingProviders = false;
   11080                     for (j = 0; j < launchingCount; j++) {
   11081                         if (mLaunchingProviders.get(j) == dst) {
   11082                             mLaunchingProviders.remove(j);
   11083                             wasInLaunchingProviders = true;
   11084                             j--;
   11085                             launchingCount--;
   11086                         }
   11087                     }
   11088                     if (wasInLaunchingProviders) {
   11089                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
   11090                     }
   11091                     synchronized (dst) {
   11092                         dst.provider = src.provider;
   11093                         dst.proc = r;
   11094                         dst.notifyAll();
   11095                     }
   11096                     updateOomAdjLocked(r);
   11097                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
   11098                             src.info.authority);
   11099                 }
   11100             }
   11101 
   11102             Binder.restoreCallingIdentity(origId);
   11103         }
   11104     }
   11105 
   11106     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
   11107         ContentProviderConnection conn;
   11108         try {
   11109             conn = (ContentProviderConnection)connection;
   11110         } catch (ClassCastException e) {
   11111             String msg ="refContentProvider: " + connection
   11112                     + " not a ContentProviderConnection";
   11113             Slog.w(TAG, msg);
   11114             throw new IllegalArgumentException(msg);
   11115         }
   11116         if (conn == null) {
   11117             throw new NullPointerException("connection is null");
   11118         }
   11119 
   11120         synchronized (this) {
   11121             if (stable > 0) {
   11122                 conn.numStableIncs += stable;
   11123             }
   11124             stable = conn.stableCount + stable;
   11125             if (stable < 0) {
   11126                 throw new IllegalStateException("stableCount < 0: " + stable);
   11127             }
   11128 
   11129             if (unstable > 0) {
   11130                 conn.numUnstableIncs += unstable;
   11131             }
   11132             unstable = conn.unstableCount + unstable;
   11133             if (unstable < 0) {
   11134                 throw new IllegalStateException("unstableCount < 0: " + unstable);
   11135             }
   11136 
   11137             if ((stable+unstable) <= 0) {
   11138                 throw new IllegalStateException("ref counts can't go to zero here: stable="
   11139                         + stable + " unstable=" + unstable);
   11140             }
   11141             conn.stableCount = stable;
   11142             conn.unstableCount = unstable;
   11143             return !conn.dead;
   11144         }
   11145     }
   11146 
   11147     public void unstableProviderDied(IBinder connection) {
   11148         ContentProviderConnection conn;
   11149         try {
   11150             conn = (ContentProviderConnection)connection;
   11151         } catch (ClassCastException e) {
   11152             String msg ="refContentProvider: " + connection
   11153                     + " not a ContentProviderConnection";
   11154             Slog.w(TAG, msg);
   11155             throw new IllegalArgumentException(msg);
   11156         }
   11157         if (conn == null) {
   11158             throw new NullPointerException("connection is null");
   11159         }
   11160 
   11161         // Safely retrieve the content provider associated with the connection.
   11162         IContentProvider provider;
   11163         synchronized (this) {
   11164             provider = conn.provider.provider;
   11165         }
   11166 
   11167         if (provider == null) {
   11168             // Um, yeah, we're way ahead of you.
   11169             return;
   11170         }
   11171 
   11172         // Make sure the caller is being honest with us.
   11173         if (provider.asBinder().pingBinder()) {
   11174             // Er, no, still looks good to us.
   11175             synchronized (this) {
   11176                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
   11177                         + " says " + conn + " died, but we don't agree");
   11178                 return;
   11179             }
   11180         }
   11181 
   11182         // Well look at that!  It's dead!
   11183         synchronized (this) {
   11184             if (conn.provider.provider != provider) {
   11185                 // But something changed...  good enough.
   11186                 return;
   11187             }
   11188 
   11189             ProcessRecord proc = conn.provider.proc;
   11190             if (proc == null || proc.thread == null) {
   11191                 // Seems like the process is already cleaned up.
   11192                 return;
   11193             }
   11194 
   11195             // As far as we're concerned, this is just like receiving a
   11196             // death notification...  just a bit prematurely.
   11197             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
   11198                     + ") early provider death");
   11199             final long ident = Binder.clearCallingIdentity();
   11200             try {
   11201                 appDiedLocked(proc);
   11202             } finally {
   11203                 Binder.restoreCallingIdentity(ident);
   11204             }
   11205         }
   11206     }
   11207 
   11208     @Override
   11209     public void appNotRespondingViaProvider(IBinder connection) {
   11210         enforceCallingPermission(
   11211                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
   11212 
   11213         final ContentProviderConnection conn = (ContentProviderConnection) connection;
   11214         if (conn == null) {
   11215             Slog.w(TAG, "ContentProviderConnection is null");
   11216             return;
   11217         }
   11218 
   11219         final ProcessRecord host = conn.provider.proc;
   11220         if (host == null) {
   11221             Slog.w(TAG, "Failed to find hosting ProcessRecord");
   11222             return;
   11223         }
   11224 
   11225         mHandler.post(new Runnable() {
   11226             @Override
   11227             public void run() {
   11228                 mAppErrors.appNotResponding(host, null, null, false,
   11229                         "ContentProvider not responding");
   11230             }
   11231         });
   11232     }
   11233 
   11234     public final void installSystemProviders() {
   11235         List<ProviderInfo> providers;
   11236         synchronized (this) {
   11237             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
   11238             providers = generateApplicationProvidersLocked(app);
   11239             if (providers != null) {
   11240                 for (int i=providers.size()-1; i>=0; i--) {
   11241                     ProviderInfo pi = (ProviderInfo)providers.get(i);
   11242                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   11243                         Slog.w(TAG, "Not installing system proc provider " + pi.name
   11244                                 + ": not system .apk");
   11245                         providers.remove(i);
   11246                     }
   11247                 }
   11248             }
   11249         }
   11250         if (providers != null) {
   11251             mSystemThread.installSystemProviders(providers);
   11252         }
   11253 
   11254         mCoreSettingsObserver = new CoreSettingsObserver(this);
   11255         mFontScaleSettingObserver = new FontScaleSettingObserver();
   11256 
   11257         //mUsageStatsService.monitorPackages();
   11258     }
   11259 
   11260     private void startPersistentApps(int matchFlags) {
   11261         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
   11262 
   11263         synchronized (this) {
   11264             try {
   11265                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
   11266                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
   11267                 for (ApplicationInfo app : apps) {
   11268                     if (!"android".equals(app.packageName)) {
   11269                         addAppLocked(app, false, null /* ABI override */);
   11270                     }
   11271                 }
   11272             } catch (RemoteException ex) {
   11273             }
   11274         }
   11275     }
   11276 
   11277     /**
   11278      * When a user is unlocked, we need to install encryption-unaware providers
   11279      * belonging to any running apps.
   11280      */
   11281     private void installEncryptionUnawareProviders(int userId) {
   11282         // We're only interested in providers that are encryption unaware, and
   11283         // we don't care about uninstalled apps, since there's no way they're
   11284         // running at this point.
   11285         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
   11286 
   11287         synchronized (this) {
   11288             final int NP = mProcessNames.getMap().size();
   11289             for (int ip = 0; ip < NP; ip++) {
   11290                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   11291                 final int NA = apps.size();
   11292                 for (int ia = 0; ia < NA; ia++) {
   11293                     final ProcessRecord app = apps.valueAt(ia);
   11294                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
   11295 
   11296                     final int NG = app.pkgList.size();
   11297                     for (int ig = 0; ig < NG; ig++) {
   11298                         try {
   11299                             final String pkgName = app.pkgList.keyAt(ig);
   11300                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
   11301                                     .getPackageInfo(pkgName, matchFlags, userId);
   11302                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
   11303                                 for (ProviderInfo pi : pkgInfo.providers) {
   11304                                     // TODO: keep in sync with generateApplicationProvidersLocked
   11305                                     final boolean processMatch = Objects.equals(pi.processName,
   11306                                             app.processName) || pi.multiprocess;
   11307                                     final boolean userMatch = isSingleton(pi.processName,
   11308                                             pi.applicationInfo, pi.name, pi.flags)
   11309                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
   11310                                     if (processMatch && userMatch) {
   11311                                         Log.v(TAG, "Installing " + pi);
   11312                                         app.thread.scheduleInstallProvider(pi);
   11313                                     } else {
   11314                                         Log.v(TAG, "Skipping " + pi);
   11315                                     }
   11316                                 }
   11317                             }
   11318                         } catch (RemoteException ignored) {
   11319                         }
   11320                     }
   11321                 }
   11322             }
   11323         }
   11324     }
   11325 
   11326     /**
   11327      * Allows apps to retrieve the MIME type of a URI.
   11328      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
   11329      * users, then it does not need permission to access the ContentProvider.
   11330      * Either, it needs cross-user uri grants.
   11331      *
   11332      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
   11333      *
   11334      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
   11335      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
   11336      */
   11337     public String getProviderMimeType(Uri uri, int userId) {
   11338         enforceNotIsolatedCaller("getProviderMimeType");
   11339         final String name = uri.getAuthority();
   11340         int callingUid = Binder.getCallingUid();
   11341         int callingPid = Binder.getCallingPid();
   11342         long ident = 0;
   11343         boolean clearedIdentity = false;
   11344         synchronized (this) {
   11345             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
   11346         }
   11347         if (canClearIdentity(callingPid, callingUid, userId)) {
   11348             clearedIdentity = true;
   11349             ident = Binder.clearCallingIdentity();
   11350         }
   11351         ContentProviderHolder holder = null;
   11352         try {
   11353             holder = getContentProviderExternalUnchecked(name, null, userId);
   11354             if (holder != null) {
   11355                 return holder.provider.getType(uri);
   11356             }
   11357         } catch (RemoteException e) {
   11358             Log.w(TAG, "Content provider dead retrieving " + uri, e);
   11359             return null;
   11360         } catch (Exception e) {
   11361             Log.w(TAG, "Exception while determining type of " + uri, e);
   11362             return null;
   11363         } finally {
   11364             // We need to clear the identity to call removeContentProviderExternalUnchecked
   11365             if (!clearedIdentity) {
   11366                 ident = Binder.clearCallingIdentity();
   11367             }
   11368             try {
   11369                 if (holder != null) {
   11370                     removeContentProviderExternalUnchecked(name, null, userId);
   11371                 }
   11372             } finally {
   11373                 Binder.restoreCallingIdentity(ident);
   11374             }
   11375         }
   11376 
   11377         return null;
   11378     }
   11379 
   11380     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
   11381         if (UserHandle.getUserId(callingUid) == userId) {
   11382             return true;
   11383         }
   11384         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
   11385                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
   11386                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
   11387                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
   11388                 return true;
   11389         }
   11390         return false;
   11391     }
   11392 
   11393     // =========================================================
   11394     // GLOBAL MANAGEMENT
   11395     // =========================================================
   11396 
   11397     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
   11398             boolean isolated, int isolatedUid) {
   11399         String proc = customProcess != null ? customProcess : info.processName;
   11400         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   11401         final int userId = UserHandle.getUserId(info.uid);
   11402         int uid = info.uid;
   11403         if (isolated) {
   11404             if (isolatedUid == 0) {
   11405                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
   11406                 while (true) {
   11407                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
   11408                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
   11409                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
   11410                     }
   11411                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
   11412                     mNextIsolatedProcessUid++;
   11413                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
   11414                         // No process for this uid, use it.
   11415                         break;
   11416                     }
   11417                     stepsLeft--;
   11418                     if (stepsLeft <= 0) {
   11419                         return null;
   11420                     }
   11421                 }
   11422             } else {
   11423                 // Special case for startIsolatedProcess (internal only), where
   11424                 // the uid of the isolated process is specified by the caller.
   11425                 uid = isolatedUid;
   11426             }
   11427         }
   11428         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
   11429         if (!mBooted && !mBooting
   11430                 && userId == UserHandle.USER_SYSTEM
   11431                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
   11432             r.persistent = true;
   11433         }
   11434         addProcessNameLocked(r);
   11435         return r;
   11436     }
   11437 
   11438     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
   11439             String abiOverride) {
   11440         ProcessRecord app;
   11441         if (!isolated) {
   11442             app = getProcessRecordLocked(info.processName, info.uid, true);
   11443         } else {
   11444             app = null;
   11445         }
   11446 
   11447         if (app == null) {
   11448             app = newProcessRecordLocked(info, null, isolated, 0);
   11449             updateLruProcessLocked(app, false, null);
   11450             updateOomAdjLocked();
   11451         }
   11452 
   11453         // This package really, really can not be stopped.
   11454         try {
   11455             AppGlobals.getPackageManager().setPackageStoppedState(
   11456                     info.packageName, false, UserHandle.getUserId(app.uid));
   11457         } catch (RemoteException e) {
   11458         } catch (IllegalArgumentException e) {
   11459             Slog.w(TAG, "Failed trying to unstop package "
   11460                     + info.packageName + ": " + e);
   11461         }
   11462 
   11463         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
   11464             app.persistent = true;
   11465             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
   11466         }
   11467         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
   11468             mPersistentStartingProcesses.add(app);
   11469             startProcessLocked(app, "added application", app.processName, abiOverride,
   11470                     null /* entryPoint */, null /* entryPointArgs */);
   11471         }
   11472 
   11473         return app;
   11474     }
   11475 
   11476     public void unhandledBack() {
   11477         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
   11478                 "unhandledBack()");
   11479 
   11480         synchronized(this) {
   11481             final long origId = Binder.clearCallingIdentity();
   11482             try {
   11483                 getFocusedStack().unhandledBackLocked();
   11484             } finally {
   11485                 Binder.restoreCallingIdentity(origId);
   11486             }
   11487         }
   11488     }
   11489 
   11490     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
   11491         enforceNotIsolatedCaller("openContentUri");
   11492         final int userId = UserHandle.getCallingUserId();
   11493         String name = uri.getAuthority();
   11494         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
   11495         ParcelFileDescriptor pfd = null;
   11496         if (cph != null) {
   11497             // We record the binder invoker's uid in thread-local storage before
   11498             // going to the content provider to open the file.  Later, in the code
   11499             // that handles all permissions checks, we look for this uid and use
   11500             // that rather than the Activity Manager's own uid.  The effect is that
   11501             // we do the check against the caller's permissions even though it looks
   11502             // to the content provider like the Activity Manager itself is making
   11503             // the request.
   11504             Binder token = new Binder();
   11505             sCallerIdentity.set(new Identity(
   11506                     token, Binder.getCallingPid(), Binder.getCallingUid()));
   11507             try {
   11508                 pfd = cph.provider.openFile(null, uri, "r", null, token);
   11509             } catch (FileNotFoundException e) {
   11510                 // do nothing; pfd will be returned null
   11511             } finally {
   11512                 // Ensure that whatever happens, we clean up the identity state
   11513                 sCallerIdentity.remove();
   11514                 // Ensure we're done with the provider.
   11515                 removeContentProviderExternalUnchecked(name, null, userId);
   11516             }
   11517         } else {
   11518             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
   11519         }
   11520         return pfd;
   11521     }
   11522 
   11523     // Actually is sleeping or shutting down or whatever else in the future
   11524     // is an inactive state.
   11525     boolean isSleepingOrShuttingDownLocked() {
   11526         return isSleepingLocked() || mShuttingDown;
   11527     }
   11528 
   11529     boolean isShuttingDownLocked() {
   11530         return mShuttingDown;
   11531     }
   11532 
   11533     boolean isSleepingLocked() {
   11534         return mSleeping;
   11535     }
   11536 
   11537     void onWakefulnessChanged(int wakefulness) {
   11538         synchronized(this) {
   11539             mWakefulness = wakefulness;
   11540             updateSleepIfNeededLocked();
   11541         }
   11542     }
   11543 
   11544     void finishRunningVoiceLocked() {
   11545         if (mRunningVoice != null) {
   11546             mRunningVoice = null;
   11547             mVoiceWakeLock.release();
   11548             updateSleepIfNeededLocked();
   11549         }
   11550     }
   11551 
   11552     void startTimeTrackingFocusedActivityLocked() {
   11553         if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
   11554             mCurAppTimeTracker.start(mFocusedActivity.packageName);
   11555         }
   11556     }
   11557 
   11558     void updateSleepIfNeededLocked() {
   11559         if (mSleeping && !shouldSleepLocked()) {
   11560             mSleeping = false;
   11561             startTimeTrackingFocusedActivityLocked();
   11562             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
   11563             mStackSupervisor.comeOutOfSleepIfNeededLocked();
   11564             updateOomAdjLocked();
   11565         } else if (!mSleeping && shouldSleepLocked()) {
   11566             mSleeping = true;
   11567             if (mCurAppTimeTracker != null) {
   11568                 mCurAppTimeTracker.stop();
   11569             }
   11570             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
   11571             mStackSupervisor.goingToSleepLocked();
   11572             updateOomAdjLocked();
   11573 
   11574             // Initialize the wake times of all processes.
   11575             checkExcessivePowerUsageLocked(false);
   11576             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   11577             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   11578             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   11579         }
   11580     }
   11581 
   11582     private boolean shouldSleepLocked() {
   11583         // Resume applications while running a voice interactor.
   11584         if (mRunningVoice != null) {
   11585             return false;
   11586         }
   11587 
   11588         // TODO: Transform the lock screen state into a sleep token instead.
   11589         switch (mWakefulness) {
   11590             case PowerManagerInternal.WAKEFULNESS_AWAKE:
   11591             case PowerManagerInternal.WAKEFULNESS_DREAMING:
   11592             case PowerManagerInternal.WAKEFULNESS_DOZING:
   11593                 // Pause applications whenever the lock screen is shown or any sleep
   11594                 // tokens have been acquired.
   11595                 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
   11596             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
   11597             default:
   11598                 // If we're asleep then pause applications unconditionally.
   11599                 return true;
   11600         }
   11601     }
   11602 
   11603     /** Pokes the task persister. */
   11604     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
   11605         mRecentTasks.notifyTaskPersisterLocked(task, flush);
   11606     }
   11607 
   11608     /** Notifies all listeners when the task stack has changed. */
   11609     void notifyTaskStackChangedLocked() {
   11610         mHandler.sendEmptyMessage(LOG_STACK_STATE);
   11611         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
   11612         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
   11613         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
   11614     }
   11615 
   11616     /** Notifies all listeners when an Activity is pinned. */
   11617     void notifyActivityPinnedLocked() {
   11618         mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
   11619         mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
   11620     }
   11621 
   11622     /**
   11623      * Notifies all listeners when an attempt was made to start an an activity that is already
   11624      * running in the pinned stack and the activity was not actually started, but the task is
   11625      * either brought to the front or a new Intent is delivered to it.
   11626      */
   11627     void notifyPinnedActivityRestartAttemptLocked() {
   11628         mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
   11629         mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
   11630     }
   11631 
   11632     /** Notifies all listeners when the pinned stack animation ends. */
   11633     @Override
   11634     public void notifyPinnedStackAnimationEnded() {
   11635         synchronized (this) {
   11636             mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
   11637             mHandler.obtainMessage(
   11638                     NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
   11639         }
   11640     }
   11641 
   11642     @Override
   11643     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
   11644         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
   11645     }
   11646 
   11647     @Override
   11648     public boolean shutdown(int timeout) {
   11649         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
   11650                 != PackageManager.PERMISSION_GRANTED) {
   11651             throw new SecurityException("Requires permission "
   11652                     + android.Manifest.permission.SHUTDOWN);
   11653         }
   11654 
   11655         boolean timedout = false;
   11656 
   11657         synchronized(this) {
   11658             mShuttingDown = true;
   11659             updateEventDispatchingLocked();
   11660             timedout = mStackSupervisor.shutdownLocked(timeout);
   11661         }
   11662 
   11663         mAppOpsService.shutdown();
   11664         if (mUsageStatsService != null) {
   11665             mUsageStatsService.prepareShutdown();
   11666         }
   11667         mBatteryStatsService.shutdown();
   11668         synchronized (this) {
   11669             mProcessStats.shutdownLocked();
   11670             notifyTaskPersisterLocked(null, true);
   11671         }
   11672 
   11673         return timedout;
   11674     }
   11675 
   11676     public final void activitySlept(IBinder token) {
   11677         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
   11678 
   11679         final long origId = Binder.clearCallingIdentity();
   11680 
   11681         synchronized (this) {
   11682             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   11683             if (r != null) {
   11684                 mStackSupervisor.activitySleptLocked(r);
   11685             }
   11686         }
   11687 
   11688         Binder.restoreCallingIdentity(origId);
   11689     }
   11690 
   11691     private String lockScreenShownToString() {
   11692         switch (mLockScreenShown) {
   11693             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
   11694             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
   11695             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
   11696             default: return "Unknown=" + mLockScreenShown;
   11697         }
   11698     }
   11699 
   11700     void logLockScreen(String msg) {
   11701         if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
   11702                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
   11703                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
   11704                 + " mSleeping=" + mSleeping);
   11705     }
   11706 
   11707     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
   11708         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
   11709         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
   11710         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
   11711             boolean wasRunningVoice = mRunningVoice != null;
   11712             mRunningVoice = session;
   11713             if (!wasRunningVoice) {
   11714                 mVoiceWakeLock.acquire();
   11715                 updateSleepIfNeededLocked();
   11716             }
   11717         }
   11718     }
   11719 
   11720     private void updateEventDispatchingLocked() {
   11721         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
   11722     }
   11723 
   11724     public void setLockScreenShown(boolean showing, boolean occluded) {
   11725         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   11726                 != PackageManager.PERMISSION_GRANTED) {
   11727             throw new SecurityException("Requires permission "
   11728                     + android.Manifest.permission.DEVICE_POWER);
   11729         }
   11730 
   11731         synchronized(this) {
   11732             long ident = Binder.clearCallingIdentity();
   11733             try {
   11734                 if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
   11735                 mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
   11736                 if (showing && occluded) {
   11737                     // The lock screen is currently showing, but is occluded by a window that can
   11738                     // show on top of the lock screen. In this can we want to dismiss the docked
   11739                     // stack since it will be complicated/risky to try to put the activity on top
   11740                     // of the lock screen in the right fullscreen configuration.
   11741                     mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
   11742                             mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
   11743                 }
   11744 
   11745                 updateSleepIfNeededLocked();
   11746             } finally {
   11747                 Binder.restoreCallingIdentity(ident);
   11748             }
   11749         }
   11750     }
   11751 
   11752     @Override
   11753     public void notifyLockedProfile(@UserIdInt int userId) {
   11754         try {
   11755             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
   11756                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
   11757             }
   11758         } catch (RemoteException ex) {
   11759             throw new SecurityException("Fail to check is caller a privileged app", ex);
   11760         }
   11761 
   11762         synchronized (this) {
   11763             if (mStackSupervisor.isUserLockedProfile(userId)) {
   11764                 final long ident = Binder.clearCallingIdentity();
   11765                 try {
   11766                     final int currentUserId = mUserController.getCurrentUserIdLocked();
   11767                     if (mUserController.isLockScreenDisabled(currentUserId)) {
   11768                         // If there is no device lock, we will show the profile's credential page.
   11769                         mActivityStarter.showConfirmDeviceCredential(userId);
   11770                     } else {
   11771                         // Showing launcher to avoid user entering credential twice.
   11772                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
   11773                     }
   11774                 } finally {
   11775                     Binder.restoreCallingIdentity(ident);
   11776                 }
   11777             }
   11778         }
   11779     }
   11780 
   11781     @Override
   11782     public void startConfirmDeviceCredentialIntent(Intent intent) {
   11783         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
   11784         synchronized (this) {
   11785             final long ident = Binder.clearCallingIdentity();
   11786             try {
   11787                 mActivityStarter.startConfirmCredentialIntent(intent);
   11788             } finally {
   11789                 Binder.restoreCallingIdentity(ident);
   11790             }
   11791         }
   11792     }
   11793 
   11794     @Override
   11795     public void stopAppSwitches() {
   11796         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   11797                 != PackageManager.PERMISSION_GRANTED) {
   11798             throw new SecurityException("viewquires permission "
   11799                     + android.Manifest.permission.STOP_APP_SWITCHES);
   11800         }
   11801 
   11802         synchronized(this) {
   11803             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
   11804                     + APP_SWITCH_DELAY_TIME;
   11805             mDidAppSwitch = false;
   11806             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   11807             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   11808             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
   11809         }
   11810     }
   11811 
   11812     public void resumeAppSwitches() {
   11813         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   11814                 != PackageManager.PERMISSION_GRANTED) {
   11815             throw new SecurityException("Requires permission "
   11816                     + android.Manifest.permission.STOP_APP_SWITCHES);
   11817         }
   11818 
   11819         synchronized(this) {
   11820             // Note that we don't execute any pending app switches... we will
   11821             // let those wait until either the timeout, or the next start
   11822             // activity request.
   11823             mAppSwitchesAllowedTime = 0;
   11824         }
   11825     }
   11826 
   11827     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
   11828             int callingPid, int callingUid, String name) {
   11829         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
   11830             return true;
   11831         }
   11832 
   11833         int perm = checkComponentPermission(
   11834                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
   11835                 sourceUid, -1, true);
   11836         if (perm == PackageManager.PERMISSION_GRANTED) {
   11837             return true;
   11838         }
   11839 
   11840         // If the actual IPC caller is different from the logical source, then
   11841         // also see if they are allowed to control app switches.
   11842         if (callingUid != -1 && callingUid != sourceUid) {
   11843             perm = checkComponentPermission(
   11844                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
   11845                     callingUid, -1, true);
   11846             if (perm == PackageManager.PERMISSION_GRANTED) {
   11847                 return true;
   11848             }
   11849         }
   11850 
   11851         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
   11852         return false;
   11853     }
   11854 
   11855     public void setDebugApp(String packageName, boolean waitForDebugger,
   11856             boolean persistent) {
   11857         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   11858                 "setDebugApp()");
   11859 
   11860         long ident = Binder.clearCallingIdentity();
   11861         try {
   11862             // Note that this is not really thread safe if there are multiple
   11863             // callers into it at the same time, but that's not a situation we
   11864             // care about.
   11865             if (persistent) {
   11866                 final ContentResolver resolver = mContext.getContentResolver();
   11867                 Settings.Global.putString(
   11868                     resolver, Settings.Global.DEBUG_APP,
   11869                     packageName);
   11870                 Settings.Global.putInt(
   11871                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
   11872                     waitForDebugger ? 1 : 0);
   11873             }
   11874 
   11875             synchronized (this) {
   11876                 if (!persistent) {
   11877                     mOrigDebugApp = mDebugApp;
   11878                     mOrigWaitForDebugger = mWaitForDebugger;
   11879                 }
   11880                 mDebugApp = packageName;
   11881                 mWaitForDebugger = waitForDebugger;
   11882                 mDebugTransient = !persistent;
   11883                 if (packageName != null) {
   11884                     forceStopPackageLocked(packageName, -1, false, false, true, true,
   11885                             false, UserHandle.USER_ALL, "set debug app");
   11886                 }
   11887             }
   11888         } finally {
   11889             Binder.restoreCallingIdentity(ident);
   11890         }
   11891     }
   11892 
   11893     void setTrackAllocationApp(ApplicationInfo app, String processName) {
   11894         synchronized (this) {
   11895             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   11896             if (!isDebuggable) {
   11897                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   11898                     throw new SecurityException("Process not debuggable: " + app.packageName);
   11899                 }
   11900             }
   11901 
   11902             mTrackAllocationApp = processName;
   11903         }
   11904     }
   11905 
   11906     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
   11907         synchronized (this) {
   11908             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   11909             if (!isDebuggable) {
   11910                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   11911                     throw new SecurityException("Process not debuggable: " + app.packageName);
   11912                 }
   11913             }
   11914             mProfileApp = processName;
   11915             mProfileFile = profilerInfo.profileFile;
   11916             if (mProfileFd != null) {
   11917                 try {
   11918                     mProfileFd.close();
   11919                 } catch (IOException e) {
   11920                 }
   11921                 mProfileFd = null;
   11922             }
   11923             mProfileFd = profilerInfo.profileFd;
   11924             mSamplingInterval = profilerInfo.samplingInterval;
   11925             mAutoStopProfiler = profilerInfo.autoStopProfiler;
   11926             mProfileType = 0;
   11927         }
   11928     }
   11929 
   11930     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
   11931         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   11932         if (!isDebuggable) {
   11933             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   11934                 throw new SecurityException("Process not debuggable: " + app.packageName);
   11935             }
   11936         }
   11937         mNativeDebuggingApp = processName;
   11938     }
   11939 
   11940     @Override
   11941     public void setAlwaysFinish(boolean enabled) {
   11942         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
   11943                 "setAlwaysFinish()");
   11944 
   11945         long ident = Binder.clearCallingIdentity();
   11946         try {
   11947             Settings.Global.putInt(
   11948                     mContext.getContentResolver(),
   11949                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
   11950 
   11951             synchronized (this) {
   11952                 mAlwaysFinishActivities = enabled;
   11953             }
   11954         } finally {
   11955             Binder.restoreCallingIdentity(ident);
   11956         }
   11957     }
   11958 
   11959     @Override
   11960     public void setLenientBackgroundCheck(boolean enabled) {
   11961         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   11962                 "setLenientBackgroundCheck()");
   11963 
   11964         long ident = Binder.clearCallingIdentity();
   11965         try {
   11966             Settings.Global.putInt(
   11967                     mContext.getContentResolver(),
   11968                     Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
   11969 
   11970             synchronized (this) {
   11971                 mLenientBackgroundCheck = enabled;
   11972             }
   11973         } finally {
   11974             Binder.restoreCallingIdentity(ident);
   11975         }
   11976     }
   11977 
   11978     @Override
   11979     public void setActivityController(IActivityController controller, boolean imAMonkey) {
   11980         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   11981                 "setActivityController()");
   11982         synchronized (this) {
   11983             mController = controller;
   11984             mControllerIsAMonkey = imAMonkey;
   11985             Watchdog.getInstance().setActivityController(controller);
   11986         }
   11987     }
   11988 
   11989     @Override
   11990     public void setUserIsMonkey(boolean userIsMonkey) {
   11991         synchronized (this) {
   11992             synchronized (mPidsSelfLocked) {
   11993                 final int callingPid = Binder.getCallingPid();
   11994                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
   11995                 if (precessRecord == null) {
   11996                     throw new SecurityException("Unknown process: " + callingPid);
   11997                 }
   11998                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
   11999                     throw new SecurityException("Only an instrumentation process "
   12000                             + "with a UiAutomation can call setUserIsMonkey");
   12001                 }
   12002             }
   12003             mUserIsMonkey = userIsMonkey;
   12004         }
   12005     }
   12006 
   12007     @Override
   12008     public boolean isUserAMonkey() {
   12009         synchronized (this) {
   12010             // If there is a controller also implies the user is a monkey.
   12011             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
   12012         }
   12013     }
   12014 
   12015     public void requestBugReport(int bugreportType) {
   12016         String service = null;
   12017         switch (bugreportType) {
   12018             case ActivityManager.BUGREPORT_OPTION_FULL:
   12019                 service = "bugreport";
   12020                 break;
   12021             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
   12022                 service = "bugreportplus";
   12023                 break;
   12024             case ActivityManager.BUGREPORT_OPTION_REMOTE:
   12025                 service = "bugreportremote";
   12026                 break;
   12027         }
   12028         if (service == null) {
   12029             throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
   12030                     + bugreportType);
   12031         }
   12032         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
   12033         SystemProperties.set("ctl.start", service);
   12034     }
   12035 
   12036     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
   12037         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
   12038     }
   12039 
   12040     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
   12041         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
   12042             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
   12043         }
   12044         return KEY_DISPATCHING_TIMEOUT;
   12045     }
   12046 
   12047     @Override
   12048     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
   12049         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   12050                 != PackageManager.PERMISSION_GRANTED) {
   12051             throw new SecurityException("Requires permission "
   12052                     + android.Manifest.permission.FILTER_EVENTS);
   12053         }
   12054         ProcessRecord proc;
   12055         long timeout;
   12056         synchronized (this) {
   12057             synchronized (mPidsSelfLocked) {
   12058                 proc = mPidsSelfLocked.get(pid);
   12059             }
   12060             timeout = getInputDispatchingTimeoutLocked(proc);
   12061         }
   12062 
   12063         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
   12064             return -1;
   12065         }
   12066 
   12067         return timeout;
   12068     }
   12069 
   12070     /**
   12071      * Handle input dispatching timeouts.
   12072      * Returns whether input dispatching should be aborted or not.
   12073      */
   12074     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
   12075             final ActivityRecord activity, final ActivityRecord parent,
   12076             final boolean aboveSystem, String reason) {
   12077         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   12078                 != PackageManager.PERMISSION_GRANTED) {
   12079             throw new SecurityException("Requires permission "
   12080                     + android.Manifest.permission.FILTER_EVENTS);
   12081         }
   12082 
   12083         final String annotation;
   12084         if (reason == null) {
   12085             annotation = "Input dispatching timed out";
   12086         } else {
   12087             annotation = "Input dispatching timed out (" + reason + ")";
   12088         }
   12089 
   12090         if (proc != null) {
   12091             synchronized (this) {
   12092                 if (proc.debugging) {
   12093                     return false;
   12094                 }
   12095 
   12096                 if (mDidDexOpt) {
   12097                     // Give more time since we were dexopting.
   12098                     mDidDexOpt = false;
   12099                     return false;
   12100                 }
   12101 
   12102                 if (proc.instrumentationClass != null) {
   12103                     Bundle info = new Bundle();
   12104                     info.putString("shortMsg", "keyDispatchingTimedOut");
   12105                     info.putString("longMsg", annotation);
   12106                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
   12107                     return true;
   12108                 }
   12109             }
   12110             mHandler.post(new Runnable() {
   12111                 @Override
   12112                 public void run() {
   12113                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
   12114                 }
   12115             });
   12116         }
   12117 
   12118         return true;
   12119     }
   12120 
   12121     @Override
   12122     public Bundle getAssistContextExtras(int requestType) {
   12123         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
   12124                 null, null, true /* focused */, true /* newSessionId */,
   12125                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
   12126         if (pae == null) {
   12127             return null;
   12128         }
   12129         synchronized (pae) {
   12130             while (!pae.haveResult) {
   12131                 try {
   12132                     pae.wait();
   12133                 } catch (InterruptedException e) {
   12134                 }
   12135             }
   12136         }
   12137         synchronized (this) {
   12138             buildAssistBundleLocked(pae, pae.result);
   12139             mPendingAssistExtras.remove(pae);
   12140             mUiHandler.removeCallbacks(pae);
   12141         }
   12142         return pae.extras;
   12143     }
   12144 
   12145     @Override
   12146     public boolean isAssistDataAllowedOnCurrentActivity() {
   12147         int userId;
   12148         synchronized (this) {
   12149             userId = mUserController.getCurrentUserIdLocked();
   12150             ActivityRecord activity = getFocusedStack().topActivity();
   12151             if (activity == null) {
   12152                 return false;
   12153             }
   12154             userId = activity.userId;
   12155         }
   12156         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
   12157                 Context.DEVICE_POLICY_SERVICE);
   12158         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
   12159     }
   12160 
   12161     @Override
   12162     public boolean showAssistFromActivity(IBinder token, Bundle args) {
   12163         long ident = Binder.clearCallingIdentity();
   12164         try {
   12165             synchronized (this) {
   12166                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
   12167                 ActivityRecord top = getFocusedStack().topActivity();
   12168                 if (top != caller) {
   12169                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
   12170                             + " is not current top " + top);
   12171                     return false;
   12172                 }
   12173                 if (!top.nowVisible) {
   12174                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
   12175                             + " is not visible");
   12176                     return false;
   12177                 }
   12178             }
   12179             AssistUtils utils = new AssistUtils(mContext);
   12180             return utils.showSessionForActiveService(args,
   12181                     VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
   12182         } finally {
   12183             Binder.restoreCallingIdentity(ident);
   12184         }
   12185     }
   12186 
   12187     @Override
   12188     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
   12189             Bundle receiverExtras,
   12190             IBinder activityToken, boolean focused, boolean newSessionId) {
   12191         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
   12192                 activityToken, focused, newSessionId,
   12193                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
   12194                 != null;
   12195     }
   12196 
   12197     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
   12198             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
   12199             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
   12200         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
   12201                 "enqueueAssistContext()");
   12202         synchronized (this) {
   12203             ActivityRecord activity = getFocusedStack().topActivity();
   12204             if (activity == null) {
   12205                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
   12206                 return null;
   12207             }
   12208             if (activity.app == null || activity.app.thread == null) {
   12209                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
   12210                 return null;
   12211             }
   12212             if (focused) {
   12213                 if (activityToken != null) {
   12214                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
   12215                     if (activity != caller) {
   12216                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
   12217                                 + " is not current top " + activity);
   12218                         return null;
   12219                     }
   12220                 }
   12221             } else {
   12222                 activity = ActivityRecord.forTokenLocked(activityToken);
   12223                 if (activity == null) {
   12224                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
   12225                             + " couldn't be found");
   12226                     return null;
   12227                 }
   12228             }
   12229 
   12230             PendingAssistExtras pae;
   12231             Bundle extras = new Bundle();
   12232             if (args != null) {
   12233                 extras.putAll(args);
   12234             }
   12235             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
   12236             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
   12237             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
   12238                     userHandle);
   12239             // Increment the sessionId if necessary
   12240             if (newSessionId) {
   12241                 mViSessionId++;
   12242             }
   12243             try {
   12244                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
   12245                         requestType, mViSessionId);
   12246                 mPendingAssistExtras.add(pae);
   12247                 mUiHandler.postDelayed(pae, timeout);
   12248             } catch (RemoteException e) {
   12249                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
   12250                 return null;
   12251             }
   12252             return pae;
   12253         }
   12254     }
   12255 
   12256     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
   12257         IResultReceiver receiver;
   12258         synchronized (this) {
   12259             mPendingAssistExtras.remove(pae);
   12260             receiver = pae.receiver;
   12261         }
   12262         if (receiver != null) {
   12263             // Caller wants result sent back to them.
   12264             Bundle sendBundle = new Bundle();
   12265             // At least return the receiver extras
   12266             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
   12267                     pae.receiverExtras);
   12268             try {
   12269                 pae.receiver.send(0, sendBundle);
   12270             } catch (RemoteException e) {
   12271             }
   12272         }
   12273     }
   12274 
   12275     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
   12276         if (result != null) {
   12277             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
   12278         }
   12279         if (pae.hint != null) {
   12280             pae.extras.putBoolean(pae.hint, true);
   12281         }
   12282     }
   12283 
   12284     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
   12285             AssistContent content, Uri referrer) {
   12286         PendingAssistExtras pae = (PendingAssistExtras)token;
   12287         synchronized (pae) {
   12288             pae.result = extras;
   12289             pae.structure = structure;
   12290             pae.content = content;
   12291             if (referrer != null) {
   12292                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
   12293             }
   12294             pae.haveResult = true;
   12295             pae.notifyAll();
   12296             if (pae.intent == null && pae.receiver == null) {
   12297                 // Caller is just waiting for the result.
   12298                 return;
   12299             }
   12300         }
   12301 
   12302         // We are now ready to launch the assist activity.
   12303         IResultReceiver sendReceiver = null;
   12304         Bundle sendBundle = null;
   12305         synchronized (this) {
   12306             buildAssistBundleLocked(pae, extras);
   12307             boolean exists = mPendingAssistExtras.remove(pae);
   12308             mUiHandler.removeCallbacks(pae);
   12309             if (!exists) {
   12310                 // Timed out.
   12311                 return;
   12312             }
   12313             if ((sendReceiver=pae.receiver) != null) {
   12314                 // Caller wants result sent back to them.
   12315                 sendBundle = new Bundle();
   12316                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
   12317                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
   12318                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
   12319                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
   12320                         pae.receiverExtras);
   12321             }
   12322         }
   12323         if (sendReceiver != null) {
   12324             try {
   12325                 sendReceiver.send(0, sendBundle);
   12326             } catch (RemoteException e) {
   12327             }
   12328             return;
   12329         }
   12330 
   12331         long ident = Binder.clearCallingIdentity();
   12332         try {
   12333             pae.intent.replaceExtras(pae.extras);
   12334             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
   12335                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
   12336                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
   12337             closeSystemDialogs("assist");
   12338             try {
   12339                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
   12340             } catch (ActivityNotFoundException e) {
   12341                 Slog.w(TAG, "No activity to handle assist action.", e);
   12342             }
   12343         } finally {
   12344             Binder.restoreCallingIdentity(ident);
   12345         }
   12346     }
   12347 
   12348     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
   12349             Bundle args) {
   12350         return enqueueAssistContext(requestType, intent, hint, null, null, null,
   12351                 true /* focused */, true /* newSessionId */,
   12352                 userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
   12353     }
   12354 
   12355     public void registerProcessObserver(IProcessObserver observer) {
   12356         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   12357                 "registerProcessObserver()");
   12358         synchronized (this) {
   12359             mProcessObservers.register(observer);
   12360         }
   12361     }
   12362 
   12363     @Override
   12364     public void unregisterProcessObserver(IProcessObserver observer) {
   12365         synchronized (this) {
   12366             mProcessObservers.unregister(observer);
   12367         }
   12368     }
   12369 
   12370     @Override
   12371     public void registerUidObserver(IUidObserver observer, int which) {
   12372         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   12373                 "registerUidObserver()");
   12374         synchronized (this) {
   12375             mUidObservers.register(observer, which);
   12376         }
   12377     }
   12378 
   12379     @Override
   12380     public void unregisterUidObserver(IUidObserver observer) {
   12381         synchronized (this) {
   12382             mUidObservers.unregister(observer);
   12383         }
   12384     }
   12385 
   12386     @Override
   12387     public boolean convertFromTranslucent(IBinder token) {
   12388         final long origId = Binder.clearCallingIdentity();
   12389         try {
   12390             synchronized (this) {
   12391                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12392                 if (r == null) {
   12393                     return false;
   12394                 }
   12395                 final boolean translucentChanged = r.changeWindowTranslucency(true);
   12396                 if (translucentChanged) {
   12397                     r.task.stack.releaseBackgroundResources(r);
   12398                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   12399                 }
   12400                 mWindowManager.setAppFullscreen(token, true);
   12401                 return translucentChanged;
   12402             }
   12403         } finally {
   12404             Binder.restoreCallingIdentity(origId);
   12405         }
   12406     }
   12407 
   12408     @Override
   12409     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
   12410         final long origId = Binder.clearCallingIdentity();
   12411         try {
   12412             synchronized (this) {
   12413                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12414                 if (r == null) {
   12415                     return false;
   12416                 }
   12417                 int index = r.task.mActivities.lastIndexOf(r);
   12418                 if (index > 0) {
   12419                     ActivityRecord under = r.task.mActivities.get(index - 1);
   12420                     under.returningOptions = options;
   12421                 }
   12422                 final boolean translucentChanged = r.changeWindowTranslucency(false);
   12423                 if (translucentChanged) {
   12424                     r.task.stack.convertActivityToTranslucent(r);
   12425                 }
   12426                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   12427                 mWindowManager.setAppFullscreen(token, false);
   12428                 return translucentChanged;
   12429             }
   12430         } finally {
   12431             Binder.restoreCallingIdentity(origId);
   12432         }
   12433     }
   12434 
   12435     @Override
   12436     public boolean requestVisibleBehind(IBinder token, boolean visible) {
   12437         final long origId = Binder.clearCallingIdentity();
   12438         try {
   12439             synchronized (this) {
   12440                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12441                 if (r != null) {
   12442                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
   12443                 }
   12444             }
   12445             return false;
   12446         } finally {
   12447             Binder.restoreCallingIdentity(origId);
   12448         }
   12449     }
   12450 
   12451     @Override
   12452     public boolean isBackgroundVisibleBehind(IBinder token) {
   12453         final long origId = Binder.clearCallingIdentity();
   12454         try {
   12455             synchronized (this) {
   12456                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
   12457                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
   12458                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
   12459                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
   12460                 return visible;
   12461             }
   12462         } finally {
   12463             Binder.restoreCallingIdentity(origId);
   12464         }
   12465     }
   12466 
   12467     @Override
   12468     public ActivityOptions getActivityOptions(IBinder token) {
   12469         final long origId = Binder.clearCallingIdentity();
   12470         try {
   12471             synchronized (this) {
   12472                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12473                 if (r != null) {
   12474                     final ActivityOptions activityOptions = r.pendingOptions;
   12475                     r.pendingOptions = null;
   12476                     return activityOptions;
   12477                 }
   12478                 return null;
   12479             }
   12480         } finally {
   12481             Binder.restoreCallingIdentity(origId);
   12482         }
   12483     }
   12484 
   12485     @Override
   12486     public void setImmersive(IBinder token, boolean immersive) {
   12487         synchronized(this) {
   12488             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12489             if (r == null) {
   12490                 throw new IllegalArgumentException();
   12491             }
   12492             r.immersive = immersive;
   12493 
   12494             // update associated state if we're frontmost
   12495             if (r == mFocusedActivity) {
   12496                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
   12497                 applyUpdateLockStateLocked(r);
   12498             }
   12499         }
   12500     }
   12501 
   12502     @Override
   12503     public boolean isImmersive(IBinder token) {
   12504         synchronized (this) {
   12505             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12506             if (r == null) {
   12507                 throw new IllegalArgumentException();
   12508             }
   12509             return r.immersive;
   12510         }
   12511     }
   12512 
   12513     @Override
   12514     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
   12515         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
   12516             throw new UnsupportedOperationException("VR mode not supported on this device!");
   12517         }
   12518 
   12519         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
   12520 
   12521         ActivityRecord r;
   12522         synchronized (this) {
   12523             r = ActivityRecord.isInStackLocked(token);
   12524         }
   12525 
   12526         if (r == null) {
   12527             throw new IllegalArgumentException();
   12528         }
   12529 
   12530         int err;
   12531         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
   12532                 VrManagerInternal.NO_ERROR) {
   12533             return err;
   12534         }
   12535 
   12536         synchronized(this) {
   12537             r.requestedVrComponent = (enabled) ? packageName : null;
   12538 
   12539             // Update associated state if this activity is currently focused
   12540             if (r == mFocusedActivity) {
   12541                 applyUpdateVrModeLocked(r);
   12542             }
   12543             return 0;
   12544         }
   12545     }
   12546 
   12547     @Override
   12548     public boolean isVrModePackageEnabled(ComponentName packageName) {
   12549         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
   12550             throw new UnsupportedOperationException("VR mode not supported on this device!");
   12551         }
   12552 
   12553         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
   12554 
   12555         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
   12556                 VrManagerInternal.NO_ERROR;
   12557     }
   12558 
   12559     public boolean isTopActivityImmersive() {
   12560         enforceNotIsolatedCaller("startActivity");
   12561         synchronized (this) {
   12562             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
   12563             return (r != null) ? r.immersive : false;
   12564         }
   12565     }
   12566 
   12567     @Override
   12568     public boolean isTopOfTask(IBinder token) {
   12569         synchronized (this) {
   12570             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12571             if (r == null) {
   12572                 throw new IllegalArgumentException();
   12573             }
   12574             return r.task.getTopActivity() == r;
   12575         }
   12576     }
   12577 
   12578     public final void enterSafeMode() {
   12579         synchronized(this) {
   12580             // It only makes sense to do this before the system is ready
   12581             // and started launching other packages.
   12582             if (!mSystemReady) {
   12583                 try {
   12584                     AppGlobals.getPackageManager().enterSafeMode();
   12585                 } catch (RemoteException e) {
   12586                 }
   12587             }
   12588 
   12589             mSafeMode = true;
   12590         }
   12591     }
   12592 
   12593     public final void showSafeModeOverlay() {
   12594         View v = LayoutInflater.from(mContext).inflate(
   12595                 com.android.internal.R.layout.safe_mode, null);
   12596         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
   12597         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
   12598         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
   12599         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
   12600         lp.gravity = Gravity.BOTTOM | Gravity.START;
   12601         lp.format = v.getBackground().getOpacity();
   12602         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
   12603                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
   12604         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
   12605         ((WindowManager)mContext.getSystemService(
   12606                 Context.WINDOW_SERVICE)).addView(v, lp);
   12607     }
   12608 
   12609     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
   12610         if (sender != null && !(sender instanceof PendingIntentRecord)) {
   12611             return;
   12612         }
   12613         final PendingIntentRecord rec = (PendingIntentRecord)sender;
   12614         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   12615         synchronized (stats) {
   12616             if (mBatteryStatsService.isOnBattery()) {
   12617                 mBatteryStatsService.enforceCallingPermission();
   12618                 int MY_UID = Binder.getCallingUid();
   12619                 final int uid;
   12620                 if (sender == null) {
   12621                     uid = sourceUid;
   12622                 } else {
   12623                     uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   12624                 }
   12625                 BatteryStatsImpl.Uid.Pkg pkg =
   12626                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
   12627                             sourcePkg != null ? sourcePkg : rec.key.packageName);
   12628                 pkg.noteWakeupAlarmLocked(tag);
   12629             }
   12630         }
   12631     }
   12632 
   12633     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
   12634         if (sender != null && !(sender instanceof PendingIntentRecord)) {
   12635             return;
   12636         }
   12637         final PendingIntentRecord rec = (PendingIntentRecord)sender;
   12638         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   12639         synchronized (stats) {
   12640             mBatteryStatsService.enforceCallingPermission();
   12641             int MY_UID = Binder.getCallingUid();
   12642             final int uid;
   12643             if (sender == null) {
   12644                 uid = sourceUid;
   12645             } else {
   12646                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   12647             }
   12648             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
   12649         }
   12650     }
   12651 
   12652     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
   12653         if (sender != null && !(sender instanceof PendingIntentRecord)) {
   12654             return;
   12655         }
   12656         final PendingIntentRecord rec = (PendingIntentRecord)sender;
   12657         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   12658         synchronized (stats) {
   12659             mBatteryStatsService.enforceCallingPermission();
   12660             int MY_UID = Binder.getCallingUid();
   12661             final int uid;
   12662             if (sender == null) {
   12663                 uid = sourceUid;
   12664             } else {
   12665                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   12666             }
   12667             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
   12668         }
   12669     }
   12670 
   12671     public boolean killPids(int[] pids, String pReason, boolean secure) {
   12672         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   12673             throw new SecurityException("killPids only available to the system");
   12674         }
   12675         String reason = (pReason == null) ? "Unknown" : pReason;
   12676         // XXX Note: don't acquire main activity lock here, because the window
   12677         // manager calls in with its locks held.
   12678 
   12679         boolean killed = false;
   12680         synchronized (mPidsSelfLocked) {
   12681             int worstType = 0;
   12682             for (int i=0; i<pids.length; i++) {
   12683                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   12684                 if (proc != null) {
   12685                     int type = proc.setAdj;
   12686                     if (type > worstType) {
   12687                         worstType = type;
   12688                     }
   12689                 }
   12690             }
   12691 
   12692             // If the worst oom_adj is somewhere in the cached proc LRU range,
   12693             // then constrain it so we will kill all cached procs.
   12694             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
   12695                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
   12696                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
   12697             }
   12698 
   12699             // If this is not a secure call, don't let it kill processes that
   12700             // are important.
   12701             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
   12702                 worstType = ProcessList.SERVICE_ADJ;
   12703             }
   12704 
   12705             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
   12706             for (int i=0; i<pids.length; i++) {
   12707                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   12708                 if (proc == null) {
   12709                     continue;
   12710                 }
   12711                 int adj = proc.setAdj;
   12712                 if (adj >= worstType && !proc.killedByAm) {
   12713                     proc.kill(reason, true);
   12714                     killed = true;
   12715                 }
   12716             }
   12717         }
   12718         return killed;
   12719     }
   12720 
   12721     @Override
   12722     public void killUid(int appId, int userId, String reason) {
   12723         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
   12724         synchronized (this) {
   12725             final long identity = Binder.clearCallingIdentity();
   12726             try {
   12727                 killPackageProcessesLocked(null, appId, userId,
   12728                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
   12729                         reason != null ? reason : "kill uid");
   12730             } finally {
   12731                 Binder.restoreCallingIdentity(identity);
   12732             }
   12733         }
   12734     }
   12735 
   12736     @Override
   12737     public boolean killProcessesBelowForeground(String reason) {
   12738         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   12739             throw new SecurityException("killProcessesBelowForeground() only available to system");
   12740         }
   12741 
   12742         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
   12743     }
   12744 
   12745     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
   12746         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   12747             throw new SecurityException("killProcessesBelowAdj() only available to system");
   12748         }
   12749 
   12750         boolean killed = false;
   12751         synchronized (mPidsSelfLocked) {
   12752             final int size = mPidsSelfLocked.size();
   12753             for (int i = 0; i < size; i++) {
   12754                 final int pid = mPidsSelfLocked.keyAt(i);
   12755                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   12756                 if (proc == null) continue;
   12757 
   12758                 final int adj = proc.setAdj;
   12759                 if (adj > belowAdj && !proc.killedByAm) {
   12760                     proc.kill(reason, true);
   12761                     killed = true;
   12762                 }
   12763             }
   12764         }
   12765         return killed;
   12766     }
   12767 
   12768     @Override
   12769     public void hang(final IBinder who, boolean allowRestart) {
   12770         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   12771                 != PackageManager.PERMISSION_GRANTED) {
   12772             throw new SecurityException("Requires permission "
   12773                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   12774         }
   12775 
   12776         final IBinder.DeathRecipient death = new DeathRecipient() {
   12777             @Override
   12778             public void binderDied() {
   12779                 synchronized (this) {
   12780                     notifyAll();
   12781                 }
   12782             }
   12783         };
   12784 
   12785         try {
   12786             who.linkToDeath(death, 0);
   12787         } catch (RemoteException e) {
   12788             Slog.w(TAG, "hang: given caller IBinder is already dead.");
   12789             return;
   12790         }
   12791 
   12792         synchronized (this) {
   12793             Watchdog.getInstance().setAllowRestart(allowRestart);
   12794             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
   12795             synchronized (death) {
   12796                 while (who.isBinderAlive()) {
   12797                     try {
   12798                         death.wait();
   12799                     } catch (InterruptedException e) {
   12800                     }
   12801                 }
   12802             }
   12803             Watchdog.getInstance().setAllowRestart(true);
   12804         }
   12805     }
   12806 
   12807     @Override
   12808     public void restart() {
   12809         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   12810                 != PackageManager.PERMISSION_GRANTED) {
   12811             throw new SecurityException("Requires permission "
   12812                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   12813         }
   12814 
   12815         Log.i(TAG, "Sending shutdown broadcast...");
   12816 
   12817         BroadcastReceiver br = new BroadcastReceiver() {
   12818             @Override public void onReceive(Context context, Intent intent) {
   12819                 // Now the broadcast is done, finish up the low-level shutdown.
   12820                 Log.i(TAG, "Shutting down activity manager...");
   12821                 shutdown(10000);
   12822                 Log.i(TAG, "Shutdown complete, restarting!");
   12823                 Process.killProcess(Process.myPid());
   12824                 System.exit(10);
   12825             }
   12826         };
   12827 
   12828         // First send the high-level shut down broadcast.
   12829         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
   12830         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   12831         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
   12832         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
   12833         mContext.sendOrderedBroadcastAsUser(intent,
   12834                 UserHandle.ALL, null, br, mHandler, 0, null, null);
   12835         */
   12836         br.onReceive(mContext, intent);
   12837     }
   12838 
   12839     private long getLowRamTimeSinceIdle(long now) {
   12840         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
   12841     }
   12842 
   12843     @Override
   12844     public void performIdleMaintenance() {
   12845         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   12846                 != PackageManager.PERMISSION_GRANTED) {
   12847             throw new SecurityException("Requires permission "
   12848                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   12849         }
   12850 
   12851         synchronized (this) {
   12852             final long now = SystemClock.uptimeMillis();
   12853             final long timeSinceLastIdle = now - mLastIdleTime;
   12854             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
   12855             mLastIdleTime = now;
   12856             mLowRamTimeSinceLastIdle = 0;
   12857             if (mLowRamStartTime != 0) {
   12858                 mLowRamStartTime = now;
   12859             }
   12860 
   12861             StringBuilder sb = new StringBuilder(128);
   12862             sb.append("Idle maintenance over ");
   12863             TimeUtils.formatDuration(timeSinceLastIdle, sb);
   12864             sb.append(" low RAM for ");
   12865             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
   12866             Slog.i(TAG, sb.toString());
   12867 
   12868             // If at least 1/3 of our time since the last idle period has been spent
   12869             // with RAM low, then we want to kill processes.
   12870             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
   12871 
   12872             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   12873                 ProcessRecord proc = mLruProcesses.get(i);
   12874                 if (proc.notCachedSinceIdle) {
   12875                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
   12876                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
   12877                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
   12878                         if (doKilling && proc.initialIdlePss != 0
   12879                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
   12880                             sb = new StringBuilder(128);
   12881                             sb.append("Kill");
   12882                             sb.append(proc.processName);
   12883                             sb.append(" in idle maint: pss=");
   12884                             sb.append(proc.lastPss);
   12885                             sb.append(", swapPss=");
   12886                             sb.append(proc.lastSwapPss);
   12887                             sb.append(", initialPss=");
   12888                             sb.append(proc.initialIdlePss);
   12889                             sb.append(", period=");
   12890                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
   12891                             sb.append(", lowRamPeriod=");
   12892                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
   12893                             Slog.wtfQuiet(TAG, sb.toString());
   12894                             proc.kill("idle maint (pss " + proc.lastPss
   12895                                     + " from " + proc.initialIdlePss + ")", true);
   12896                         }
   12897                     }
   12898                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
   12899                         && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
   12900                     proc.notCachedSinceIdle = true;
   12901                     proc.initialIdlePss = 0;
   12902                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
   12903                             mTestPssMode, isSleepingLocked(), now);
   12904                 }
   12905             }
   12906 
   12907             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
   12908             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
   12909         }
   12910     }
   12911 
   12912     @Override
   12913     public void sendIdleJobTrigger() {
   12914         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   12915                 != PackageManager.PERMISSION_GRANTED) {
   12916             throw new SecurityException("Requires permission "
   12917                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   12918         }
   12919 
   12920         final long ident = Binder.clearCallingIdentity();
   12921         try {
   12922             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
   12923                     .setPackage("android")
   12924                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   12925             broadcastIntent(null, intent, null, null, 0, null, null, null,
   12926                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
   12927         } finally {
   12928             Binder.restoreCallingIdentity(ident);
   12929         }
   12930     }
   12931 
   12932     private void retrieveSettings() {
   12933         final ContentResolver resolver = mContext.getContentResolver();
   12934         final boolean freeformWindowManagement =
   12935                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
   12936                         || Settings.Global.getInt(
   12937                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
   12938         final boolean supportsPictureInPicture =
   12939                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
   12940 
   12941         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
   12942         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
   12943         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
   12944         final boolean alwaysFinishActivities =
   12945                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
   12946         final boolean lenientBackgroundCheck =
   12947                 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
   12948         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
   12949         final boolean forceResizable = Settings.Global.getInt(
   12950                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
   12951         final boolean supportsLeanbackOnly =
   12952                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
   12953 
   12954         // Transfer any global setting for forcing RTL layout, into a System Property
   12955         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
   12956 
   12957         final Configuration configuration = new Configuration();
   12958         Settings.System.getConfiguration(resolver, configuration);
   12959         if (forceRtl) {
   12960             // This will take care of setting the correct layout direction flags
   12961             configuration.setLayoutDirection(configuration.locale);
   12962         }
   12963 
   12964         synchronized (this) {
   12965             mDebugApp = mOrigDebugApp = debugApp;
   12966             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
   12967             mAlwaysFinishActivities = alwaysFinishActivities;
   12968             mLenientBackgroundCheck = lenientBackgroundCheck;
   12969             mSupportsLeanbackOnly = supportsLeanbackOnly;
   12970             mForceResizableActivities = forceResizable;
   12971             mWindowManager.setForceResizableTasks(mForceResizableActivities);
   12972             if (supportsMultiWindow || forceResizable) {
   12973                 mSupportsMultiWindow = true;
   12974                 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
   12975                 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
   12976             } else {
   12977                 mSupportsMultiWindow = false;
   12978                 mSupportsFreeformWindowManagement = false;
   12979                 mSupportsPictureInPicture = false;
   12980             }
   12981             // This happens before any activities are started, so we can
   12982             // change mConfiguration in-place.
   12983             updateConfigurationLocked(configuration, null, true);
   12984             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
   12985                     "Initial config: " + mConfiguration);
   12986 
   12987             // Load resources only after the current configuration has been set.
   12988             final Resources res = mContext.getResources();
   12989             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
   12990             mThumbnailWidth = res.getDimensionPixelSize(
   12991                     com.android.internal.R.dimen.thumbnail_width);
   12992             mThumbnailHeight = res.getDimensionPixelSize(
   12993                     com.android.internal.R.dimen.thumbnail_height);
   12994             mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
   12995                     com.android.internal.R.string.config_defaultPictureInPictureBounds));
   12996             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
   12997                     com.android.internal.R.string.config_appsNotReportingCrashes));
   12998             if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
   12999                 mFullscreenThumbnailScale = (float) res
   13000                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
   13001                     (float) mConfiguration.screenWidthDp;
   13002             } else {
   13003                 mFullscreenThumbnailScale = res.getFraction(
   13004                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
   13005             }
   13006         }
   13007     }
   13008 
   13009     public boolean testIsSystemReady() {
   13010         // no need to synchronize(this) just to read & return the value
   13011         return mSystemReady;
   13012     }
   13013 
   13014     public void systemReady(final Runnable goingCallback) {
   13015         synchronized(this) {
   13016             if (mSystemReady) {
   13017                 // If we're done calling all the receivers, run the next "boot phase" passed in
   13018                 // by the SystemServer
   13019                 if (goingCallback != null) {
   13020                     goingCallback.run();
   13021                 }
   13022                 return;
   13023             }
   13024 
   13025             mLocalDeviceIdleController
   13026                     = LocalServices.getService(DeviceIdleController.LocalService.class);
   13027 
   13028             // Make sure we have the current profile info, since it is needed for security checks.
   13029             mUserController.onSystemReady();
   13030             mRecentTasks.onSystemReadyLocked();
   13031             mAppOpsService.systemReady();
   13032             mSystemReady = true;
   13033         }
   13034 
   13035         ArrayList<ProcessRecord> procsToKill = null;
   13036         synchronized(mPidsSelfLocked) {
   13037             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
   13038                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   13039                 if (!isAllowedWhileBooting(proc.info)){
   13040                     if (procsToKill == null) {
   13041                         procsToKill = new ArrayList<ProcessRecord>();
   13042                     }
   13043                     procsToKill.add(proc);
   13044                 }
   13045             }
   13046         }
   13047 
   13048         synchronized(this) {
   13049             if (procsToKill != null) {
   13050                 for (int i=procsToKill.size()-1; i>=0; i--) {
   13051                     ProcessRecord proc = procsToKill.get(i);
   13052                     Slog.i(TAG, "Removing system update proc: " + proc);
   13053                     removeProcessLocked(proc, true, false, "system update done");
   13054                 }
   13055             }
   13056 
   13057             // Now that we have cleaned up any update processes, we
   13058             // are ready to start launching real processes and know that
   13059             // we won't trample on them any more.
   13060             mProcessesReady = true;
   13061         }
   13062 
   13063         Slog.i(TAG, "System now ready");
   13064         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
   13065             SystemClock.uptimeMillis());
   13066 
   13067         synchronized(this) {
   13068             // Make sure we have no pre-ready processes sitting around.
   13069 
   13070             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   13071                 ResolveInfo ri = mContext.getPackageManager()
   13072                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
   13073                                 STOCK_PM_FLAGS);
   13074                 CharSequence errorMsg = null;
   13075                 if (ri != null) {
   13076                     ActivityInfo ai = ri.activityInfo;
   13077                     ApplicationInfo app = ai.applicationInfo;
   13078                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   13079                         mTopAction = Intent.ACTION_FACTORY_TEST;
   13080                         mTopData = null;
   13081                         mTopComponent = new ComponentName(app.packageName,
   13082                                 ai.name);
   13083                     } else {
   13084                         errorMsg = mContext.getResources().getText(
   13085                                 com.android.internal.R.string.factorytest_not_system);
   13086                     }
   13087                 } else {
   13088                     errorMsg = mContext.getResources().getText(
   13089                             com.android.internal.R.string.factorytest_no_action);
   13090                 }
   13091                 if (errorMsg != null) {
   13092                     mTopAction = null;
   13093                     mTopData = null;
   13094                     mTopComponent = null;
   13095                     Message msg = Message.obtain();
   13096                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
   13097                     msg.getData().putCharSequence("msg", errorMsg);
   13098                     mUiHandler.sendMessage(msg);
   13099                 }
   13100             }
   13101         }
   13102 
   13103         retrieveSettings();
   13104         final int currentUserId;
   13105         synchronized (this) {
   13106             currentUserId = mUserController.getCurrentUserIdLocked();
   13107             readGrantedUriPermissionsLocked();
   13108         }
   13109 
   13110         if (goingCallback != null) goingCallback.run();
   13111 
   13112         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
   13113                 Integer.toString(currentUserId), currentUserId);
   13114         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
   13115                 Integer.toString(currentUserId), currentUserId);
   13116         mSystemServiceManager.startUser(currentUserId);
   13117 
   13118         synchronized (this) {
   13119             // Only start up encryption-aware persistent apps; once user is
   13120             // unlocked we'll come back around and start unaware apps
   13121             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
   13122 
   13123             // Start up initial activity.
   13124             mBooting = true;
   13125             // Enable home activity for system user, so that the system can always boot
   13126             if (UserManager.isSplitSystemUser()) {
   13127                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
   13128                 try {
   13129                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
   13130                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
   13131                             UserHandle.USER_SYSTEM);
   13132                 } catch (RemoteException e) {
   13133                     throw e.rethrowAsRuntimeException();
   13134                 }
   13135             }
   13136             startHomeActivityLocked(currentUserId, "systemReady");
   13137 
   13138             try {
   13139                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
   13140                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
   13141                             + " data partition or your device will be unstable.");
   13142                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
   13143                 }
   13144             } catch (RemoteException e) {
   13145             }
   13146 
   13147             if (!Build.isBuildConsistent()) {
   13148                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
   13149                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
   13150             }
   13151 
   13152             long ident = Binder.clearCallingIdentity();
   13153             try {
   13154                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
   13155                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   13156                         | Intent.FLAG_RECEIVER_FOREGROUND);
   13157                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
   13158                 broadcastIntentLocked(null, null, intent,
   13159                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   13160                         null, false, false, MY_PID, Process.SYSTEM_UID,
   13161                         currentUserId);
   13162                 intent = new Intent(Intent.ACTION_USER_STARTING);
   13163                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   13164                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
   13165                 broadcastIntentLocked(null, null, intent,
   13166                         null, new IIntentReceiver.Stub() {
   13167                             @Override
   13168                             public void performReceive(Intent intent, int resultCode, String data,
   13169                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
   13170                                     throws RemoteException {
   13171                             }
   13172                         }, 0, null, null,
   13173                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
   13174                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   13175             } catch (Throwable t) {
   13176                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
   13177             } finally {
   13178                 Binder.restoreCallingIdentity(ident);
   13179             }
   13180             mStackSupervisor.resumeFocusedStackTopActivityLocked();
   13181             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
   13182         }
   13183     }
   13184 
   13185     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
   13186         synchronized (this) {
   13187             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
   13188         }
   13189     }
   13190 
   13191     void skipCurrentReceiverLocked(ProcessRecord app) {
   13192         for (BroadcastQueue queue : mBroadcastQueues) {
   13193             queue.skipCurrentReceiverLocked(app);
   13194         }
   13195     }
   13196 
   13197     /**
   13198      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
   13199      * The application process will exit immediately after this call returns.
   13200      * @param app object of the crashing app, null for the system server
   13201      * @param crashInfo describing the exception
   13202      */
   13203     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
   13204         ProcessRecord r = findAppProcess(app, "Crash");
   13205         final String processName = app == null ? "system_server"
   13206                 : (r == null ? "unknown" : r.processName);
   13207 
   13208         handleApplicationCrashInner("crash", r, processName, crashInfo);
   13209     }
   13210 
   13211     /* Native crash reporting uses this inner version because it needs to be somewhat
   13212      * decoupled from the AM-managed cleanup lifecycle
   13213      */
   13214     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
   13215             ApplicationErrorReport.CrashInfo crashInfo) {
   13216         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
   13217                 UserHandle.getUserId(Binder.getCallingUid()), processName,
   13218                 r == null ? -1 : r.info.flags,
   13219                 crashInfo.exceptionClassName,
   13220                 crashInfo.exceptionMessage,
   13221                 crashInfo.throwFileName,
   13222                 crashInfo.throwLineNumber);
   13223 
   13224         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
   13225 
   13226         mAppErrors.crashApplication(r, crashInfo);
   13227     }
   13228 
   13229     public void handleApplicationStrictModeViolation(
   13230             IBinder app,
   13231             int violationMask,
   13232             StrictMode.ViolationInfo info) {
   13233         ProcessRecord r = findAppProcess(app, "StrictMode");
   13234         if (r == null) {
   13235             return;
   13236         }
   13237 
   13238         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
   13239             Integer stackFingerprint = info.hashCode();
   13240             boolean logIt = true;
   13241             synchronized (mAlreadyLoggedViolatedStacks) {
   13242                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
   13243                     logIt = false;
   13244                     // TODO: sub-sample into EventLog for these, with
   13245                     // the info.durationMillis?  Then we'd get
   13246                     // the relative pain numbers, without logging all
   13247                     // the stack traces repeatedly.  We'd want to do
   13248                     // likewise in the client code, which also does
   13249                     // dup suppression, before the Binder call.
   13250                 } else {
   13251                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
   13252                         mAlreadyLoggedViolatedStacks.clear();
   13253                     }
   13254                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
   13255                 }
   13256             }
   13257             if (logIt) {
   13258                 logStrictModeViolationToDropBox(r, info);
   13259             }
   13260         }
   13261 
   13262         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
   13263             AppErrorResult result = new AppErrorResult();
   13264             synchronized (this) {
   13265                 final long origId = Binder.clearCallingIdentity();
   13266 
   13267                 Message msg = Message.obtain();
   13268                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
   13269                 HashMap<String, Object> data = new HashMap<String, Object>();
   13270                 data.put("result", result);
   13271                 data.put("app", r);
   13272                 data.put("violationMask", violationMask);
   13273                 data.put("info", info);
   13274                 msg.obj = data;
   13275                 mUiHandler.sendMessage(msg);
   13276 
   13277                 Binder.restoreCallingIdentity(origId);
   13278             }
   13279             int res = result.get();
   13280             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
   13281         }
   13282     }
   13283 
   13284     // Depending on the policy in effect, there could be a bunch of
   13285     // these in quick succession so we try to batch these together to
   13286     // minimize disk writes, number of dropbox entries, and maximize
   13287     // compression, by having more fewer, larger records.
   13288     private void logStrictModeViolationToDropBox(
   13289             ProcessRecord process,
   13290             StrictMode.ViolationInfo info) {
   13291         if (info == null) {
   13292             return;
   13293         }
   13294         final boolean isSystemApp = process == null ||
   13295                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
   13296                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
   13297         final String processName = process == null ? "unknown" : process.processName;
   13298         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
   13299         final DropBoxManager dbox = (DropBoxManager)
   13300                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   13301 
   13302         // Exit early if the dropbox isn't configured to accept this report type.
   13303         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   13304 
   13305         boolean bufferWasEmpty;
   13306         boolean needsFlush;
   13307         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
   13308         synchronized (sb) {
   13309             bufferWasEmpty = sb.length() == 0;
   13310             appendDropBoxProcessHeaders(process, processName, sb);
   13311             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   13312             sb.append("System-App: ").append(isSystemApp).append("\n");
   13313             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
   13314             if (info.violationNumThisLoop != 0) {
   13315                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
   13316             }
   13317             if (info.numAnimationsRunning != 0) {
   13318                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
   13319             }
   13320             if (info.broadcastIntentAction != null) {
   13321                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
   13322             }
   13323             if (info.durationMillis != -1) {
   13324                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
   13325             }
   13326             if (info.numInstances != -1) {
   13327                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
   13328             }
   13329             if (info.tags != null) {
   13330                 for (String tag : info.tags) {
   13331                     sb.append("Span-Tag: ").append(tag).append("\n");
   13332                 }
   13333             }
   13334             sb.append("\n");
   13335             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
   13336                 sb.append(info.crashInfo.stackTrace);
   13337                 sb.append("\n");
   13338             }
   13339             if (info.message != null) {
   13340                 sb.append(info.message);
   13341                 sb.append("\n");
   13342             }
   13343 
   13344             // Only buffer up to ~64k.  Various logging bits truncate
   13345             // things at 128k.
   13346             needsFlush = (sb.length() > 64 * 1024);
   13347         }
   13348 
   13349         // Flush immediately if the buffer's grown too large, or this
   13350         // is a non-system app.  Non-system apps are isolated with a
   13351         // different tag & policy and not batched.
   13352         //
   13353         // Batching is useful during internal testing with
   13354         // StrictMode settings turned up high.  Without batching,
   13355         // thousands of separate files could be created on boot.
   13356         if (!isSystemApp || needsFlush) {
   13357             new Thread("Error dump: " + dropboxTag) {
   13358                 @Override
   13359                 public void run() {
   13360                     String report;
   13361                     synchronized (sb) {
   13362                         report = sb.toString();
   13363                         sb.delete(0, sb.length());
   13364                         sb.trimToSize();
   13365                     }
   13366                     if (report.length() != 0) {
   13367                         dbox.addText(dropboxTag, report);
   13368                     }
   13369                 }
   13370             }.start();
   13371             return;
   13372         }
   13373 
   13374         // System app batching:
   13375         if (!bufferWasEmpty) {
   13376             // An existing dropbox-writing thread is outstanding, so
   13377             // we don't need to start it up.  The existing thread will
   13378             // catch the buffer appends we just did.
   13379             return;
   13380         }
   13381 
   13382         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
   13383         // (After this point, we shouldn't access AMS internal data structures.)
   13384         new Thread("Error dump: " + dropboxTag) {
   13385             @Override
   13386             public void run() {
   13387                 // 5 second sleep to let stacks arrive and be batched together
   13388                 try {
   13389                     Thread.sleep(5000);  // 5 seconds
   13390                 } catch (InterruptedException e) {}
   13391 
   13392                 String errorReport;
   13393                 synchronized (mStrictModeBuffer) {
   13394                     errorReport = mStrictModeBuffer.toString();
   13395                     if (errorReport.length() == 0) {
   13396                         return;
   13397                     }
   13398                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
   13399                     mStrictModeBuffer.trimToSize();
   13400                 }
   13401                 dbox.addText(dropboxTag, errorReport);
   13402             }
   13403         }.start();
   13404     }
   13405 
   13406     /**
   13407      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
   13408      * @param app object of the crashing app, null for the system server
   13409      * @param tag reported by the caller
   13410      * @param system whether this wtf is coming from the system
   13411      * @param crashInfo describing the context of the error
   13412      * @return true if the process should exit immediately (WTF is fatal)
   13413      */
   13414     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
   13415             final ApplicationErrorReport.CrashInfo crashInfo) {
   13416         final int callingUid = Binder.getCallingUid();
   13417         final int callingPid = Binder.getCallingPid();
   13418 
   13419         if (system) {
   13420             // If this is coming from the system, we could very well have low-level
   13421             // system locks held, so we want to do this all asynchronously.  And we
   13422             // never want this to become fatal, so there is that too.
   13423             mHandler.post(new Runnable() {
   13424                 @Override public void run() {
   13425                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
   13426                 }
   13427             });
   13428             return false;
   13429         }
   13430 
   13431         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
   13432                 crashInfo);
   13433 
   13434         if (r != null && r.pid != Process.myPid() &&
   13435                 Settings.Global.getInt(mContext.getContentResolver(),
   13436                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
   13437             mAppErrors.crashApplication(r, crashInfo);
   13438             return true;
   13439         } else {
   13440             return false;
   13441         }
   13442     }
   13443 
   13444     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
   13445             final ApplicationErrorReport.CrashInfo crashInfo) {
   13446         final ProcessRecord r = findAppProcess(app, "WTF");
   13447         final String processName = app == null ? "system_server"
   13448                 : (r == null ? "unknown" : r.processName);
   13449 
   13450         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
   13451                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
   13452 
   13453         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
   13454 
   13455         return r;
   13456     }
   13457 
   13458     /**
   13459      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
   13460      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
   13461      */
   13462     private ProcessRecord findAppProcess(IBinder app, String reason) {
   13463         if (app == null) {
   13464             return null;
   13465         }
   13466 
   13467         synchronized (this) {
   13468             final int NP = mProcessNames.getMap().size();
   13469             for (int ip=0; ip<NP; ip++) {
   13470                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   13471                 final int NA = apps.size();
   13472                 for (int ia=0; ia<NA; ia++) {
   13473                     ProcessRecord p = apps.valueAt(ia);
   13474                     if (p.thread != null && p.thread.asBinder() == app) {
   13475                         return p;
   13476                     }
   13477                 }
   13478             }
   13479 
   13480             Slog.w(TAG, "Can't find mystery application for " + reason
   13481                     + " from pid=" + Binder.getCallingPid()
   13482                     + " uid=" + Binder.getCallingUid() + ": " + app);
   13483             return null;
   13484         }
   13485     }
   13486 
   13487     /**
   13488      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
   13489      * to append various headers to the dropbox log text.
   13490      */
   13491     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
   13492             StringBuilder sb) {
   13493         // Watchdog thread ends up invoking this function (with
   13494         // a null ProcessRecord) to add the stack file to dropbox.
   13495         // Do not acquire a lock on this (am) in such cases, as it
   13496         // could cause a potential deadlock, if and when watchdog
   13497         // is invoked due to unavailability of lock on am and it
   13498         // would prevent watchdog from killing system_server.
   13499         if (process == null) {
   13500             sb.append("Process: ").append(processName).append("\n");
   13501             return;
   13502         }
   13503         // Note: ProcessRecord 'process' is guarded by the service
   13504         // instance.  (notably process.pkgList, which could otherwise change
   13505         // concurrently during execution of this method)
   13506         synchronized (this) {
   13507             sb.append("Process: ").append(processName).append("\n");
   13508             int flags = process.info.flags;
   13509             IPackageManager pm = AppGlobals.getPackageManager();
   13510             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
   13511             for (int ip=0; ip<process.pkgList.size(); ip++) {
   13512                 String pkg = process.pkgList.keyAt(ip);
   13513                 sb.append("Package: ").append(pkg);
   13514                 try {
   13515                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
   13516                     if (pi != null) {
   13517                         sb.append(" v").append(pi.versionCode);
   13518                         if (pi.versionName != null) {
   13519                             sb.append(" (").append(pi.versionName).append(")");
   13520                         }
   13521                     }
   13522                 } catch (RemoteException e) {
   13523                     Slog.e(TAG, "Error getting package info: " + pkg, e);
   13524                 }
   13525                 sb.append("\n");
   13526             }
   13527         }
   13528     }
   13529 
   13530     private static String processClass(ProcessRecord process) {
   13531         if (process == null || process.pid == MY_PID) {
   13532             return "system_server";
   13533         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   13534             return "system_app";
   13535         } else {
   13536             return "data_app";
   13537         }
   13538     }
   13539 
   13540     private volatile long mWtfClusterStart;
   13541     private volatile int mWtfClusterCount;
   13542 
   13543     /**
   13544      * Write a description of an error (crash, WTF, ANR) to the drop box.
   13545      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
   13546      * @param process which caused the error, null means the system server
   13547      * @param activity which triggered the error, null if unknown
   13548      * @param parent activity related to the error, null if unknown
   13549      * @param subject line related to the error, null if absent
   13550      * @param report in long form describing the error, null if absent
   13551      * @param dataFile text file to include in the report, null if none
   13552      * @param crashInfo giving an application stack trace, null if absent
   13553      */
   13554     public void addErrorToDropBox(String eventType,
   13555             ProcessRecord process, String processName, ActivityRecord activity,
   13556             ActivityRecord parent, String subject,
   13557             final String report, final File dataFile,
   13558             final ApplicationErrorReport.CrashInfo crashInfo) {
   13559         // NOTE -- this must never acquire the ActivityManagerService lock,
   13560         // otherwise the watchdog may be prevented from resetting the system.
   13561 
   13562         final String dropboxTag = processClass(process) + "_" + eventType;
   13563         final DropBoxManager dbox = (DropBoxManager)
   13564                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   13565 
   13566         // Exit early if the dropbox isn't configured to accept this report type.
   13567         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   13568 
   13569         // Rate-limit how often we're willing to do the heavy lifting below to
   13570         // collect and record logs; currently 5 logs per 10 second period.
   13571         final long now = SystemClock.elapsedRealtime();
   13572         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
   13573             mWtfClusterStart = now;
   13574             mWtfClusterCount = 1;
   13575         } else {
   13576             if (mWtfClusterCount++ >= 5) return;
   13577         }
   13578 
   13579         final StringBuilder sb = new StringBuilder(1024);
   13580         appendDropBoxProcessHeaders(process, processName, sb);
   13581         if (process != null) {
   13582             sb.append("Foreground: ")
   13583                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
   13584                     .append("\n");
   13585         }
   13586         if (activity != null) {
   13587             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
   13588         }
   13589         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
   13590             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
   13591         }
   13592         if (parent != null && parent != activity) {
   13593             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
   13594         }
   13595         if (subject != null) {
   13596             sb.append("Subject: ").append(subject).append("\n");
   13597         }
   13598         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   13599         if (Debug.isDebuggerConnected()) {
   13600             sb.append("Debugger: Connected\n");
   13601         }
   13602         sb.append("\n");
   13603 
   13604         // Do the rest in a worker thread to avoid blocking the caller on I/O
   13605         // (After this point, we shouldn't access AMS internal data structures.)
   13606         Thread worker = new Thread("Error dump: " + dropboxTag) {
   13607             @Override
   13608             public void run() {
   13609                 if (report != null) {
   13610                     sb.append(report);
   13611                 }
   13612 
   13613                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
   13614                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
   13615                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
   13616                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
   13617 
   13618                 if (dataFile != null && maxDataFileSize > 0) {
   13619                     try {
   13620                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
   13621                                     "\n\n[[TRUNCATED]]"));
   13622                     } catch (IOException e) {
   13623                         Slog.e(TAG, "Error reading " + dataFile, e);
   13624                     }
   13625                 }
   13626                 if (crashInfo != null && crashInfo.stackTrace != null) {
   13627                     sb.append(crashInfo.stackTrace);
   13628                 }
   13629 
   13630                 if (lines > 0) {
   13631                     sb.append("\n");
   13632 
   13633                     // Merge several logcat streams, and take the last N lines
   13634                     InputStreamReader input = null;
   13635                     try {
   13636                         java.lang.Process logcat = new ProcessBuilder(
   13637                                 "/system/bin/timeout", "-k", "15s", "10s",
   13638                                 "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
   13639                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
   13640                                         .redirectErrorStream(true).start();
   13641 
   13642                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
   13643                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
   13644                         input = new InputStreamReader(logcat.getInputStream());
   13645 
   13646                         int num;
   13647                         char[] buf = new char[8192];
   13648                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
   13649                     } catch (IOException e) {
   13650                         Slog.e(TAG, "Error running logcat", e);
   13651                     } finally {
   13652                         if (input != null) try { input.close(); } catch (IOException e) {}
   13653                     }
   13654                 }
   13655 
   13656                 dbox.addText(dropboxTag, sb.toString());
   13657             }
   13658         };
   13659 
   13660         if (process == null) {
   13661             // If process is null, we are being called from some internal code
   13662             // and may be about to die -- run this synchronously.
   13663             worker.run();
   13664         } else {
   13665             worker.start();
   13666         }
   13667     }
   13668 
   13669     @Override
   13670     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
   13671         enforceNotIsolatedCaller("getProcessesInErrorState");
   13672         // assume our apps are happy - lazy create the list
   13673         List<ActivityManager.ProcessErrorStateInfo> errList = null;
   13674 
   13675         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
   13676                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
   13677         int userId = UserHandle.getUserId(Binder.getCallingUid());
   13678 
   13679         synchronized (this) {
   13680 
   13681             // iterate across all processes
   13682             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   13683                 ProcessRecord app = mLruProcesses.get(i);
   13684                 if (!allUsers && app.userId != userId) {
   13685                     continue;
   13686                 }
   13687                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
   13688                     // This one's in trouble, so we'll generate a report for it
   13689                     // crashes are higher priority (in case there's a crash *and* an anr)
   13690                     ActivityManager.ProcessErrorStateInfo report = null;
   13691                     if (app.crashing) {
   13692                         report = app.crashingReport;
   13693                     } else if (app.notResponding) {
   13694                         report = app.notRespondingReport;
   13695                     }
   13696 
   13697                     if (report != null) {
   13698                         if (errList == null) {
   13699                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
   13700                         }
   13701                         errList.add(report);
   13702                     } else {
   13703                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
   13704                                 " crashing = " + app.crashing +
   13705                                 " notResponding = " + app.notResponding);
   13706                     }
   13707                 }
   13708             }
   13709         }
   13710 
   13711         return errList;
   13712     }
   13713 
   13714     static int procStateToImportance(int procState, int memAdj,
   13715             ActivityManager.RunningAppProcessInfo currApp) {
   13716         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
   13717         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
   13718             currApp.lru = memAdj;
   13719         } else {
   13720             currApp.lru = 0;
   13721         }
   13722         return imp;
   13723     }
   13724 
   13725     private void fillInProcMemInfo(ProcessRecord app,
   13726             ActivityManager.RunningAppProcessInfo outInfo) {
   13727         outInfo.pid = app.pid;
   13728         outInfo.uid = app.info.uid;
   13729         if (mHeavyWeightProcess == app) {
   13730             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
   13731         }
   13732         if (app.persistent) {
   13733             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
   13734         }
   13735         if (app.activities.size() > 0) {
   13736             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
   13737         }
   13738         outInfo.lastTrimLevel = app.trimMemoryLevel;
   13739         int adj = app.curAdj;
   13740         int procState = app.curProcState;
   13741         outInfo.importance = procStateToImportance(procState, adj, outInfo);
   13742         outInfo.importanceReasonCode = app.adjTypeCode;
   13743         outInfo.processState = app.curProcState;
   13744     }
   13745 
   13746     @Override
   13747     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
   13748         enforceNotIsolatedCaller("getRunningAppProcesses");
   13749 
   13750         final int callingUid = Binder.getCallingUid();
   13751 
   13752         // Lazy instantiation of list
   13753         List<ActivityManager.RunningAppProcessInfo> runList = null;
   13754         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
   13755                 callingUid) == PackageManager.PERMISSION_GRANTED;
   13756         final int userId = UserHandle.getUserId(callingUid);
   13757         final boolean allUids = isGetTasksAllowed(
   13758                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
   13759 
   13760         synchronized (this) {
   13761             // Iterate across all processes
   13762             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   13763                 ProcessRecord app = mLruProcesses.get(i);
   13764                 if ((!allUsers && app.userId != userId)
   13765                         || (!allUids && app.uid != callingUid)) {
   13766                     continue;
   13767                 }
   13768                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
   13769                     // Generate process state info for running application
   13770                     ActivityManager.RunningAppProcessInfo currApp =
   13771                         new ActivityManager.RunningAppProcessInfo(app.processName,
   13772                                 app.pid, app.getPackageList());
   13773                     fillInProcMemInfo(app, currApp);
   13774                     if (app.adjSource instanceof ProcessRecord) {
   13775                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
   13776                         currApp.importanceReasonImportance =
   13777                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
   13778                                         app.adjSourceProcState);
   13779                     } else if (app.adjSource instanceof ActivityRecord) {
   13780                         ActivityRecord r = (ActivityRecord)app.adjSource;
   13781                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
   13782                     }
   13783                     if (app.adjTarget instanceof ComponentName) {
   13784                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
   13785                     }
   13786                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
   13787                     //        + " lru=" + currApp.lru);
   13788                     if (runList == null) {
   13789                         runList = new ArrayList<>();
   13790                     }
   13791                     runList.add(currApp);
   13792                 }
   13793             }
   13794         }
   13795         return runList;
   13796     }
   13797 
   13798     @Override
   13799     public List<ApplicationInfo> getRunningExternalApplications() {
   13800         enforceNotIsolatedCaller("getRunningExternalApplications");
   13801         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
   13802         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
   13803         if (runningApps != null && runningApps.size() > 0) {
   13804             Set<String> extList = new HashSet<String>();
   13805             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
   13806                 if (app.pkgList != null) {
   13807                     for (String pkg : app.pkgList) {
   13808                         extList.add(pkg);
   13809                     }
   13810                 }
   13811             }
   13812             IPackageManager pm = AppGlobals.getPackageManager();
   13813             for (String pkg : extList) {
   13814                 try {
   13815                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
   13816                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
   13817                         retList.add(info);
   13818                     }
   13819                 } catch (RemoteException e) {
   13820                 }
   13821             }
   13822         }
   13823         return retList;
   13824     }
   13825 
   13826     @Override
   13827     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
   13828         enforceNotIsolatedCaller("getMyMemoryState");
   13829         synchronized (this) {
   13830             ProcessRecord proc;
   13831             synchronized (mPidsSelfLocked) {
   13832                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   13833             }
   13834             fillInProcMemInfo(proc, outInfo);
   13835         }
   13836     }
   13837 
   13838     @Override
   13839     public int getMemoryTrimLevel() {
   13840         enforceNotIsolatedCaller("getMyMemoryState");
   13841         synchronized (this) {
   13842             return mLastMemoryLevel;
   13843         }
   13844     }
   13845 
   13846     @Override
   13847     public void onShellCommand(FileDescriptor in, FileDescriptor out,
   13848             FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
   13849         (new ActivityManagerShellCommand(this, false)).exec(
   13850                 this, in, out, err, args, resultReceiver);
   13851     }
   13852 
   13853     @Override
   13854     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   13855         if (checkCallingPermission(android.Manifest.permission.DUMP)
   13856                 != PackageManager.PERMISSION_GRANTED) {
   13857             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   13858                     + Binder.getCallingPid()
   13859                     + ", uid=" + Binder.getCallingUid()
   13860                     + " without permission "
   13861                     + android.Manifest.permission.DUMP);
   13862             return;
   13863         }
   13864 
   13865         boolean dumpAll = false;
   13866         boolean dumpClient = false;
   13867         boolean dumpCheckin = false;
   13868         boolean dumpCheckinFormat = false;
   13869         String dumpPackage = null;
   13870 
   13871         int opti = 0;
   13872         while (opti < args.length) {
   13873             String opt = args[opti];
   13874             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   13875                 break;
   13876             }
   13877             opti++;
   13878             if ("-a".equals(opt)) {
   13879                 dumpAll = true;
   13880             } else if ("-c".equals(opt)) {
   13881                 dumpClient = true;
   13882             } else if ("-p".equals(opt)) {
   13883                 if (opti < args.length) {
   13884                     dumpPackage = args[opti];
   13885                     opti++;
   13886                 } else {
   13887                     pw.println("Error: -p option requires package argument");
   13888                     return;
   13889                 }
   13890                 dumpClient = true;
   13891             } else if ("--checkin".equals(opt)) {
   13892                 dumpCheckin = dumpCheckinFormat = true;
   13893             } else if ("-C".equals(opt)) {
   13894                 dumpCheckinFormat = true;
   13895             } else if ("-h".equals(opt)) {
   13896                 ActivityManagerShellCommand.dumpHelp(pw, true);
   13897                 return;
   13898             } else {
   13899                 pw.println("Unknown argument: " + opt + "; use -h for help");
   13900             }
   13901         }
   13902 
   13903         long origId = Binder.clearCallingIdentity();
   13904         boolean more = false;
   13905         // Is the caller requesting to dump a particular piece of data?
   13906         if (opti < args.length) {
   13907             String cmd = args[opti];
   13908             opti++;
   13909             if ("activities".equals(cmd) || "a".equals(cmd)) {
   13910                 synchronized (this) {
   13911                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
   13912                 }
   13913             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
   13914                 synchronized (this) {
   13915                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
   13916                 }
   13917             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
   13918                 String[] newArgs;
   13919                 String name;
   13920                 if (opti >= args.length) {
   13921                     name = null;
   13922                     newArgs = EMPTY_STRING_ARRAY;
   13923                 } else {
   13924                     dumpPackage = args[opti];
   13925                     opti++;
   13926                     newArgs = new String[args.length - opti];
   13927                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   13928                             args.length - opti);
   13929                 }
   13930                 synchronized (this) {
   13931                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
   13932                 }
   13933             } else if ("broadcast-stats".equals(cmd)) {
   13934                 String[] newArgs;
   13935                 String name;
   13936                 if (opti >= args.length) {
   13937                     name = null;
   13938                     newArgs = EMPTY_STRING_ARRAY;
   13939                 } else {
   13940                     dumpPackage = args[opti];
   13941                     opti++;
   13942                     newArgs = new String[args.length - opti];
   13943                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   13944                             args.length - opti);
   13945                 }
   13946                 synchronized (this) {
   13947                     if (dumpCheckinFormat) {
   13948                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
   13949                                 dumpPackage);
   13950                     } else {
   13951                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
   13952                     }
   13953                 }
   13954             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
   13955                 String[] newArgs;
   13956                 String name;
   13957                 if (opti >= args.length) {
   13958                     name = null;
   13959                     newArgs = EMPTY_STRING_ARRAY;
   13960                 } else {
   13961                     dumpPackage = args[opti];
   13962                     opti++;
   13963                     newArgs = new String[args.length - opti];
   13964                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   13965                             args.length - opti);
   13966                 }
   13967                 synchronized (this) {
   13968                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
   13969                 }
   13970             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
   13971                 String[] newArgs;
   13972                 String name;
   13973                 if (opti >= args.length) {
   13974                     name = null;
   13975                     newArgs = EMPTY_STRING_ARRAY;
   13976                 } else {
   13977                     dumpPackage = args[opti];
   13978                     opti++;
   13979                     newArgs = new String[args.length - opti];
   13980                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   13981                             args.length - opti);
   13982                 }
   13983                 synchronized (this) {
   13984                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
   13985                 }
   13986             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
   13987                 synchronized (this) {
   13988                     dumpOomLocked(fd, pw, args, opti, true);
   13989                 }
   13990             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
   13991                 synchronized (this) {
   13992                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
   13993                 }
   13994             } else if ("provider".equals(cmd)) {
   13995                 String[] newArgs;
   13996                 String name;
   13997                 if (opti >= args.length) {
   13998                     name = null;
   13999                     newArgs = EMPTY_STRING_ARRAY;
   14000                 } else {
   14001                     name = args[opti];
   14002                     opti++;
   14003                     newArgs = new String[args.length - opti];
   14004                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   14005                 }
   14006                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
   14007                     pw.println("No providers match: " + name);
   14008                     pw.println("Use -h for help.");
   14009                 }
   14010             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
   14011                 synchronized (this) {
   14012                     dumpProvidersLocked(fd, pw, args, opti, true, null);
   14013                 }
   14014             } else if ("service".equals(cmd)) {
   14015                 String[] newArgs;
   14016                 String name;
   14017                 if (opti >= args.length) {
   14018                     name = null;
   14019                     newArgs = EMPTY_STRING_ARRAY;
   14020                 } else {
   14021                     name = args[opti];
   14022                     opti++;
   14023                     newArgs = new String[args.length - opti];
   14024                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   14025                             args.length - opti);
   14026                 }
   14027                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
   14028                     pw.println("No services match: " + name);
   14029                     pw.println("Use -h for help.");
   14030                 }
   14031             } else if ("package".equals(cmd)) {
   14032                 String[] newArgs;
   14033                 if (opti >= args.length) {
   14034                     pw.println("package: no package name specified");
   14035                     pw.println("Use -h for help.");
   14036                 } else {
   14037                     dumpPackage = args[opti];
   14038                     opti++;
   14039                     newArgs = new String[args.length - opti];
   14040                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   14041                             args.length - opti);
   14042                     args = newArgs;
   14043                     opti = 0;
   14044                     more = true;
   14045                 }
   14046             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
   14047                 synchronized (this) {
   14048                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
   14049                 }
   14050             } else if ("services".equals(cmd) || "s".equals(cmd)) {
   14051                 if (dumpClient) {
   14052                     ActiveServices.ServiceDumper dumper;
   14053                     synchronized (this) {
   14054                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
   14055                                 dumpPackage);
   14056                     }
   14057                     dumper.dumpWithClient();
   14058                 } else {
   14059                     synchronized (this) {
   14060                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
   14061                                 dumpPackage).dumpLocked();
   14062                     }
   14063                 }
   14064             } else if ("locks".equals(cmd)) {
   14065                 LockGuard.dump(fd, pw, args);
   14066             } else {
   14067                 // Dumping a single activity?
   14068                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
   14069                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
   14070                     int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
   14071                     if (res < 0) {
   14072                         pw.println("Bad activity command, or no activities match: " + cmd);
   14073                         pw.println("Use -h for help.");
   14074                     }
   14075                 }
   14076             }
   14077             if (!more) {
   14078                 Binder.restoreCallingIdentity(origId);
   14079                 return;
   14080             }
   14081         }
   14082 
   14083         // No piece of data specified, dump everything.
   14084         if (dumpCheckinFormat) {
   14085             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
   14086         } else if (dumpClient) {
   14087             ActiveServices.ServiceDumper sdumper;
   14088             synchronized (this) {
   14089                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14090                 pw.println();
   14091                 if (dumpAll) {
   14092                     pw.println("-------------------------------------------------------------------------------");
   14093                 }
   14094                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14095                 pw.println();
   14096                 if (dumpAll) {
   14097                     pw.println("-------------------------------------------------------------------------------");
   14098                 }
   14099                 if (dumpAll || dumpPackage != null) {
   14100                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14101                     pw.println();
   14102                     if (dumpAll) {
   14103                         pw.println("-------------------------------------------------------------------------------");
   14104                     }
   14105                 }
   14106                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14107                 pw.println();
   14108                 if (dumpAll) {
   14109                     pw.println("-------------------------------------------------------------------------------");
   14110                 }
   14111                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14112                 pw.println();
   14113                 if (dumpAll) {
   14114                     pw.println("-------------------------------------------------------------------------------");
   14115                 }
   14116                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
   14117                         dumpPackage);
   14118             }
   14119             sdumper.dumpWithClient();
   14120             pw.println();
   14121             synchronized (this) {
   14122                 if (dumpAll) {
   14123                     pw.println("-------------------------------------------------------------------------------");
   14124                 }
   14125                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14126                 pw.println();
   14127                 if (dumpAll) {
   14128                     pw.println("-------------------------------------------------------------------------------");
   14129                 }
   14130                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   14131                 if (mAssociations.size() > 0) {
   14132                     pw.println();
   14133                     if (dumpAll) {
   14134                         pw.println("-------------------------------------------------------------------------------");
   14135                     }
   14136                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   14137                 }
   14138                 pw.println();
   14139                 if (dumpAll) {
   14140                     pw.println("-------------------------------------------------------------------------------");
   14141                 }
   14142                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14143             }
   14144 
   14145         } else {
   14146             synchronized (this) {
   14147                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14148                 pw.println();
   14149                 if (dumpAll) {
   14150                     pw.println("-------------------------------------------------------------------------------");
   14151                 }
   14152                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14153                 pw.println();
   14154                 if (dumpAll) {
   14155                     pw.println("-------------------------------------------------------------------------------");
   14156                 }
   14157                 if (dumpAll || dumpPackage != null) {
   14158                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14159                     pw.println();
   14160                     if (dumpAll) {
   14161                         pw.println("-------------------------------------------------------------------------------");
   14162                     }
   14163                 }
   14164                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14165                 pw.println();
   14166                 if (dumpAll) {
   14167                     pw.println("-------------------------------------------------------------------------------");
   14168                 }
   14169                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14170                 pw.println();
   14171                 if (dumpAll) {
   14172                     pw.println("-------------------------------------------------------------------------------");
   14173                 }
   14174                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
   14175                         .dumpLocked();
   14176                 pw.println();
   14177                 if (dumpAll) {
   14178                     pw.println("-------------------------------------------------------------------------------");
   14179                 }
   14180                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14181                 pw.println();
   14182                 if (dumpAll) {
   14183                     pw.println("-------------------------------------------------------------------------------");
   14184                 }
   14185                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   14186                 if (mAssociations.size() > 0) {
   14187                     pw.println();
   14188                     if (dumpAll) {
   14189                         pw.println("-------------------------------------------------------------------------------");
   14190                     }
   14191                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   14192                 }
   14193                 pw.println();
   14194                 if (dumpAll) {
   14195                     pw.println("-------------------------------------------------------------------------------");
   14196                 }
   14197                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14198             }
   14199         }
   14200         Binder.restoreCallingIdentity(origId);
   14201     }
   14202 
   14203     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   14204             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   14205         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
   14206 
   14207         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
   14208                 dumpPackage);
   14209         boolean needSep = printedAnything;
   14210 
   14211         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
   14212                 dumpPackage, needSep, "  mFocusedActivity: ");
   14213         if (printed) {
   14214             printedAnything = true;
   14215             needSep = false;
   14216         }
   14217 
   14218         if (dumpPackage == null) {
   14219             if (needSep) {
   14220                 pw.println();
   14221             }
   14222             needSep = true;
   14223             printedAnything = true;
   14224             mStackSupervisor.dump(pw, "  ");
   14225         }
   14226 
   14227         if (!printedAnything) {
   14228             pw.println("  (nothing)");
   14229         }
   14230     }
   14231 
   14232     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   14233             int opti, boolean dumpAll, String dumpPackage) {
   14234         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
   14235 
   14236         boolean printedAnything = false;
   14237 
   14238         if (mRecentTasks != null && mRecentTasks.size() > 0) {
   14239             boolean printedHeader = false;
   14240 
   14241             final int N = mRecentTasks.size();
   14242             for (int i=0; i<N; i++) {
   14243                 TaskRecord tr = mRecentTasks.get(i);
   14244                 if (dumpPackage != null) {
   14245                     if (tr.realActivity == null ||
   14246                             !dumpPackage.equals(tr.realActivity)) {
   14247                         continue;
   14248                     }
   14249                 }
   14250                 if (!printedHeader) {
   14251                     pw.println("  Recent tasks:");
   14252                     printedHeader = true;
   14253                     printedAnything = true;
   14254                 }
   14255                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
   14256                         pw.println(tr);
   14257                 if (dumpAll) {
   14258                     mRecentTasks.get(i).dump(pw, "    ");
   14259                 }
   14260             }
   14261         }
   14262 
   14263         if (!printedAnything) {
   14264             pw.println("  (nothing)");
   14265         }
   14266     }
   14267 
   14268     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   14269             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   14270         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
   14271 
   14272         int dumpUid = 0;
   14273         if (dumpPackage != null) {
   14274             IPackageManager pm = AppGlobals.getPackageManager();
   14275             try {
   14276                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
   14277             } catch (RemoteException e) {
   14278             }
   14279         }
   14280 
   14281         boolean printedAnything = false;
   14282 
   14283         final long now = SystemClock.uptimeMillis();
   14284 
   14285         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
   14286             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
   14287                     = mAssociations.valueAt(i1);
   14288             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
   14289                 SparseArray<ArrayMap<String, Association>> sourceUids
   14290                         = targetComponents.valueAt(i2);
   14291                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
   14292                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
   14293                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
   14294                         Association ass = sourceProcesses.valueAt(i4);
   14295                         if (dumpPackage != null) {
   14296                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
   14297                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
   14298                                 continue;
   14299                             }
   14300                         }
   14301                         printedAnything = true;
   14302                         pw.print("  ");
   14303                         pw.print(ass.mTargetProcess);
   14304                         pw.print("/");
   14305                         UserHandle.formatUid(pw, ass.mTargetUid);
   14306                         pw.print(" <- ");
   14307                         pw.print(ass.mSourceProcess);
   14308                         pw.print("/");
   14309                         UserHandle.formatUid(pw, ass.mSourceUid);
   14310                         pw.println();
   14311                         pw.print("    via ");
   14312                         pw.print(ass.mTargetComponent.flattenToShortString());
   14313                         pw.println();
   14314                         pw.print("    ");
   14315                         long dur = ass.mTime;
   14316                         if (ass.mNesting > 0) {
   14317                             dur += now - ass.mStartTime;
   14318                         }
   14319                         TimeUtils.formatDuration(dur, pw);
   14320                         pw.print(" (");
   14321                         pw.print(ass.mCount);
   14322                         pw.print(" times)");
   14323                         pw.print("  ");
   14324                         for (int i=0; i<ass.mStateTimes.length; i++) {
   14325                             long amt = ass.mStateTimes[i];
   14326                             if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
   14327                                 amt += now - ass.mLastStateUptime;
   14328                             }
   14329                             if (amt != 0) {
   14330                                 pw.print(" ");
   14331                                 pw.print(ProcessList.makeProcStateString(
   14332                                             i + ActivityManager.MIN_PROCESS_STATE));
   14333                                 pw.print("=");
   14334                                 TimeUtils.formatDuration(amt, pw);
   14335                                 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
   14336                                     pw.print("*");
   14337                                 }
   14338                             }
   14339                         }
   14340                         pw.println();
   14341                         if (ass.mNesting > 0) {
   14342                             pw.print("    Currently active: ");
   14343                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
   14344                             pw.println();
   14345                         }
   14346                     }
   14347                 }
   14348             }
   14349 
   14350         }
   14351 
   14352         if (!printedAnything) {
   14353             pw.println("  (nothing)");
   14354         }
   14355     }
   14356 
   14357     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
   14358             String header, boolean needSep) {
   14359         boolean printed = false;
   14360         int whichAppId = -1;
   14361         if (dumpPackage != null) {
   14362             try {
   14363                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
   14364                         dumpPackage, 0);
   14365                 whichAppId = UserHandle.getAppId(info.uid);
   14366             } catch (NameNotFoundException e) {
   14367                 e.printStackTrace();
   14368             }
   14369         }
   14370         for (int i=0; i<uids.size(); i++) {
   14371             UidRecord uidRec = uids.valueAt(i);
   14372             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
   14373                 continue;
   14374             }
   14375             if (!printed) {
   14376                 printed = true;
   14377                 if (needSep) {
   14378                     pw.println();
   14379                 }
   14380                 pw.print("  ");
   14381                 pw.println(header);
   14382                 needSep = true;
   14383             }
   14384             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
   14385             pw.print(": "); pw.println(uidRec);
   14386         }
   14387         return printed;
   14388     }
   14389 
   14390     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   14391             int opti, boolean dumpAll, String dumpPackage) {
   14392         boolean needSep = false;
   14393         boolean printedAnything = false;
   14394         int numPers = 0;
   14395 
   14396         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
   14397 
   14398         if (dumpAll) {
   14399             final int NP = mProcessNames.getMap().size();
   14400             for (int ip=0; ip<NP; ip++) {
   14401                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
   14402                 final int NA = procs.size();
   14403                 for (int ia=0; ia<NA; ia++) {
   14404                     ProcessRecord r = procs.valueAt(ia);
   14405                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   14406                         continue;
   14407                     }
   14408                     if (!needSep) {
   14409                         pw.println("  All known processes:");
   14410                         needSep = true;
   14411                         printedAnything = true;
   14412                     }
   14413                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
   14414                         pw.print(" UID "); pw.print(procs.keyAt(ia));
   14415                         pw.print(" "); pw.println(r);
   14416                     r.dump(pw, "    ");
   14417                     if (r.persistent) {
   14418                         numPers++;
   14419                     }
   14420                 }
   14421             }
   14422         }
   14423 
   14424         if (mIsolatedProcesses.size() > 0) {
   14425             boolean printed = false;
   14426             for (int i=0; i<mIsolatedProcesses.size(); i++) {
   14427                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
   14428                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   14429                     continue;
   14430                 }
   14431                 if (!printed) {
   14432                     if (needSep) {
   14433                         pw.println();
   14434                     }
   14435                     pw.println("  Isolated process list (sorted by uid):");
   14436                     printedAnything = true;
   14437                     printed = true;
   14438                     needSep = true;
   14439                 }
   14440                 pw.println(String.format("%sIsolated #%2d: %s",
   14441                         "    ", i, r.toString()));
   14442             }
   14443         }
   14444 
   14445         if (mActiveUids.size() > 0) {
   14446             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
   14447                 printedAnything = needSep = true;
   14448             }
   14449         }
   14450         if (mValidateUids.size() > 0) {
   14451             if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
   14452                 printedAnything = needSep = true;
   14453             }
   14454         }
   14455 
   14456         if (mLruProcesses.size() > 0) {
   14457             if (needSep) {
   14458                 pw.println();
   14459             }
   14460             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
   14461                     pw.print(" total, non-act at ");
   14462                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   14463                     pw.print(", non-svc at ");
   14464                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   14465                     pw.println("):");
   14466             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
   14467             needSep = true;
   14468             printedAnything = true;
   14469         }
   14470 
   14471         if (dumpAll || dumpPackage != null) {
   14472             synchronized (mPidsSelfLocked) {
   14473                 boolean printed = false;
   14474                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   14475                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
   14476                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   14477                         continue;
   14478                     }
   14479                     if (!printed) {
   14480                         if (needSep) pw.println();
   14481                         needSep = true;
   14482                         pw.println("  PID mappings:");
   14483                         printed = true;
   14484                         printedAnything = true;
   14485                     }
   14486                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
   14487                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
   14488                 }
   14489             }
   14490         }
   14491 
   14492         if (mForegroundProcesses.size() > 0) {
   14493             synchronized (mPidsSelfLocked) {
   14494                 boolean printed = false;
   14495                 for (int i=0; i<mForegroundProcesses.size(); i++) {
   14496                     ProcessRecord r = mPidsSelfLocked.get(
   14497                             mForegroundProcesses.valueAt(i).pid);
   14498                     if (dumpPackage != null && (r == null
   14499                             || !r.pkgList.containsKey(dumpPackage))) {
   14500                         continue;
   14501                     }
   14502                     if (!printed) {
   14503                         if (needSep) pw.println();
   14504                         needSep = true;
   14505                         pw.println("  Foreground Processes:");
   14506                         printed = true;
   14507                         printedAnything = true;
   14508                     }
   14509                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
   14510                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
   14511                 }
   14512             }
   14513         }
   14514 
   14515         if (mPersistentStartingProcesses.size() > 0) {
   14516             if (needSep) pw.println();
   14517             needSep = true;
   14518             printedAnything = true;
   14519             pw.println("  Persisent processes that are starting:");
   14520             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
   14521                     "Starting Norm", "Restarting PERS", dumpPackage);
   14522         }
   14523 
   14524         if (mRemovedProcesses.size() > 0) {
   14525             if (needSep) pw.println();
   14526             needSep = true;
   14527             printedAnything = true;
   14528             pw.println("  Processes that are being removed:");
   14529             dumpProcessList(pw, this, mRemovedProcesses, "    ",
   14530                     "Removed Norm", "Removed PERS", dumpPackage);
   14531         }
   14532 
   14533         if (mProcessesOnHold.size() > 0) {
   14534             if (needSep) pw.println();
   14535             needSep = true;
   14536             printedAnything = true;
   14537             pw.println("  Processes that are on old until the system is ready:");
   14538             dumpProcessList(pw, this, mProcessesOnHold, "    ",
   14539                     "OnHold Norm", "OnHold PERS", dumpPackage);
   14540         }
   14541 
   14542         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
   14543 
   14544         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
   14545         if (needSep) {
   14546             printedAnything = true;
   14547         }
   14548 
   14549         if (dumpPackage == null) {
   14550             pw.println();
   14551             needSep = false;
   14552             mUserController.dump(pw, dumpAll);
   14553         }
   14554         if (mHomeProcess != null && (dumpPackage == null
   14555                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
   14556             if (needSep) {
   14557                 pw.println();
   14558                 needSep = false;
   14559             }
   14560             pw.println("  mHomeProcess: " + mHomeProcess);
   14561         }
   14562         if (mPreviousProcess != null && (dumpPackage == null
   14563                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
   14564             if (needSep) {
   14565                 pw.println();
   14566                 needSep = false;
   14567             }
   14568             pw.println("  mPreviousProcess: " + mPreviousProcess);
   14569         }
   14570         if (dumpAll) {
   14571             StringBuilder sb = new StringBuilder(128);
   14572             sb.append("  mPreviousProcessVisibleTime: ");
   14573             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
   14574             pw.println(sb);
   14575         }
   14576         if (mHeavyWeightProcess != null && (dumpPackage == null
   14577                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
   14578             if (needSep) {
   14579                 pw.println();
   14580                 needSep = false;
   14581             }
   14582             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   14583         }
   14584         if (dumpPackage == null) {
   14585             pw.println("  mConfiguration: " + mConfiguration);
   14586         }
   14587         if (dumpAll) {
   14588             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
   14589             if (mCompatModePackages.getPackages().size() > 0) {
   14590                 boolean printed = false;
   14591                 for (Map.Entry<String, Integer> entry
   14592                         : mCompatModePackages.getPackages().entrySet()) {
   14593                     String pkg = entry.getKey();
   14594                     int mode = entry.getValue();
   14595                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
   14596                         continue;
   14597                     }
   14598                     if (!printed) {
   14599                         pw.println("  mScreenCompatPackages:");
   14600                         printed = true;
   14601                     }
   14602                     pw.print("    "); pw.print(pkg); pw.print(": ");
   14603                             pw.print(mode); pw.println();
   14604                 }
   14605             }
   14606         }
   14607         if (dumpPackage == null) {
   14608             pw.println("  mWakefulness="
   14609                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
   14610             pw.println("  mSleepTokens=" + mSleepTokens);
   14611             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
   14612                     + lockScreenShownToString());
   14613             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
   14614             if (mRunningVoice != null) {
   14615                 pw.println("  mRunningVoice=" + mRunningVoice);
   14616                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
   14617             }
   14618         }
   14619         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
   14620                 || mOrigWaitForDebugger) {
   14621             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
   14622                     || dumpPackage.equals(mOrigDebugApp)) {
   14623                 if (needSep) {
   14624                     pw.println();
   14625                     needSep = false;
   14626                 }
   14627                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
   14628                         + " mDebugTransient=" + mDebugTransient
   14629                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
   14630             }
   14631         }
   14632         if (mCurAppTimeTracker != null) {
   14633             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
   14634         }
   14635         if (mMemWatchProcesses.getMap().size() > 0) {
   14636             pw.println("  Mem watch processes:");
   14637             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
   14638                     = mMemWatchProcesses.getMap();
   14639             for (int i=0; i<procs.size(); i++) {
   14640                 final String proc = procs.keyAt(i);
   14641                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
   14642                 for (int j=0; j<uids.size(); j++) {
   14643                     if (needSep) {
   14644                         pw.println();
   14645                         needSep = false;
   14646                     }
   14647                     StringBuilder sb = new StringBuilder();
   14648                     sb.append("    ").append(proc).append('/');
   14649                     UserHandle.formatUid(sb, uids.keyAt(j));
   14650                     Pair<Long, String> val = uids.valueAt(j);
   14651                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
   14652                     if (val.second != null) {
   14653                         sb.append(", report to ").append(val.second);
   14654                     }
   14655                     pw.println(sb.toString());
   14656                 }
   14657             }
   14658             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
   14659             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
   14660             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
   14661                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
   14662         }
   14663         if (mTrackAllocationApp != null) {
   14664             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
   14665                 if (needSep) {
   14666                     pw.println();
   14667                     needSep = false;
   14668                 }
   14669                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
   14670             }
   14671         }
   14672         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
   14673                 || mProfileFd != null) {
   14674             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
   14675                 if (needSep) {
   14676                     pw.println();
   14677                     needSep = false;
   14678                 }
   14679                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
   14680                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
   14681                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
   14682                         + mAutoStopProfiler);
   14683                 pw.println("  mProfileType=" + mProfileType);
   14684             }
   14685         }
   14686         if (mNativeDebuggingApp != null) {
   14687             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
   14688                 if (needSep) {
   14689                     pw.println();
   14690                     needSep = false;
   14691                 }
   14692                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
   14693             }
   14694         }
   14695         if (dumpPackage == null) {
   14696             if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
   14697                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
   14698                         + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
   14699             }
   14700             if (mController != null) {
   14701                 pw.println("  mController=" + mController
   14702                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
   14703             }
   14704             if (dumpAll) {
   14705                 pw.println("  Total persistent processes: " + numPers);
   14706                 pw.println("  mProcessesReady=" + mProcessesReady
   14707                         + " mSystemReady=" + mSystemReady
   14708                         + " mBooted=" + mBooted
   14709                         + " mFactoryTest=" + mFactoryTest);
   14710                 pw.println("  mBooting=" + mBooting
   14711                         + " mCallFinishBooting=" + mCallFinishBooting
   14712                         + " mBootAnimationComplete=" + mBootAnimationComplete);
   14713                 pw.print("  mLastPowerCheckRealtime=");
   14714                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
   14715                         pw.println("");
   14716                 pw.print("  mLastPowerCheckUptime=");
   14717                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
   14718                         pw.println("");
   14719                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
   14720                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
   14721                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
   14722                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
   14723                         + " (" + mLruProcesses.size() + " total)"
   14724                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
   14725                         + " mNumServiceProcs=" + mNumServiceProcs
   14726                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
   14727                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
   14728                         + " mLastMemoryLevel=" + mLastMemoryLevel
   14729                         + " mLastNumProcesses=" + mLastNumProcesses);
   14730                 long now = SystemClock.uptimeMillis();
   14731                 pw.print("  mLastIdleTime=");
   14732                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
   14733                         pw.print(" mLowRamSinceLastIdle=");
   14734                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
   14735                         pw.println();
   14736             }
   14737         }
   14738 
   14739         if (!printedAnything) {
   14740             pw.println("  (nothing)");
   14741         }
   14742     }
   14743 
   14744     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
   14745             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
   14746         if (mProcessesToGc.size() > 0) {
   14747             boolean printed = false;
   14748             long now = SystemClock.uptimeMillis();
   14749             for (int i=0; i<mProcessesToGc.size(); i++) {
   14750                 ProcessRecord proc = mProcessesToGc.get(i);
   14751                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
   14752                     continue;
   14753                 }
   14754                 if (!printed) {
   14755                     if (needSep) pw.println();
   14756                     needSep = true;
   14757                     pw.println("  Processes that are waiting to GC:");
   14758                     printed = true;
   14759                 }
   14760                 pw.print("    Process "); pw.println(proc);
   14761                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
   14762                         pw.print(", last gced=");
   14763                         pw.print(now-proc.lastRequestedGc);
   14764                         pw.print(" ms ago, last lowMem=");
   14765                         pw.print(now-proc.lastLowMemory);
   14766                         pw.println(" ms ago");
   14767 
   14768             }
   14769         }
   14770         return needSep;
   14771     }
   14772 
   14773     void printOomLevel(PrintWriter pw, String name, int adj) {
   14774         pw.print("    ");
   14775         if (adj >= 0) {
   14776             pw.print(' ');
   14777             if (adj < 10) pw.print(' ');
   14778         } else {
   14779             if (adj > -10) pw.print(' ');
   14780         }
   14781         pw.print(adj);
   14782         pw.print(": ");
   14783         pw.print(name);
   14784         pw.print(" (");
   14785         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
   14786         pw.println(")");
   14787     }
   14788 
   14789     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   14790             int opti, boolean dumpAll) {
   14791         boolean needSep = false;
   14792 
   14793         if (mLruProcesses.size() > 0) {
   14794             if (needSep) pw.println();
   14795             needSep = true;
   14796             pw.println("  OOM levels:");
   14797             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
   14798             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
   14799             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
   14800             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
   14801             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
   14802             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
   14803             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
   14804             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
   14805             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
   14806             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
   14807             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
   14808             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
   14809             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
   14810             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
   14811 
   14812             if (needSep) pw.println();
   14813             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
   14814                     pw.print(" total, non-act at ");
   14815                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   14816                     pw.print(", non-svc at ");
   14817                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   14818                     pw.println("):");
   14819             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
   14820             needSep = true;
   14821         }
   14822 
   14823         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
   14824 
   14825         pw.println();
   14826         pw.println("  mHomeProcess: " + mHomeProcess);
   14827         pw.println("  mPreviousProcess: " + mPreviousProcess);
   14828         if (mHeavyWeightProcess != null) {
   14829             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   14830         }
   14831 
   14832         return true;
   14833     }
   14834 
   14835     /**
   14836      * There are three ways to call this:
   14837      *  - no provider specified: dump all the providers
   14838      *  - a flattened component name that matched an existing provider was specified as the
   14839      *    first arg: dump that one provider
   14840      *  - the first arg isn't the flattened component name of an existing provider:
   14841      *    dump all providers whose component contains the first arg as a substring
   14842      */
   14843     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   14844             int opti, boolean dumpAll) {
   14845         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
   14846     }
   14847 
   14848     static class ItemMatcher {
   14849         ArrayList<ComponentName> components;
   14850         ArrayList<String> strings;
   14851         ArrayList<Integer> objects;
   14852         boolean all;
   14853 
   14854         ItemMatcher() {
   14855             all = true;
   14856         }
   14857 
   14858         void build(String name) {
   14859             ComponentName componentName = ComponentName.unflattenFromString(name);
   14860             if (componentName != null) {
   14861                 if (components == null) {
   14862                     components = new ArrayList<ComponentName>();
   14863                 }
   14864                 components.add(componentName);
   14865                 all = false;
   14866             } else {
   14867                 int objectId = 0;
   14868                 // Not a '/' separated full component name; maybe an object ID?
   14869                 try {
   14870                     objectId = Integer.parseInt(name, 16);
   14871                     if (objects == null) {
   14872                         objects = new ArrayList<Integer>();
   14873                     }
   14874                     objects.add(objectId);
   14875                     all = false;
   14876                 } catch (RuntimeException e) {
   14877                     // Not an integer; just do string match.
   14878                     if (strings == null) {
   14879                         strings = new ArrayList<String>();
   14880                     }
   14881                     strings.add(name);
   14882                     all = false;
   14883                 }
   14884             }
   14885         }
   14886 
   14887         int build(String[] args, int opti) {
   14888             for (; opti<args.length; opti++) {
   14889                 String name = args[opti];
   14890                 if ("--".equals(name)) {
   14891                     return opti+1;
   14892                 }
   14893                 build(name);
   14894             }
   14895             return opti;
   14896         }
   14897 
   14898         boolean match(Object object, ComponentName comp) {
   14899             if (all) {
   14900                 return true;
   14901             }
   14902             if (components != null) {
   14903                 for (int i=0; i<components.size(); i++) {
   14904                     if (components.get(i).equals(comp)) {
   14905                         return true;
   14906                     }
   14907                 }
   14908             }
   14909             if (objects != null) {
   14910                 for (int i=0; i<objects.size(); i++) {
   14911                     if (System.identityHashCode(object) == objects.get(i)) {
   14912                         return true;
   14913                     }
   14914                 }
   14915             }
   14916             if (strings != null) {
   14917                 String flat = comp.flattenToString();
   14918                 for (int i=0; i<strings.size(); i++) {
   14919                     if (flat.contains(strings.get(i))) {
   14920                         return true;
   14921                     }
   14922                 }
   14923             }
   14924             return false;
   14925         }
   14926     }
   14927 
   14928     /**
   14929      * There are three things that cmd can be:
   14930      *  - a flattened component name that matches an existing activity
   14931      *  - the cmd arg isn't the flattened component name of an existing activity:
   14932      *    dump all activity whose component contains the cmd as a substring
   14933      *  - A hex number of the ActivityRecord object instance.
   14934      */
   14935     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   14936             int opti, boolean dumpAll) {
   14937         ArrayList<ActivityRecord> activities;
   14938 
   14939         synchronized (this) {
   14940             activities = mStackSupervisor.getDumpActivitiesLocked(name);
   14941         }
   14942 
   14943         if (activities.size() <= 0) {
   14944             return false;
   14945         }
   14946 
   14947         String[] newArgs = new String[args.length - opti];
   14948         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   14949 
   14950         TaskRecord lastTask = null;
   14951         boolean needSep = false;
   14952         for (int i=activities.size()-1; i>=0; i--) {
   14953             ActivityRecord r = activities.get(i);
   14954             if (needSep) {
   14955                 pw.println();
   14956             }
   14957             needSep = true;
   14958             synchronized (this) {
   14959                 if (lastTask != r.task) {
   14960                     lastTask = r.task;
   14961                     pw.print("TASK "); pw.print(lastTask.affinity);
   14962                             pw.print(" id="); pw.println(lastTask.taskId);
   14963                     if (dumpAll) {
   14964                         lastTask.dump(pw, "  ");
   14965                     }
   14966                 }
   14967             }
   14968             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
   14969         }
   14970         return true;
   14971     }
   14972 
   14973     /**
   14974      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
   14975      * there is a thread associated with the activity.
   14976      */
   14977     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
   14978             final ActivityRecord r, String[] args, boolean dumpAll) {
   14979         String innerPrefix = prefix + "  ";
   14980         synchronized (this) {
   14981             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
   14982                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
   14983                     pw.print(" pid=");
   14984                     if (r.app != null) pw.println(r.app.pid);
   14985                     else pw.println("(not running)");
   14986             if (dumpAll) {
   14987                 r.dump(pw, innerPrefix);
   14988             }
   14989         }
   14990         if (r.app != null && r.app.thread != null) {
   14991             // flush anything that is already in the PrintWriter since the thread is going
   14992             // to write to the file descriptor directly
   14993             pw.flush();
   14994             try {
   14995                 TransferPipe tp = new TransferPipe();
   14996                 try {
   14997                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   14998                             r.appToken, innerPrefix, args);
   14999                     tp.go(fd);
   15000                 } finally {
   15001                     tp.kill();
   15002                 }
   15003             } catch (IOException e) {
   15004                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   15005             } catch (RemoteException e) {
   15006                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   15007             }
   15008         }
   15009     }
   15010 
   15011     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15012             int opti, boolean dumpAll, String dumpPackage) {
   15013         boolean needSep = false;
   15014         boolean onlyHistory = false;
   15015         boolean printedAnything = false;
   15016 
   15017         if ("history".equals(dumpPackage)) {
   15018             if (opti < args.length && "-s".equals(args[opti])) {
   15019                 dumpAll = false;
   15020             }
   15021             onlyHistory = true;
   15022             dumpPackage = null;
   15023         }
   15024 
   15025         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
   15026         if (!onlyHistory && dumpAll) {
   15027             if (mRegisteredReceivers.size() > 0) {
   15028                 boolean printed = false;
   15029                 Iterator it = mRegisteredReceivers.values().iterator();
   15030                 while (it.hasNext()) {
   15031                     ReceiverList r = (ReceiverList)it.next();
   15032                     if (dumpPackage != null && (r.app == null ||
   15033                             !dumpPackage.equals(r.app.info.packageName))) {
   15034                         continue;
   15035                     }
   15036                     if (!printed) {
   15037                         pw.println("  Registered Receivers:");
   15038                         needSep = true;
   15039                         printed = true;
   15040                         printedAnything = true;
   15041                     }
   15042                     pw.print("  * "); pw.println(r);
   15043                     r.dump(pw, "    ");
   15044                 }
   15045             }
   15046 
   15047             if (mReceiverResolver.dump(pw, needSep ?
   15048                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
   15049                     "    ", dumpPackage, false, false)) {
   15050                 needSep = true;
   15051                 printedAnything = true;
   15052             }
   15053         }
   15054 
   15055         for (BroadcastQueue q : mBroadcastQueues) {
   15056             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
   15057             printedAnything |= needSep;
   15058         }
   15059 
   15060         needSep = true;
   15061 
   15062         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
   15063             for (int user=0; user<mStickyBroadcasts.size(); user++) {
   15064                 if (needSep) {
   15065                     pw.println();
   15066                 }
   15067                 needSep = true;
   15068                 printedAnything = true;
   15069                 pw.print("  Sticky broadcasts for user ");
   15070                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
   15071                 StringBuilder sb = new StringBuilder(128);
   15072                 for (Map.Entry<String, ArrayList<Intent>> ent
   15073                         : mStickyBroadcasts.valueAt(user).entrySet()) {
   15074                     pw.print("  * Sticky action "); pw.print(ent.getKey());
   15075                     if (dumpAll) {
   15076                         pw.println(":");
   15077                         ArrayList<Intent> intents = ent.getValue();
   15078                         final int N = intents.size();
   15079                         for (int i=0; i<N; i++) {
   15080                             sb.setLength(0);
   15081                             sb.append("    Intent: ");
   15082                             intents.get(i).toShortString(sb, false, true, false, false);
   15083                             pw.println(sb.toString());
   15084                             Bundle bundle = intents.get(i).getExtras();
   15085                             if (bundle != null) {
   15086                                 pw.print("      ");
   15087                                 pw.println(bundle.toString());
   15088                             }
   15089                         }
   15090                     } else {
   15091                         pw.println("");
   15092                     }
   15093                 }
   15094             }
   15095         }
   15096 
   15097         if (!onlyHistory && dumpAll) {
   15098             pw.println();
   15099             for (BroadcastQueue queue : mBroadcastQueues) {
   15100                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
   15101                         + queue.mBroadcastsScheduled);
   15102             }
   15103             pw.println("  mHandler:");
   15104             mHandler.dump(new PrintWriterPrinter(pw), "    ");
   15105             needSep = true;
   15106             printedAnything = true;
   15107         }
   15108 
   15109         if (!printedAnything) {
   15110             pw.println("  (nothing)");
   15111         }
   15112     }
   15113 
   15114     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15115             int opti, boolean dumpAll, String dumpPackage) {
   15116         if (mCurBroadcastStats == null) {
   15117             return;
   15118         }
   15119 
   15120         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
   15121         final long now = SystemClock.elapsedRealtime();
   15122         if (mLastBroadcastStats != null) {
   15123             pw.print("  Last stats (from ");
   15124             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
   15125             pw.print(" to ");
   15126             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
   15127             pw.print(", ");
   15128             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
   15129                     - mLastBroadcastStats.mStartUptime, pw);
   15130             pw.println(" uptime):");
   15131             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
   15132                 pw.println("    (nothing)");
   15133             }
   15134             pw.println();
   15135         }
   15136         pw.print("  Current stats (from ");
   15137         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
   15138         pw.print(" to now, ");
   15139         TimeUtils.formatDuration(SystemClock.uptimeMillis()
   15140                 - mCurBroadcastStats.mStartUptime, pw);
   15141         pw.println(" uptime):");
   15142         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
   15143             pw.println("    (nothing)");
   15144         }
   15145     }
   15146 
   15147     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15148             int opti, boolean fullCheckin, String dumpPackage) {
   15149         if (mCurBroadcastStats == null) {
   15150             return;
   15151         }
   15152 
   15153         if (mLastBroadcastStats != null) {
   15154             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
   15155             if (fullCheckin) {
   15156                 mLastBroadcastStats = null;
   15157                 return;
   15158             }
   15159         }
   15160         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
   15161         if (fullCheckin) {
   15162             mCurBroadcastStats = null;
   15163         }
   15164     }
   15165 
   15166     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15167             int opti, boolean dumpAll, String dumpPackage) {
   15168         boolean needSep;
   15169         boolean printedAnything = false;
   15170 
   15171         ItemMatcher matcher = new ItemMatcher();
   15172         matcher.build(args, opti);
   15173 
   15174         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
   15175 
   15176         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
   15177         printedAnything |= needSep;
   15178 
   15179         if (mLaunchingProviders.size() > 0) {
   15180             boolean printed = false;
   15181             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
   15182                 ContentProviderRecord r = mLaunchingProviders.get(i);
   15183                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
   15184                     continue;
   15185                 }
   15186                 if (!printed) {
   15187                     if (needSep) pw.println();
   15188                     needSep = true;
   15189                     pw.println("  Launching content providers:");
   15190                     printed = true;
   15191                     printedAnything = true;
   15192                 }
   15193                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
   15194                         pw.println(r);
   15195             }
   15196         }
   15197 
   15198         if (!printedAnything) {
   15199             pw.println("  (nothing)");
   15200         }
   15201     }
   15202 
   15203     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15204             int opti, boolean dumpAll, String dumpPackage) {
   15205         boolean needSep = false;
   15206         boolean printedAnything = false;
   15207 
   15208         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
   15209 
   15210         if (mGrantedUriPermissions.size() > 0) {
   15211             boolean printed = false;
   15212             int dumpUid = -2;
   15213             if (dumpPackage != null) {
   15214                 try {
   15215                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
   15216                             MATCH_UNINSTALLED_PACKAGES, 0);
   15217                 } catch (NameNotFoundException e) {
   15218                     dumpUid = -1;
   15219                 }
   15220             }
   15221             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
   15222                 int uid = mGrantedUriPermissions.keyAt(i);
   15223                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
   15224                     continue;
   15225                 }
   15226                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   15227                 if (!printed) {
   15228                     if (needSep) pw.println();
   15229                     needSep = true;
   15230                     pw.println("  Granted Uri Permissions:");
   15231                     printed = true;
   15232                     printedAnything = true;
   15233                 }
   15234                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
   15235                 for (UriPermission perm : perms.values()) {
   15236                     pw.print("    "); pw.println(perm);
   15237                     if (dumpAll) {
   15238                         perm.dump(pw, "      ");
   15239                     }
   15240                 }
   15241             }
   15242         }
   15243 
   15244         if (!printedAnything) {
   15245             pw.println("  (nothing)");
   15246         }
   15247     }
   15248 
   15249     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15250             int opti, boolean dumpAll, String dumpPackage) {
   15251         boolean printed = false;
   15252 
   15253         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
   15254 
   15255         if (mIntentSenderRecords.size() > 0) {
   15256             Iterator<WeakReference<PendingIntentRecord>> it
   15257                     = mIntentSenderRecords.values().iterator();
   15258             while (it.hasNext()) {
   15259                 WeakReference<PendingIntentRecord> ref = it.next();
   15260                 PendingIntentRecord rec = ref != null ? ref.get(): null;
   15261                 if (dumpPackage != null && (rec == null
   15262                         || !dumpPackage.equals(rec.key.packageName))) {
   15263                     continue;
   15264                 }
   15265                 printed = true;
   15266                 if (rec != null) {
   15267                     pw.print("  * "); pw.println(rec);
   15268                     if (dumpAll) {
   15269                         rec.dump(pw, "    ");
   15270                     }
   15271                 } else {
   15272                     pw.print("  * "); pw.println(ref);
   15273                 }
   15274             }
   15275         }
   15276 
   15277         if (!printed) {
   15278             pw.println("  (nothing)");
   15279         }
   15280     }
   15281 
   15282     private static final int dumpProcessList(PrintWriter pw,
   15283             ActivityManagerService service, List list,
   15284             String prefix, String normalLabel, String persistentLabel,
   15285             String dumpPackage) {
   15286         int numPers = 0;
   15287         final int N = list.size()-1;
   15288         for (int i=N; i>=0; i--) {
   15289             ProcessRecord r = (ProcessRecord)list.get(i);
   15290             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   15291                 continue;
   15292             }
   15293             pw.println(String.format("%s%s #%2d: %s",
   15294                     prefix, (r.persistent ? persistentLabel : normalLabel),
   15295                     i, r.toString()));
   15296             if (r.persistent) {
   15297                 numPers++;
   15298             }
   15299         }
   15300         return numPers;
   15301     }
   15302 
   15303     private static final boolean dumpProcessOomList(PrintWriter pw,
   15304             ActivityManagerService service, List<ProcessRecord> origList,
   15305             String prefix, String normalLabel, String persistentLabel,
   15306             boolean inclDetails, String dumpPackage) {
   15307 
   15308         ArrayList<Pair<ProcessRecord, Integer>> list
   15309                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
   15310         for (int i=0; i<origList.size(); i++) {
   15311             ProcessRecord r = origList.get(i);
   15312             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   15313                 continue;
   15314             }
   15315             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
   15316         }
   15317 
   15318         if (list.size() <= 0) {
   15319             return false;
   15320         }
   15321 
   15322         Comparator<Pair<ProcessRecord, Integer>> comparator
   15323                 = new Comparator<Pair<ProcessRecord, Integer>>() {
   15324             @Override
   15325             public int compare(Pair<ProcessRecord, Integer> object1,
   15326                     Pair<ProcessRecord, Integer> object2) {
   15327                 if (object1.first.setAdj != object2.first.setAdj) {
   15328                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
   15329                 }
   15330                 if (object1.first.setProcState != object2.first.setProcState) {
   15331                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
   15332                 }
   15333                 if (object1.second.intValue() != object2.second.intValue()) {
   15334                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
   15335                 }
   15336                 return 0;
   15337             }
   15338         };
   15339 
   15340         Collections.sort(list, comparator);
   15341 
   15342         final long curRealtime = SystemClock.elapsedRealtime();
   15343         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
   15344         final long curUptime = SystemClock.uptimeMillis();
   15345         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
   15346 
   15347         for (int i=list.size()-1; i>=0; i--) {
   15348             ProcessRecord r = list.get(i).first;
   15349             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
   15350             char schedGroup;
   15351             switch (r.setSchedGroup) {
   15352                 case ProcessList.SCHED_GROUP_BACKGROUND:
   15353                     schedGroup = 'B';
   15354                     break;
   15355                 case ProcessList.SCHED_GROUP_DEFAULT:
   15356                     schedGroup = 'F';
   15357                     break;
   15358                 case ProcessList.SCHED_GROUP_TOP_APP:
   15359                     schedGroup = 'T';
   15360                     break;
   15361                 default:
   15362                     schedGroup = '?';
   15363                     break;
   15364             }
   15365             char foreground;
   15366             if (r.foregroundActivities) {
   15367                 foreground = 'A';
   15368             } else if (r.foregroundServices) {
   15369                 foreground = 'S';
   15370             } else {
   15371                 foreground = ' ';
   15372             }
   15373             String procState = ProcessList.makeProcStateString(r.curProcState);
   15374             pw.print(prefix);
   15375             pw.print(r.persistent ? persistentLabel : normalLabel);
   15376             pw.print(" #");
   15377             int num = (origList.size()-1)-list.get(i).second;
   15378             if (num < 10) pw.print(' ');
   15379             pw.print(num);
   15380             pw.print(": ");
   15381             pw.print(oomAdj);
   15382             pw.print(' ');
   15383             pw.print(schedGroup);
   15384             pw.print('/');
   15385             pw.print(foreground);
   15386             pw.print('/');
   15387             pw.print(procState);
   15388             pw.print(" trm:");
   15389             if (r.trimMemoryLevel < 10) pw.print(' ');
   15390             pw.print(r.trimMemoryLevel);
   15391             pw.print(' ');
   15392             pw.print(r.toShortString());
   15393             pw.print(" (");
   15394             pw.print(r.adjType);
   15395             pw.println(')');
   15396             if (r.adjSource != null || r.adjTarget != null) {
   15397                 pw.print(prefix);
   15398                 pw.print("    ");
   15399                 if (r.adjTarget instanceof ComponentName) {
   15400                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
   15401                 } else if (r.adjTarget != null) {
   15402                     pw.print(r.adjTarget.toString());
   15403                 } else {
   15404                     pw.print("{null}");
   15405                 }
   15406                 pw.print("<=");
   15407                 if (r.adjSource instanceof ProcessRecord) {
   15408                     pw.print("Proc{");
   15409                     pw.print(((ProcessRecord)r.adjSource).toShortString());
   15410                     pw.println("}");
   15411                 } else if (r.adjSource != null) {
   15412                     pw.println(r.adjSource.toString());
   15413                 } else {
   15414                     pw.println("{null}");
   15415                 }
   15416             }
   15417             if (inclDetails) {
   15418                 pw.print(prefix);
   15419                 pw.print("    ");
   15420                 pw.print("oom: max="); pw.print(r.maxAdj);
   15421                 pw.print(" curRaw="); pw.print(r.curRawAdj);
   15422                 pw.print(" setRaw="); pw.print(r.setRawAdj);
   15423                 pw.print(" cur="); pw.print(r.curAdj);
   15424                 pw.print(" set="); pw.println(r.setAdj);
   15425                 pw.print(prefix);
   15426                 pw.print("    ");
   15427                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
   15428                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
   15429                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
   15430                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
   15431                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
   15432                 pw.println();
   15433                 pw.print(prefix);
   15434                 pw.print("    ");
   15435                 pw.print("cached="); pw.print(r.cached);
   15436                 pw.print(" empty="); pw.print(r.empty);
   15437                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
   15438 
   15439                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
   15440                     if (r.lastWakeTime != 0) {
   15441                         long wtime;
   15442                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
   15443                         synchronized (stats) {
   15444                             wtime = stats.getProcessWakeTime(r.info.uid,
   15445                                     r.pid, curRealtime);
   15446                         }
   15447                         long timeUsed = wtime - r.lastWakeTime;
   15448                         pw.print(prefix);
   15449                         pw.print("    ");
   15450                         pw.print("keep awake over ");
   15451                         TimeUtils.formatDuration(realtimeSince, pw);
   15452                         pw.print(" used ");
   15453                         TimeUtils.formatDuration(timeUsed, pw);
   15454                         pw.print(" (");
   15455                         pw.print((timeUsed*100)/realtimeSince);
   15456                         pw.println("%)");
   15457                     }
   15458                     if (r.lastCpuTime != 0) {
   15459                         long timeUsed = r.curCpuTime - r.lastCpuTime;
   15460                         pw.print(prefix);
   15461                         pw.print("    ");
   15462                         pw.print("run cpu over ");
   15463                         TimeUtils.formatDuration(uptimeSince, pw);
   15464                         pw.print(" used ");
   15465                         TimeUtils.formatDuration(timeUsed, pw);
   15466                         pw.print(" (");
   15467                         pw.print((timeUsed*100)/uptimeSince);
   15468                         pw.println("%)");
   15469                     }
   15470                 }
   15471             }
   15472         }
   15473         return true;
   15474     }
   15475 
   15476     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
   15477             String[] args) {
   15478         ArrayList<ProcessRecord> procs;
   15479         synchronized (this) {
   15480             if (args != null && args.length > start
   15481                     && args[start].charAt(0) != '-') {
   15482                 procs = new ArrayList<ProcessRecord>();
   15483                 int pid = -1;
   15484                 try {
   15485                     pid = Integer.parseInt(args[start]);
   15486                 } catch (NumberFormatException e) {
   15487                 }
   15488                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   15489                     ProcessRecord proc = mLruProcesses.get(i);
   15490                     if (proc.pid == pid) {
   15491                         procs.add(proc);
   15492                     } else if (allPkgs && proc.pkgList != null
   15493                             && proc.pkgList.containsKey(args[start])) {
   15494                         procs.add(proc);
   15495                     } else if (proc.processName.equals(args[start])) {
   15496                         procs.add(proc);
   15497                     }
   15498                 }
   15499                 if (procs.size() <= 0) {
   15500                     return null;
   15501                 }
   15502             } else {
   15503                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
   15504             }
   15505         }
   15506         return procs;
   15507     }
   15508 
   15509     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
   15510             PrintWriter pw, String[] args) {
   15511         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
   15512         if (procs == null) {
   15513             pw.println("No process found for: " + args[0]);
   15514             return;
   15515         }
   15516 
   15517         long uptime = SystemClock.uptimeMillis();
   15518         long realtime = SystemClock.elapsedRealtime();
   15519         pw.println("Applications Graphics Acceleration Info:");
   15520         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   15521 
   15522         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   15523             ProcessRecord r = procs.get(i);
   15524             if (r.thread != null) {
   15525                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
   15526                 pw.flush();
   15527                 try {
   15528                     TransferPipe tp = new TransferPipe();
   15529                     try {
   15530                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
   15531                         tp.go(fd);
   15532                     } finally {
   15533                         tp.kill();
   15534                     }
   15535                 } catch (IOException e) {
   15536                     pw.println("Failure while dumping the app: " + r);
   15537                     pw.flush();
   15538                 } catch (RemoteException e) {
   15539                     pw.println("Got a RemoteException while dumping the app " + r);
   15540                     pw.flush();
   15541                 }
   15542             }
   15543         }
   15544     }
   15545 
   15546     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
   15547         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
   15548         if (procs == null) {
   15549             pw.println("No process found for: " + args[0]);
   15550             return;
   15551         }
   15552 
   15553         pw.println("Applications Database Info:");
   15554 
   15555         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   15556             ProcessRecord r = procs.get(i);
   15557             if (r.thread != null) {
   15558                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
   15559                 pw.flush();
   15560                 try {
   15561                     TransferPipe tp = new TransferPipe();
   15562                     try {
   15563                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
   15564                         tp.go(fd);
   15565                     } finally {
   15566                         tp.kill();
   15567                     }
   15568                 } catch (IOException e) {
   15569                     pw.println("Failure while dumping the app: " + r);
   15570                     pw.flush();
   15571                 } catch (RemoteException e) {
   15572                     pw.println("Got a RemoteException while dumping the app " + r);
   15573                     pw.flush();
   15574                 }
   15575             }
   15576         }
   15577     }
   15578 
   15579     final static class MemItem {
   15580         final boolean isProc;
   15581         final String label;
   15582         final String shortLabel;
   15583         final long pss;
   15584         final long swapPss;
   15585         final int id;
   15586         final boolean hasActivities;
   15587         ArrayList<MemItem> subitems;
   15588 
   15589         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
   15590                 boolean _hasActivities) {
   15591             isProc = true;
   15592             label = _label;
   15593             shortLabel = _shortLabel;
   15594             pss = _pss;
   15595             swapPss = _swapPss;
   15596             id = _id;
   15597             hasActivities = _hasActivities;
   15598         }
   15599 
   15600         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
   15601             isProc = false;
   15602             label = _label;
   15603             shortLabel = _shortLabel;
   15604             pss = _pss;
   15605             swapPss = _swapPss;
   15606             id = _id;
   15607             hasActivities = false;
   15608         }
   15609     }
   15610 
   15611     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
   15612             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
   15613         if (sort && !isCompact) {
   15614             Collections.sort(items, new Comparator<MemItem>() {
   15615                 @Override
   15616                 public int compare(MemItem lhs, MemItem rhs) {
   15617                     if (lhs.pss < rhs.pss) {
   15618                         return 1;
   15619                     } else if (lhs.pss > rhs.pss) {
   15620                         return -1;
   15621                     }
   15622                     return 0;
   15623                 }
   15624             });
   15625         }
   15626 
   15627         for (int i=0; i<items.size(); i++) {
   15628             MemItem mi = items.get(i);
   15629             if (!isCompact) {
   15630                 if (dumpSwapPss) {
   15631                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
   15632                             mi.label, stringifyKBSize(mi.swapPss));
   15633                 } else {
   15634                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
   15635                 }
   15636             } else if (mi.isProc) {
   15637                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
   15638                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
   15639                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
   15640                 pw.println(mi.hasActivities ? ",a" : ",e");
   15641             } else {
   15642                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
   15643                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
   15644             }
   15645             if (mi.subitems != null) {
   15646                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
   15647                         true, isCompact, dumpSwapPss);
   15648             }
   15649         }
   15650     }
   15651 
   15652     // These are in KB.
   15653     static final long[] DUMP_MEM_BUCKETS = new long[] {
   15654         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
   15655         120*1024, 160*1024, 200*1024,
   15656         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
   15657         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
   15658     };
   15659 
   15660     static final void appendMemBucket(StringBuilder out, long memKB, String label,
   15661             boolean stackLike) {
   15662         int start = label.lastIndexOf('.');
   15663         if (start >= 0) start++;
   15664         else start = 0;
   15665         int end = label.length();
   15666         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
   15667             if (DUMP_MEM_BUCKETS[i] >= memKB) {
   15668                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
   15669                 out.append(bucket);
   15670                 out.append(stackLike ? "MB." : "MB ");
   15671                 out.append(label, start, end);
   15672                 return;
   15673             }
   15674         }
   15675         out.append(memKB/1024);
   15676         out.append(stackLike ? "MB." : "MB ");
   15677         out.append(label, start, end);
   15678     }
   15679 
   15680     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
   15681             ProcessList.NATIVE_ADJ,
   15682             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
   15683             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
   15684             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
   15685             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
   15686             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
   15687             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
   15688     };
   15689     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
   15690             "Native",
   15691             "System", "Persistent", "Persistent Service", "Foreground",
   15692             "Visible", "Perceptible",
   15693             "Heavy Weight", "Backup",
   15694             "A Services", "Home",
   15695             "Previous", "B Services", "Cached"
   15696     };
   15697     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
   15698             "native",
   15699             "sys", "pers", "persvc", "fore",
   15700             "vis", "percept",
   15701             "heavy", "backup",
   15702             "servicea", "home",
   15703             "prev", "serviceb", "cached"
   15704     };
   15705 
   15706     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
   15707             long realtime, boolean isCheckinRequest, boolean isCompact) {
   15708         if (isCompact) {
   15709             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
   15710         }
   15711         if (isCheckinRequest || isCompact) {
   15712             // short checkin version
   15713             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
   15714         } else {
   15715             pw.println("Applications Memory Usage (in Kilobytes):");
   15716             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   15717         }
   15718     }
   15719 
   15720     private static final int KSM_SHARED = 0;
   15721     private static final int KSM_SHARING = 1;
   15722     private static final int KSM_UNSHARED = 2;
   15723     private static final int KSM_VOLATILE = 3;
   15724 
   15725     private final long[] getKsmInfo() {
   15726         long[] longOut = new long[4];
   15727         final int[] SINGLE_LONG_FORMAT = new int[] {
   15728             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
   15729         };
   15730         long[] longTmp = new long[1];
   15731         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
   15732                 SINGLE_LONG_FORMAT, null, longTmp, null);
   15733         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   15734         longTmp[0] = 0;
   15735         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
   15736                 SINGLE_LONG_FORMAT, null, longTmp, null);
   15737         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   15738         longTmp[0] = 0;
   15739         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
   15740                 SINGLE_LONG_FORMAT, null, longTmp, null);
   15741         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   15742         longTmp[0] = 0;
   15743         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
   15744                 SINGLE_LONG_FORMAT, null, longTmp, null);
   15745         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   15746         return longOut;
   15747     }
   15748 
   15749     private static String stringifySize(long size, int order) {
   15750         Locale locale = Locale.US;
   15751         switch (order) {
   15752             case 1:
   15753                 return String.format(locale, "%,13d", size);
   15754             case 1024:
   15755                 return String.format(locale, "%,9dK", size / 1024);
   15756             case 1024 * 1024:
   15757                 return String.format(locale, "%,5dM", size / 1024 / 1024);
   15758             case 1024 * 1024 * 1024:
   15759                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
   15760             default:
   15761                 throw new IllegalArgumentException("Invalid size order");
   15762         }
   15763     }
   15764 
   15765     private static String stringifyKBSize(long size) {
   15766         return stringifySize(size * 1024, 1024);
   15767     }
   15768 
   15769     // Update this version number in case you change the 'compact' format
   15770     private static final int MEMINFO_COMPACT_VERSION = 1;
   15771 
   15772     final void dumpApplicationMemoryUsage(FileDescriptor fd,
   15773             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
   15774         boolean dumpDetails = false;
   15775         boolean dumpFullDetails = false;
   15776         boolean dumpDalvik = false;
   15777         boolean dumpSummaryOnly = false;
   15778         boolean dumpUnreachable = false;
   15779         boolean oomOnly = false;
   15780         boolean isCompact = false;
   15781         boolean localOnly = false;
   15782         boolean packages = false;
   15783         boolean isCheckinRequest = false;
   15784         boolean dumpSwapPss = false;
   15785 
   15786         int opti = 0;
   15787         while (opti < args.length) {
   15788             String opt = args[opti];
   15789             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   15790                 break;
   15791             }
   15792             opti++;
   15793             if ("-a".equals(opt)) {
   15794                 dumpDetails = true;
   15795                 dumpFullDetails = true;
   15796                 dumpDalvik = true;
   15797                 dumpSwapPss = true;
   15798             } else if ("-d".equals(opt)) {
   15799                 dumpDalvik = true;
   15800             } else if ("-c".equals(opt)) {
   15801                 isCompact = true;
   15802             } else if ("-s".equals(opt)) {
   15803                 dumpDetails = true;
   15804                 dumpSummaryOnly = true;
   15805             } else if ("-S".equals(opt)) {
   15806                 dumpSwapPss = true;
   15807             } else if ("--unreachable".equals(opt)) {
   15808                 dumpUnreachable = true;
   15809             } else if ("--oom".equals(opt)) {
   15810                 oomOnly = true;
   15811             } else if ("--local".equals(opt)) {
   15812                 localOnly = true;
   15813             } else if ("--package".equals(opt)) {
   15814                 packages = true;
   15815             } else if ("--checkin".equals(opt)) {
   15816                 isCheckinRequest = true;
   15817 
   15818             } else if ("-h".equals(opt)) {
   15819                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
   15820                 pw.println("  -a: include all available information for each process.");
   15821                 pw.println("  -d: include dalvik details.");
   15822                 pw.println("  -c: dump in a compact machine-parseable representation.");
   15823                 pw.println("  -s: dump only summary of application memory usage.");
   15824                 pw.println("  -S: dump also SwapPss.");
   15825                 pw.println("  --oom: only show processes organized by oom adj.");
   15826                 pw.println("  --local: only collect details locally, don't call process.");
   15827                 pw.println("  --package: interpret process arg as package, dumping all");
   15828                 pw.println("             processes that have loaded that package.");
   15829                 pw.println("  --checkin: dump data for a checkin");
   15830                 pw.println("If [process] is specified it can be the name or ");
   15831                 pw.println("pid of a specific process to dump.");
   15832                 return;
   15833             } else {
   15834                 pw.println("Unknown argument: " + opt + "; use -h for help");
   15835             }
   15836         }
   15837 
   15838         long uptime = SystemClock.uptimeMillis();
   15839         long realtime = SystemClock.elapsedRealtime();
   15840         final long[] tmpLong = new long[1];
   15841 
   15842         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
   15843         if (procs == null) {
   15844             // No Java processes.  Maybe they want to print a native process.
   15845             if (args != null && args.length > opti
   15846                     && args[opti].charAt(0) != '-') {
   15847                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
   15848                         = new ArrayList<ProcessCpuTracker.Stats>();
   15849                 updateCpuStatsNow();
   15850                 int findPid = -1;
   15851                 try {
   15852                     findPid = Integer.parseInt(args[opti]);
   15853                 } catch (NumberFormatException e) {
   15854                 }
   15855                 synchronized (mProcessCpuTracker) {
   15856                     final int N = mProcessCpuTracker.countStats();
   15857                     for (int i=0; i<N; i++) {
   15858                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   15859                         if (st.pid == findPid || (st.baseName != null
   15860                                 && st.baseName.equals(args[opti]))) {
   15861                             nativeProcs.add(st);
   15862                         }
   15863                     }
   15864                 }
   15865                 if (nativeProcs.size() > 0) {
   15866                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
   15867                             isCompact);
   15868                     Debug.MemoryInfo mi = null;
   15869                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
   15870                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
   15871                         final int pid = r.pid;
   15872                         if (!isCheckinRequest && dumpDetails) {
   15873                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
   15874                         }
   15875                         if (mi == null) {
   15876                             mi = new Debug.MemoryInfo();
   15877                         }
   15878                         if (dumpDetails || (!brief && !oomOnly)) {
   15879                             Debug.getMemoryInfo(pid, mi);
   15880                         } else {
   15881                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
   15882                             mi.dalvikPrivateDirty = (int)tmpLong[0];
   15883                         }
   15884                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
   15885                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
   15886                         if (isCheckinRequest) {
   15887                             pw.println();
   15888                         }
   15889                     }
   15890                     return;
   15891                 }
   15892             }
   15893             pw.println("No process found for: " + args[opti]);
   15894             return;
   15895         }
   15896 
   15897         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
   15898             dumpDetails = true;
   15899         }
   15900 
   15901         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
   15902 
   15903         String[] innerArgs = new String[args.length-opti];
   15904         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
   15905 
   15906         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
   15907         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
   15908         long nativePss = 0;
   15909         long nativeSwapPss = 0;
   15910         long dalvikPss = 0;
   15911         long dalvikSwapPss = 0;
   15912         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
   15913                 EmptyArray.LONG;
   15914         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
   15915                 EmptyArray.LONG;
   15916         long otherPss = 0;
   15917         long otherSwapPss = 0;
   15918         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   15919         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   15920 
   15921         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   15922         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   15923         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
   15924                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
   15925 
   15926         long totalPss = 0;
   15927         long totalSwapPss = 0;
   15928         long cachedPss = 0;
   15929         long cachedSwapPss = 0;
   15930         boolean hasSwapPss = false;
   15931 
   15932         Debug.MemoryInfo mi = null;
   15933         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   15934             final ProcessRecord r = procs.get(i);
   15935             final IApplicationThread thread;
   15936             final int pid;
   15937             final int oomAdj;
   15938             final boolean hasActivities;
   15939             synchronized (this) {
   15940                 thread = r.thread;
   15941                 pid = r.pid;
   15942                 oomAdj = r.getSetAdjWithServices();
   15943                 hasActivities = r.activities.size() > 0;
   15944             }
   15945             if (thread != null) {
   15946                 if (!isCheckinRequest && dumpDetails) {
   15947                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
   15948                 }
   15949                 if (mi == null) {
   15950                     mi = new Debug.MemoryInfo();
   15951                 }
   15952                 if (dumpDetails || (!brief && !oomOnly)) {
   15953                     Debug.getMemoryInfo(pid, mi);
   15954                     hasSwapPss = mi.hasSwappedOutPss;
   15955                 } else {
   15956                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
   15957                     mi.dalvikPrivateDirty = (int)tmpLong[0];
   15958                 }
   15959                 if (dumpDetails) {
   15960                     if (localOnly) {
   15961                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
   15962                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
   15963                         if (isCheckinRequest) {
   15964                             pw.println();
   15965                         }
   15966                     } else {
   15967                         try {
   15968                             pw.flush();
   15969                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
   15970                                     dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
   15971                         } catch (RemoteException e) {
   15972                             if (!isCheckinRequest) {
   15973                                 pw.println("Got RemoteException!");
   15974                                 pw.flush();
   15975                             }
   15976                         }
   15977                     }
   15978                 }
   15979 
   15980                 final long myTotalPss = mi.getTotalPss();
   15981                 final long myTotalUss = mi.getTotalUss();
   15982                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
   15983 
   15984                 synchronized (this) {
   15985                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
   15986                         // Record this for posterity if the process has been stable.
   15987                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
   15988                     }
   15989                 }
   15990 
   15991                 if (!isCheckinRequest && mi != null) {
   15992                     totalPss += myTotalPss;
   15993                     totalSwapPss += myTotalSwapPss;
   15994                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
   15995                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
   15996                             myTotalSwapPss, pid, hasActivities);
   15997                     procMems.add(pssItem);
   15998                     procMemsMap.put(pid, pssItem);
   15999 
   16000                     nativePss += mi.nativePss;
   16001                     nativeSwapPss += mi.nativeSwappedOutPss;
   16002                     dalvikPss += mi.dalvikPss;
   16003                     dalvikSwapPss += mi.dalvikSwappedOutPss;
   16004                     for (int j=0; j<dalvikSubitemPss.length; j++) {
   16005                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   16006                         dalvikSubitemSwapPss[j] +=
   16007                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   16008                     }
   16009                     otherPss += mi.otherPss;
   16010                     otherSwapPss += mi.otherSwappedOutPss;
   16011                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   16012                         long mem = mi.getOtherPss(j);
   16013                         miscPss[j] += mem;
   16014                         otherPss -= mem;
   16015                         mem = mi.getOtherSwappedOutPss(j);
   16016                         miscSwapPss[j] += mem;
   16017                         otherSwapPss -= mem;
   16018                     }
   16019 
   16020                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   16021                         cachedPss += myTotalPss;
   16022                         cachedSwapPss += myTotalSwapPss;
   16023                     }
   16024 
   16025                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
   16026                         if (oomIndex == (oomPss.length - 1)
   16027                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
   16028                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
   16029                             oomPss[oomIndex] += myTotalPss;
   16030                             oomSwapPss[oomIndex] += myTotalSwapPss;
   16031                             if (oomProcs[oomIndex] == null) {
   16032                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
   16033                             }
   16034                             oomProcs[oomIndex].add(pssItem);
   16035                             break;
   16036                         }
   16037                     }
   16038                 }
   16039             }
   16040         }
   16041 
   16042         long nativeProcTotalPss = 0;
   16043 
   16044         if (!isCheckinRequest && procs.size() > 1 && !packages) {
   16045             // If we are showing aggregations, also look for native processes to
   16046             // include so that our aggregations are more accurate.
   16047             updateCpuStatsNow();
   16048             mi = null;
   16049             synchronized (mProcessCpuTracker) {
   16050                 final int N = mProcessCpuTracker.countStats();
   16051                 for (int i=0; i<N; i++) {
   16052                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   16053                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
   16054                         if (mi == null) {
   16055                             mi = new Debug.MemoryInfo();
   16056                         }
   16057                         if (!brief && !oomOnly) {
   16058                             Debug.getMemoryInfo(st.pid, mi);
   16059                         } else {
   16060                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
   16061                             mi.nativePrivateDirty = (int)tmpLong[0];
   16062                         }
   16063 
   16064                         final long myTotalPss = mi.getTotalPss();
   16065                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
   16066                         totalPss += myTotalPss;
   16067                         nativeProcTotalPss += myTotalPss;
   16068 
   16069                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
   16070                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
   16071                         procMems.add(pssItem);
   16072 
   16073                         nativePss += mi.nativePss;
   16074                         nativeSwapPss += mi.nativeSwappedOutPss;
   16075                         dalvikPss += mi.dalvikPss;
   16076                         dalvikSwapPss += mi.dalvikSwappedOutPss;
   16077                         for (int j=0; j<dalvikSubitemPss.length; j++) {
   16078                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   16079                             dalvikSubitemSwapPss[j] +=
   16080                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   16081                         }
   16082                         otherPss += mi.otherPss;
   16083                         otherSwapPss += mi.otherSwappedOutPss;
   16084                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   16085                             long mem = mi.getOtherPss(j);
   16086                             miscPss[j] += mem;
   16087                             otherPss -= mem;
   16088                             mem = mi.getOtherSwappedOutPss(j);
   16089                             miscSwapPss[j] += mem;
   16090                             otherSwapPss -= mem;
   16091                         }
   16092                         oomPss[0] += myTotalPss;
   16093                         oomSwapPss[0] += myTotalSwapPss;
   16094                         if (oomProcs[0] == null) {
   16095                             oomProcs[0] = new ArrayList<MemItem>();
   16096                         }
   16097                         oomProcs[0].add(pssItem);
   16098                     }
   16099                 }
   16100             }
   16101 
   16102             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
   16103 
   16104             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
   16105             final MemItem dalvikItem =
   16106                     new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
   16107             if (dalvikSubitemPss.length > 0) {
   16108                 dalvikItem.subitems = new ArrayList<MemItem>();
   16109                 for (int j=0; j<dalvikSubitemPss.length; j++) {
   16110                     final String name = Debug.MemoryInfo.getOtherLabel(
   16111                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
   16112                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
   16113                                     dalvikSubitemSwapPss[j], j));
   16114                 }
   16115             }
   16116             catMems.add(dalvikItem);
   16117             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
   16118             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   16119                 String label = Debug.MemoryInfo.getOtherLabel(j);
   16120                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
   16121             }
   16122 
   16123             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
   16124             for (int j=0; j<oomPss.length; j++) {
   16125                 if (oomPss[j] != 0) {
   16126                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
   16127                             : DUMP_MEM_OOM_LABEL[j];
   16128                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
   16129                             DUMP_MEM_OOM_ADJ[j]);
   16130                     item.subitems = oomProcs[j];
   16131                     oomMems.add(item);
   16132                 }
   16133             }
   16134 
   16135             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
   16136             if (!brief && !oomOnly && !isCompact) {
   16137                 pw.println();
   16138                 pw.println("Total PSS by process:");
   16139                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
   16140                 pw.println();
   16141             }
   16142             if (!isCompact) {
   16143                 pw.println("Total PSS by OOM adjustment:");
   16144             }
   16145             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
   16146             if (!brief && !oomOnly) {
   16147                 PrintWriter out = categoryPw != null ? categoryPw : pw;
   16148                 if (!isCompact) {
   16149                     out.println();
   16150                     out.println("Total PSS by category:");
   16151                 }
   16152                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
   16153             }
   16154             if (!isCompact) {
   16155                 pw.println();
   16156             }
   16157             MemInfoReader memInfo = new MemInfoReader();
   16158             memInfo.readMemInfo();
   16159             if (nativeProcTotalPss > 0) {
   16160                 synchronized (this) {
   16161                     final long cachedKb = memInfo.getCachedSizeKb();
   16162                     final long freeKb = memInfo.getFreeSizeKb();
   16163                     final long zramKb = memInfo.getZramTotalSizeKb();
   16164                     final long kernelKb = memInfo.getKernelUsedSizeKb();
   16165                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
   16166                             kernelKb*1024, nativeProcTotalPss*1024);
   16167                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
   16168                             nativeProcTotalPss);
   16169                 }
   16170             }
   16171             if (!brief) {
   16172                 if (!isCompact) {
   16173                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
   16174                     pw.print(" (status ");
   16175                     switch (mLastMemoryLevel) {
   16176                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
   16177                             pw.println("normal)");
   16178                             break;
   16179                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
   16180                             pw.println("moderate)");
   16181                             break;
   16182                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
   16183                             pw.println("low)");
   16184                             break;
   16185                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
   16186                             pw.println("critical)");
   16187                             break;
   16188                         default:
   16189                             pw.print(mLastMemoryLevel);
   16190                             pw.println(")");
   16191                             break;
   16192                     }
   16193                     pw.print(" Free RAM: ");
   16194                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
   16195                             + memInfo.getFreeSizeKb()));
   16196                     pw.print(" (");
   16197                     pw.print(stringifyKBSize(cachedPss));
   16198                     pw.print(" cached pss + ");
   16199                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
   16200                     pw.print(" cached kernel + ");
   16201                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
   16202                     pw.println(" free)");
   16203                 } else {
   16204                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
   16205                     pw.print(cachedPss + memInfo.getCachedSizeKb()
   16206                             + memInfo.getFreeSizeKb()); pw.print(",");
   16207                     pw.println(totalPss - cachedPss);
   16208                 }
   16209             }
   16210             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
   16211                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
   16212                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
   16213             if (!isCompact) {
   16214                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
   16215                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
   16216                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
   16217                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
   16218                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
   16219             } else {
   16220                 pw.print("lostram,"); pw.println(lostRAM);
   16221             }
   16222             if (!brief) {
   16223                 if (memInfo.getZramTotalSizeKb() != 0) {
   16224                     if (!isCompact) {
   16225                         pw.print("     ZRAM: ");
   16226                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
   16227                                 pw.print(" physical used for ");
   16228                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
   16229                                         - memInfo.getSwapFreeSizeKb()));
   16230                                 pw.print(" in swap (");
   16231                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
   16232                                 pw.println(" total swap)");
   16233                     } else {
   16234                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
   16235                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
   16236                                 pw.println(memInfo.getSwapFreeSizeKb());
   16237                     }
   16238                 }
   16239                 final long[] ksm = getKsmInfo();
   16240                 if (!isCompact) {
   16241                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
   16242                             || ksm[KSM_VOLATILE] != 0) {
   16243                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
   16244                                 pw.print(" saved from shared ");
   16245                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
   16246                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
   16247                                 pw.print(" unshared; ");
   16248                                 pw.print(stringifyKBSize(
   16249                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
   16250                     }
   16251                     pw.print("   Tuning: ");
   16252                     pw.print(ActivityManager.staticGetMemoryClass());
   16253                     pw.print(" (large ");
   16254                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   16255                     pw.print("), oom ");
   16256                     pw.print(stringifySize(
   16257                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
   16258                     pw.print(", restore limit ");
   16259                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
   16260                     if (ActivityManager.isLowRamDeviceStatic()) {
   16261                         pw.print(" (low-ram)");
   16262                     }
   16263                     if (ActivityManager.isHighEndGfx()) {
   16264                         pw.print(" (high-end-gfx)");
   16265                     }
   16266                     pw.println();
   16267                 } else {
   16268                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
   16269                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
   16270                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
   16271                     pw.print("tuning,");
   16272                     pw.print(ActivityManager.staticGetMemoryClass());
   16273                     pw.print(',');
   16274                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   16275                     pw.print(',');
   16276                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
   16277                     if (ActivityManager.isLowRamDeviceStatic()) {
   16278                         pw.print(",low-ram");
   16279                     }
   16280                     if (ActivityManager.isHighEndGfx()) {
   16281                         pw.print(",high-end-gfx");
   16282                     }
   16283                     pw.println();
   16284                 }
   16285             }
   16286         }
   16287     }
   16288 
   16289     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
   16290             long memtrack, String name) {
   16291         sb.append("  ");
   16292         sb.append(ProcessList.makeOomAdjString(oomAdj));
   16293         sb.append(' ');
   16294         sb.append(ProcessList.makeProcStateString(procState));
   16295         sb.append(' ');
   16296         ProcessList.appendRamKb(sb, pss);
   16297         sb.append(": ");
   16298         sb.append(name);
   16299         if (memtrack > 0) {
   16300             sb.append(" (");
   16301             sb.append(stringifyKBSize(memtrack));
   16302             sb.append(" memtrack)");
   16303         }
   16304     }
   16305 
   16306     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
   16307         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
   16308         sb.append(" (pid ");
   16309         sb.append(mi.pid);
   16310         sb.append(") ");
   16311         sb.append(mi.adjType);
   16312         sb.append('\n');
   16313         if (mi.adjReason != null) {
   16314             sb.append("                      ");
   16315             sb.append(mi.adjReason);
   16316             sb.append('\n');
   16317         }
   16318     }
   16319 
   16320     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
   16321         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
   16322         for (int i=0, N=memInfos.size(); i<N; i++) {
   16323             ProcessMemInfo mi = memInfos.get(i);
   16324             infoMap.put(mi.pid, mi);
   16325         }
   16326         updateCpuStatsNow();
   16327         long[] memtrackTmp = new long[1];
   16328         synchronized (mProcessCpuTracker) {
   16329             final int N = mProcessCpuTracker.countStats();
   16330             for (int i=0; i<N; i++) {
   16331                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   16332                 if (st.vsize > 0) {
   16333                     long pss = Debug.getPss(st.pid, null, memtrackTmp);
   16334                     if (pss > 0) {
   16335                         if (infoMap.indexOfKey(st.pid) < 0) {
   16336                             ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
   16337                                     ProcessList.NATIVE_ADJ, -1, "native", null);
   16338                             mi.pss = pss;
   16339                             mi.memtrack = memtrackTmp[0];
   16340                             memInfos.add(mi);
   16341                         }
   16342                     }
   16343                 }
   16344             }
   16345         }
   16346 
   16347         long totalPss = 0;
   16348         long totalMemtrack = 0;
   16349         for (int i=0, N=memInfos.size(); i<N; i++) {
   16350             ProcessMemInfo mi = memInfos.get(i);
   16351             if (mi.pss == 0) {
   16352                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
   16353                 mi.memtrack = memtrackTmp[0];
   16354             }
   16355             totalPss += mi.pss;
   16356             totalMemtrack += mi.memtrack;
   16357         }
   16358         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
   16359             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
   16360                 if (lhs.oomAdj != rhs.oomAdj) {
   16361                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
   16362                 }
   16363                 if (lhs.pss != rhs.pss) {
   16364                     return lhs.pss < rhs.pss ? 1 : -1;
   16365                 }
   16366                 return 0;
   16367             }
   16368         });
   16369 
   16370         StringBuilder tag = new StringBuilder(128);
   16371         StringBuilder stack = new StringBuilder(128);
   16372         tag.append("Low on memory -- ");
   16373         appendMemBucket(tag, totalPss, "total", false);
   16374         appendMemBucket(stack, totalPss, "total", true);
   16375 
   16376         StringBuilder fullNativeBuilder = new StringBuilder(1024);
   16377         StringBuilder shortNativeBuilder = new StringBuilder(1024);
   16378         StringBuilder fullJavaBuilder = new StringBuilder(1024);
   16379 
   16380         boolean firstLine = true;
   16381         int lastOomAdj = Integer.MIN_VALUE;
   16382         long extraNativeRam = 0;
   16383         long extraNativeMemtrack = 0;
   16384         long cachedPss = 0;
   16385         for (int i=0, N=memInfos.size(); i<N; i++) {
   16386             ProcessMemInfo mi = memInfos.get(i);
   16387 
   16388             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   16389                 cachedPss += mi.pss;
   16390             }
   16391 
   16392             if (mi.oomAdj != ProcessList.NATIVE_ADJ
   16393                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
   16394                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
   16395                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
   16396                 if (lastOomAdj != mi.oomAdj) {
   16397                     lastOomAdj = mi.oomAdj;
   16398                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   16399                         tag.append(" / ");
   16400                     }
   16401                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
   16402                         if (firstLine) {
   16403                             stack.append(":");
   16404                             firstLine = false;
   16405                         }
   16406                         stack.append("\n\t at ");
   16407                     } else {
   16408                         stack.append("$");
   16409                     }
   16410                 } else {
   16411                     tag.append(" ");
   16412                     stack.append("$");
   16413                 }
   16414                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   16415                     appendMemBucket(tag, mi.pss, mi.name, false);
   16416                 }
   16417                 appendMemBucket(stack, mi.pss, mi.name, true);
   16418                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
   16419                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
   16420                     stack.append("(");
   16421                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
   16422                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
   16423                             stack.append(DUMP_MEM_OOM_LABEL[k]);
   16424                             stack.append(":");
   16425                             stack.append(DUMP_MEM_OOM_ADJ[k]);
   16426                         }
   16427                     }
   16428                     stack.append(")");
   16429                 }
   16430             }
   16431 
   16432             appendMemInfo(fullNativeBuilder, mi);
   16433             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
   16434                 // The short form only has native processes that are >= 512K.
   16435                 if (mi.pss >= 512) {
   16436                     appendMemInfo(shortNativeBuilder, mi);
   16437                 } else {
   16438                     extraNativeRam += mi.pss;
   16439                     extraNativeMemtrack += mi.memtrack;
   16440                 }
   16441             } else {
   16442                 // Short form has all other details, but if we have collected RAM
   16443                 // from smaller native processes let's dump a summary of that.
   16444                 if (extraNativeRam > 0) {
   16445                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
   16446                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
   16447                     shortNativeBuilder.append('\n');
   16448                     extraNativeRam = 0;
   16449                 }
   16450                 appendMemInfo(fullJavaBuilder, mi);
   16451             }
   16452         }
   16453 
   16454         fullJavaBuilder.append("           ");
   16455         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
   16456         fullJavaBuilder.append(": TOTAL");
   16457         if (totalMemtrack > 0) {
   16458             fullJavaBuilder.append(" (");
   16459             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
   16460             fullJavaBuilder.append(" memtrack)");
   16461         } else {
   16462         }
   16463         fullJavaBuilder.append("\n");
   16464 
   16465         MemInfoReader memInfo = new MemInfoReader();
   16466         memInfo.readMemInfo();
   16467         final long[] infos = memInfo.getRawInfo();
   16468 
   16469         StringBuilder memInfoBuilder = new StringBuilder(1024);
   16470         Debug.getMemInfo(infos);
   16471         memInfoBuilder.append("  MemInfo: ");
   16472         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
   16473         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
   16474         memInfoBuilder.append(stringifyKBSize(
   16475                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
   16476         memInfoBuilder.append(stringifyKBSize(
   16477                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
   16478         memInfoBuilder.append(stringifyKBSize(
   16479                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
   16480         memInfoBuilder.append("           ");
   16481         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
   16482         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
   16483         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
   16484         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
   16485         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
   16486             memInfoBuilder.append("  ZRAM: ");
   16487             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
   16488             memInfoBuilder.append(" RAM, ");
   16489             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
   16490             memInfoBuilder.append(" swap total, ");
   16491             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
   16492             memInfoBuilder.append(" swap free\n");
   16493         }
   16494         final long[] ksm = getKsmInfo();
   16495         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
   16496                 || ksm[KSM_VOLATILE] != 0) {
   16497             memInfoBuilder.append("  KSM: ");
   16498             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
   16499             memInfoBuilder.append(" saved from shared ");
   16500             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
   16501             memInfoBuilder.append("\n       ");
   16502             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
   16503             memInfoBuilder.append(" unshared; ");
   16504             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
   16505             memInfoBuilder.append(" volatile\n");
   16506         }
   16507         memInfoBuilder.append("  Free RAM: ");
   16508         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
   16509                 + memInfo.getFreeSizeKb()));
   16510         memInfoBuilder.append("\n");
   16511         memInfoBuilder.append("  Used RAM: ");
   16512         memInfoBuilder.append(stringifyKBSize(
   16513                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
   16514         memInfoBuilder.append("\n");
   16515         memInfoBuilder.append("  Lost RAM: ");
   16516         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
   16517                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
   16518                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
   16519         memInfoBuilder.append("\n");
   16520         Slog.i(TAG, "Low on memory:");
   16521         Slog.i(TAG, shortNativeBuilder.toString());
   16522         Slog.i(TAG, fullJavaBuilder.toString());
   16523         Slog.i(TAG, memInfoBuilder.toString());
   16524 
   16525         StringBuilder dropBuilder = new StringBuilder(1024);
   16526         /*
   16527         StringWriter oomSw = new StringWriter();
   16528         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
   16529         StringWriter catSw = new StringWriter();
   16530         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
   16531         String[] emptyArgs = new String[] { };
   16532         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
   16533         oomPw.flush();
   16534         String oomString = oomSw.toString();
   16535         */
   16536         dropBuilder.append("Low on memory:");
   16537         dropBuilder.append(stack);
   16538         dropBuilder.append('\n');
   16539         dropBuilder.append(fullNativeBuilder);
   16540         dropBuilder.append(fullJavaBuilder);
   16541         dropBuilder.append('\n');
   16542         dropBuilder.append(memInfoBuilder);
   16543         dropBuilder.append('\n');
   16544         /*
   16545         dropBuilder.append(oomString);
   16546         dropBuilder.append('\n');
   16547         */
   16548         StringWriter catSw = new StringWriter();
   16549         synchronized (ActivityManagerService.this) {
   16550             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
   16551             String[] emptyArgs = new String[] { };
   16552             catPw.println();
   16553             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
   16554             catPw.println();
   16555             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
   16556                     false, null).dumpLocked();
   16557             catPw.println();
   16558             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
   16559             catPw.flush();
   16560         }
   16561         dropBuilder.append(catSw.toString());
   16562         addErrorToDropBox("lowmem", null, "system_server", null,
   16563                 null, tag.toString(), dropBuilder.toString(), null, null);
   16564         //Slog.i(TAG, "Sent to dropbox:");
   16565         //Slog.i(TAG, dropBuilder.toString());
   16566         synchronized (ActivityManagerService.this) {
   16567             long now = SystemClock.uptimeMillis();
   16568             if (mLastMemUsageReportTime < now) {
   16569                 mLastMemUsageReportTime = now;
   16570             }
   16571         }
   16572     }
   16573 
   16574     /**
   16575      * Searches array of arguments for the specified string
   16576      * @param args array of argument strings
   16577      * @param value value to search for
   16578      * @return true if the value is contained in the array
   16579      */
   16580     private static boolean scanArgs(String[] args, String value) {
   16581         if (args != null) {
   16582             for (String arg : args) {
   16583                 if (value.equals(arg)) {
   16584                     return true;
   16585                 }
   16586             }
   16587         }
   16588         return false;
   16589     }
   16590 
   16591     private final boolean removeDyingProviderLocked(ProcessRecord proc,
   16592             ContentProviderRecord cpr, boolean always) {
   16593         final boolean inLaunching = mLaunchingProviders.contains(cpr);
   16594 
   16595         if (!inLaunching || always) {
   16596             synchronized (cpr) {
   16597                 cpr.launchingApp = null;
   16598                 cpr.notifyAll();
   16599             }
   16600             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
   16601             String names[] = cpr.info.authority.split(";");
   16602             for (int j = 0; j < names.length; j++) {
   16603                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
   16604             }
   16605         }
   16606 
   16607         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
   16608             ContentProviderConnection conn = cpr.connections.get(i);
   16609             if (conn.waiting) {
   16610                 // If this connection is waiting for the provider, then we don't
   16611                 // need to mess with its process unless we are always removing
   16612                 // or for some reason the provider is not currently launching.
   16613                 if (inLaunching && !always) {
   16614                     continue;
   16615                 }
   16616             }
   16617             ProcessRecord capp = conn.client;
   16618             conn.dead = true;
   16619             if (conn.stableCount > 0) {
   16620                 if (!capp.persistent && capp.thread != null
   16621                         && capp.pid != 0
   16622                         && capp.pid != MY_PID) {
   16623                     capp.kill("depends on provider "
   16624                             + cpr.name.flattenToShortString()
   16625                             + " in dying proc " + (proc != null ? proc.processName : "??")
   16626                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
   16627                 }
   16628             } else if (capp.thread != null && conn.provider.provider != null) {
   16629                 try {
   16630                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
   16631                 } catch (RemoteException e) {
   16632                 }
   16633                 // In the protocol here, we don't expect the client to correctly
   16634                 // clean up this connection, we'll just remove it.
   16635                 cpr.connections.remove(i);
   16636                 if (conn.client.conProviders.remove(conn)) {
   16637                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
   16638                 }
   16639             }
   16640         }
   16641 
   16642         if (inLaunching && always) {
   16643             mLaunchingProviders.remove(cpr);
   16644         }
   16645         return inLaunching;
   16646     }
   16647 
   16648     /**
   16649      * Main code for cleaning up a process when it has gone away.  This is
   16650      * called both as a result of the process dying, or directly when stopping
   16651      * a process when running in single process mode.
   16652      *
   16653      * @return Returns true if the given process has been restarted, so the
   16654      * app that was passed in must remain on the process lists.
   16655      */
   16656     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
   16657             boolean restarting, boolean allowRestart, int index) {
   16658         if (index >= 0) {
   16659             removeLruProcessLocked(app);
   16660             ProcessList.remove(app.pid);
   16661         }
   16662 
   16663         mProcessesToGc.remove(app);
   16664         mPendingPssProcesses.remove(app);
   16665 
   16666         // Dismiss any open dialogs.
   16667         if (app.crashDialog != null && !app.forceCrashReport) {
   16668             app.crashDialog.dismiss();
   16669             app.crashDialog = null;
   16670         }
   16671         if (app.anrDialog != null) {
   16672             app.anrDialog.dismiss();
   16673             app.anrDialog = null;
   16674         }
   16675         if (app.waitDialog != null) {
   16676             app.waitDialog.dismiss();
   16677             app.waitDialog = null;
   16678         }
   16679 
   16680         app.crashing = false;
   16681         app.notResponding = false;
   16682 
   16683         app.resetPackageList(mProcessStats);
   16684         app.unlinkDeathRecipient();
   16685         app.makeInactive(mProcessStats);
   16686         app.waitingToKill = null;
   16687         app.forcingToForeground = null;
   16688         updateProcessForegroundLocked(app, false, false);
   16689         app.foregroundActivities = false;
   16690         app.hasShownUi = false;
   16691         app.treatLikeActivity = false;
   16692         app.hasAboveClient = false;
   16693         app.hasClientActivities = false;
   16694 
   16695         mServices.killServicesLocked(app, allowRestart);
   16696 
   16697         boolean restart = false;
   16698 
   16699         // Remove published content providers.
   16700         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
   16701             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
   16702             final boolean always = app.bad || !allowRestart;
   16703             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
   16704             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
   16705                 // We left the provider in the launching list, need to
   16706                 // restart it.
   16707                 restart = true;
   16708             }
   16709 
   16710             cpr.provider = null;
   16711             cpr.proc = null;
   16712         }
   16713         app.pubProviders.clear();
   16714 
   16715         // Take care of any launching providers waiting for this process.
   16716         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
   16717             restart = true;
   16718         }
   16719 
   16720         // Unregister from connected content providers.
   16721         if (!app.conProviders.isEmpty()) {
   16722             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
   16723                 ContentProviderConnection conn = app.conProviders.get(i);
   16724                 conn.provider.connections.remove(conn);
   16725                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
   16726                         conn.provider.name);
   16727             }
   16728             app.conProviders.clear();
   16729         }
   16730 
   16731         // At this point there may be remaining entries in mLaunchingProviders
   16732         // where we were the only one waiting, so they are no longer of use.
   16733         // Look for these and clean up if found.
   16734         // XXX Commented out for now.  Trying to figure out a way to reproduce
   16735         // the actual situation to identify what is actually going on.
   16736         if (false) {
   16737             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
   16738                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
   16739                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
   16740                     synchronized (cpr) {
   16741                         cpr.launchingApp = null;
   16742                         cpr.notifyAll();
   16743                     }
   16744                 }
   16745             }
   16746         }
   16747 
   16748         skipCurrentReceiverLocked(app);
   16749 
   16750         // Unregister any receivers.
   16751         for (int i = app.receivers.size() - 1; i >= 0; i--) {
   16752             removeReceiverLocked(app.receivers.valueAt(i));
   16753         }
   16754         app.receivers.clear();
   16755 
   16756         // If the app is undergoing backup, tell the backup manager about it
   16757         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
   16758             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
   16759                     + mBackupTarget.appInfo + " died during backup");
   16760             try {
   16761                 IBackupManager bm = IBackupManager.Stub.asInterface(
   16762                         ServiceManager.getService(Context.BACKUP_SERVICE));
   16763                 bm.agentDisconnected(app.info.packageName);
   16764             } catch (RemoteException e) {
   16765                 // can't happen; backup manager is local
   16766             }
   16767         }
   16768 
   16769         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
   16770             ProcessChangeItem item = mPendingProcessChanges.get(i);
   16771             if (item.pid == app.pid) {
   16772                 mPendingProcessChanges.remove(i);
   16773                 mAvailProcessChanges.add(item);
   16774             }
   16775         }
   16776         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
   16777                 null).sendToTarget();
   16778 
   16779         // If the caller is restarting this app, then leave it in its
   16780         // current lists and let the caller take care of it.
   16781         if (restarting) {
   16782             return false;
   16783         }
   16784 
   16785         if (!app.persistent || app.isolated) {
   16786             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
   16787                     "Removing non-persistent process during cleanup: " + app);
   16788             removeProcessNameLocked(app.processName, app.uid);
   16789             if (mHeavyWeightProcess == app) {
   16790                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   16791                         mHeavyWeightProcess.userId, 0));
   16792                 mHeavyWeightProcess = null;
   16793             }
   16794         } else if (!app.removed) {
   16795             // This app is persistent, so we need to keep its record around.
   16796             // If it is not already on the pending app list, add it there
   16797             // and start a new process for it.
   16798             if (mPersistentStartingProcesses.indexOf(app) < 0) {
   16799                 mPersistentStartingProcesses.add(app);
   16800                 restart = true;
   16801             }
   16802         }
   16803         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
   16804                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
   16805         mProcessesOnHold.remove(app);
   16806 
   16807         if (app == mHomeProcess) {
   16808             mHomeProcess = null;
   16809         }
   16810         if (app == mPreviousProcess) {
   16811             mPreviousProcess = null;
   16812         }
   16813 
   16814         if (restart && !app.isolated) {
   16815             // We have components that still need to be running in the
   16816             // process, so re-launch it.
   16817             if (index < 0) {
   16818                 ProcessList.remove(app.pid);
   16819             }
   16820             addProcessNameLocked(app);
   16821             startProcessLocked(app, "restart", app.processName);
   16822             return true;
   16823         } else if (app.pid > 0 && app.pid != MY_PID) {
   16824             // Goodbye!
   16825             boolean removed;
   16826             synchronized (mPidsSelfLocked) {
   16827                 mPidsSelfLocked.remove(app.pid);
   16828                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   16829             }
   16830             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   16831             if (app.isolated) {
   16832                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   16833             }
   16834             app.setPid(0);
   16835         }
   16836         return false;
   16837     }
   16838 
   16839     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
   16840         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
   16841             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   16842             if (cpr.launchingApp == app) {
   16843                 return true;
   16844             }
   16845         }
   16846         return false;
   16847     }
   16848 
   16849     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
   16850         // Look through the content providers we are waiting to have launched,
   16851         // and if any run in this process then either schedule a restart of
   16852         // the process or kill the client waiting for it if this process has
   16853         // gone bad.
   16854         boolean restart = false;
   16855         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
   16856             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   16857             if (cpr.launchingApp == app) {
   16858                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
   16859                     restart = true;
   16860                 } else {
   16861                     removeDyingProviderLocked(app, cpr, true);
   16862                 }
   16863             }
   16864         }
   16865         return restart;
   16866     }
   16867 
   16868     // =========================================================
   16869     // SERVICES
   16870     // =========================================================
   16871 
   16872     @Override
   16873     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
   16874             int flags) {
   16875         enforceNotIsolatedCaller("getServices");
   16876         synchronized (this) {
   16877             return mServices.getRunningServiceInfoLocked(maxNum, flags);
   16878         }
   16879     }
   16880 
   16881     @Override
   16882     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
   16883         enforceNotIsolatedCaller("getRunningServiceControlPanel");
   16884         synchronized (this) {
   16885             return mServices.getRunningServiceControlPanelLocked(name);
   16886         }
   16887     }
   16888 
   16889     @Override
   16890     public ComponentName startService(IApplicationThread caller, Intent service,
   16891             String resolvedType, String callingPackage, int userId)
   16892             throws TransactionTooLargeException {
   16893         enforceNotIsolatedCaller("startService");
   16894         // Refuse possible leaked file descriptors
   16895         if (service != null && service.hasFileDescriptors() == true) {
   16896             throw new IllegalArgumentException("File descriptors passed in Intent");
   16897         }
   16898 
   16899         if (callingPackage == null) {
   16900             throw new IllegalArgumentException("callingPackage cannot be null");
   16901         }
   16902 
   16903         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
   16904                 "startService: " + service + " type=" + resolvedType);
   16905         synchronized(this) {
   16906             final int callingPid = Binder.getCallingPid();
   16907             final int callingUid = Binder.getCallingUid();
   16908             final long origId = Binder.clearCallingIdentity();
   16909             ComponentName res = mServices.startServiceLocked(caller, service,
   16910                     resolvedType, callingPid, callingUid, callingPackage, userId);
   16911             Binder.restoreCallingIdentity(origId);
   16912             return res;
   16913         }
   16914     }
   16915 
   16916     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
   16917             String callingPackage, int userId)
   16918             throws TransactionTooLargeException {
   16919         synchronized(this) {
   16920             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
   16921                     "startServiceInPackage: " + service + " type=" + resolvedType);
   16922             final long origId = Binder.clearCallingIdentity();
   16923             ComponentName res = mServices.startServiceLocked(null, service,
   16924                     resolvedType, -1, uid, callingPackage, userId);
   16925             Binder.restoreCallingIdentity(origId);
   16926             return res;
   16927         }
   16928     }
   16929 
   16930     @Override
   16931     public int stopService(IApplicationThread caller, Intent service,
   16932             String resolvedType, int userId) {
   16933         enforceNotIsolatedCaller("stopService");
   16934         // Refuse possible leaked file descriptors
   16935         if (service != null && service.hasFileDescriptors() == true) {
   16936             throw new IllegalArgumentException("File descriptors passed in Intent");
   16937         }
   16938 
   16939         synchronized(this) {
   16940             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
   16941         }
   16942     }
   16943 
   16944     @Override
   16945     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
   16946         enforceNotIsolatedCaller("peekService");
   16947         // Refuse possible leaked file descriptors
   16948         if (service != null && service.hasFileDescriptors() == true) {
   16949             throw new IllegalArgumentException("File descriptors passed in Intent");
   16950         }
   16951 
   16952         if (callingPackage == null) {
   16953             throw new IllegalArgumentException("callingPackage cannot be null");
   16954         }
   16955 
   16956         synchronized(this) {
   16957             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
   16958         }
   16959     }
   16960 
   16961     @Override
   16962     public boolean stopServiceToken(ComponentName className, IBinder token,
   16963             int startId) {
   16964         synchronized(this) {
   16965             return mServices.stopServiceTokenLocked(className, token, startId);
   16966         }
   16967     }
   16968 
   16969     @Override
   16970     public void setServiceForeground(ComponentName className, IBinder token,
   16971             int id, Notification notification, int flags) {
   16972         synchronized(this) {
   16973             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
   16974         }
   16975     }
   16976 
   16977     @Override
   16978     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
   16979             boolean requireFull, String name, String callerPackage) {
   16980         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
   16981                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
   16982     }
   16983 
   16984     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
   16985             String className, int flags) {
   16986         boolean result = false;
   16987         // For apps that don't have pre-defined UIDs, check for permission
   16988         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
   16989             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
   16990                 if (ActivityManager.checkUidPermission(
   16991                         INTERACT_ACROSS_USERS,
   16992                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
   16993                     ComponentName comp = new ComponentName(aInfo.packageName, className);
   16994                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
   16995                             + " requests FLAG_SINGLE_USER, but app does not hold "
   16996                             + INTERACT_ACROSS_USERS;
   16997                     Slog.w(TAG, msg);
   16998                     throw new SecurityException(msg);
   16999                 }
   17000                 // Permission passed
   17001                 result = true;
   17002             }
   17003         } else if ("system".equals(componentProcessName)) {
   17004             result = true;
   17005         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
   17006             // Phone app and persistent apps are allowed to export singleuser providers.
   17007             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
   17008                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
   17009         }
   17010         if (DEBUG_MU) Slog.v(TAG_MU,
   17011                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
   17012                 + Integer.toHexString(flags) + ") = " + result);
   17013         return result;
   17014     }
   17015 
   17016     /**
   17017      * Checks to see if the caller is in the same app as the singleton
   17018      * component, or the component is in a special app. It allows special apps
   17019      * to export singleton components but prevents exporting singleton
   17020      * components for regular apps.
   17021      */
   17022     boolean isValidSingletonCall(int callingUid, int componentUid) {
   17023         int componentAppId = UserHandle.getAppId(componentUid);
   17024         return UserHandle.isSameApp(callingUid, componentUid)
   17025                 || componentAppId == Process.SYSTEM_UID
   17026                 || componentAppId == Process.PHONE_UID
   17027                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
   17028                         == PackageManager.PERMISSION_GRANTED;
   17029     }
   17030 
   17031     public int bindService(IApplicationThread caller, IBinder token, Intent service,
   17032             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
   17033             int userId) throws TransactionTooLargeException {
   17034         enforceNotIsolatedCaller("bindService");
   17035 
   17036         // Refuse possible leaked file descriptors
   17037         if (service != null && service.hasFileDescriptors() == true) {
   17038             throw new IllegalArgumentException("File descriptors passed in Intent");
   17039         }
   17040 
   17041         if (callingPackage == null) {
   17042             throw new IllegalArgumentException("callingPackage cannot be null");
   17043         }
   17044 
   17045         synchronized(this) {
   17046             return mServices.bindServiceLocked(caller, token, service,
   17047                     resolvedType, connection, flags, callingPackage, userId);
   17048         }
   17049     }
   17050 
   17051     public boolean unbindService(IServiceConnection connection) {
   17052         synchronized (this) {
   17053             return mServices.unbindServiceLocked(connection);
   17054         }
   17055     }
   17056 
   17057     public void publishService(IBinder token, Intent intent, IBinder service) {
   17058         // Refuse possible leaked file descriptors
   17059         if (intent != null && intent.hasFileDescriptors() == true) {
   17060             throw new IllegalArgumentException("File descriptors passed in Intent");
   17061         }
   17062 
   17063         synchronized(this) {
   17064             if (!(token instanceof ServiceRecord)) {
   17065                 throw new IllegalArgumentException("Invalid service token");
   17066             }
   17067             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
   17068         }
   17069     }
   17070 
   17071     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
   17072         // Refuse possible leaked file descriptors
   17073         if (intent != null && intent.hasFileDescriptors() == true) {
   17074             throw new IllegalArgumentException("File descriptors passed in Intent");
   17075         }
   17076 
   17077         synchronized(this) {
   17078             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
   17079         }
   17080     }
   17081 
   17082     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
   17083         synchronized(this) {
   17084             if (!(token instanceof ServiceRecord)) {
   17085                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
   17086                 throw new IllegalArgumentException("Invalid service token");
   17087             }
   17088             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
   17089         }
   17090     }
   17091 
   17092     // =========================================================
   17093     // BACKUP AND RESTORE
   17094     // =========================================================
   17095 
   17096     // Cause the target app to be launched if necessary and its backup agent
   17097     // instantiated.  The backup agent will invoke backupAgentCreated() on the
   17098     // activity manager to announce its creation.
   17099     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
   17100         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
   17101         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
   17102 
   17103         IPackageManager pm = AppGlobals.getPackageManager();
   17104         ApplicationInfo app = null;
   17105         try {
   17106             app = pm.getApplicationInfo(packageName, 0, userId);
   17107         } catch (RemoteException e) {
   17108             // can't happen; package manager is process-local
   17109         }
   17110         if (app == null) {
   17111             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
   17112             return false;
   17113         }
   17114 
   17115         synchronized(this) {
   17116             // !!! TODO: currently no check here that we're already bound
   17117             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   17118             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   17119             synchronized (stats) {
   17120                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
   17121             }
   17122 
   17123             // Backup agent is now in use, its package can't be stopped.
   17124             try {
   17125                 AppGlobals.getPackageManager().setPackageStoppedState(
   17126                         app.packageName, false, UserHandle.getUserId(app.uid));
   17127             } catch (RemoteException e) {
   17128             } catch (IllegalArgumentException e) {
   17129                 Slog.w(TAG, "Failed trying to unstop package "
   17130                         + app.packageName + ": " + e);
   17131             }
   17132 
   17133             BackupRecord r = new BackupRecord(ss, app, backupMode);
   17134             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
   17135                     ? new ComponentName(app.packageName, app.backupAgentName)
   17136                     : new ComponentName("android", "FullBackupAgent");
   17137             // startProcessLocked() returns existing proc's record if it's already running
   17138             ProcessRecord proc = startProcessLocked(app.processName, app,
   17139                     false, 0, "backup", hostingName, false, false, false);
   17140             if (proc == null) {
   17141                 Slog.e(TAG, "Unable to start backup agent process " + r);
   17142                 return false;
   17143             }
   17144 
   17145             // If the app is a regular app (uid >= 10000) and not the system server or phone
   17146             // process, etc, then mark it as being in full backup so that certain calls to the
   17147             // process can be blocked. This is not reset to false anywhere because we kill the
   17148             // process after the full backup is done and the ProcessRecord will vaporize anyway.
   17149             if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
   17150                 proc.inFullBackup = true;
   17151             }
   17152             r.app = proc;
   17153             mBackupTarget = r;
   17154             mBackupAppName = app.packageName;
   17155 
   17156             // Try not to kill the process during backup
   17157             updateOomAdjLocked(proc);
   17158 
   17159             // If the process is already attached, schedule the creation of the backup agent now.
   17160             // If it is not yet live, this will be done when it attaches to the framework.
   17161             if (proc.thread != null) {
   17162                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
   17163                 try {
   17164                     proc.thread.scheduleCreateBackupAgent(app,
   17165                             compatibilityInfoForPackageLocked(app), backupMode);
   17166                 } catch (RemoteException e) {
   17167                     // Will time out on the backup manager side
   17168                 }
   17169             } else {
   17170                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
   17171             }
   17172             // Invariants: at this point, the target app process exists and the application
   17173             // is either already running or in the process of coming up.  mBackupTarget and
   17174             // mBackupAppName describe the app, so that when it binds back to the AM we
   17175             // know that it's scheduled for a backup-agent operation.
   17176         }
   17177 
   17178         return true;
   17179     }
   17180 
   17181     @Override
   17182     public void clearPendingBackup() {
   17183         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
   17184         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
   17185 
   17186         synchronized (this) {
   17187             mBackupTarget = null;
   17188             mBackupAppName = null;
   17189         }
   17190     }
   17191 
   17192     // A backup agent has just come up
   17193     public void backupAgentCreated(String agentPackageName, IBinder agent) {
   17194         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
   17195                 + " = " + agent);
   17196 
   17197         synchronized(this) {
   17198             if (!agentPackageName.equals(mBackupAppName)) {
   17199                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
   17200                 return;
   17201             }
   17202         }
   17203 
   17204         long oldIdent = Binder.clearCallingIdentity();
   17205         try {
   17206             IBackupManager bm = IBackupManager.Stub.asInterface(
   17207                     ServiceManager.getService(Context.BACKUP_SERVICE));
   17208             bm.agentConnected(agentPackageName, agent);
   17209         } catch (RemoteException e) {
   17210             // can't happen; the backup manager service is local
   17211         } catch (Exception e) {
   17212             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
   17213             e.printStackTrace();
   17214         } finally {
   17215             Binder.restoreCallingIdentity(oldIdent);
   17216         }
   17217     }
   17218 
   17219     // done with this agent
   17220     public void unbindBackupAgent(ApplicationInfo appInfo) {
   17221         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
   17222         if (appInfo == null) {
   17223             Slog.w(TAG, "unbind backup agent for null app");
   17224             return;
   17225         }
   17226 
   17227         synchronized(this) {
   17228             try {
   17229                 if (mBackupAppName == null) {
   17230                     Slog.w(TAG, "Unbinding backup agent with no active backup");
   17231                     return;
   17232                 }
   17233 
   17234                 if (!mBackupAppName.equals(appInfo.packageName)) {
   17235                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
   17236                     return;
   17237                 }
   17238 
   17239                 // Not backing this app up any more; reset its OOM adjustment
   17240                 final ProcessRecord proc = mBackupTarget.app;
   17241                 updateOomAdjLocked(proc);
   17242 
   17243                 // If the app crashed during backup, 'thread' will be null here
   17244                 if (proc.thread != null) {
   17245                     try {
   17246                         proc.thread.scheduleDestroyBackupAgent(appInfo,
   17247                                 compatibilityInfoForPackageLocked(appInfo));
   17248                     } catch (Exception e) {
   17249                         Slog.e(TAG, "Exception when unbinding backup agent:");
   17250                         e.printStackTrace();
   17251                     }
   17252                 }
   17253             } finally {
   17254                 mBackupTarget = null;
   17255                 mBackupAppName = null;
   17256             }
   17257         }
   17258     }
   17259     // =========================================================
   17260     // BROADCASTS
   17261     // =========================================================
   17262 
   17263     boolean isPendingBroadcastProcessLocked(int pid) {
   17264         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
   17265                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
   17266     }
   17267 
   17268     void skipPendingBroadcastLocked(int pid) {
   17269             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   17270             for (BroadcastQueue queue : mBroadcastQueues) {
   17271                 queue.skipPendingBroadcastLocked(pid);
   17272             }
   17273     }
   17274 
   17275     // The app just attached; send any pending broadcasts that it should receive
   17276     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
   17277         boolean didSomething = false;
   17278         for (BroadcastQueue queue : mBroadcastQueues) {
   17279             didSomething |= queue.sendPendingBroadcastsLocked(app);
   17280         }
   17281         return didSomething;
   17282     }
   17283 
   17284     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
   17285             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
   17286         enforceNotIsolatedCaller("registerReceiver");
   17287         ArrayList<Intent> stickyIntents = null;
   17288         ProcessRecord callerApp = null;
   17289         int callingUid;
   17290         int callingPid;
   17291         synchronized(this) {
   17292             if (caller != null) {
   17293                 callerApp = getRecordForAppLocked(caller);
   17294                 if (callerApp == null) {
   17295                     throw new SecurityException(
   17296                             "Unable to find app for caller " + caller
   17297                             + " (pid=" + Binder.getCallingPid()
   17298                             + ") when registering receiver " + receiver);
   17299                 }
   17300                 if (callerApp.info.uid != Process.SYSTEM_UID &&
   17301                         !callerApp.pkgList.containsKey(callerPackage) &&
   17302                         !"android".equals(callerPackage)) {
   17303                     throw new SecurityException("Given caller package " + callerPackage
   17304                             + " is not running in process " + callerApp);
   17305                 }
   17306                 callingUid = callerApp.info.uid;
   17307                 callingPid = callerApp.pid;
   17308             } else {
   17309                 callerPackage = null;
   17310                 callingUid = Binder.getCallingUid();
   17311                 callingPid = Binder.getCallingPid();
   17312             }
   17313 
   17314             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
   17315                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
   17316 
   17317             Iterator<String> actions = filter.actionsIterator();
   17318             if (actions == null) {
   17319                 ArrayList<String> noAction = new ArrayList<String>(1);
   17320                 noAction.add(null);
   17321                 actions = noAction.iterator();
   17322             }
   17323 
   17324             // Collect stickies of users
   17325             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
   17326             while (actions.hasNext()) {
   17327                 String action = actions.next();
   17328                 for (int id : userIds) {
   17329                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
   17330                     if (stickies != null) {
   17331                         ArrayList<Intent> intents = stickies.get(action);
   17332                         if (intents != null) {
   17333                             if (stickyIntents == null) {
   17334                                 stickyIntents = new ArrayList<Intent>();
   17335                             }
   17336                             stickyIntents.addAll(intents);
   17337                         }
   17338                     }
   17339                 }
   17340             }
   17341         }
   17342 
   17343         ArrayList<Intent> allSticky = null;
   17344         if (stickyIntents != null) {
   17345             final ContentResolver resolver = mContext.getContentResolver();
   17346             // Look for any matching sticky broadcasts...
   17347             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
   17348                 Intent intent = stickyIntents.get(i);
   17349                 // If intent has scheme "content", it will need to acccess
   17350                 // provider that needs to lock mProviderMap in ActivityThread
   17351                 // and also it may need to wait application response, so we
   17352                 // cannot lock ActivityManagerService here.
   17353                 if (filter.match(resolver, intent, true, TAG) >= 0) {
   17354                     if (allSticky == null) {
   17355                         allSticky = new ArrayList<Intent>();
   17356                     }
   17357                     allSticky.add(intent);
   17358                 }
   17359             }
   17360         }
   17361 
   17362         // The first sticky in the list is returned directly back to the client.
   17363         Intent sticky = allSticky != null ? allSticky.get(0) : null;
   17364         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
   17365         if (receiver == null) {
   17366             return sticky;
   17367         }
   17368 
   17369         synchronized (this) {
   17370             if (callerApp != null && (callerApp.thread == null
   17371                     || callerApp.thread.asBinder() != caller.asBinder())) {
   17372                 // Original caller already died
   17373                 return null;
   17374             }
   17375             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
   17376             if (rl == null) {
   17377                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
   17378                         userId, receiver);
   17379                 if (rl.app != null) {
   17380                     rl.app.receivers.add(rl);
   17381                 } else {
   17382                     try {
   17383                         receiver.asBinder().linkToDeath(rl, 0);
   17384                     } catch (RemoteException e) {
   17385                         return sticky;
   17386                     }
   17387                     rl.linkedToDeath = true;
   17388                 }
   17389                 mRegisteredReceivers.put(receiver.asBinder(), rl);
   17390             } else if (rl.uid != callingUid) {
   17391                 throw new IllegalArgumentException(
   17392                         "Receiver requested to register for uid " + callingUid
   17393                         + " was previously registered for uid " + rl.uid);
   17394             } else if (rl.pid != callingPid) {
   17395                 throw new IllegalArgumentException(
   17396                         "Receiver requested to register for pid " + callingPid
   17397                         + " was previously registered for pid " + rl.pid);
   17398             } else if (rl.userId != userId) {
   17399                 throw new IllegalArgumentException(
   17400                         "Receiver requested to register for user " + userId
   17401                         + " was previously registered for user " + rl.userId);
   17402             }
   17403             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
   17404                     permission, callingUid, userId);
   17405             rl.add(bf);
   17406             if (!bf.debugCheck()) {
   17407                 Slog.w(TAG, "==> For Dynamic broadcast");
   17408             }
   17409             mReceiverResolver.addFilter(bf);
   17410 
   17411             // Enqueue broadcasts for all existing stickies that match
   17412             // this filter.
   17413             if (allSticky != null) {
   17414                 ArrayList receivers = new ArrayList();
   17415                 receivers.add(bf);
   17416 
   17417                 final int stickyCount = allSticky.size();
   17418                 for (int i = 0; i < stickyCount; i++) {
   17419                     Intent intent = allSticky.get(i);
   17420                     BroadcastQueue queue = broadcastQueueForIntent(intent);
   17421                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
   17422                             null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
   17423                             null, 0, null, null, false, true, true, -1);
   17424                     queue.enqueueParallelBroadcastLocked(r);
   17425                     queue.scheduleBroadcastsLocked();
   17426                 }
   17427             }
   17428 
   17429             return sticky;
   17430         }
   17431     }
   17432 
   17433     public void unregisterReceiver(IIntentReceiver receiver) {
   17434         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
   17435 
   17436         final long origId = Binder.clearCallingIdentity();
   17437         try {
   17438             boolean doTrim = false;
   17439 
   17440             synchronized(this) {
   17441                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
   17442                 if (rl != null) {
   17443                     final BroadcastRecord r = rl.curBroadcast;
   17444                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
   17445                         final boolean doNext = r.queue.finishReceiverLocked(
   17446                                 r, r.resultCode, r.resultData, r.resultExtras,
   17447                                 r.resultAbort, false);
   17448                         if (doNext) {
   17449                             doTrim = true;
   17450                             r.queue.processNextBroadcast(false);
   17451                         }
   17452                     }
   17453 
   17454                     if (rl.app != null) {
   17455                         rl.app.receivers.remove(rl);
   17456                     }
   17457                     removeReceiverLocked(rl);
   17458                     if (rl.linkedToDeath) {
   17459                         rl.linkedToDeath = false;
   17460                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
   17461                     }
   17462                 }
   17463             }
   17464 
   17465             // If we actually concluded any broadcasts, we might now be able
   17466             // to trim the recipients' apps from our working set
   17467             if (doTrim) {
   17468                 trimApplications();
   17469                 return;
   17470             }
   17471 
   17472         } finally {
   17473             Binder.restoreCallingIdentity(origId);
   17474         }
   17475     }
   17476 
   17477     void removeReceiverLocked(ReceiverList rl) {
   17478         mRegisteredReceivers.remove(rl.receiver.asBinder());
   17479         for (int i = rl.size() - 1; i >= 0; i--) {
   17480             mReceiverResolver.removeFilter(rl.get(i));
   17481         }
   17482     }
   17483 
   17484     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
   17485         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   17486             ProcessRecord r = mLruProcesses.get(i);
   17487             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
   17488                 try {
   17489                     r.thread.dispatchPackageBroadcast(cmd, packages);
   17490                 } catch (RemoteException ex) {
   17491                 }
   17492             }
   17493         }
   17494     }
   17495 
   17496     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
   17497             int callingUid, int[] users) {
   17498         // TODO: come back and remove this assumption to triage all broadcasts
   17499         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
   17500 
   17501         List<ResolveInfo> receivers = null;
   17502         try {
   17503             HashSet<ComponentName> singleUserReceivers = null;
   17504             boolean scannedFirstReceivers = false;
   17505             for (int user : users) {
   17506                 // Skip users that have Shell restrictions, with exception of always permitted
   17507                 // Shell broadcasts
   17508                 if (callingUid == Process.SHELL_UID
   17509                         && mUserController.hasUserRestriction(
   17510                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
   17511                         && !isPermittedShellBroadcast(intent)) {
   17512                     continue;
   17513                 }
   17514                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
   17515                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
   17516                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
   17517                     // If this is not the system user, we need to check for
   17518                     // any receivers that should be filtered out.
   17519                     for (int i=0; i<newReceivers.size(); i++) {
   17520                         ResolveInfo ri = newReceivers.get(i);
   17521                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
   17522                             newReceivers.remove(i);
   17523                             i--;
   17524                         }
   17525                     }
   17526                 }
   17527                 if (newReceivers != null && newReceivers.size() == 0) {
   17528                     newReceivers = null;
   17529                 }
   17530                 if (receivers == null) {
   17531                     receivers = newReceivers;
   17532                 } else if (newReceivers != null) {
   17533                     // We need to concatenate the additional receivers
   17534                     // found with what we have do far.  This would be easy,
   17535                     // but we also need to de-dup any receivers that are
   17536                     // singleUser.
   17537                     if (!scannedFirstReceivers) {
   17538                         // Collect any single user receivers we had already retrieved.
   17539                         scannedFirstReceivers = true;
   17540                         for (int i=0; i<receivers.size(); i++) {
   17541                             ResolveInfo ri = receivers.get(i);
   17542                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   17543                                 ComponentName cn = new ComponentName(
   17544                                         ri.activityInfo.packageName, ri.activityInfo.name);
   17545                                 if (singleUserReceivers == null) {
   17546                                     singleUserReceivers = new HashSet<ComponentName>();
   17547                                 }
   17548                                 singleUserReceivers.add(cn);
   17549                             }
   17550                         }
   17551                     }
   17552                     // Add the new results to the existing results, tracking
   17553                     // and de-dupping single user receivers.
   17554                     for (int i=0; i<newReceivers.size(); i++) {
   17555                         ResolveInfo ri = newReceivers.get(i);
   17556                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   17557                             ComponentName cn = new ComponentName(
   17558                                     ri.activityInfo.packageName, ri.activityInfo.name);
   17559                             if (singleUserReceivers == null) {
   17560                                 singleUserReceivers = new HashSet<ComponentName>();
   17561                             }
   17562                             if (!singleUserReceivers.contains(cn)) {
   17563                                 singleUserReceivers.add(cn);
   17564                                 receivers.add(ri);
   17565                             }
   17566                         } else {
   17567                             receivers.add(ri);
   17568                         }
   17569                     }
   17570                 }
   17571             }
   17572         } catch (RemoteException ex) {
   17573             // pm is in same process, this will never happen.
   17574         }
   17575         return receivers;
   17576     }
   17577 
   17578     private boolean isPermittedShellBroadcast(Intent intent) {
   17579         // remote bugreport should always be allowed to be taken
   17580         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
   17581     }
   17582 
   17583     final int broadcastIntentLocked(ProcessRecord callerApp,
   17584             String callerPackage, Intent intent, String resolvedType,
   17585             IIntentReceiver resultTo, int resultCode, String resultData,
   17586             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
   17587             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
   17588         intent = new Intent(intent);
   17589 
   17590         // By default broadcasts do not go to stopped apps.
   17591         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
   17592 
   17593         // If we have not finished booting, don't allow this to launch new processes.
   17594         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
   17595             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   17596         }
   17597 
   17598         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
   17599                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
   17600                 + " ordered=" + ordered + " userid=" + userId);
   17601         if ((resultTo != null) && !ordered) {
   17602             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
   17603         }
   17604 
   17605         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
   17606                 ALLOW_NON_FULL, "broadcast", callerPackage);
   17607 
   17608         // Make sure that the user who is receiving this broadcast is running.
   17609         // If not, we will just skip it. Make an exception for shutdown broadcasts
   17610         // and upgrade steps.
   17611 
   17612         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
   17613             if ((callingUid != Process.SYSTEM_UID
   17614                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
   17615                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
   17616                 Slog.w(TAG, "Skipping broadcast of " + intent
   17617                         + ": user " + userId + " is stopped");
   17618                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
   17619             }
   17620         }
   17621 
   17622         BroadcastOptions brOptions = null;
   17623         if (bOptions != null) {
   17624             brOptions = new BroadcastOptions(bOptions);
   17625             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
   17626                 // See if the caller is allowed to do this.  Note we are checking against
   17627                 // the actual real caller (not whoever provided the operation as say a
   17628                 // PendingIntent), because that who is actually supplied the arguments.
   17629                 if (checkComponentPermission(
   17630                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
   17631                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
   17632                         != PackageManager.PERMISSION_GRANTED) {
   17633                     String msg = "Permission Denial: " + intent.getAction()
   17634                             + " broadcast from " + callerPackage + " (pid=" + callingPid
   17635                             + ", uid=" + callingUid + ")"
   17636                             + " requires "
   17637                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
   17638                     Slog.w(TAG, msg);
   17639                     throw new SecurityException(msg);
   17640                 }
   17641             }
   17642         }
   17643 
   17644         // Verify that protected broadcasts are only being sent by system code,
   17645         // and that system code is only sending protected broadcasts.
   17646         final String action = intent.getAction();
   17647         final boolean isProtectedBroadcast;
   17648         try {
   17649             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
   17650         } catch (RemoteException e) {
   17651             Slog.w(TAG, "Remote exception", e);
   17652             return ActivityManager.BROADCAST_SUCCESS;
   17653         }
   17654 
   17655         final boolean isCallerSystem;
   17656         switch (UserHandle.getAppId(callingUid)) {
   17657             case Process.ROOT_UID:
   17658             case Process.SYSTEM_UID:
   17659             case Process.PHONE_UID:
   17660             case Process.BLUETOOTH_UID:
   17661             case Process.NFC_UID:
   17662                 isCallerSystem = true;
   17663                 break;
   17664             default:
   17665                 isCallerSystem = (callerApp != null) && callerApp.persistent;
   17666                 break;
   17667         }
   17668 
   17669         if (isCallerSystem) {
   17670             if (isProtectedBroadcast
   17671                     || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
   17672                     || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
   17673                     || Intent.ACTION_MEDIA_BUTTON.equals(action)
   17674                     || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
   17675                     || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
   17676                     || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
   17677                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
   17678                     || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
   17679                     || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
   17680                     || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
   17681                 // Broadcast is either protected, or it's a public action that
   17682                 // we've relaxed, so it's fine for system internals to send.
   17683             } else {
   17684                 // The vast majority of broadcasts sent from system internals
   17685                 // should be protected to avoid security holes, so yell loudly
   17686                 // to ensure we examine these cases.
   17687                 if (callerApp != null) {
   17688                     Log.wtf(TAG, "Sending non-protected broadcast " + action
   17689                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
   17690                             new Throwable());
   17691                 } else {
   17692                     Log.wtf(TAG, "Sending non-protected broadcast " + action
   17693                             + " from system uid " + UserHandle.formatUid(callingUid)
   17694                             + " pkg " + callerPackage,
   17695                             new Throwable());
   17696                 }
   17697             }
   17698 
   17699         } else {
   17700             if (isProtectedBroadcast) {
   17701                 String msg = "Permission Denial: not allowed to send broadcast "
   17702                         + action + " from pid="
   17703                         + callingPid + ", uid=" + callingUid;
   17704                 Slog.w(TAG, msg);
   17705                 throw new SecurityException(msg);
   17706 
   17707             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
   17708                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
   17709                 // Special case for compatibility: we don't want apps to send this,
   17710                 // but historically it has not been protected and apps may be using it
   17711                 // to poke their own app widget.  So, instead of making it protected,
   17712                 // just limit it to the caller.
   17713                 if (callerPackage == null) {
   17714                     String msg = "Permission Denial: not allowed to send broadcast "
   17715                             + action + " from unknown caller.";
   17716                     Slog.w(TAG, msg);
   17717                     throw new SecurityException(msg);
   17718                 } else if (intent.getComponent() != null) {
   17719                     // They are good enough to send to an explicit component...  verify
   17720                     // it is being sent to the calling app.
   17721                     if (!intent.getComponent().getPackageName().equals(
   17722                             callerPackage)) {
   17723                         String msg = "Permission Denial: not allowed to send broadcast "
   17724                                 + action + " to "
   17725                                 + intent.getComponent().getPackageName() + " from "
   17726                                 + callerPackage;
   17727                         Slog.w(TAG, msg);
   17728                         throw new SecurityException(msg);
   17729                     }
   17730                 } else {
   17731                     // Limit broadcast to their own package.
   17732                     intent.setPackage(callerPackage);
   17733                 }
   17734             }
   17735         }
   17736 
   17737         if (action != null) {
   17738             switch (action) {
   17739                 case Intent.ACTION_UID_REMOVED:
   17740                 case Intent.ACTION_PACKAGE_REMOVED:
   17741                 case Intent.ACTION_PACKAGE_CHANGED:
   17742                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
   17743                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
   17744                 case Intent.ACTION_PACKAGES_SUSPENDED:
   17745                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
   17746                     // Handle special intents: if this broadcast is from the package
   17747                     // manager about a package being removed, we need to remove all of
   17748                     // its activities from the history stack.
   17749                     if (checkComponentPermission(
   17750                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
   17751                             callingPid, callingUid, -1, true)
   17752                             != PackageManager.PERMISSION_GRANTED) {
   17753                         String msg = "Permission Denial: " + intent.getAction()
   17754                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
   17755                                 + ", uid=" + callingUid + ")"
   17756                                 + " requires "
   17757                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
   17758                         Slog.w(TAG, msg);
   17759                         throw new SecurityException(msg);
   17760                     }
   17761                     switch (action) {
   17762                         case Intent.ACTION_UID_REMOVED:
   17763                             final Bundle intentExtras = intent.getExtras();
   17764                             final int uid = intentExtras != null
   17765                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
   17766                             if (uid >= 0) {
   17767                                 mBatteryStatsService.removeUid(uid);
   17768                                 mAppOpsService.uidRemoved(uid);
   17769                             }
   17770                             break;
   17771                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
   17772                             // If resources are unavailable just force stop all those packages
   17773                             // and flush the attribute cache as well.
   17774                             String list[] =
   17775                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   17776                             if (list != null && list.length > 0) {
   17777                                 for (int i = 0; i < list.length; i++) {
   17778                                     forceStopPackageLocked(list[i], -1, false, true, true,
   17779                                             false, false, userId, "storage unmount");
   17780                                 }
   17781                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
   17782                                 sendPackageBroadcastLocked(
   17783                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
   17784                                         userId);
   17785                             }
   17786                             break;
   17787                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
   17788                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
   17789                             break;
   17790                         case Intent.ACTION_PACKAGE_REMOVED:
   17791                         case Intent.ACTION_PACKAGE_CHANGED:
   17792                             Uri data = intent.getData();
   17793                             String ssp;
   17794                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   17795                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
   17796                                 final boolean replacing =
   17797                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
   17798                                 final boolean killProcess =
   17799                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
   17800                                 final boolean fullUninstall = removed && !replacing;
   17801                                 if (removed) {
   17802                                     if (killProcess) {
   17803                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
   17804                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
   17805                                                 false, true, true, false, fullUninstall, userId,
   17806                                                 removed ? "pkg removed" : "pkg changed");
   17807                                     }
   17808                                     final int cmd = killProcess
   17809                                             ? IApplicationThread.PACKAGE_REMOVED
   17810                                             : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
   17811                                     sendPackageBroadcastLocked(cmd,
   17812                                             new String[] {ssp}, userId);
   17813                                     if (fullUninstall) {
   17814                                         mAppOpsService.packageRemoved(
   17815                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
   17816 
   17817                                         // Remove all permissions granted from/to this package
   17818                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
   17819 
   17820                                         removeTasksByPackageNameLocked(ssp, userId);
   17821 
   17822                                         // Hide the "unsupported display" dialog if necessary.
   17823                                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
   17824                                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
   17825                                             mUnsupportedDisplaySizeDialog.dismiss();
   17826                                             mUnsupportedDisplaySizeDialog = null;
   17827                                         }
   17828                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
   17829                                         mBatteryStatsService.notePackageUninstalled(ssp);
   17830                                     }
   17831                                 } else {
   17832                                     if (killProcess) {
   17833                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
   17834                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
   17835                                                 userId, ProcessList.INVALID_ADJ,
   17836                                                 false, true, true, false, "change " + ssp);
   17837                                     }
   17838                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
   17839                                             intent.getStringArrayExtra(
   17840                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
   17841                                 }
   17842                             }
   17843                             break;
   17844                         case Intent.ACTION_PACKAGES_SUSPENDED:
   17845                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
   17846                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
   17847                                     intent.getAction());
   17848                             final String[] packageNames = intent.getStringArrayExtra(
   17849                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
   17850                             final int userHandle = intent.getIntExtra(
   17851                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
   17852 
   17853                             synchronized(ActivityManagerService.this) {
   17854                                 mRecentTasks.onPackagesSuspendedChanged(
   17855                                         packageNames, suspended, userHandle);
   17856                             }
   17857                             break;
   17858                     }
   17859                     break;
   17860                 case Intent.ACTION_PACKAGE_REPLACED:
   17861                 {
   17862                     final Uri data = intent.getData();
   17863                     final String ssp;
   17864                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
   17865                         final ApplicationInfo aInfo =
   17866                                 getPackageManagerInternalLocked().getApplicationInfo(
   17867                                         ssp,
   17868                                         userId);
   17869                         if (aInfo == null) {
   17870                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
   17871                                     + " ssp=" + ssp + " data=" + data);
   17872                             return ActivityManager.BROADCAST_SUCCESS;
   17873                         }
   17874                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
   17875                         sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
   17876                                 new String[] {ssp}, userId);
   17877                     }
   17878                     break;
   17879                 }
   17880                 case Intent.ACTION_PACKAGE_ADDED:
   17881                 {
   17882                     // Special case for adding a package: by default turn on compatibility mode.
   17883                     Uri data = intent.getData();
   17884                     String ssp;
   17885                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
   17886                         final boolean replacing =
   17887                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
   17888                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
   17889 
   17890                         try {
   17891                             ApplicationInfo ai = AppGlobals.getPackageManager().
   17892                                     getApplicationInfo(ssp, 0, 0);
   17893                             mBatteryStatsService.notePackageInstalled(ssp,
   17894                                     ai != null ? ai.versionCode : 0);
   17895                         } catch (RemoteException e) {
   17896                         }
   17897                     }
   17898                     break;
   17899                 }
   17900                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
   17901                 {
   17902                     Uri data = intent.getData();
   17903                     String ssp;
   17904                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
   17905                         // Hide the "unsupported display" dialog if necessary.
   17906                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
   17907                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
   17908                             mUnsupportedDisplaySizeDialog.dismiss();
   17909                             mUnsupportedDisplaySizeDialog = null;
   17910                         }
   17911                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
   17912                     }
   17913                     break;
   17914                 }
   17915                 case Intent.ACTION_TIMEZONE_CHANGED:
   17916                     // If this is the time zone changed action, queue up a message that will reset
   17917                     // the timezone of all currently running processes. This message will get
   17918                     // queued up before the broadcast happens.
   17919                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
   17920                     break;
   17921                 case Intent.ACTION_TIME_CHANGED:
   17922                     // If the user set the time, let all running processes know.
   17923                     final int is24Hour =
   17924                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
   17925                                     : 0;
   17926                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
   17927                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   17928                     synchronized (stats) {
   17929                         stats.noteCurrentTimeChangedLocked();
   17930                     }
   17931                     break;
   17932                 case Intent.ACTION_CLEAR_DNS_CACHE:
   17933                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
   17934                     break;
   17935                 case Proxy.PROXY_CHANGE_ACTION:
   17936                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
   17937                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
   17938                     break;
   17939                 case android.hardware.Camera.ACTION_NEW_PICTURE:
   17940                 case android.hardware.Camera.ACTION_NEW_VIDEO:
   17941                     // These broadcasts are no longer allowed by the system, since they can
   17942                     // cause significant thrashing at a crictical point (using the camera).
   17943                     // Apps should use JobScehduler to monitor for media provider changes.
   17944                     Slog.w(TAG, action + " no longer allowed; dropping from "
   17945                             + UserHandle.formatUid(callingUid));
   17946                     if (resultTo != null) {
   17947                         final BroadcastQueue queue = broadcastQueueForIntent(intent);
   17948                         try {
   17949                             queue.performReceiveLocked(callerApp, resultTo, intent,
   17950                                     Activity.RESULT_CANCELED, null, null,
   17951                                     false, false, userId);
   17952                         } catch (RemoteException e) {
   17953                             Slog.w(TAG, "Failure ["
   17954                                     + queue.mQueueName + "] sending broadcast result of "
   17955                                     + intent, e);
   17956 
   17957                         }
   17958                     }
   17959                     // Lie; we don't want to crash the app.
   17960                     return ActivityManager.BROADCAST_SUCCESS;
   17961             }
   17962         }
   17963 
   17964         // Add to the sticky list if requested.
   17965         if (sticky) {
   17966             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
   17967                     callingPid, callingUid)
   17968                     != PackageManager.PERMISSION_GRANTED) {
   17969                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
   17970                         + callingPid + ", uid=" + callingUid
   17971                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   17972                 Slog.w(TAG, msg);
   17973                 throw new SecurityException(msg);
   17974             }
   17975             if (requiredPermissions != null && requiredPermissions.length > 0) {
   17976                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
   17977                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
   17978                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
   17979             }
   17980             if (intent.getComponent() != null) {
   17981                 throw new SecurityException(
   17982                         "Sticky broadcasts can't target a specific component");
   17983             }
   17984             // We use userId directly here, since the "all" target is maintained
   17985             // as a separate set of sticky broadcasts.
   17986             if (userId != UserHandle.USER_ALL) {
   17987                 // But first, if this is not a broadcast to all users, then
   17988                 // make sure it doesn't conflict with an existing broadcast to
   17989                 // all users.
   17990                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
   17991                         UserHandle.USER_ALL);
   17992                 if (stickies != null) {
   17993                     ArrayList<Intent> list = stickies.get(intent.getAction());
   17994                     if (list != null) {
   17995                         int N = list.size();
   17996                         int i;
   17997                         for (i=0; i<N; i++) {
   17998                             if (intent.filterEquals(list.get(i))) {
   17999                                 throw new IllegalArgumentException(
   18000                                         "Sticky broadcast " + intent + " for user "
   18001                                         + userId + " conflicts with existing global broadcast");
   18002                             }
   18003                         }
   18004                     }
   18005                 }
   18006             }
   18007             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   18008             if (stickies == null) {
   18009                 stickies = new ArrayMap<>();
   18010                 mStickyBroadcasts.put(userId, stickies);
   18011             }
   18012             ArrayList<Intent> list = stickies.get(intent.getAction());
   18013             if (list == null) {
   18014                 list = new ArrayList<>();
   18015                 stickies.put(intent.getAction(), list);
   18016             }
   18017             final int stickiesCount = list.size();
   18018             int i;
   18019             for (i = 0; i < stickiesCount; i++) {
   18020                 if (intent.filterEquals(list.get(i))) {
   18021                     // This sticky already exists, replace it.
   18022                     list.set(i, new Intent(intent));
   18023                     break;
   18024                 }
   18025             }
   18026             if (i >= stickiesCount) {
   18027                 list.add(new Intent(intent));
   18028             }
   18029         }
   18030 
   18031         int[] users;
   18032         if (userId == UserHandle.USER_ALL) {
   18033             // Caller wants broadcast to go to all started users.
   18034             users = mUserController.getStartedUserArrayLocked();
   18035         } else {
   18036             // Caller wants broadcast to go to one specific user.
   18037             users = new int[] {userId};
   18038         }
   18039 
   18040         // Figure out who all will receive this broadcast.
   18041         List receivers = null;
   18042         List<BroadcastFilter> registeredReceivers = null;
   18043         // Need to resolve the intent to interested receivers...
   18044         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
   18045                  == 0) {
   18046             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
   18047         }
   18048         if (intent.getComponent() == null) {
   18049             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
   18050                 // Query one target user at a time, excluding shell-restricted users
   18051                 for (int i = 0; i < users.length; i++) {
   18052                     if (mUserController.hasUserRestriction(
   18053                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
   18054                         continue;
   18055                     }
   18056                     List<BroadcastFilter> registeredReceiversForUser =
   18057                             mReceiverResolver.queryIntent(intent,
   18058                                     resolvedType, false, users[i]);
   18059                     if (registeredReceivers == null) {
   18060                         registeredReceivers = registeredReceiversForUser;
   18061                     } else if (registeredReceiversForUser != null) {
   18062                         registeredReceivers.addAll(registeredReceiversForUser);
   18063                     }
   18064                 }
   18065             } else {
   18066                 registeredReceivers = mReceiverResolver.queryIntent(intent,
   18067                         resolvedType, false, userId);
   18068             }
   18069         }
   18070 
   18071         final boolean replacePending =
   18072                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
   18073 
   18074         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
   18075                 + " replacePending=" + replacePending);
   18076 
   18077         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
   18078         if (!ordered && NR > 0) {
   18079             // If we are not serializing this broadcast, then send the
   18080             // registered receivers separately so they don't wait for the
   18081             // components to be launched.
   18082             final BroadcastQueue queue = broadcastQueueForIntent(intent);
   18083             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   18084                     callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
   18085                     appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
   18086                     resultExtras, ordered, sticky, false, userId);
   18087             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
   18088             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
   18089             if (!replaced) {
   18090                 queue.enqueueParallelBroadcastLocked(r);
   18091                 queue.scheduleBroadcastsLocked();
   18092             }
   18093             registeredReceivers = null;
   18094             NR = 0;
   18095         }
   18096 
   18097         // Merge into one list.
   18098         int ir = 0;
   18099         if (receivers != null) {
   18100             // A special case for PACKAGE_ADDED: do not allow the package
   18101             // being added to see this broadcast.  This prevents them from
   18102             // using this as a back door to get run as soon as they are
   18103             // installed.  Maybe in the future we want to have a special install
   18104             // broadcast or such for apps, but we'd like to deliberately make
   18105             // this decision.
   18106             String skipPackages[] = null;
   18107             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
   18108                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
   18109                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
   18110                 Uri data = intent.getData();
   18111                 if (data != null) {
   18112                     String pkgName = data.getSchemeSpecificPart();
   18113                     if (pkgName != null) {
   18114                         skipPackages = new String[] { pkgName };
   18115                     }
   18116                 }
   18117             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
   18118                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   18119             }
   18120             if (skipPackages != null && (skipPackages.length > 0)) {
   18121                 for (String skipPackage : skipPackages) {
   18122                     if (skipPackage != null) {
   18123                         int NT = receivers.size();
   18124                         for (int it=0; it<NT; it++) {
   18125                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
   18126                             if (curt.activityInfo.packageName.equals(skipPackage)) {
   18127                                 receivers.remove(it);
   18128                                 it--;
   18129                                 NT--;
   18130                             }
   18131                         }
   18132                     }
   18133                 }
   18134             }
   18135 
   18136             int NT = receivers != null ? receivers.size() : 0;
   18137             int it = 0;
   18138             ResolveInfo curt = null;
   18139             BroadcastFilter curr = null;
   18140             while (it < NT && ir < NR) {
   18141                 if (curt == null) {
   18142                     curt = (ResolveInfo)receivers.get(it);
   18143                 }
   18144                 if (curr == null) {
   18145                     curr = registeredReceivers.get(ir);
   18146                 }
   18147                 if (curr.getPriority() >= curt.priority) {
   18148                     // Insert this broadcast record into the final list.
   18149                     receivers.add(it, curr);
   18150                     ir++;
   18151                     curr = null;
   18152                     it++;
   18153                     NT++;
   18154                 } else {
   18155                     // Skip to the next ResolveInfo in the final list.
   18156                     it++;
   18157                     curt = null;
   18158                 }
   18159             }
   18160         }
   18161         while (ir < NR) {
   18162             if (receivers == null) {
   18163                 receivers = new ArrayList();
   18164             }
   18165             receivers.add(registeredReceivers.get(ir));
   18166             ir++;
   18167         }
   18168 
   18169         if ((receivers != null && receivers.size() > 0)
   18170                 || resultTo != null) {
   18171             BroadcastQueue queue = broadcastQueueForIntent(intent);
   18172             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   18173                     callerPackage, callingPid, callingUid, resolvedType,
   18174                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
   18175                     resultData, resultExtras, ordered, sticky, false, userId);
   18176 
   18177             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
   18178                     + ": prev had " + queue.mOrderedBroadcasts.size());
   18179             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
   18180                     "Enqueueing broadcast " + r.intent.getAction());
   18181 
   18182             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
   18183             if (!replaced) {
   18184                 queue.enqueueOrderedBroadcastLocked(r);
   18185                 queue.scheduleBroadcastsLocked();
   18186             }
   18187         } else {
   18188             // There was nobody interested in the broadcast, but we still want to record
   18189             // that it happened.
   18190             if (intent.getComponent() == null && intent.getPackage() == null
   18191                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   18192                 // This was an implicit broadcast... let's record it for posterity.
   18193                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
   18194             }
   18195         }
   18196 
   18197         return ActivityManager.BROADCAST_SUCCESS;
   18198     }
   18199 
   18200     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
   18201             int skipCount, long dispatchTime) {
   18202         final long now = SystemClock.elapsedRealtime();
   18203         if (mCurBroadcastStats == null ||
   18204                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
   18205             mLastBroadcastStats = mCurBroadcastStats;
   18206             if (mLastBroadcastStats != null) {
   18207                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
   18208                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
   18209             }
   18210             mCurBroadcastStats = new BroadcastStats();
   18211         }
   18212         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
   18213     }
   18214 
   18215     final Intent verifyBroadcastLocked(Intent intent) {
   18216         // Refuse possible leaked file descriptors
   18217         if (intent != null && intent.hasFileDescriptors() == true) {
   18218             throw new IllegalArgumentException("File descriptors passed in Intent");
   18219         }
   18220 
   18221         int flags = intent.getFlags();
   18222 
   18223         if (!mProcessesReady) {
   18224             // if the caller really truly claims to know what they're doing, go
   18225             // ahead and allow the broadcast without launching any receivers
   18226             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
   18227                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
   18228             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   18229                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
   18230                         + " before boot completion");
   18231                 throw new IllegalStateException("Cannot broadcast before boot completed");
   18232             }
   18233         }
   18234 
   18235         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   18236             throw new IllegalArgumentException(
   18237                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   18238         }
   18239 
   18240         return intent;
   18241     }
   18242 
   18243     public final int broadcastIntent(IApplicationThread caller,
   18244             Intent intent, String resolvedType, IIntentReceiver resultTo,
   18245             int resultCode, String resultData, Bundle resultExtras,
   18246             String[] requiredPermissions, int appOp, Bundle bOptions,
   18247             boolean serialized, boolean sticky, int userId) {
   18248         enforceNotIsolatedCaller("broadcastIntent");
   18249         synchronized(this) {
   18250             intent = verifyBroadcastLocked(intent);
   18251 
   18252             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   18253             final int callingPid = Binder.getCallingPid();
   18254             final int callingUid = Binder.getCallingUid();
   18255             final long origId = Binder.clearCallingIdentity();
   18256             int res = broadcastIntentLocked(callerApp,
   18257                     callerApp != null ? callerApp.info.packageName : null,
   18258                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
   18259                     requiredPermissions, appOp, bOptions, serialized, sticky,
   18260                     callingPid, callingUid, userId);
   18261             Binder.restoreCallingIdentity(origId);
   18262             return res;
   18263         }
   18264     }
   18265 
   18266 
   18267     int broadcastIntentInPackage(String packageName, int uid,
   18268             Intent intent, String resolvedType, IIntentReceiver resultTo,
   18269             int resultCode, String resultData, Bundle resultExtras,
   18270             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
   18271             int userId) {
   18272         synchronized(this) {
   18273             intent = verifyBroadcastLocked(intent);
   18274 
   18275             final long origId = Binder.clearCallingIdentity();
   18276             String[] requiredPermissions = requiredPermission == null ? null
   18277                     : new String[] {requiredPermission};
   18278             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
   18279                     resultTo, resultCode, resultData, resultExtras,
   18280                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
   18281                     sticky, -1, uid, userId);
   18282             Binder.restoreCallingIdentity(origId);
   18283             return res;
   18284         }
   18285     }
   18286 
   18287     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
   18288         // Refuse possible leaked file descriptors
   18289         if (intent != null && intent.hasFileDescriptors() == true) {
   18290             throw new IllegalArgumentException("File descriptors passed in Intent");
   18291         }
   18292 
   18293         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   18294                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
   18295 
   18296         synchronized(this) {
   18297             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
   18298                     != PackageManager.PERMISSION_GRANTED) {
   18299                 String msg = "Permission Denial: unbroadcastIntent() from pid="
   18300                         + Binder.getCallingPid()
   18301                         + ", uid=" + Binder.getCallingUid()
   18302                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   18303                 Slog.w(TAG, msg);
   18304                 throw new SecurityException(msg);
   18305             }
   18306             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   18307             if (stickies != null) {
   18308                 ArrayList<Intent> list = stickies.get(intent.getAction());
   18309                 if (list != null) {
   18310                     int N = list.size();
   18311                     int i;
   18312                     for (i=0; i<N; i++) {
   18313                         if (intent.filterEquals(list.get(i))) {
   18314                             list.remove(i);
   18315                             break;
   18316                         }
   18317                     }
   18318                     if (list.size() <= 0) {
   18319                         stickies.remove(intent.getAction());
   18320                     }
   18321                 }
   18322                 if (stickies.size() <= 0) {
   18323                     mStickyBroadcasts.remove(userId);
   18324                 }
   18325             }
   18326         }
   18327     }
   18328 
   18329     void backgroundServicesFinishedLocked(int userId) {
   18330         for (BroadcastQueue queue : mBroadcastQueues) {
   18331             queue.backgroundServicesFinishedLocked(userId);
   18332         }
   18333     }
   18334 
   18335     public void finishReceiver(IBinder who, int resultCode, String resultData,
   18336             Bundle resultExtras, boolean resultAbort, int flags) {
   18337         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
   18338 
   18339         // Refuse possible leaked file descriptors
   18340         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
   18341             throw new IllegalArgumentException("File descriptors passed in Bundle");
   18342         }
   18343 
   18344         final long origId = Binder.clearCallingIdentity();
   18345         try {
   18346             boolean doNext = false;
   18347             BroadcastRecord r;
   18348 
   18349             synchronized(this) {
   18350                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
   18351                         ? mFgBroadcastQueue : mBgBroadcastQueue;
   18352                 r = queue.getMatchingOrderedReceiver(who);
   18353                 if (r != null) {
   18354                     doNext = r.queue.finishReceiverLocked(r, resultCode,
   18355                         resultData, resultExtras, resultAbort, true);
   18356                 }
   18357             }
   18358 
   18359             if (doNext) {
   18360                 r.queue.processNextBroadcast(false);
   18361             }
   18362             trimApplications();
   18363         } finally {
   18364             Binder.restoreCallingIdentity(origId);
   18365         }
   18366     }
   18367 
   18368     // =========================================================
   18369     // INSTRUMENTATION
   18370     // =========================================================
   18371 
   18372     public boolean startInstrumentation(ComponentName className,
   18373             String profileFile, int flags, Bundle arguments,
   18374             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
   18375             int userId, String abiOverride) {
   18376         enforceNotIsolatedCaller("startInstrumentation");
   18377         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   18378                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
   18379         // Refuse possible leaked file descriptors
   18380         if (arguments != null && arguments.hasFileDescriptors()) {
   18381             throw new IllegalArgumentException("File descriptors passed in Bundle");
   18382         }
   18383 
   18384         synchronized(this) {
   18385             InstrumentationInfo ii = null;
   18386             ApplicationInfo ai = null;
   18387             try {
   18388                 ii = mContext.getPackageManager().getInstrumentationInfo(
   18389                     className, STOCK_PM_FLAGS);
   18390                 ai = AppGlobals.getPackageManager().getApplicationInfo(
   18391                         ii.targetPackage, STOCK_PM_FLAGS, userId);
   18392             } catch (PackageManager.NameNotFoundException e) {
   18393             } catch (RemoteException e) {
   18394             }
   18395             if (ii == null) {
   18396                 reportStartInstrumentationFailureLocked(watcher, className,
   18397                         "Unable to find instrumentation info for: " + className);
   18398                 return false;
   18399             }
   18400             if (ai == null) {
   18401                 reportStartInstrumentationFailureLocked(watcher, className,
   18402                         "Unable to find instrumentation target package: " + ii.targetPackage);
   18403                 return false;
   18404             }
   18405             if (!ai.hasCode()) {
   18406                 reportStartInstrumentationFailureLocked(watcher, className,
   18407                         "Instrumentation target has no code: " + ii.targetPackage);
   18408                 return false;
   18409             }
   18410 
   18411             int match = mContext.getPackageManager().checkSignatures(
   18412                     ii.targetPackage, ii.packageName);
   18413             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
   18414                 String msg = "Permission Denial: starting instrumentation "
   18415                         + className + " from pid="
   18416                         + Binder.getCallingPid()
   18417                         + ", uid=" + Binder.getCallingPid()
   18418                         + " not allowed because package " + ii.packageName
   18419                         + " does not have a signature matching the target "
   18420                         + ii.targetPackage;
   18421                 reportStartInstrumentationFailureLocked(watcher, className, msg);
   18422                 throw new SecurityException(msg);
   18423             }
   18424 
   18425             final long origId = Binder.clearCallingIdentity();
   18426             // Instrumentation can kill and relaunch even persistent processes
   18427             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
   18428                     "start instr");
   18429             ProcessRecord app = addAppLocked(ai, false, abiOverride);
   18430             app.instrumentationClass = className;
   18431             app.instrumentationInfo = ai;
   18432             app.instrumentationProfileFile = profileFile;
   18433             app.instrumentationArguments = arguments;
   18434             app.instrumentationWatcher = watcher;
   18435             app.instrumentationUiAutomationConnection = uiAutomationConnection;
   18436             app.instrumentationResultClass = className;
   18437             Binder.restoreCallingIdentity(origId);
   18438         }
   18439 
   18440         return true;
   18441     }
   18442 
   18443     /**
   18444      * Report errors that occur while attempting to start Instrumentation.  Always writes the
   18445      * error to the logs, but if somebody is watching, send the report there too.  This enables
   18446      * the "am" command to report errors with more information.
   18447      *
   18448      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
   18449      * @param cn The component name of the instrumentation.
   18450      * @param report The error report.
   18451      */
   18452     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
   18453             ComponentName cn, String report) {
   18454         Slog.w(TAG, report);
   18455         if (watcher != null) {
   18456             Bundle results = new Bundle();
   18457             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
   18458             results.putString("Error", report);
   18459             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
   18460         }
   18461     }
   18462 
   18463     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
   18464         if (app.instrumentationWatcher != null) {
   18465             mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
   18466                     app.instrumentationClass, resultCode, results);
   18467         }
   18468 
   18469         // Can't call out of the system process with a lock held, so post a message.
   18470         if (app.instrumentationUiAutomationConnection != null) {
   18471             mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
   18472                     app.instrumentationUiAutomationConnection).sendToTarget();
   18473         }
   18474 
   18475         app.instrumentationWatcher = null;
   18476         app.instrumentationUiAutomationConnection = null;
   18477         app.instrumentationClass = null;
   18478         app.instrumentationInfo = null;
   18479         app.instrumentationProfileFile = null;
   18480         app.instrumentationArguments = null;
   18481 
   18482         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
   18483                 "finished inst");
   18484     }
   18485 
   18486     public void finishInstrumentation(IApplicationThread target,
   18487             int resultCode, Bundle results) {
   18488         int userId = UserHandle.getCallingUserId();
   18489         // Refuse possible leaked file descriptors
   18490         if (results != null && results.hasFileDescriptors()) {
   18491             throw new IllegalArgumentException("File descriptors passed in Intent");
   18492         }
   18493 
   18494         synchronized(this) {
   18495             ProcessRecord app = getRecordForAppLocked(target);
   18496             if (app == null) {
   18497                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
   18498                 return;
   18499             }
   18500             final long origId = Binder.clearCallingIdentity();
   18501             finishInstrumentationLocked(app, resultCode, results);
   18502             Binder.restoreCallingIdentity(origId);
   18503         }
   18504     }
   18505 
   18506     // =========================================================
   18507     // CONFIGURATION
   18508     // =========================================================
   18509 
   18510     public ConfigurationInfo getDeviceConfigurationInfo() {
   18511         ConfigurationInfo config = new ConfigurationInfo();
   18512         synchronized (this) {
   18513             config.reqTouchScreen = mConfiguration.touchscreen;
   18514             config.reqKeyboardType = mConfiguration.keyboard;
   18515             config.reqNavigation = mConfiguration.navigation;
   18516             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
   18517                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
   18518                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
   18519             }
   18520             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
   18521                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
   18522                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
   18523             }
   18524             config.reqGlEsVersion = GL_ES_VERSION;
   18525         }
   18526         return config;
   18527     }
   18528 
   18529     ActivityStack getFocusedStack() {
   18530         return mStackSupervisor.getFocusedStack();
   18531     }
   18532 
   18533     @Override
   18534     public int getFocusedStackId() throws RemoteException {
   18535         ActivityStack focusedStack = getFocusedStack();
   18536         if (focusedStack != null) {
   18537             return focusedStack.getStackId();
   18538         }
   18539         return -1;
   18540     }
   18541 
   18542     public Configuration getConfiguration() {
   18543         Configuration ci;
   18544         synchronized(this) {
   18545             ci = new Configuration(mConfiguration);
   18546             ci.userSetLocale = false;
   18547         }
   18548         return ci;
   18549     }
   18550 
   18551     @Override
   18552     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
   18553         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
   18554         synchronized (this) {
   18555             mSuppressResizeConfigChanges = suppress;
   18556         }
   18557     }
   18558 
   18559     @Override
   18560     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
   18561         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
   18562         if (fromStackId == HOME_STACK_ID) {
   18563             throw new IllegalArgumentException("You can't move tasks from the home stack.");
   18564         }
   18565         synchronized (this) {
   18566             final long origId = Binder.clearCallingIdentity();
   18567             try {
   18568                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
   18569             } finally {
   18570                 Binder.restoreCallingIdentity(origId);
   18571             }
   18572         }
   18573     }
   18574 
   18575     @Override
   18576     public void updatePersistentConfiguration(Configuration values) {
   18577         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   18578                 "updateConfiguration()");
   18579         enforceWriteSettingsPermission("updateConfiguration()");
   18580         if (values == null) {
   18581             throw new NullPointerException("Configuration must not be null");
   18582         }
   18583 
   18584         int userId = UserHandle.getCallingUserId();
   18585 
   18586         synchronized(this) {
   18587             final long origId = Binder.clearCallingIdentity();
   18588             updateConfigurationLocked(values, null, false, true, userId);
   18589             Binder.restoreCallingIdentity(origId);
   18590         }
   18591     }
   18592 
   18593     private void updateFontScaleIfNeeded() {
   18594         final int currentUserId;
   18595         synchronized(this) {
   18596             currentUserId = mUserController.getCurrentUserIdLocked();
   18597         }
   18598         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
   18599                 FONT_SCALE, 1.0f, currentUserId);
   18600         if (mConfiguration.fontScale != scaleFactor) {
   18601             final Configuration configuration = mWindowManager.computeNewConfiguration();
   18602             configuration.fontScale = scaleFactor;
   18603             updatePersistentConfiguration(configuration);
   18604         }
   18605     }
   18606 
   18607     private void enforceWriteSettingsPermission(String func) {
   18608         int uid = Binder.getCallingUid();
   18609         if (uid == Process.ROOT_UID) {
   18610             return;
   18611         }
   18612 
   18613         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
   18614                 Settings.getPackageNameForUid(mContext, uid), false)) {
   18615             return;
   18616         }
   18617 
   18618         String msg = "Permission Denial: " + func + " from pid="
   18619                 + Binder.getCallingPid()
   18620                 + ", uid=" + uid
   18621                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
   18622         Slog.w(TAG, msg);
   18623         throw new SecurityException(msg);
   18624     }
   18625 
   18626     public void updateConfiguration(Configuration values) {
   18627         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   18628                 "updateConfiguration()");
   18629 
   18630         synchronized(this) {
   18631             if (values == null && mWindowManager != null) {
   18632                 // sentinel: fetch the current configuration from the window manager
   18633                 values = mWindowManager.computeNewConfiguration();
   18634             }
   18635 
   18636             if (mWindowManager != null) {
   18637                 mProcessList.applyDisplaySize(mWindowManager);
   18638             }
   18639 
   18640             final long origId = Binder.clearCallingIdentity();
   18641             if (values != null) {
   18642                 Settings.System.clearConfiguration(values);
   18643             }
   18644             updateConfigurationLocked(values, null, false);
   18645             Binder.restoreCallingIdentity(origId);
   18646         }
   18647     }
   18648 
   18649     void updateUserConfigurationLocked() {
   18650         Configuration configuration = new Configuration(mConfiguration);
   18651         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
   18652                 mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
   18653         updateConfigurationLocked(configuration, null, false);
   18654     }
   18655 
   18656     boolean updateConfigurationLocked(Configuration values,
   18657             ActivityRecord starting, boolean initLocale) {
   18658         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
   18659         return updateConfigurationLocked(values, starting, initLocale, false,
   18660                 UserHandle.USER_NULL);
   18661     }
   18662 
   18663     // To cache the list of supported system locales
   18664     private String[] mSupportedSystemLocales = null;
   18665 
   18666     /**
   18667      * Do either or both things: (1) change the current configuration, and (2)
   18668      * make sure the given activity is running with the (now) current
   18669      * configuration.  Returns true if the activity has been left running, or
   18670      * false if <var>starting</var> is being destroyed to match the new
   18671      * configuration.
   18672      *
   18673      * @param userId is only used when persistent parameter is set to true to persist configuration
   18674      *               for that particular user
   18675      */
   18676     private boolean updateConfigurationLocked(Configuration values,
   18677             ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
   18678         int changes = 0;
   18679 
   18680         if (mWindowManager != null) {
   18681             mWindowManager.deferSurfaceLayout();
   18682         }
   18683         if (values != null) {
   18684             Configuration newConfig = new Configuration(mConfiguration);
   18685             changes = newConfig.updateFrom(values);
   18686             if (changes != 0) {
   18687                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
   18688                         "Updating configuration to: " + values);
   18689 
   18690                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
   18691 
   18692                 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
   18693                     final LocaleList locales = values.getLocales();
   18694                     int bestLocaleIndex = 0;
   18695                     if (locales.size() > 1) {
   18696                         if (mSupportedSystemLocales == null) {
   18697                             mSupportedSystemLocales =
   18698                                     Resources.getSystem().getAssets().getLocales();
   18699                         }
   18700                         bestLocaleIndex = Math.max(0,
   18701                                 locales.getFirstMatchIndex(mSupportedSystemLocales));
   18702                     }
   18703                     SystemProperties.set("persist.sys.locale",
   18704                             locales.get(bestLocaleIndex).toLanguageTag());
   18705                     LocaleList.setDefault(locales, bestLocaleIndex);
   18706                     mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
   18707                             locales.get(bestLocaleIndex)));
   18708                 }
   18709 
   18710                 mConfigurationSeq++;
   18711                 if (mConfigurationSeq <= 0) {
   18712                     mConfigurationSeq = 1;
   18713                 }
   18714                 newConfig.seq = mConfigurationSeq;
   18715                 mConfiguration = newConfig;
   18716                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
   18717                 mUsageStatsService.reportConfigurationChange(newConfig,
   18718                         mUserController.getCurrentUserIdLocked());
   18719                 //mUsageStatsService.noteStartConfig(newConfig);
   18720 
   18721                 final Configuration configCopy = new Configuration(mConfiguration);
   18722 
   18723                 // TODO: If our config changes, should we auto dismiss any currently
   18724                 // showing dialogs?
   18725                 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
   18726 
   18727                 AttributeCache ac = AttributeCache.instance();
   18728                 if (ac != null) {
   18729                     ac.updateConfiguration(configCopy);
   18730                 }
   18731 
   18732                 // Make sure all resources in our process are updated
   18733                 // right now, so that anyone who is going to retrieve
   18734                 // resource values after we return will be sure to get
   18735                 // the new ones.  This is especially important during
   18736                 // boot, where the first config change needs to guarantee
   18737                 // all resources have that config before following boot
   18738                 // code is executed.
   18739                 mSystemThread.applyConfigurationToResources(configCopy);
   18740 
   18741                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
   18742                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
   18743                     msg.obj = new Configuration(configCopy);
   18744                     msg.arg1 = userId;
   18745                     mHandler.sendMessage(msg);
   18746                 }
   18747 
   18748                 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
   18749                 if (isDensityChange) {
   18750                     // Reset the unsupported display size dialog.
   18751                     mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
   18752 
   18753                     killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
   18754                             ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
   18755                 }
   18756 
   18757                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   18758                     ProcessRecord app = mLruProcesses.get(i);
   18759                     try {
   18760                         if (app.thread != null) {
   18761                             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
   18762                                     + app.processName + " new config " + mConfiguration);
   18763                             app.thread.scheduleConfigurationChanged(configCopy);
   18764                         }
   18765                     } catch (Exception e) {
   18766                     }
   18767                 }
   18768                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
   18769                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   18770                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
   18771                         | Intent.FLAG_RECEIVER_FOREGROUND);
   18772                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
   18773                         null, AppOpsManager.OP_NONE, null, false, false,
   18774                         MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   18775                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
   18776                     // Tell the shortcut manager that the system locale changed.  It needs to know
   18777                     // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
   18778                     // we "push" from here, rather than having the service listen to the broadcast.
   18779                     final ShortcutServiceInternal shortcutService =
   18780                             LocalServices.getService(ShortcutServiceInternal.class);
   18781                     if (shortcutService != null) {
   18782                         shortcutService.onSystemLocaleChangedNoLock();
   18783                     }
   18784 
   18785                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
   18786                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   18787                     if (!mProcessesReady) {
   18788                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   18789                     }
   18790                     broadcastIntentLocked(null, null, intent,
   18791                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   18792                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   18793                 }
   18794             }
   18795             // Update the configuration with WM first and check if any of the stacks need to be
   18796             // resized due to the configuration change. If so, resize the stacks now and do any
   18797             // relaunches if necessary. This way we don't need to relaunch again below in
   18798             // ensureActivityConfigurationLocked().
   18799             if (mWindowManager != null) {
   18800                 final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
   18801                 if (resizedStacks != null) {
   18802                     for (int stackId : resizedStacks) {
   18803                         final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
   18804                         mStackSupervisor.resizeStackLocked(
   18805                                 stackId, newBounds, null, null, false, false, !DEFER_RESUME);
   18806                     }
   18807                 }
   18808             }
   18809         }
   18810 
   18811         boolean kept = true;
   18812         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
   18813         // mainStack is null during startup.
   18814         if (mainStack != null) {
   18815             if (changes != 0 && starting == null) {
   18816                 // If the configuration changed, and the caller is not already
   18817                 // in the process of starting an activity, then find the top
   18818                 // activity to check if its configuration needs to change.
   18819                 starting = mainStack.topRunningActivityLocked();
   18820             }
   18821 
   18822             if (starting != null) {
   18823                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
   18824                 // And we need to make sure at this point that all other activities
   18825                 // are made visible with the correct configuration.
   18826                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
   18827                         !PRESERVE_WINDOWS);
   18828             }
   18829         }
   18830         if (mWindowManager != null) {
   18831             mWindowManager.continueSurfaceLayout();
   18832         }
   18833         return kept;
   18834     }
   18835 
   18836     /**
   18837      * Decide based on the configuration whether we should shouw the ANR,
   18838      * crash, etc dialogs.  The idea is that if there is no affordnace to
   18839      * press the on-screen buttons, we shouldn't show the dialog.
   18840      *
   18841      * A thought: SystemUI might also want to get told about this, the Power
   18842      * dialog / global actions also might want different behaviors.
   18843      */
   18844     private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
   18845         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
   18846                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
   18847                                    && config.navigation == Configuration.NAVIGATION_NONAV);
   18848         final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
   18849                                     == Configuration.UI_MODE_TYPE_CAR);
   18850         return inputMethodExists && uiIsNotCarType && !inVrMode;
   18851     }
   18852 
   18853     @Override
   18854     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
   18855         synchronized (this) {
   18856             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
   18857             if (srec != null) {
   18858                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
   18859             }
   18860         }
   18861         return false;
   18862     }
   18863 
   18864     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
   18865             Intent resultData) {
   18866 
   18867         synchronized (this) {
   18868             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   18869             if (r != null) {
   18870                 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
   18871             }
   18872             return false;
   18873         }
   18874     }
   18875 
   18876     public int getLaunchedFromUid(IBinder activityToken) {
   18877         ActivityRecord srec;
   18878         synchronized (this) {
   18879             srec = ActivityRecord.forTokenLocked(activityToken);
   18880         }
   18881         if (srec == null) {
   18882             return -1;
   18883         }
   18884         return srec.launchedFromUid;
   18885     }
   18886 
   18887     public String getLaunchedFromPackage(IBinder activityToken) {
   18888         ActivityRecord srec;
   18889         synchronized (this) {
   18890             srec = ActivityRecord.forTokenLocked(activityToken);
   18891         }
   18892         if (srec == null) {
   18893             return null;
   18894         }
   18895         return srec.launchedFromPackage;
   18896     }
   18897 
   18898     // =========================================================
   18899     // LIFETIME MANAGEMENT
   18900     // =========================================================
   18901 
   18902     // Returns which broadcast queue the app is the current [or imminent] receiver
   18903     // on, or 'null' if the app is not an active broadcast recipient.
   18904     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
   18905         BroadcastRecord r = app.curReceiver;
   18906         if (r != null) {
   18907             return r.queue;
   18908         }
   18909 
   18910         // It's not the current receiver, but it might be starting up to become one
   18911         synchronized (this) {
   18912             for (BroadcastQueue queue : mBroadcastQueues) {
   18913                 r = queue.mPendingBroadcast;
   18914                 if (r != null && r.curApp == app) {
   18915                     // found it; report which queue it's in
   18916                     return queue;
   18917                 }
   18918             }
   18919         }
   18920 
   18921         return null;
   18922     }
   18923 
   18924     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
   18925             int targetUid, ComponentName targetComponent, String targetProcess) {
   18926         if (!mTrackingAssociations) {
   18927             return null;
   18928         }
   18929         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
   18930                 = mAssociations.get(targetUid);
   18931         if (components == null) {
   18932             components = new ArrayMap<>();
   18933             mAssociations.put(targetUid, components);
   18934         }
   18935         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
   18936         if (sourceUids == null) {
   18937             sourceUids = new SparseArray<>();
   18938             components.put(targetComponent, sourceUids);
   18939         }
   18940         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
   18941         if (sourceProcesses == null) {
   18942             sourceProcesses = new ArrayMap<>();
   18943             sourceUids.put(sourceUid, sourceProcesses);
   18944         }
   18945         Association ass = sourceProcesses.get(sourceProcess);
   18946         if (ass == null) {
   18947             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
   18948                     targetProcess);
   18949             sourceProcesses.put(sourceProcess, ass);
   18950         }
   18951         ass.mCount++;
   18952         ass.mNesting++;
   18953         if (ass.mNesting == 1) {
   18954             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
   18955             ass.mLastState = sourceState;
   18956         }
   18957         return ass;
   18958     }
   18959 
   18960     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
   18961             ComponentName targetComponent) {
   18962         if (!mTrackingAssociations) {
   18963             return;
   18964         }
   18965         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
   18966                 = mAssociations.get(targetUid);
   18967         if (components == null) {
   18968             return;
   18969         }
   18970         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
   18971         if (sourceUids == null) {
   18972             return;
   18973         }
   18974         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
   18975         if (sourceProcesses == null) {
   18976             return;
   18977         }
   18978         Association ass = sourceProcesses.get(sourceProcess);
   18979         if (ass == null || ass.mNesting <= 0) {
   18980             return;
   18981         }
   18982         ass.mNesting--;
   18983         if (ass.mNesting == 0) {
   18984             long uptime = SystemClock.uptimeMillis();
   18985             ass.mTime += uptime - ass.mStartTime;
   18986             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
   18987                     += uptime - ass.mLastStateUptime;
   18988             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
   18989         }
   18990     }
   18991 
   18992     private void noteUidProcessState(final int uid, final int state) {
   18993         mBatteryStatsService.noteUidProcessState(uid, state);
   18994         if (mTrackingAssociations) {
   18995             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
   18996                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
   18997                         = mAssociations.valueAt(i1);
   18998                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
   18999                     SparseArray<ArrayMap<String, Association>> sourceUids
   19000                             = targetComponents.valueAt(i2);
   19001                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
   19002                     if (sourceProcesses != null) {
   19003                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
   19004                             Association ass = sourceProcesses.valueAt(i4);
   19005                             if (ass.mNesting >= 1) {
   19006                                 // currently associated
   19007                                 long uptime = SystemClock.uptimeMillis();
   19008                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
   19009                                         += uptime - ass.mLastStateUptime;
   19010                                 ass.mLastState = state;
   19011                                 ass.mLastStateUptime = uptime;
   19012                             }
   19013                         }
   19014                     }
   19015                 }
   19016             }
   19017         }
   19018     }
   19019 
   19020     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
   19021             boolean doingAll, long now) {
   19022         if (mAdjSeq == app.adjSeq) {
   19023             // This adjustment has already been computed.
   19024             return app.curRawAdj;
   19025         }
   19026 
   19027         if (app.thread == null) {
   19028             app.adjSeq = mAdjSeq;
   19029             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   19030             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   19031             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
   19032         }
   19033 
   19034         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
   19035         app.adjSource = null;
   19036         app.adjTarget = null;
   19037         app.empty = false;
   19038         app.cached = false;
   19039 
   19040         final int activitiesSize = app.activities.size();
   19041 
   19042         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   19043             // The max adjustment doesn't allow this app to be anything
   19044             // below foreground, so it is not worth doing work for it.
   19045             app.adjType = "fixed";
   19046             app.adjSeq = mAdjSeq;
   19047             app.curRawAdj = app.maxAdj;
   19048             app.foregroundActivities = false;
   19049             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19050             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
   19051             // System processes can do UI, and when they do we want to have
   19052             // them trim their memory after the user leaves the UI.  To
   19053             // facilitate this, here we need to determine whether or not it
   19054             // is currently showing UI.
   19055             app.systemNoUi = true;
   19056             if (app == TOP_APP) {
   19057                 app.systemNoUi = false;
   19058                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
   19059                 app.adjType = "pers-top-activity";
   19060             } else if (activitiesSize > 0) {
   19061                 for (int j = 0; j < activitiesSize; j++) {
   19062                     final ActivityRecord r = app.activities.get(j);
   19063                     if (r.visible) {
   19064                         app.systemNoUi = false;
   19065                     }
   19066                 }
   19067             }
   19068             if (!app.systemNoUi) {
   19069                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
   19070             }
   19071             return (app.curAdj=app.maxAdj);
   19072         }
   19073 
   19074         app.systemNoUi = false;
   19075 
   19076         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
   19077 
   19078         // Determine the importance of the process, starting with most
   19079         // important to least, and assign an appropriate OOM adjustment.
   19080         int adj;
   19081         int schedGroup;
   19082         int procState;
   19083         boolean foregroundActivities = false;
   19084         BroadcastQueue queue;
   19085         if (app == TOP_APP) {
   19086             // The last app on the list is the foreground app.
   19087             adj = ProcessList.FOREGROUND_APP_ADJ;
   19088             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
   19089             app.adjType = "top-activity";
   19090             foregroundActivities = true;
   19091             procState = PROCESS_STATE_CUR_TOP;
   19092         } else if (app.instrumentationClass != null) {
   19093             // Don't want to kill running instrumentation.
   19094             adj = ProcessList.FOREGROUND_APP_ADJ;
   19095             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19096             app.adjType = "instrumentation";
   19097             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
   19098         } else if ((queue = isReceivingBroadcast(app)) != null) {
   19099             // An app that is currently receiving a broadcast also
   19100             // counts as being in the foreground for OOM killer purposes.
   19101             // It's placed in a sched group based on the nature of the
   19102             // broadcast as reflected by which queue it's active in.
   19103             adj = ProcessList.FOREGROUND_APP_ADJ;
   19104             schedGroup = (queue == mFgBroadcastQueue)
   19105                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
   19106             app.adjType = "broadcast";
   19107             procState = ActivityManager.PROCESS_STATE_RECEIVER;
   19108         } else if (app.executingServices.size() > 0) {
   19109             // An app that is currently executing a service callback also
   19110             // counts as being in the foreground.
   19111             adj = ProcessList.FOREGROUND_APP_ADJ;
   19112             schedGroup = app.execServicesFg ?
   19113                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
   19114             app.adjType = "exec-service";
   19115             procState = ActivityManager.PROCESS_STATE_SERVICE;
   19116             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
   19117         } else {
   19118             // As far as we know the process is empty.  We may change our mind later.
   19119             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   19120             // At this point we don't actually know the adjustment.  Use the cached adj
   19121             // value that the caller wants us to.
   19122             adj = cachedAdj;
   19123             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   19124             app.cached = true;
   19125             app.empty = true;
   19126             app.adjType = "cch-empty";
   19127         }
   19128 
   19129         // Examine all activities if not already foreground.
   19130         if (!foregroundActivities && activitiesSize > 0) {
   19131             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
   19132             for (int j = 0; j < activitiesSize; j++) {
   19133                 final ActivityRecord r = app.activities.get(j);
   19134                 if (r.app != app) {
   19135                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
   19136                             + " instead of expected " + app);
   19137                     if (r.app == null || (r.app.uid == app.uid)) {
   19138                         // Only fix things up when they look sane
   19139                         r.app = app;
   19140                     } else {
   19141                         continue;
   19142                     }
   19143                 }
   19144                 if (r.visible) {
   19145                     // App has a visible activity; only upgrade adjustment.
   19146                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   19147                         adj = ProcessList.VISIBLE_APP_ADJ;
   19148                         app.adjType = "visible";
   19149                     }
   19150                     if (procState > PROCESS_STATE_CUR_TOP) {
   19151                         procState = PROCESS_STATE_CUR_TOP;
   19152                     }
   19153                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19154                     app.cached = false;
   19155                     app.empty = false;
   19156                     foregroundActivities = true;
   19157                     if (r.task != null && minLayer > 0) {
   19158                         final int layer = r.task.mLayerRank;
   19159                         if (layer >= 0 && minLayer > layer) {
   19160                             minLayer = layer;
   19161                         }
   19162                     }
   19163                     break;
   19164                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
   19165                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   19166                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   19167                         app.adjType = "pausing";
   19168                     }
   19169                     if (procState > PROCESS_STATE_CUR_TOP) {
   19170                         procState = PROCESS_STATE_CUR_TOP;
   19171                     }
   19172                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19173                     app.cached = false;
   19174                     app.empty = false;
   19175                     foregroundActivities = true;
   19176                 } else if (r.state == ActivityState.STOPPING) {
   19177                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   19178                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   19179                         app.adjType = "stopping";
   19180                     }
   19181                     // For the process state, we will at this point consider the
   19182                     // process to be cached.  It will be cached either as an activity
   19183                     // or empty depending on whether the activity is finishing.  We do
   19184                     // this so that we can treat the process as cached for purposes of
   19185                     // memory trimming (determing current memory level, trim command to
   19186                     // send to process) since there can be an arbitrary number of stopping
   19187                     // processes and they should soon all go into the cached state.
   19188                     if (!r.finishing) {
   19189                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   19190                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   19191                         }
   19192                     }
   19193                     app.cached = false;
   19194                     app.empty = false;
   19195                     foregroundActivities = true;
   19196                 } else {
   19197                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   19198                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   19199                         app.adjType = "cch-act";
   19200                     }
   19201                 }
   19202             }
   19203             if (adj == ProcessList.VISIBLE_APP_ADJ) {
   19204                 adj += minLayer;
   19205             }
   19206         }
   19207 
   19208         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
   19209                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
   19210             if (app.foregroundServices) {
   19211                 // The user is aware of this app, so make it visible.
   19212                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   19213                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
   19214                 app.cached = false;
   19215                 app.adjType = "fg-service";
   19216                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19217             } else if (app.forcingToForeground != null) {
   19218                 // The user is aware of this app, so make it visible.
   19219                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   19220                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   19221                 app.cached = false;
   19222                 app.adjType = "force-fg";
   19223                 app.adjSource = app.forcingToForeground;
   19224                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19225             }
   19226         }
   19227 
   19228         if (app == mHeavyWeightProcess) {
   19229             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   19230                 // We don't want to kill the current heavy-weight process.
   19231                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
   19232                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   19233                 app.cached = false;
   19234                 app.adjType = "heavy";
   19235             }
   19236             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
   19237                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
   19238             }
   19239         }
   19240 
   19241         if (app == mHomeProcess) {
   19242             if (adj > ProcessList.HOME_APP_ADJ) {
   19243                 // This process is hosting what we currently consider to be the
   19244                 // home app, so we don't want to let it go into the background.
   19245                 adj = ProcessList.HOME_APP_ADJ;
   19246                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   19247                 app.cached = false;
   19248                 app.adjType = "home";
   19249             }
   19250             if (procState > ActivityManager.PROCESS_STATE_HOME) {
   19251                 procState = ActivityManager.PROCESS_STATE_HOME;
   19252             }
   19253         }
   19254 
   19255         if (app == mPreviousProcess && app.activities.size() > 0) {
   19256             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
   19257                 // This was the previous process that showed UI to the user.
   19258                 // We want to try to keep it around more aggressively, to give
   19259                 // a good experience around switching between two apps.
   19260                 adj = ProcessList.PREVIOUS_APP_ADJ;
   19261                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   19262                 app.cached = false;
   19263                 app.adjType = "previous";
   19264             }
   19265             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   19266                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   19267             }
   19268         }
   19269 
   19270         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
   19271                 + " reason=" + app.adjType);
   19272 
   19273         // By default, we use the computed adjustment.  It may be changed if
   19274         // there are applications dependent on our services or providers, but
   19275         // this gives us a baseline and makes sure we don't get into an
   19276         // infinite recursion.
   19277         app.adjSeq = mAdjSeq;
   19278         app.curRawAdj = adj;
   19279         app.hasStartedServices = false;
   19280 
   19281         if (mBackupTarget != null && app == mBackupTarget.app) {
   19282             // If possible we want to avoid killing apps while they're being backed up
   19283             if (adj > ProcessList.BACKUP_APP_ADJ) {
   19284                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
   19285                 adj = ProcessList.BACKUP_APP_ADJ;
   19286                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   19287                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
   19288                 }
   19289                 app.adjType = "backup";
   19290                 app.cached = false;
   19291             }
   19292             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
   19293                 procState = ActivityManager.PROCESS_STATE_BACKUP;
   19294             }
   19295         }
   19296 
   19297         boolean mayBeTop = false;
   19298 
   19299         for (int is = app.services.size()-1;
   19300                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   19301                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   19302                         || procState > ActivityManager.PROCESS_STATE_TOP);
   19303                 is--) {
   19304             ServiceRecord s = app.services.valueAt(is);
   19305             if (s.startRequested) {
   19306                 app.hasStartedServices = true;
   19307                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
   19308                     procState = ActivityManager.PROCESS_STATE_SERVICE;
   19309                 }
   19310                 if (app.hasShownUi && app != mHomeProcess) {
   19311                     // If this process has shown some UI, let it immediately
   19312                     // go to the LRU list because it may be pretty heavy with
   19313                     // UI stuff.  We'll tag it with a label just to help
   19314                     // debug and understand what is going on.
   19315                     if (adj > ProcessList.SERVICE_ADJ) {
   19316                         app.adjType = "cch-started-ui-services";
   19317                     }
   19318                 } else {
   19319                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   19320                         // This service has seen some activity within
   19321                         // recent memory, so we will keep its process ahead
   19322                         // of the background processes.
   19323                         if (adj > ProcessList.SERVICE_ADJ) {
   19324                             adj = ProcessList.SERVICE_ADJ;
   19325                             app.adjType = "started-services";
   19326                             app.cached = false;
   19327                         }
   19328                     }
   19329                     // If we have let the service slide into the background
   19330                     // state, still have some text describing what it is doing
   19331                     // even though the service no longer has an impact.
   19332                     if (adj > ProcessList.SERVICE_ADJ) {
   19333                         app.adjType = "cch-started-services";
   19334                     }
   19335                 }
   19336             }
   19337 
   19338             for (int conni = s.connections.size()-1;
   19339                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   19340                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   19341                             || procState > ActivityManager.PROCESS_STATE_TOP);
   19342                     conni--) {
   19343                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
   19344                 for (int i = 0;
   19345                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
   19346                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   19347                                 || procState > ActivityManager.PROCESS_STATE_TOP);
   19348                         i++) {
   19349                     // XXX should compute this based on the max of
   19350                     // all connected clients.
   19351                     ConnectionRecord cr = clist.get(i);
   19352                     if (cr.binding.client == app) {
   19353                         // Binding to ourself is not interesting.
   19354                         continue;
   19355                     }
   19356 
   19357                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
   19358                         ProcessRecord client = cr.binding.client;
   19359                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
   19360                                 TOP_APP, doingAll, now);
   19361                         int clientProcState = client.curProcState;
   19362                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   19363                             // If the other app is cached for any reason, for purposes here
   19364                             // we are going to consider it empty.  The specific cached state
   19365                             // doesn't propagate except under certain conditions.
   19366                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   19367                         }
   19368                         String adjType = null;
   19369                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
   19370                             // Not doing bind OOM management, so treat
   19371                             // this guy more like a started service.
   19372                             if (app.hasShownUi && app != mHomeProcess) {
   19373                                 // If this process has shown some UI, let it immediately
   19374                                 // go to the LRU list because it may be pretty heavy with
   19375                                 // UI stuff.  We'll tag it with a label just to help
   19376                                 // debug and understand what is going on.
   19377                                 if (adj > clientAdj) {
   19378                                     adjType = "cch-bound-ui-services";
   19379                                 }
   19380                                 app.cached = false;
   19381                                 clientAdj = adj;
   19382                                 clientProcState = procState;
   19383                             } else {
   19384                                 if (now >= (s.lastActivity
   19385                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   19386                                     // This service has not seen activity within
   19387                                     // recent memory, so allow it to drop to the
   19388                                     // LRU list if there is no other reason to keep
   19389                                     // it around.  We'll also tag it with a label just
   19390                                     // to help debug and undertand what is going on.
   19391                                     if (adj > clientAdj) {
   19392                                         adjType = "cch-bound-services";
   19393                                     }
   19394                                     clientAdj = adj;
   19395                                 }
   19396                             }
   19397                         }
   19398                         if (adj > clientAdj) {
   19399                             // If this process has recently shown UI, and
   19400                             // the process that is binding to it is less
   19401                             // important than being visible, then we don't
   19402                             // care about the binding as much as we care
   19403                             // about letting this process get into the LRU
   19404                             // list to be killed and restarted if needed for
   19405                             // memory.
   19406                             if (app.hasShownUi && app != mHomeProcess
   19407                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   19408                                 adjType = "cch-bound-ui-services";
   19409                             } else {
   19410                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
   19411                                         |Context.BIND_IMPORTANT)) != 0) {
   19412                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
   19413                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
   19414                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
   19415                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
   19416                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   19417                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   19418                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   19419                                     adj = clientAdj;
   19420                                 } else {
   19421                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   19422                                         adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
   19423                                     }
   19424                                 }
   19425                                 if (!client.cached) {
   19426                                     app.cached = false;
   19427                                 }
   19428                                 adjType = "service";
   19429                             }
   19430                         }
   19431                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   19432                             // This will treat important bound services identically to
   19433                             // the top app, which may behave differently than generic
   19434                             // foreground work.
   19435                             if (client.curSchedGroup > schedGroup) {
   19436                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
   19437                                     schedGroup = client.curSchedGroup;
   19438                                 } else {
   19439                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19440                                 }
   19441                             }
   19442                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   19443                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   19444                                     // Special handling of clients who are in the top state.
   19445                                     // We *may* want to consider this process to be in the
   19446                                     // top state as well, but only if there is not another
   19447                                     // reason for it to be running.  Being on the top is a
   19448                                     // special state, meaning you are specifically running
   19449                                     // for the current top app.  If the process is already
   19450                                     // running in the background for some other reason, it
   19451                                     // is more important to continue considering it to be
   19452                                     // in the background state.
   19453                                     mayBeTop = true;
   19454                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   19455                                 } else {
   19456                                     // Special handling for above-top states (persistent
   19457                                     // processes).  These should not bring the current process
   19458                                     // into the top state, since they are not on top.  Instead
   19459                                     // give them the best state after that.
   19460                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
   19461                                         clientProcState =
   19462                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
   19463                                     } else if (mWakefulness
   19464                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
   19465                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
   19466                                                     != 0) {
   19467                                         clientProcState =
   19468                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
   19469                                     } else {
   19470                                         clientProcState =
   19471                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   19472                                     }
   19473                                 }
   19474                             }
   19475                         } else {
   19476                             if (clientProcState <
   19477                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   19478                                 clientProcState =
   19479                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
   19480                             }
   19481                         }
   19482                         if (procState > clientProcState) {
   19483                             procState = clientProcState;
   19484                         }
   19485                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   19486                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
   19487                             app.pendingUiClean = true;
   19488                         }
   19489                         if (adjType != null) {
   19490                             app.adjType = adjType;
   19491                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   19492                                     .REASON_SERVICE_IN_USE;
   19493                             app.adjSource = cr.binding.client;
   19494                             app.adjSourceProcState = clientProcState;
   19495                             app.adjTarget = s.name;
   19496                         }
   19497                     }
   19498                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
   19499                         app.treatLikeActivity = true;
   19500                     }
   19501                     final ActivityRecord a = cr.activity;
   19502                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
   19503                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
   19504                             (a.visible || a.state == ActivityState.RESUMED ||
   19505                              a.state == ActivityState.PAUSING)) {
   19506                             adj = ProcessList.FOREGROUND_APP_ADJ;
   19507                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   19508                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
   19509                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
   19510                                 } else {
   19511                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19512                                 }
   19513                             }
   19514                             app.cached = false;
   19515                             app.adjType = "service";
   19516                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   19517                                     .REASON_SERVICE_IN_USE;
   19518                             app.adjSource = a;
   19519                             app.adjSourceProcState = procState;
   19520                             app.adjTarget = s.name;
   19521                         }
   19522                     }
   19523                 }
   19524             }
   19525         }
   19526 
   19527         for (int provi = app.pubProviders.size()-1;
   19528                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   19529                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   19530                         || procState > ActivityManager.PROCESS_STATE_TOP);
   19531                 provi--) {
   19532             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
   19533             for (int i = cpr.connections.size()-1;
   19534                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   19535                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   19536                             || procState > ActivityManager.PROCESS_STATE_TOP);
   19537                     i--) {
   19538                 ContentProviderConnection conn = cpr.connections.get(i);
   19539                 ProcessRecord client = conn.client;
   19540                 if (client == app) {
   19541                     // Being our own client is not interesting.
   19542                     continue;
   19543                 }
   19544                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
   19545                 int clientProcState = client.curProcState;
   19546                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   19547                     // If the other app is cached for any reason, for purposes here
   19548                     // we are going to consider it empty.
   19549                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   19550                 }
   19551                 if (adj > clientAdj) {
   19552                     if (app.hasShownUi && app != mHomeProcess
   19553                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   19554                         app.adjType = "cch-ui-provider";
   19555                     } else {
   19556                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
   19557                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
   19558                         app.adjType = "provider";
   19559                     }
   19560                     app.cached &= client.cached;
   19561                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   19562                             .REASON_PROVIDER_IN_USE;
   19563                     app.adjSource = client;
   19564                     app.adjSourceProcState = clientProcState;
   19565                     app.adjTarget = cpr.name;
   19566                 }
   19567                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   19568                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   19569                         // Special handling of clients who are in the top state.
   19570                         // We *may* want to consider this process to be in the
   19571                         // top state as well, but only if there is not another
   19572                         // reason for it to be running.  Being on the top is a
   19573                         // special state, meaning you are specifically running
   19574                         // for the current top app.  If the process is already
   19575                         // running in the background for some other reason, it
   19576                         // is more important to continue considering it to be
   19577                         // in the background state.
   19578                         mayBeTop = true;
   19579                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   19580                     } else {
   19581                         // Special handling for above-top states (persistent
   19582                         // processes).  These should not bring the current process
   19583                         // into the top state, since they are not on top.  Instead
   19584                         // give them the best state after that.
   19585                         clientProcState =
   19586                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
   19587                     }
   19588                 }
   19589                 if (procState > clientProcState) {
   19590                     procState = clientProcState;
   19591                 }
   19592                 if (client.curSchedGroup > schedGroup) {
   19593                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19594                 }
   19595             }
   19596             // If the provider has external (non-framework) process
   19597             // dependencies, ensure that its adjustment is at least
   19598             // FOREGROUND_APP_ADJ.
   19599             if (cpr.hasExternalProcessHandles()) {
   19600                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
   19601                     adj = ProcessList.FOREGROUND_APP_ADJ;
   19602                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19603                     app.cached = false;
   19604                     app.adjType = "provider";
   19605                     app.adjTarget = cpr.name;
   19606                 }
   19607                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
   19608                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   19609                 }
   19610             }
   19611         }
   19612 
   19613         if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
   19614             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
   19615                 adj = ProcessList.PREVIOUS_APP_ADJ;
   19616                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   19617                 app.cached = false;
   19618                 app.adjType = "provider";
   19619             }
   19620             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   19621                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   19622             }
   19623         }
   19624 
   19625         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
   19626             // A client of one of our services or providers is in the top state.  We
   19627             // *may* want to be in the top state, but not if we are already running in
   19628             // the background for some other reason.  For the decision here, we are going
   19629             // to pick out a few specific states that we want to remain in when a client
   19630             // is top (states that tend to be longer-term) and otherwise allow it to go
   19631             // to the top state.
   19632             switch (procState) {
   19633                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
   19634                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
   19635                 case ActivityManager.PROCESS_STATE_SERVICE:
   19636                     // These all are longer-term states, so pull them up to the top
   19637                     // of the background states, but not all the way to the top state.
   19638                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
   19639                     break;
   19640                 default:
   19641                     // Otherwise, top is a better choice, so take it.
   19642                     procState = ActivityManager.PROCESS_STATE_TOP;
   19643                     break;
   19644             }
   19645         }
   19646 
   19647         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
   19648             if (app.hasClientActivities) {
   19649                 // This is a cached process, but with client activities.  Mark it so.
   19650                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
   19651                 app.adjType = "cch-client-act";
   19652             } else if (app.treatLikeActivity) {
   19653                 // This is a cached process, but somebody wants us to treat it like it has
   19654                 // an activity, okay!
   19655                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   19656                 app.adjType = "cch-as-act";
   19657             }
   19658         }
   19659 
   19660         if (adj == ProcessList.SERVICE_ADJ) {
   19661             if (doingAll) {
   19662                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
   19663                 mNewNumServiceProcs++;
   19664                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
   19665                 if (!app.serviceb) {
   19666                     // This service isn't far enough down on the LRU list to
   19667                     // normally be a B service, but if we are low on RAM and it
   19668                     // is large we want to force it down since we would prefer to
   19669                     // keep launcher over it.
   19670                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
   19671                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
   19672                         app.serviceHighRam = true;
   19673                         app.serviceb = true;
   19674                         //Slog.i(TAG, "ADJ " + app + " high ram!");
   19675                     } else {
   19676                         mNewNumAServiceProcs++;
   19677                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
   19678                     }
   19679                 } else {
   19680                     app.serviceHighRam = false;
   19681                 }
   19682             }
   19683             if (app.serviceb) {
   19684                 adj = ProcessList.SERVICE_B_ADJ;
   19685             }
   19686         }
   19687 
   19688         app.curRawAdj = adj;
   19689 
   19690         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
   19691         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
   19692         if (adj > app.maxAdj) {
   19693             adj = app.maxAdj;
   19694             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   19695                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19696             }
   19697         }
   19698 
   19699         // Do final modification to adj.  Everything we do between here and applying
   19700         // the final setAdj must be done in this function, because we will also use
   19701         // it when computing the final cached adj later.  Note that we don't need to
   19702         // worry about this for max adj above, since max adj will always be used to
   19703         // keep it out of the cached vaues.
   19704         app.curAdj = app.modifyRawOomAdj(adj);
   19705         app.curSchedGroup = schedGroup;
   19706         app.curProcState = procState;
   19707         app.foregroundActivities = foregroundActivities;
   19708 
   19709         return app.curRawAdj;
   19710     }
   19711 
   19712     /**
   19713      * Record new PSS sample for a process.
   19714      */
   19715     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
   19716             long now) {
   19717         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
   19718                 swapPss * 1024);
   19719         proc.lastPssTime = now;
   19720         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
   19721         if (DEBUG_PSS) Slog.d(TAG_PSS,
   19722                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
   19723                 + " state=" + ProcessList.makeProcStateString(procState));
   19724         if (proc.initialIdlePss == 0) {
   19725             proc.initialIdlePss = pss;
   19726         }
   19727         proc.lastPss = pss;
   19728         proc.lastSwapPss = swapPss;
   19729         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
   19730             proc.lastCachedPss = pss;
   19731             proc.lastCachedSwapPss = swapPss;
   19732         }
   19733 
   19734         final SparseArray<Pair<Long, String>> watchUids
   19735                 = mMemWatchProcesses.getMap().get(proc.processName);
   19736         Long check = null;
   19737         if (watchUids != null) {
   19738             Pair<Long, String> val = watchUids.get(proc.uid);
   19739             if (val == null) {
   19740                 val = watchUids.get(0);
   19741             }
   19742             if (val != null) {
   19743                 check = val.first;
   19744             }
   19745         }
   19746         if (check != null) {
   19747             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
   19748                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   19749                 if (!isDebuggable) {
   19750                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   19751                         isDebuggable = true;
   19752                     }
   19753                 }
   19754                 if (isDebuggable) {
   19755                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
   19756                     final ProcessRecord myProc = proc;
   19757                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
   19758                     mMemWatchDumpProcName = proc.processName;
   19759                     mMemWatchDumpFile = heapdumpFile.toString();
   19760                     mMemWatchDumpPid = proc.pid;
   19761                     mMemWatchDumpUid = proc.uid;
   19762                     BackgroundThread.getHandler().post(new Runnable() {
   19763                         @Override
   19764                         public void run() {
   19765                             revokeUriPermission(ActivityThread.currentActivityThread()
   19766                                             .getApplicationThread(),
   19767                                     DumpHeapActivity.JAVA_URI,
   19768                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
   19769                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
   19770                                     UserHandle.myUserId());
   19771                             ParcelFileDescriptor fd = null;
   19772                             try {
   19773                                 heapdumpFile.delete();
   19774                                 fd = ParcelFileDescriptor.open(heapdumpFile,
   19775                                         ParcelFileDescriptor.MODE_CREATE |
   19776                                                 ParcelFileDescriptor.MODE_TRUNCATE |
   19777                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
   19778                                                 ParcelFileDescriptor.MODE_APPEND);
   19779                                 IApplicationThread thread = myProc.thread;
   19780                                 if (thread != null) {
   19781                                     try {
   19782                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
   19783                                                 "Requesting dump heap from "
   19784                                                 + myProc + " to " + heapdumpFile);
   19785                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
   19786                                     } catch (RemoteException e) {
   19787                                     }
   19788                                 }
   19789                             } catch (FileNotFoundException e) {
   19790                                 e.printStackTrace();
   19791                             } finally {
   19792                                 if (fd != null) {
   19793                                     try {
   19794                                         fd.close();
   19795                                     } catch (IOException e) {
   19796                                     }
   19797                                 }
   19798                             }
   19799                         }
   19800                     });
   19801                 } else {
   19802                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
   19803                             + ", but debugging not enabled");
   19804                 }
   19805             }
   19806         }
   19807     }
   19808 
   19809     /**
   19810      * Schedule PSS collection of a process.
   19811      */
   19812     void requestPssLocked(ProcessRecord proc, int procState) {
   19813         if (mPendingPssProcesses.contains(proc)) {
   19814             return;
   19815         }
   19816         if (mPendingPssProcesses.size() == 0) {
   19817             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   19818         }
   19819         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
   19820         proc.pssProcState = procState;
   19821         mPendingPssProcesses.add(proc);
   19822     }
   19823 
   19824     /**
   19825      * Schedule PSS collection of all processes.
   19826      */
   19827     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
   19828         if (!always) {
   19829             if (now < (mLastFullPssTime +
   19830                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
   19831                 return;
   19832             }
   19833         }
   19834         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
   19835         mLastFullPssTime = now;
   19836         mFullPssPending = true;
   19837         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
   19838         mPendingPssProcesses.clear();
   19839         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   19840             ProcessRecord app = mLruProcesses.get(i);
   19841             if (app.thread == null
   19842                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
   19843                 continue;
   19844             }
   19845             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
   19846                 app.pssProcState = app.setProcState;
   19847                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
   19848                         mTestPssMode, isSleepingLocked(), now);
   19849                 mPendingPssProcesses.add(app);
   19850             }
   19851         }
   19852         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   19853     }
   19854 
   19855     public void setTestPssMode(boolean enabled) {
   19856         synchronized (this) {
   19857             mTestPssMode = enabled;
   19858             if (enabled) {
   19859                 // Whenever we enable the mode, we want to take a snapshot all of current
   19860                 // process mem use.
   19861                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
   19862             }
   19863         }
   19864     }
   19865 
   19866     /**
   19867      * Ask a given process to GC right now.
   19868      */
   19869     final void performAppGcLocked(ProcessRecord app) {
   19870         try {
   19871             app.lastRequestedGc = SystemClock.uptimeMillis();
   19872             if (app.thread != null) {
   19873                 if (app.reportLowMemory) {
   19874                     app.reportLowMemory = false;
   19875                     app.thread.scheduleLowMemory();
   19876                 } else {
   19877                     app.thread.processInBackground();
   19878                 }
   19879             }
   19880         } catch (Exception e) {
   19881             // whatever.
   19882         }
   19883     }
   19884 
   19885     /**
   19886      * Returns true if things are idle enough to perform GCs.
   19887      */
   19888     private final boolean canGcNowLocked() {
   19889         boolean processingBroadcasts = false;
   19890         for (BroadcastQueue q : mBroadcastQueues) {
   19891             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
   19892                 processingBroadcasts = true;
   19893             }
   19894         }
   19895         return !processingBroadcasts
   19896                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
   19897     }
   19898 
   19899     /**
   19900      * Perform GCs on all processes that are waiting for it, but only
   19901      * if things are idle.
   19902      */
   19903     final void performAppGcsLocked() {
   19904         final int N = mProcessesToGc.size();
   19905         if (N <= 0) {
   19906             return;
   19907         }
   19908         if (canGcNowLocked()) {
   19909             while (mProcessesToGc.size() > 0) {
   19910                 ProcessRecord proc = mProcessesToGc.remove(0);
   19911                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
   19912                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
   19913                             <= SystemClock.uptimeMillis()) {
   19914                         // To avoid spamming the system, we will GC processes one
   19915                         // at a time, waiting a few seconds between each.
   19916                         performAppGcLocked(proc);
   19917                         scheduleAppGcsLocked();
   19918                         return;
   19919                     } else {
   19920                         // It hasn't been long enough since we last GCed this
   19921                         // process...  put it in the list to wait for its time.
   19922                         addProcessToGcListLocked(proc);
   19923                         break;
   19924                     }
   19925                 }
   19926             }
   19927 
   19928             scheduleAppGcsLocked();
   19929         }
   19930     }
   19931 
   19932     /**
   19933      * If all looks good, perform GCs on all processes waiting for them.
   19934      */
   19935     final void performAppGcsIfAppropriateLocked() {
   19936         if (canGcNowLocked()) {
   19937             performAppGcsLocked();
   19938             return;
   19939         }
   19940         // Still not idle, wait some more.
   19941         scheduleAppGcsLocked();
   19942     }
   19943 
   19944     /**
   19945      * Schedule the execution of all pending app GCs.
   19946      */
   19947     final void scheduleAppGcsLocked() {
   19948         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
   19949 
   19950         if (mProcessesToGc.size() > 0) {
   19951             // Schedule a GC for the time to the next process.
   19952             ProcessRecord proc = mProcessesToGc.get(0);
   19953             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
   19954 
   19955             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
   19956             long now = SystemClock.uptimeMillis();
   19957             if (when < (now+GC_TIMEOUT)) {
   19958                 when = now + GC_TIMEOUT;
   19959             }
   19960             mHandler.sendMessageAtTime(msg, when);
   19961         }
   19962     }
   19963 
   19964     /**
   19965      * Add a process to the array of processes waiting to be GCed.  Keeps the
   19966      * list in sorted order by the last GC time.  The process can't already be
   19967      * on the list.
   19968      */
   19969     final void addProcessToGcListLocked(ProcessRecord proc) {
   19970         boolean added = false;
   19971         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
   19972             if (mProcessesToGc.get(i).lastRequestedGc <
   19973                     proc.lastRequestedGc) {
   19974                 added = true;
   19975                 mProcessesToGc.add(i+1, proc);
   19976                 break;
   19977             }
   19978         }
   19979         if (!added) {
   19980             mProcessesToGc.add(0, proc);
   19981         }
   19982     }
   19983 
   19984     /**
   19985      * Set up to ask a process to GC itself.  This will either do it
   19986      * immediately, or put it on the list of processes to gc the next
   19987      * time things are idle.
   19988      */
   19989     final void scheduleAppGcLocked(ProcessRecord app) {
   19990         long now = SystemClock.uptimeMillis();
   19991         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
   19992             return;
   19993         }
   19994         if (!mProcessesToGc.contains(app)) {
   19995             addProcessToGcListLocked(app);
   19996             scheduleAppGcsLocked();
   19997         }
   19998     }
   19999 
   20000     final void checkExcessivePowerUsageLocked(boolean doKills) {
   20001         updateCpuStatsNow();
   20002 
   20003         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   20004         boolean doWakeKills = doKills;
   20005         boolean doCpuKills = doKills;
   20006         if (mLastPowerCheckRealtime == 0) {
   20007             doWakeKills = false;
   20008         }
   20009         if (mLastPowerCheckUptime == 0) {
   20010             doCpuKills = false;
   20011         }
   20012         if (stats.isScreenOn()) {
   20013             doWakeKills = false;
   20014         }
   20015         final long curRealtime = SystemClock.elapsedRealtime();
   20016         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
   20017         final long curUptime = SystemClock.uptimeMillis();
   20018         final long uptimeSince = curUptime - mLastPowerCheckUptime;
   20019         mLastPowerCheckRealtime = curRealtime;
   20020         mLastPowerCheckUptime = curUptime;
   20021         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
   20022             doWakeKills = false;
   20023         }
   20024         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
   20025             doCpuKills = false;
   20026         }
   20027         int i = mLruProcesses.size();
   20028         while (i > 0) {
   20029             i--;
   20030             ProcessRecord app = mLruProcesses.get(i);
   20031             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
   20032                 long wtime;
   20033                 synchronized (stats) {
   20034                     wtime = stats.getProcessWakeTime(app.info.uid,
   20035                             app.pid, curRealtime);
   20036                 }
   20037                 long wtimeUsed = wtime - app.lastWakeTime;
   20038                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
   20039                 if (DEBUG_POWER) {
   20040                     StringBuilder sb = new StringBuilder(128);
   20041                     sb.append("Wake for ");
   20042                     app.toShortString(sb);
   20043                     sb.append(": over ");
   20044                     TimeUtils.formatDuration(realtimeSince, sb);
   20045                     sb.append(" used ");
   20046                     TimeUtils.formatDuration(wtimeUsed, sb);
   20047                     sb.append(" (");
   20048                     sb.append((wtimeUsed*100)/realtimeSince);
   20049                     sb.append("%)");
   20050                     Slog.i(TAG_POWER, sb.toString());
   20051                     sb.setLength(0);
   20052                     sb.append("CPU for ");
   20053                     app.toShortString(sb);
   20054                     sb.append(": over ");
   20055                     TimeUtils.formatDuration(uptimeSince, sb);
   20056                     sb.append(" used ");
   20057                     TimeUtils.formatDuration(cputimeUsed, sb);
   20058                     sb.append(" (");
   20059                     sb.append((cputimeUsed*100)/uptimeSince);
   20060                     sb.append("%)");
   20061                     Slog.i(TAG_POWER, sb.toString());
   20062                 }
   20063                 // If a process has held a wake lock for more
   20064                 // than 50% of the time during this period,
   20065                 // that sounds bad.  Kill!
   20066                 if (doWakeKills && realtimeSince > 0
   20067                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
   20068                     synchronized (stats) {
   20069                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
   20070                                 realtimeSince, wtimeUsed);
   20071                     }
   20072                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
   20073                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
   20074                 } else if (doCpuKills && uptimeSince > 0
   20075                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
   20076                     synchronized (stats) {
   20077                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
   20078                                 uptimeSince, cputimeUsed);
   20079                     }
   20080                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
   20081                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
   20082                 } else {
   20083                     app.lastWakeTime = wtime;
   20084                     app.lastCpuTime = app.curCpuTime;
   20085                 }
   20086             }
   20087         }
   20088     }
   20089 
   20090     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
   20091             long nowElapsed) {
   20092         boolean success = true;
   20093 
   20094         if (app.curRawAdj != app.setRawAdj) {
   20095             app.setRawAdj = app.curRawAdj;
   20096         }
   20097 
   20098         int changes = 0;
   20099 
   20100         if (app.curAdj != app.setAdj) {
   20101             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
   20102             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   20103                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
   20104                     + app.adjType);
   20105             app.setAdj = app.curAdj;
   20106             app.verifiedAdj = ProcessList.INVALID_ADJ;
   20107         }
   20108 
   20109         if (app.setSchedGroup != app.curSchedGroup) {
   20110             app.setSchedGroup = app.curSchedGroup;
   20111             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   20112                     "Setting sched group of " + app.processName
   20113                     + " to " + app.curSchedGroup);
   20114             if (app.waitingToKill != null && app.curReceiver == null
   20115                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
   20116                 app.kill(app.waitingToKill, true);
   20117                 success = false;
   20118             } else {
   20119                 int processGroup;
   20120                 switch (app.curSchedGroup) {
   20121                     case ProcessList.SCHED_GROUP_BACKGROUND:
   20122                         processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   20123                         break;
   20124                     case ProcessList.SCHED_GROUP_TOP_APP:
   20125                         processGroup = Process.THREAD_GROUP_TOP_APP;
   20126                         break;
   20127                     default:
   20128                         processGroup = Process.THREAD_GROUP_DEFAULT;
   20129                         break;
   20130                 }
   20131                 if (true) {
   20132                     long oldId = Binder.clearCallingIdentity();
   20133                     try {
   20134                         Process.setProcessGroup(app.pid, processGroup);
   20135                     } catch (Exception e) {
   20136                         Slog.w(TAG, "Failed setting process group of " + app.pid
   20137                                 + " to " + app.curSchedGroup);
   20138                         e.printStackTrace();
   20139                     } finally {
   20140                         Binder.restoreCallingIdentity(oldId);
   20141                     }
   20142                 } else {
   20143                     if (app.thread != null) {
   20144                         try {
   20145                             app.thread.setSchedulingGroup(processGroup);
   20146                         } catch (RemoteException e) {
   20147                         }
   20148                     }
   20149                 }
   20150             }
   20151         }
   20152         if (app.repForegroundActivities != app.foregroundActivities) {
   20153             app.repForegroundActivities = app.foregroundActivities;
   20154             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
   20155         }
   20156         if (app.repProcState != app.curProcState) {
   20157             app.repProcState = app.curProcState;
   20158             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
   20159             if (app.thread != null) {
   20160                 try {
   20161                     if (false) {
   20162                         //RuntimeException h = new RuntimeException("here");
   20163                         Slog.i(TAG, "Sending new process state " + app.repProcState
   20164                                 + " to " + app /*, h*/);
   20165                     }
   20166                     app.thread.setProcessState(app.repProcState);
   20167                 } catch (RemoteException e) {
   20168                 }
   20169             }
   20170         }
   20171         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
   20172                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
   20173             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
   20174                 // Experimental code to more aggressively collect pss while
   20175                 // running test...  the problem is that this tends to collect
   20176                 // the data right when a process is transitioning between process
   20177                 // states, which well tend to give noisy data.
   20178                 long start = SystemClock.uptimeMillis();
   20179                 long pss = Debug.getPss(app.pid, mTmpLong, null);
   20180                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
   20181                 mPendingPssProcesses.remove(app);
   20182                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
   20183                         + " to " + app.curProcState + ": "
   20184                         + (SystemClock.uptimeMillis()-start) + "ms");
   20185             }
   20186             app.lastStateTime = now;
   20187             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
   20188                     mTestPssMode, isSleepingLocked(), now);
   20189             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
   20190                     + ProcessList.makeProcStateString(app.setProcState) + " to "
   20191                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
   20192                     + (app.nextPssTime-now) + ": " + app);
   20193         } else {
   20194             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
   20195                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
   20196                     mTestPssMode)))) {
   20197                 requestPssLocked(app, app.setProcState);
   20198                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
   20199                         mTestPssMode, isSleepingLocked(), now);
   20200             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
   20201                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
   20202         }
   20203         if (app.setProcState != app.curProcState) {
   20204             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   20205                     "Proc state change of " + app.processName
   20206                             + " to " + app.curProcState);
   20207             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
   20208             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
   20209             if (setImportant && !curImportant) {
   20210                 // This app is no longer something we consider important enough to allow to
   20211                 // use arbitrary amounts of battery power.  Note
   20212                 // its current wake lock time to later know to kill it if
   20213                 // it is not behaving well.
   20214                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   20215                 synchronized (stats) {
   20216                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
   20217                             app.pid, nowElapsed);
   20218                 }
   20219                 app.lastCpuTime = app.curCpuTime;
   20220 
   20221             }
   20222             // Inform UsageStats of important process state change
   20223             // Must be called before updating setProcState
   20224             maybeUpdateUsageStatsLocked(app, nowElapsed);
   20225 
   20226             app.setProcState = app.curProcState;
   20227             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
   20228                 app.notCachedSinceIdle = false;
   20229             }
   20230             if (!doingAll) {
   20231                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
   20232             } else {
   20233                 app.procStateChanged = true;
   20234             }
   20235         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
   20236                 > USAGE_STATS_INTERACTION_INTERVAL) {
   20237             // For apps that sit around for a long time in the interactive state, we need
   20238             // to report this at least once a day so they don't go idle.
   20239             maybeUpdateUsageStatsLocked(app, nowElapsed);
   20240         }
   20241 
   20242         if (changes != 0) {
   20243             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   20244                     "Changes in " + app + ": " + changes);
   20245             int i = mPendingProcessChanges.size()-1;
   20246             ProcessChangeItem item = null;
   20247             while (i >= 0) {
   20248                 item = mPendingProcessChanges.get(i);
   20249                 if (item.pid == app.pid) {
   20250                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   20251                             "Re-using existing item: " + item);
   20252                     break;
   20253                 }
   20254                 i--;
   20255             }
   20256             if (i < 0) {
   20257                 // No existing item in pending changes; need a new one.
   20258                 final int NA = mAvailProcessChanges.size();
   20259                 if (NA > 0) {
   20260                     item = mAvailProcessChanges.remove(NA-1);
   20261                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   20262                             "Retrieving available item: " + item);
   20263                 } else {
   20264                     item = new ProcessChangeItem();
   20265                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   20266                             "Allocating new item: " + item);
   20267                 }
   20268                 item.changes = 0;
   20269                 item.pid = app.pid;
   20270                 item.uid = app.info.uid;
   20271                 if (mPendingProcessChanges.size() == 0) {
   20272                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   20273                             "*** Enqueueing dispatch processes changed!");
   20274                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
   20275                 }
   20276                 mPendingProcessChanges.add(item);
   20277             }
   20278             item.changes |= changes;
   20279             item.processState = app.repProcState;
   20280             item.foregroundActivities = app.repForegroundActivities;
   20281             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   20282                     "Item " + Integer.toHexString(System.identityHashCode(item))
   20283                     + " " + app.toShortString() + ": changes=" + item.changes
   20284                     + " procState=" + item.processState
   20285                     + " foreground=" + item.foregroundActivities
   20286                     + " type=" + app.adjType + " source=" + app.adjSource
   20287                     + " target=" + app.adjTarget);
   20288         }
   20289 
   20290         return success;
   20291     }
   20292 
   20293     private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
   20294         final UidRecord.ChangeItem pendingChange;
   20295         if (uidRec == null || uidRec.pendingChange == null) {
   20296             if (mPendingUidChanges.size() == 0) {
   20297                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   20298                         "*** Enqueueing dispatch uid changed!");
   20299                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
   20300             }
   20301             final int NA = mAvailUidChanges.size();
   20302             if (NA > 0) {
   20303                 pendingChange = mAvailUidChanges.remove(NA-1);
   20304                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   20305                         "Retrieving available item: " + pendingChange);
   20306             } else {
   20307                 pendingChange = new UidRecord.ChangeItem();
   20308                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   20309                         "Allocating new item: " + pendingChange);
   20310             }
   20311             if (uidRec != null) {
   20312                 uidRec.pendingChange = pendingChange;
   20313                 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
   20314                     // If this uid is going away, and we haven't yet reported it is gone,
   20315                     // then do so now.
   20316                     change = UidRecord.CHANGE_GONE_IDLE;
   20317                 }
   20318             } else if (uid < 0) {
   20319                 throw new IllegalArgumentException("No UidRecord or uid");
   20320             }
   20321             pendingChange.uidRecord = uidRec;
   20322             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
   20323             mPendingUidChanges.add(pendingChange);
   20324         } else {
   20325             pendingChange = uidRec.pendingChange;
   20326             if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
   20327                 change = UidRecord.CHANGE_GONE_IDLE;
   20328             }
   20329         }
   20330         pendingChange.change = change;
   20331         pendingChange.processState = uidRec != null
   20332                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
   20333     }
   20334 
   20335     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
   20336             String authority) {
   20337         if (app == null) return;
   20338         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
   20339             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
   20340             if (userState == null) return;
   20341             final long now = SystemClock.elapsedRealtime();
   20342             Long lastReported = userState.mProviderLastReportedFg.get(authority);
   20343             if (lastReported == null || lastReported < now - 60 * 1000L) {
   20344                 mUsageStatsService.reportContentProviderUsage(
   20345                         authority, providerPkgName, app.userId);
   20346                 userState.mProviderLastReportedFg.put(authority, now);
   20347             }
   20348         }
   20349     }
   20350 
   20351     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
   20352         if (DEBUG_USAGE_STATS) {
   20353             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
   20354                     + "] state changes: old = " + app.setProcState + ", new = "
   20355                     + app.curProcState);
   20356         }
   20357         if (mUsageStatsService == null) {
   20358             return;
   20359         }
   20360         boolean isInteraction;
   20361         // To avoid some abuse patterns, we are going to be careful about what we consider
   20362         // to be an app interaction.  Being the top activity doesn't count while the display
   20363         // is sleeping, nor do short foreground services.
   20364         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
   20365             isInteraction = true;
   20366             app.fgInteractionTime = 0;
   20367         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
   20368             if (app.fgInteractionTime == 0) {
   20369                 app.fgInteractionTime = nowElapsed;
   20370                 isInteraction = false;
   20371             } else {
   20372                 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
   20373             }
   20374         } else {
   20375             isInteraction = app.curProcState
   20376                     <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   20377             app.fgInteractionTime = 0;
   20378         }
   20379         if (isInteraction && (!app.reportedInteraction
   20380                 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
   20381             app.interactionEventTime = nowElapsed;
   20382             String[] packages = app.getPackageList();
   20383             if (packages != null) {
   20384                 for (int i = 0; i < packages.length; i++) {
   20385                     mUsageStatsService.reportEvent(packages[i], app.userId,
   20386                             UsageEvents.Event.SYSTEM_INTERACTION);
   20387                 }
   20388             }
   20389         }
   20390         app.reportedInteraction = isInteraction;
   20391         if (!isInteraction) {
   20392             app.interactionEventTime = 0;
   20393         }
   20394     }
   20395 
   20396     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
   20397         if (proc.thread != null) {
   20398             if (proc.baseProcessTracker != null) {
   20399                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
   20400             }
   20401         }
   20402     }
   20403 
   20404     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
   20405             ProcessRecord TOP_APP, boolean doingAll, long now) {
   20406         if (app.thread == null) {
   20407             return false;
   20408         }
   20409 
   20410         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
   20411 
   20412         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
   20413     }
   20414 
   20415     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
   20416             boolean oomAdj) {
   20417         if (isForeground != proc.foregroundServices) {
   20418             proc.foregroundServices = isForeground;
   20419             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
   20420                     proc.info.uid);
   20421             if (isForeground) {
   20422                 if (curProcs == null) {
   20423                     curProcs = new ArrayList<ProcessRecord>();
   20424                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
   20425                 }
   20426                 if (!curProcs.contains(proc)) {
   20427                     curProcs.add(proc);
   20428                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
   20429                             proc.info.packageName, proc.info.uid);
   20430                 }
   20431             } else {
   20432                 if (curProcs != null) {
   20433                     if (curProcs.remove(proc)) {
   20434                         mBatteryStatsService.noteEvent(
   20435                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
   20436                                 proc.info.packageName, proc.info.uid);
   20437                         if (curProcs.size() <= 0) {
   20438                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
   20439                         }
   20440                     }
   20441                 }
   20442             }
   20443             if (oomAdj) {
   20444                 updateOomAdjLocked();
   20445             }
   20446         }
   20447     }
   20448 
   20449     private final ActivityRecord resumedAppLocked() {
   20450         ActivityRecord act = mStackSupervisor.resumedAppLocked();
   20451         String pkg;
   20452         int uid;
   20453         if (act != null) {
   20454             pkg = act.packageName;
   20455             uid = act.info.applicationInfo.uid;
   20456         } else {
   20457             pkg = null;
   20458             uid = -1;
   20459         }
   20460         // Has the UID or resumed package name changed?
   20461         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
   20462                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
   20463             if (mCurResumedPackage != null) {
   20464                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
   20465                         mCurResumedPackage, mCurResumedUid);
   20466             }
   20467             mCurResumedPackage = pkg;
   20468             mCurResumedUid = uid;
   20469             if (mCurResumedPackage != null) {
   20470                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
   20471                         mCurResumedPackage, mCurResumedUid);
   20472             }
   20473         }
   20474         return act;
   20475     }
   20476 
   20477     final boolean updateOomAdjLocked(ProcessRecord app) {
   20478         final ActivityRecord TOP_ACT = resumedAppLocked();
   20479         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   20480         final boolean wasCached = app.cached;
   20481 
   20482         mAdjSeq++;
   20483 
   20484         // This is the desired cached adjusment we want to tell it to use.
   20485         // If our app is currently cached, we know it, and that is it.  Otherwise,
   20486         // we don't know it yet, and it needs to now be cached we will then
   20487         // need to do a complete oom adj.
   20488         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
   20489                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
   20490         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
   20491                 SystemClock.uptimeMillis());
   20492         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
   20493             // Changed to/from cached state, so apps after it in the LRU
   20494             // list may also be changed.
   20495             updateOomAdjLocked();
   20496         }
   20497         return success;
   20498     }
   20499 
   20500     final void updateOomAdjLocked() {
   20501         final ActivityRecord TOP_ACT = resumedAppLocked();
   20502         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   20503         final long now = SystemClock.uptimeMillis();
   20504         final long nowElapsed = SystemClock.elapsedRealtime();
   20505         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
   20506         final int N = mLruProcesses.size();
   20507 
   20508         if (false) {
   20509             RuntimeException e = new RuntimeException();
   20510             e.fillInStackTrace();
   20511             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
   20512         }
   20513 
   20514         // Reset state in all uid records.
   20515         for (int i=mActiveUids.size()-1; i>=0; i--) {
   20516             final UidRecord uidRec = mActiveUids.valueAt(i);
   20517             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   20518                     "Starting update of " + uidRec);
   20519             uidRec.reset();
   20520         }
   20521 
   20522         mStackSupervisor.rankTaskLayersIfNeeded();
   20523 
   20524         mAdjSeq++;
   20525         mNewNumServiceProcs = 0;
   20526         mNewNumAServiceProcs = 0;
   20527 
   20528         final int emptyProcessLimit;
   20529         final int cachedProcessLimit;
   20530         if (mProcessLimit <= 0) {
   20531             emptyProcessLimit = cachedProcessLimit = 0;
   20532         } else if (mProcessLimit == 1) {
   20533             emptyProcessLimit = 1;
   20534             cachedProcessLimit = 0;
   20535         } else {
   20536             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
   20537             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
   20538         }
   20539 
   20540         // Let's determine how many processes we have running vs.
   20541         // how many slots we have for background processes; we may want
   20542         // to put multiple processes in a slot of there are enough of
   20543         // them.
   20544         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
   20545                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
   20546         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
   20547         if (numEmptyProcs > cachedProcessLimit) {
   20548             // If there are more empty processes than our limit on cached
   20549             // processes, then use the cached process limit for the factor.
   20550             // This ensures that the really old empty processes get pushed
   20551             // down to the bottom, so if we are running low on memory we will
   20552             // have a better chance at keeping around more cached processes
   20553             // instead of a gazillion empty processes.
   20554             numEmptyProcs = cachedProcessLimit;
   20555         }
   20556         int emptyFactor = numEmptyProcs/numSlots;
   20557         if (emptyFactor < 1) emptyFactor = 1;
   20558         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
   20559         if (cachedFactor < 1) cachedFactor = 1;
   20560         int stepCached = 0;
   20561         int stepEmpty = 0;
   20562         int numCached = 0;
   20563         int numEmpty = 0;
   20564         int numTrimming = 0;
   20565 
   20566         mNumNonCachedProcs = 0;
   20567         mNumCachedHiddenProcs = 0;
   20568 
   20569         // First update the OOM adjustment for each of the
   20570         // application processes based on their current state.
   20571         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
   20572         int nextCachedAdj = curCachedAdj+1;
   20573         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
   20574         int nextEmptyAdj = curEmptyAdj+2;
   20575         for (int i=N-1; i>=0; i--) {
   20576             ProcessRecord app = mLruProcesses.get(i);
   20577             if (!app.killedByAm && app.thread != null) {
   20578                 app.procStateChanged = false;
   20579                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
   20580 
   20581                 // If we haven't yet assigned the final cached adj
   20582                 // to the process, do that now.
   20583                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
   20584                     switch (app.curProcState) {
   20585                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   20586                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   20587                             // This process is a cached process holding activities...
   20588                             // assign it the next cached value for that type, and then
   20589                             // step that cached level.
   20590                             app.curRawAdj = curCachedAdj;
   20591                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
   20592                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
   20593                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
   20594                                     + ")");
   20595                             if (curCachedAdj != nextCachedAdj) {
   20596                                 stepCached++;
   20597                                 if (stepCached >= cachedFactor) {
   20598                                     stepCached = 0;
   20599                                     curCachedAdj = nextCachedAdj;
   20600                                     nextCachedAdj += 2;
   20601                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   20602                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
   20603                                     }
   20604                                 }
   20605                             }
   20606                             break;
   20607                         default:
   20608                             // For everything else, assign next empty cached process
   20609                             // level and bump that up.  Note that this means that
   20610                             // long-running services that have dropped down to the
   20611                             // cached level will be treated as empty (since their process
   20612                             // state is still as a service), which is what we want.
   20613                             app.curRawAdj = curEmptyAdj;
   20614                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
   20615                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
   20616                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
   20617                                     + ")");
   20618                             if (curEmptyAdj != nextEmptyAdj) {
   20619                                 stepEmpty++;
   20620                                 if (stepEmpty >= emptyFactor) {
   20621                                     stepEmpty = 0;
   20622                                     curEmptyAdj = nextEmptyAdj;
   20623                                     nextEmptyAdj += 2;
   20624                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   20625                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
   20626                                     }
   20627                                 }
   20628                             }
   20629                             break;
   20630                     }
   20631                 }
   20632 
   20633                 applyOomAdjLocked(app, true, now, nowElapsed);
   20634 
   20635                 // Count the number of process types.
   20636                 switch (app.curProcState) {
   20637                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   20638                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   20639                         mNumCachedHiddenProcs++;
   20640                         numCached++;
   20641                         if (numCached > cachedProcessLimit) {
   20642                             app.kill("cached #" + numCached, true);
   20643                         }
   20644                         break;
   20645                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
   20646                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
   20647                                 && app.lastActivityTime < oldTime) {
   20648                             app.kill("empty for "
   20649                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
   20650                                     / 1000) + "s", true);
   20651                         } else {
   20652                             numEmpty++;
   20653                             if (numEmpty > emptyProcessLimit) {
   20654                                 app.kill("empty #" + numEmpty, true);
   20655                             }
   20656                         }
   20657                         break;
   20658                     default:
   20659                         mNumNonCachedProcs++;
   20660                         break;
   20661                 }
   20662 
   20663                 if (app.isolated && app.services.size() <= 0) {
   20664                     // If this is an isolated process, and there are no
   20665                     // services running in it, then the process is no longer
   20666                     // needed.  We agressively kill these because we can by
   20667                     // definition not re-use the same process again, and it is
   20668                     // good to avoid having whatever code was running in them
   20669                     // left sitting around after no longer needed.
   20670                     app.kill("isolated not needed", true);
   20671                 } else {
   20672                     // Keeping this process, update its uid.
   20673                     final UidRecord uidRec = app.uidRecord;
   20674                     if (uidRec != null && uidRec.curProcState > app.curProcState) {
   20675                         uidRec.curProcState = app.curProcState;
   20676                     }
   20677                 }
   20678 
   20679                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   20680                         && !app.killedByAm) {
   20681                     numTrimming++;
   20682                 }
   20683             }
   20684         }
   20685 
   20686         mNumServiceProcs = mNewNumServiceProcs;
   20687 
   20688         // Now determine the memory trimming level of background processes.
   20689         // Unfortunately we need to start at the back of the list to do this
   20690         // properly.  We only do this if the number of background apps we
   20691         // are managing to keep around is less than half the maximum we desire;
   20692         // if we are keeping a good number around, we'll let them use whatever
   20693         // memory they want.
   20694         final int numCachedAndEmpty = numCached + numEmpty;
   20695         int memFactor;
   20696         if (numCached <= ProcessList.TRIM_CACHED_APPS
   20697                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
   20698             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
   20699                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
   20700             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
   20701                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
   20702             } else {
   20703                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
   20704             }
   20705         } else {
   20706             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
   20707         }
   20708         // We always allow the memory level to go up (better).  We only allow it to go
   20709         // down if we are in a state where that is allowed, *and* the total number of processes
   20710         // has gone down since last time.
   20711         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
   20712                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
   20713                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
   20714         if (memFactor > mLastMemoryLevel) {
   20715             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
   20716                 memFactor = mLastMemoryLevel;
   20717                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
   20718             }
   20719         }
   20720         if (memFactor != mLastMemoryLevel) {
   20721             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
   20722         }
   20723         mLastMemoryLevel = memFactor;
   20724         mLastNumProcesses = mLruProcesses.size();
   20725         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
   20726         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
   20727         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
   20728             if (mLowRamStartTime == 0) {
   20729                 mLowRamStartTime = now;
   20730             }
   20731             int step = 0;
   20732             int fgTrimLevel;
   20733             switch (memFactor) {
   20734                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
   20735                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
   20736                     break;
   20737                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
   20738                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
   20739                     break;
   20740                 default:
   20741                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
   20742                     break;
   20743             }
   20744             int factor = numTrimming/3;
   20745             int minFactor = 2;
   20746             if (mHomeProcess != null) minFactor++;
   20747             if (mPreviousProcess != null) minFactor++;
   20748             if (factor < minFactor) factor = minFactor;
   20749             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
   20750             for (int i=N-1; i>=0; i--) {
   20751                 ProcessRecord app = mLruProcesses.get(i);
   20752                 if (allChanged || app.procStateChanged) {
   20753                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
   20754                     app.procStateChanged = false;
   20755                 }
   20756                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   20757                         && !app.killedByAm) {
   20758                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
   20759                         try {
   20760                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   20761                                     "Trimming memory of " + app.processName + " to " + curLevel);
   20762                             app.thread.scheduleTrimMemory(curLevel);
   20763                         } catch (RemoteException e) {
   20764                         }
   20765                         if (false) {
   20766                             // For now we won't do this; our memory trimming seems
   20767                             // to be good enough at this point that destroying
   20768                             // activities causes more harm than good.
   20769                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
   20770                                     && app != mHomeProcess && app != mPreviousProcess) {
   20771                                 // Need to do this on its own message because the stack may not
   20772                                 // be in a consistent state at this point.
   20773                                 // For these apps we will also finish their activities
   20774                                 // to help them free memory.
   20775                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
   20776                             }
   20777                         }
   20778                     }
   20779                     app.trimMemoryLevel = curLevel;
   20780                     step++;
   20781                     if (step >= factor) {
   20782                         step = 0;
   20783                         switch (curLevel) {
   20784                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
   20785                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
   20786                                 break;
   20787                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
   20788                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   20789                                 break;
   20790                         }
   20791                     }
   20792                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
   20793                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
   20794                             && app.thread != null) {
   20795                         try {
   20796                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   20797                                     "Trimming memory of heavy-weight " + app.processName
   20798                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   20799                             app.thread.scheduleTrimMemory(
   20800                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   20801                         } catch (RemoteException e) {
   20802                         }
   20803                     }
   20804                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   20805                 } else {
   20806                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   20807                             || app.systemNoUi) && app.pendingUiClean) {
   20808                         // If this application is now in the background and it
   20809                         // had done UI, then give it the special trim level to
   20810                         // have it free UI resources.
   20811                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
   20812                         if (app.trimMemoryLevel < level && app.thread != null) {
   20813                             try {
   20814                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   20815                                         "Trimming memory of bg-ui " + app.processName
   20816                                         + " to " + level);
   20817                                 app.thread.scheduleTrimMemory(level);
   20818                             } catch (RemoteException e) {
   20819                             }
   20820                         }
   20821                         app.pendingUiClean = false;
   20822                     }
   20823                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
   20824                         try {
   20825                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   20826                                     "Trimming memory of fg " + app.processName
   20827                                     + " to " + fgTrimLevel);
   20828                             app.thread.scheduleTrimMemory(fgTrimLevel);
   20829                         } catch (RemoteException e) {
   20830                         }
   20831                     }
   20832                     app.trimMemoryLevel = fgTrimLevel;
   20833                 }
   20834             }
   20835         } else {
   20836             if (mLowRamStartTime != 0) {
   20837                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
   20838                 mLowRamStartTime = 0;
   20839             }
   20840             for (int i=N-1; i>=0; i--) {
   20841                 ProcessRecord app = mLruProcesses.get(i);
   20842                 if (allChanged || app.procStateChanged) {
   20843                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
   20844                     app.procStateChanged = false;
   20845                 }
   20846                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   20847                         || app.systemNoUi) && app.pendingUiClean) {
   20848                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
   20849                             && app.thread != null) {
   20850                         try {
   20851                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   20852                                     "Trimming memory of ui hidden " + app.processName
   20853                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   20854                             app.thread.scheduleTrimMemory(
   20855                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   20856                         } catch (RemoteException e) {
   20857                         }
   20858                     }
   20859                     app.pendingUiClean = false;
   20860                 }
   20861                 app.trimMemoryLevel = 0;
   20862             }
   20863         }
   20864 
   20865         if (mAlwaysFinishActivities) {
   20866             // Need to do this on its own message because the stack may not
   20867             // be in a consistent state at this point.
   20868             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
   20869         }
   20870 
   20871         if (allChanged) {
   20872             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
   20873         }
   20874 
   20875         // Update from any uid changes.
   20876         for (int i=mActiveUids.size()-1; i>=0; i--) {
   20877             final UidRecord uidRec = mActiveUids.valueAt(i);
   20878             int uidChange = UidRecord.CHANGE_PROCSTATE;
   20879             if (uidRec.setProcState != uidRec.curProcState) {
   20880                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   20881                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
   20882                         + " to " + uidRec.curProcState);
   20883                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
   20884                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
   20885                         uidRec.lastBackgroundTime = nowElapsed;
   20886                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
   20887                             // Note: the background settle time is in elapsed realtime, while
   20888                             // the handler time base is uptime.  All this means is that we may
   20889                             // stop background uids later than we had intended, but that only
   20890                             // happens because the device was sleeping so we are okay anyway.
   20891                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
   20892                         }
   20893                     }
   20894                 } else {
   20895                     if (uidRec.idle) {
   20896                         uidChange = UidRecord.CHANGE_ACTIVE;
   20897                         uidRec.idle = false;
   20898                     }
   20899                     uidRec.lastBackgroundTime = 0;
   20900                 }
   20901                 uidRec.setProcState = uidRec.curProcState;
   20902                 enqueueUidChangeLocked(uidRec, -1, uidChange);
   20903                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
   20904             }
   20905         }
   20906 
   20907         if (mProcessStats.shouldWriteNowLocked(now)) {
   20908             mHandler.post(new Runnable() {
   20909                 @Override public void run() {
   20910                     synchronized (ActivityManagerService.this) {
   20911                         mProcessStats.writeStateAsyncLocked();
   20912                     }
   20913                 }
   20914             });
   20915         }
   20916 
   20917         if (DEBUG_OOM_ADJ) {
   20918             final long duration = SystemClock.uptimeMillis() - now;
   20919             if (false) {
   20920                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
   20921                         new RuntimeException("here").fillInStackTrace());
   20922             } else {
   20923                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
   20924             }
   20925         }
   20926     }
   20927 
   20928     final void idleUids() {
   20929         synchronized (this) {
   20930             final long nowElapsed = SystemClock.elapsedRealtime();
   20931             final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
   20932             long nextTime = 0;
   20933             for (int i=mActiveUids.size()-1; i>=0; i--) {
   20934                 final UidRecord uidRec = mActiveUids.valueAt(i);
   20935                 final long bgTime = uidRec.lastBackgroundTime;
   20936                 if (bgTime > 0 && !uidRec.idle) {
   20937                     if (bgTime <= maxBgTime) {
   20938                         uidRec.idle = true;
   20939                         doStopUidLocked(uidRec.uid, uidRec);
   20940                     } else {
   20941                         if (nextTime == 0 || nextTime > bgTime) {
   20942                             nextTime = bgTime;
   20943                         }
   20944                     }
   20945                 }
   20946             }
   20947             if (nextTime > 0) {
   20948                 mHandler.removeMessages(IDLE_UIDS_MSG);
   20949                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
   20950                         nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
   20951             }
   20952         }
   20953     }
   20954 
   20955     final void runInBackgroundDisabled(int uid) {
   20956         synchronized (this) {
   20957             UidRecord uidRec = mActiveUids.get(uid);
   20958             if (uidRec != null) {
   20959                 // This uid is actually running...  should it be considered background now?
   20960                 if (uidRec.idle) {
   20961                     doStopUidLocked(uidRec.uid, uidRec);
   20962                 }
   20963             } else {
   20964                 // This uid isn't actually running...  still send a report about it being "stopped".
   20965                 doStopUidLocked(uid, null);
   20966             }
   20967         }
   20968     }
   20969 
   20970     final void doStopUidLocked(int uid, final UidRecord uidRec) {
   20971         mServices.stopInBackgroundLocked(uid);
   20972         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
   20973     }
   20974 
   20975     final void trimApplications() {
   20976         synchronized (this) {
   20977             int i;
   20978 
   20979             // First remove any unused application processes whose package
   20980             // has been removed.
   20981             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
   20982                 final ProcessRecord app = mRemovedProcesses.get(i);
   20983                 if (app.activities.size() == 0
   20984                         && app.curReceiver == null && app.services.size() == 0) {
   20985                     Slog.i(
   20986                         TAG, "Exiting empty application process "
   20987                         + app.toShortString() + " ("
   20988                         + (app.thread != null ? app.thread.asBinder() : null)
   20989                         + ")\n");
   20990                     if (app.pid > 0 && app.pid != MY_PID) {
   20991                         app.kill("empty", false);
   20992                     } else {
   20993                         try {
   20994                             app.thread.scheduleExit();
   20995                         } catch (Exception e) {
   20996                             // Ignore exceptions.
   20997                         }
   20998                     }
   20999                     cleanUpApplicationRecordLocked(app, false, true, -1);
   21000                     mRemovedProcesses.remove(i);
   21001 
   21002                     if (app.persistent) {
   21003                         addAppLocked(app.info, false, null /* ABI override */);
   21004                     }
   21005                 }
   21006             }
   21007 
   21008             // Now update the oom adj for all processes.
   21009             updateOomAdjLocked();
   21010         }
   21011     }
   21012 
   21013     /** This method sends the specified signal to each of the persistent apps */
   21014     public void signalPersistentProcesses(int sig) throws RemoteException {
   21015         if (sig != Process.SIGNAL_USR1) {
   21016             throw new SecurityException("Only SIGNAL_USR1 is allowed");
   21017         }
   21018 
   21019         synchronized (this) {
   21020             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
   21021                     != PackageManager.PERMISSION_GRANTED) {
   21022                 throw new SecurityException("Requires permission "
   21023                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
   21024             }
   21025 
   21026             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   21027                 ProcessRecord r = mLruProcesses.get(i);
   21028                 if (r.thread != null && r.persistent) {
   21029                     Process.sendSignal(r.pid, sig);
   21030                 }
   21031             }
   21032         }
   21033     }
   21034 
   21035     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
   21036         if (proc == null || proc == mProfileProc) {
   21037             proc = mProfileProc;
   21038             profileType = mProfileType;
   21039             clearProfilerLocked();
   21040         }
   21041         if (proc == null) {
   21042             return;
   21043         }
   21044         try {
   21045             proc.thread.profilerControl(false, null, profileType);
   21046         } catch (RemoteException e) {
   21047             throw new IllegalStateException("Process disappeared");
   21048         }
   21049     }
   21050 
   21051     private void clearProfilerLocked() {
   21052         if (mProfileFd != null) {
   21053             try {
   21054                 mProfileFd.close();
   21055             } catch (IOException e) {
   21056             }
   21057         }
   21058         mProfileApp = null;
   21059         mProfileProc = null;
   21060         mProfileFile = null;
   21061         mProfileType = 0;
   21062         mAutoStopProfiler = false;
   21063         mSamplingInterval = 0;
   21064     }
   21065 
   21066     public boolean profileControl(String process, int userId, boolean start,
   21067             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
   21068 
   21069         try {
   21070             synchronized (this) {
   21071                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   21072                 // its own permission.
   21073                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   21074                         != PackageManager.PERMISSION_GRANTED) {
   21075                     throw new SecurityException("Requires permission "
   21076                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   21077                 }
   21078 
   21079                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
   21080                     throw new IllegalArgumentException("null profile info or fd");
   21081                 }
   21082 
   21083                 ProcessRecord proc = null;
   21084                 if (process != null) {
   21085                     proc = findProcessLocked(process, userId, "profileControl");
   21086                 }
   21087 
   21088                 if (start && (proc == null || proc.thread == null)) {
   21089                     throw new IllegalArgumentException("Unknown process: " + process);
   21090                 }
   21091 
   21092                 if (start) {
   21093                     stopProfilerLocked(null, 0);
   21094                     setProfileApp(proc.info, proc.processName, profilerInfo);
   21095                     mProfileProc = proc;
   21096                     mProfileType = profileType;
   21097                     ParcelFileDescriptor fd = profilerInfo.profileFd;
   21098                     try {
   21099                         fd = fd.dup();
   21100                     } catch (IOException e) {
   21101                         fd = null;
   21102                     }
   21103                     profilerInfo.profileFd = fd;
   21104                     proc.thread.profilerControl(start, profilerInfo, profileType);
   21105                     fd = null;
   21106                     mProfileFd = null;
   21107                 } else {
   21108                     stopProfilerLocked(proc, profileType);
   21109                     if (profilerInfo != null && profilerInfo.profileFd != null) {
   21110                         try {
   21111                             profilerInfo.profileFd.close();
   21112                         } catch (IOException e) {
   21113                         }
   21114                     }
   21115                 }
   21116 
   21117                 return true;
   21118             }
   21119         } catch (RemoteException e) {
   21120             throw new IllegalStateException("Process disappeared");
   21121         } finally {
   21122             if (profilerInfo != null && profilerInfo.profileFd != null) {
   21123                 try {
   21124                     profilerInfo.profileFd.close();
   21125                 } catch (IOException e) {
   21126                 }
   21127             }
   21128         }
   21129     }
   21130 
   21131     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
   21132         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   21133                 userId, true, ALLOW_FULL_ONLY, callName, null);
   21134         ProcessRecord proc = null;
   21135         try {
   21136             int pid = Integer.parseInt(process);
   21137             synchronized (mPidsSelfLocked) {
   21138                 proc = mPidsSelfLocked.get(pid);
   21139             }
   21140         } catch (NumberFormatException e) {
   21141         }
   21142 
   21143         if (proc == null) {
   21144             ArrayMap<String, SparseArray<ProcessRecord>> all
   21145                     = mProcessNames.getMap();
   21146             SparseArray<ProcessRecord> procs = all.get(process);
   21147             if (procs != null && procs.size() > 0) {
   21148                 proc = procs.valueAt(0);
   21149                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
   21150                     for (int i=1; i<procs.size(); i++) {
   21151                         ProcessRecord thisProc = procs.valueAt(i);
   21152                         if (thisProc.userId == userId) {
   21153                             proc = thisProc;
   21154                             break;
   21155                         }
   21156                     }
   21157                 }
   21158             }
   21159         }
   21160 
   21161         return proc;
   21162     }
   21163 
   21164     public boolean dumpHeap(String process, int userId, boolean managed,
   21165             String path, ParcelFileDescriptor fd) throws RemoteException {
   21166 
   21167         try {
   21168             synchronized (this) {
   21169                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   21170                 // its own permission (same as profileControl).
   21171                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   21172                         != PackageManager.PERMISSION_GRANTED) {
   21173                     throw new SecurityException("Requires permission "
   21174                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   21175                 }
   21176 
   21177                 if (fd == null) {
   21178                     throw new IllegalArgumentException("null fd");
   21179                 }
   21180 
   21181                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
   21182                 if (proc == null || proc.thread == null) {
   21183                     throw new IllegalArgumentException("Unknown process: " + process);
   21184                 }
   21185 
   21186                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   21187                 if (!isDebuggable) {
   21188                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   21189                         throw new SecurityException("Process not debuggable: " + proc);
   21190                     }
   21191                 }
   21192 
   21193                 proc.thread.dumpHeap(managed, path, fd);
   21194                 fd = null;
   21195                 return true;
   21196             }
   21197         } catch (RemoteException e) {
   21198             throw new IllegalStateException("Process disappeared");
   21199         } finally {
   21200             if (fd != null) {
   21201                 try {
   21202                     fd.close();
   21203                 } catch (IOException e) {
   21204                 }
   21205             }
   21206         }
   21207     }
   21208 
   21209     @Override
   21210     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
   21211             String reportPackage) {
   21212         if (processName != null) {
   21213             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   21214                     "setDumpHeapDebugLimit()");
   21215         } else {
   21216             synchronized (mPidsSelfLocked) {
   21217                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
   21218                 if (proc == null) {
   21219                     throw new SecurityException("No process found for calling pid "
   21220                             + Binder.getCallingPid());
   21221                 }
   21222                 if (!Build.IS_DEBUGGABLE
   21223                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   21224                     throw new SecurityException("Not running a debuggable build");
   21225                 }
   21226                 processName = proc.processName;
   21227                 uid = proc.uid;
   21228                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
   21229                     throw new SecurityException("Package " + reportPackage + " is not running in "
   21230                             + proc);
   21231                 }
   21232             }
   21233         }
   21234         synchronized (this) {
   21235             if (maxMemSize > 0) {
   21236                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
   21237             } else {
   21238                 if (uid != 0) {
   21239                     mMemWatchProcesses.remove(processName, uid);
   21240                 } else {
   21241                     mMemWatchProcesses.getMap().remove(processName);
   21242                 }
   21243             }
   21244         }
   21245     }
   21246 
   21247     @Override
   21248     public void dumpHeapFinished(String path) {
   21249         synchronized (this) {
   21250             if (Binder.getCallingPid() != mMemWatchDumpPid) {
   21251                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
   21252                         + " does not match last pid " + mMemWatchDumpPid);
   21253                 return;
   21254             }
   21255             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
   21256                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
   21257                         + " does not match last path " + mMemWatchDumpFile);
   21258                 return;
   21259             }
   21260             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
   21261             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
   21262         }
   21263     }
   21264 
   21265     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
   21266     public void monitor() {
   21267         synchronized (this) { }
   21268     }
   21269 
   21270     void onCoreSettingsChange(Bundle settings) {
   21271         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   21272             ProcessRecord processRecord = mLruProcesses.get(i);
   21273             try {
   21274                 if (processRecord.thread != null) {
   21275                     processRecord.thread.setCoreSettings(settings);
   21276                 }
   21277             } catch (RemoteException re) {
   21278                 /* ignore */
   21279             }
   21280         }
   21281     }
   21282 
   21283     // Multi-user methods
   21284 
   21285     /**
   21286      * Start user, if its not already running, but don't bring it to foreground.
   21287      */
   21288     @Override
   21289     public boolean startUserInBackground(final int userId) {
   21290         return mUserController.startUser(userId, /* foreground */ false);
   21291     }
   21292 
   21293     @Override
   21294     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
   21295         return mUserController.unlockUser(userId, token, secret, listener);
   21296     }
   21297 
   21298     @Override
   21299     public boolean switchUser(final int targetUserId) {
   21300         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
   21301         UserInfo currentUserInfo;
   21302         UserInfo targetUserInfo;
   21303         synchronized (this) {
   21304             int currentUserId = mUserController.getCurrentUserIdLocked();
   21305             currentUserInfo = mUserController.getUserInfo(currentUserId);
   21306             targetUserInfo = mUserController.getUserInfo(targetUserId);
   21307             if (targetUserInfo == null) {
   21308                 Slog.w(TAG, "No user info for user #" + targetUserId);
   21309                 return false;
   21310             }
   21311             if (!targetUserInfo.supportsSwitchTo()) {
   21312                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
   21313                 return false;
   21314             }
   21315             if (targetUserInfo.isManagedProfile()) {
   21316                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
   21317                 return false;
   21318             }
   21319             mUserController.setTargetUserIdLocked(targetUserId);
   21320         }
   21321         Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
   21322         mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
   21323         mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
   21324         return true;
   21325     }
   21326 
   21327     void scheduleStartProfilesLocked() {
   21328         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
   21329             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
   21330                     DateUtils.SECOND_IN_MILLIS);
   21331         }
   21332     }
   21333 
   21334     @Override
   21335     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
   21336         return mUserController.stopUser(userId, force, callback);
   21337     }
   21338 
   21339     @Override
   21340     public UserInfo getCurrentUser() {
   21341         return mUserController.getCurrentUser();
   21342     }
   21343 
   21344     @Override
   21345     public boolean isUserRunning(int userId, int flags) {
   21346         if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
   21347                 INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
   21348             String msg = "Permission Denial: isUserRunning() from pid="
   21349                     + Binder.getCallingPid()
   21350                     + ", uid=" + Binder.getCallingUid()
   21351                     + " requires " + INTERACT_ACROSS_USERS;
   21352             Slog.w(TAG, msg);
   21353             throw new SecurityException(msg);
   21354         }
   21355         synchronized (this) {
   21356             return mUserController.isUserRunningLocked(userId, flags);
   21357         }
   21358     }
   21359 
   21360     @Override
   21361     public int[] getRunningUserIds() {
   21362         if (checkCallingPermission(INTERACT_ACROSS_USERS)
   21363                 != PackageManager.PERMISSION_GRANTED) {
   21364             String msg = "Permission Denial: isUserRunning() from pid="
   21365                     + Binder.getCallingPid()
   21366                     + ", uid=" + Binder.getCallingUid()
   21367                     + " requires " + INTERACT_ACROSS_USERS;
   21368             Slog.w(TAG, msg);
   21369             throw new SecurityException(msg);
   21370         }
   21371         synchronized (this) {
   21372             return mUserController.getStartedUserArrayLocked();
   21373         }
   21374     }
   21375 
   21376     @Override
   21377     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
   21378         mUserController.registerUserSwitchObserver(observer);
   21379     }
   21380 
   21381     @Override
   21382     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
   21383         mUserController.unregisterUserSwitchObserver(observer);
   21384     }
   21385 
   21386     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
   21387         if (info == null) return null;
   21388         ApplicationInfo newInfo = new ApplicationInfo(info);
   21389         newInfo.initForUser(userId);
   21390         return newInfo;
   21391     }
   21392 
   21393     public boolean isUserStopped(int userId) {
   21394         synchronized (this) {
   21395             return mUserController.getStartedUserStateLocked(userId) == null;
   21396         }
   21397     }
   21398 
   21399     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
   21400         if (aInfo == null
   21401                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
   21402             return aInfo;
   21403         }
   21404 
   21405         ActivityInfo info = new ActivityInfo(aInfo);
   21406         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
   21407         return info;
   21408     }
   21409 
   21410     private boolean processSanityChecksLocked(ProcessRecord process) {
   21411         if (process == null || process.thread == null) {
   21412             return false;
   21413         }
   21414 
   21415         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   21416         if (!isDebuggable) {
   21417             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   21418                 return false;
   21419             }
   21420         }
   21421 
   21422         return true;
   21423     }
   21424 
   21425     public boolean startBinderTracking() throws RemoteException {
   21426         synchronized (this) {
   21427             mBinderTransactionTrackingEnabled = true;
   21428             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
   21429             // permission (same as profileControl).
   21430             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   21431                     != PackageManager.PERMISSION_GRANTED) {
   21432                 throw new SecurityException("Requires permission "
   21433                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   21434             }
   21435 
   21436             for (int i = 0; i < mLruProcesses.size(); i++) {
   21437                 ProcessRecord process = mLruProcesses.get(i);
   21438                 if (!processSanityChecksLocked(process)) {
   21439                     continue;
   21440                 }
   21441                 try {
   21442                     process.thread.startBinderTracking();
   21443                 } catch (RemoteException e) {
   21444                     Log.v(TAG, "Process disappared");
   21445                 }
   21446             }
   21447             return true;
   21448         }
   21449     }
   21450 
   21451     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
   21452         try {
   21453             synchronized (this) {
   21454                 mBinderTransactionTrackingEnabled = false;
   21455                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
   21456                 // permission (same as profileControl).
   21457                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   21458                         != PackageManager.PERMISSION_GRANTED) {
   21459                     throw new SecurityException("Requires permission "
   21460                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   21461                 }
   21462 
   21463                 if (fd == null) {
   21464                     throw new IllegalArgumentException("null fd");
   21465                 }
   21466 
   21467                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
   21468                 pw.println("Binder transaction traces for all processes.\n");
   21469                 for (ProcessRecord process : mLruProcesses) {
   21470                     if (!processSanityChecksLocked(process)) {
   21471                         continue;
   21472                     }
   21473 
   21474                     pw.println("Traces for process: " + process.processName);
   21475                     pw.flush();
   21476                     try {
   21477                         TransferPipe tp = new TransferPipe();
   21478                         try {
   21479                             process.thread.stopBinderTrackingAndDump(
   21480                                     tp.getWriteFd().getFileDescriptor());
   21481                             tp.go(fd.getFileDescriptor());
   21482                         } finally {
   21483                             tp.kill();
   21484                         }
   21485                     } catch (IOException e) {
   21486                         pw.println("Failure while dumping IPC traces from " + process +
   21487                                 ".  Exception: " + e);
   21488                         pw.flush();
   21489                     } catch (RemoteException e) {
   21490                         pw.println("Got a RemoteException while dumping IPC traces from " +
   21491                                 process + ".  Exception: " + e);
   21492                         pw.flush();
   21493                     }
   21494                 }
   21495                 fd = null;
   21496                 return true;
   21497             }
   21498         } finally {
   21499             if (fd != null) {
   21500                 try {
   21501                     fd.close();
   21502                 } catch (IOException e) {
   21503                 }
   21504             }
   21505         }
   21506     }
   21507 
   21508     private final class LocalService extends ActivityManagerInternal {
   21509         @Override
   21510         public void onWakefulnessChanged(int wakefulness) {
   21511             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
   21512         }
   21513 
   21514         @Override
   21515         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
   21516                 String processName, String abiOverride, int uid, Runnable crashHandler) {
   21517             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
   21518                     processName, abiOverride, uid, crashHandler);
   21519         }
   21520 
   21521         @Override
   21522         public SleepToken acquireSleepToken(String tag) {
   21523             Preconditions.checkNotNull(tag);
   21524 
   21525             ComponentName requestedVrService = null;
   21526             ComponentName callingVrActivity = null;
   21527             int userId = -1;
   21528             synchronized (ActivityManagerService.this) {
   21529                 if (mFocusedActivity != null) {
   21530                     requestedVrService = mFocusedActivity.requestedVrComponent;
   21531                     callingVrActivity = mFocusedActivity.info.getComponentName();
   21532                     userId = mFocusedActivity.userId;
   21533                 }
   21534             }
   21535 
   21536             if (requestedVrService != null) {
   21537                 applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
   21538             }
   21539 
   21540             synchronized (ActivityManagerService.this) {
   21541                 SleepTokenImpl token = new SleepTokenImpl(tag);
   21542                 mSleepTokens.add(token);
   21543                 updateSleepIfNeededLocked();
   21544                 return token;
   21545             }
   21546         }
   21547 
   21548         @Override
   21549         public ComponentName getHomeActivityForUser(int userId) {
   21550             synchronized (ActivityManagerService.this) {
   21551                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
   21552                 return homeActivity == null ? null : homeActivity.realActivity;
   21553             }
   21554         }
   21555 
   21556         @Override
   21557         public void onUserRemoved(int userId) {
   21558             synchronized (ActivityManagerService.this) {
   21559                 ActivityManagerService.this.onUserStoppedLocked(userId);
   21560             }
   21561         }
   21562 
   21563         @Override
   21564         public void onLocalVoiceInteractionStarted(IBinder activity,
   21565                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
   21566             synchronized (ActivityManagerService.this) {
   21567                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
   21568                         voiceSession, voiceInteractor);
   21569             }
   21570         }
   21571 
   21572         @Override
   21573         public void notifyStartingWindowDrawn() {
   21574             synchronized (ActivityManagerService.this) {
   21575                 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
   21576             }
   21577         }
   21578 
   21579         @Override
   21580         public void notifyAppTransitionStarting(int reason) {
   21581             synchronized (ActivityManagerService.this) {
   21582                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
   21583             }
   21584         }
   21585 
   21586         @Override
   21587         public void notifyAppTransitionFinished() {
   21588             synchronized (ActivityManagerService.this) {
   21589                 mStackSupervisor.notifyAppTransitionDone();
   21590             }
   21591         }
   21592 
   21593         @Override
   21594         public void notifyAppTransitionCancelled() {
   21595             synchronized (ActivityManagerService.this) {
   21596                 mStackSupervisor.notifyAppTransitionDone();
   21597             }
   21598         }
   21599 
   21600         @Override
   21601         public List<IBinder> getTopVisibleActivities() {
   21602             synchronized (ActivityManagerService.this) {
   21603                 return mStackSupervisor.getTopVisibleActivities();
   21604             }
   21605         }
   21606 
   21607         @Override
   21608         public void notifyDockedStackMinimizedChanged(boolean minimized) {
   21609             synchronized (ActivityManagerService.this) {
   21610                 mStackSupervisor.setDockedStackMinimized(minimized);
   21611             }
   21612         }
   21613 
   21614         @Override
   21615         public void killForegroundAppsForUser(int userHandle) {
   21616             synchronized (ActivityManagerService.this) {
   21617                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
   21618                 final int NP = mProcessNames.getMap().size();
   21619                 for (int ip = 0; ip < NP; ip++) {
   21620                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   21621                     final int NA = apps.size();
   21622                     for (int ia = 0; ia < NA; ia++) {
   21623                         final ProcessRecord app = apps.valueAt(ia);
   21624                         if (app.persistent) {
   21625                             // We don't kill persistent processes.
   21626                             continue;
   21627                         }
   21628                         if (app.removed) {
   21629                             procs.add(app);
   21630                         } else if (app.userId == userHandle && app.foregroundActivities) {
   21631                             app.removed = true;
   21632                             procs.add(app);
   21633                         }
   21634                     }
   21635                 }
   21636 
   21637                 final int N = procs.size();
   21638                 for (int i = 0; i < N; i++) {
   21639                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
   21640                 }
   21641             }
   21642         }
   21643 
   21644         @Override
   21645         public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
   21646             if (!(target instanceof PendingIntentRecord)) {
   21647                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
   21648                 return;
   21649             }
   21650             ((PendingIntentRecord) target).setWhitelistDuration(duration);
   21651         }
   21652     }
   21653 
   21654     private final class SleepTokenImpl extends SleepToken {
   21655         private final String mTag;
   21656         private final long mAcquireTime;
   21657 
   21658         public SleepTokenImpl(String tag) {
   21659             mTag = tag;
   21660             mAcquireTime = SystemClock.uptimeMillis();
   21661         }
   21662 
   21663         @Override
   21664         public void release() {
   21665             synchronized (ActivityManagerService.this) {
   21666                 if (mSleepTokens.remove(this)) {
   21667                     updateSleepIfNeededLocked();
   21668                 }
   21669             }
   21670         }
   21671 
   21672         @Override
   21673         public String toString() {
   21674             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
   21675         }
   21676     }
   21677 
   21678     /**
   21679      * An implementation of IAppTask, that allows an app to manage its own tasks via
   21680      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
   21681      * only the process that calls getAppTasks() can call the AppTask methods.
   21682      */
   21683     class AppTaskImpl extends IAppTask.Stub {
   21684         private int mTaskId;
   21685         private int mCallingUid;
   21686 
   21687         public AppTaskImpl(int taskId, int callingUid) {
   21688             mTaskId = taskId;
   21689             mCallingUid = callingUid;
   21690         }
   21691 
   21692         private void checkCaller() {
   21693             if (mCallingUid != Binder.getCallingUid()) {
   21694                 throw new SecurityException("Caller " + mCallingUid
   21695                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
   21696             }
   21697         }
   21698 
   21699         @Override
   21700         public void finishAndRemoveTask() {
   21701             checkCaller();
   21702 
   21703             synchronized (ActivityManagerService.this) {
   21704                 long origId = Binder.clearCallingIdentity();
   21705                 try {
   21706                     // We remove the task from recents to preserve backwards
   21707                     if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
   21708                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   21709                     }
   21710                 } finally {
   21711                     Binder.restoreCallingIdentity(origId);
   21712                 }
   21713             }
   21714         }
   21715 
   21716         @Override
   21717         public ActivityManager.RecentTaskInfo getTaskInfo() {
   21718             checkCaller();
   21719 
   21720             synchronized (ActivityManagerService.this) {
   21721                 long origId = Binder.clearCallingIdentity();
   21722                 try {
   21723                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
   21724                     if (tr == null) {
   21725                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   21726                     }
   21727                     return createRecentTaskInfoFromTaskRecord(tr);
   21728                 } finally {
   21729                     Binder.restoreCallingIdentity(origId);
   21730                 }
   21731             }
   21732         }
   21733 
   21734         @Override
   21735         public void moveToFront() {
   21736             checkCaller();
   21737             // Will bring task to front if it already has a root activity.
   21738             final long origId = Binder.clearCallingIdentity();
   21739             try {
   21740                 synchronized (this) {
   21741                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
   21742                 }
   21743             } finally {
   21744                 Binder.restoreCallingIdentity(origId);
   21745             }
   21746         }
   21747 
   21748         @Override
   21749         public int startActivity(IBinder whoThread, String callingPackage,
   21750                 Intent intent, String resolvedType, Bundle bOptions) {
   21751             checkCaller();
   21752 
   21753             int callingUser = UserHandle.getCallingUserId();
   21754             TaskRecord tr;
   21755             IApplicationThread appThread;
   21756             synchronized (ActivityManagerService.this) {
   21757                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
   21758                 if (tr == null) {
   21759                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   21760                 }
   21761                 appThread = ApplicationThreadNative.asInterface(whoThread);
   21762                 if (appThread == null) {
   21763                     throw new IllegalArgumentException("Bad app thread " + appThread);
   21764                 }
   21765             }
   21766             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
   21767                     resolvedType, null, null, null, null, 0, 0, null, null,
   21768                     null, bOptions, false, callingUser, null, tr);
   21769         }
   21770 
   21771         @Override
   21772         public void setExcludeFromRecents(boolean exclude) {
   21773             checkCaller();
   21774 
   21775             synchronized (ActivityManagerService.this) {
   21776                 long origId = Binder.clearCallingIdentity();
   21777                 try {
   21778                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
   21779                     if (tr == null) {
   21780                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   21781                     }
   21782                     Intent intent = tr.getBaseIntent();
   21783                     if (exclude) {
   21784                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
   21785                     } else {
   21786                         intent.setFlags(intent.getFlags()
   21787                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
   21788                     }
   21789                 } finally {
   21790                     Binder.restoreCallingIdentity(origId);
   21791                 }
   21792             }
   21793         }
   21794     }
   21795 
   21796     /**
   21797      * Kill processes for the user with id userId and that depend on the package named packageName
   21798      */
   21799     @Override
   21800     public void killPackageDependents(String packageName, int userId) {
   21801         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
   21802         if (packageName == null) {
   21803             throw new NullPointerException(
   21804                     "Cannot kill the dependents of a package without its name.");
   21805         }
   21806 
   21807         long callingId = Binder.clearCallingIdentity();
   21808         IPackageManager pm = AppGlobals.getPackageManager();
   21809         int pkgUid = -1;
   21810         try {
   21811             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
   21812         } catch (RemoteException e) {
   21813         }
   21814         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
   21815             throw new IllegalArgumentException(
   21816                     "Cannot kill dependents of non-existing package " + packageName);
   21817         }
   21818         try {
   21819             synchronized(this) {
   21820                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
   21821                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
   21822                         "dep: " + packageName);
   21823             }
   21824         } finally {
   21825             Binder.restoreCallingIdentity(callingId);
   21826         }
   21827     }
   21828 }
   21829