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.Manifest.permission;
     67 import android.annotation.NonNull;
     68 import android.annotation.UserIdInt;
     69 import android.app.Activity;
     70 import android.app.ActivityManager;
     71 import android.app.ActivityManager.RunningTaskInfo;
     72 import android.app.ActivityManager.StackId;
     73 import android.app.ActivityManager.StackInfo;
     74 import android.app.ActivityManager.TaskThumbnailInfo;
     75 import android.app.ActivityManagerInternal;
     76 import android.app.ActivityManagerInternal.SleepToken;
     77 import android.app.ActivityManagerNative;
     78 import android.app.ActivityOptions;
     79 import android.app.ActivityThread;
     80 import android.app.AlertDialog;
     81 import android.app.AppGlobals;
     82 import android.app.AppOpsManager;
     83 import android.app.ApplicationErrorReport;
     84 import android.app.ApplicationThreadNative;
     85 import android.app.BroadcastOptions;
     86 import android.app.Dialog;
     87 import android.app.IActivityContainer;
     88 import android.app.IActivityContainerCallback;
     89 import android.app.IActivityController;
     90 import android.app.IAppTask;
     91 import android.app.IApplicationThread;
     92 import android.app.IInstrumentationWatcher;
     93 import android.app.INotificationManager;
     94 import android.app.IProcessObserver;
     95 import android.app.IServiceConnection;
     96 import android.app.IStopUserCallback;
     97 import android.app.ITaskStackListener;
     98 import android.app.IUiAutomationConnection;
     99 import android.app.IUidObserver;
    100 import android.app.IUserSwitchObserver;
    101 import android.app.Instrumentation;
    102 import android.app.Notification;
    103 import android.app.NotificationManager;
    104 import android.app.PendingIntent;
    105 import android.app.ProfilerInfo;
    106 import android.app.admin.DevicePolicyManager;
    107 import android.app.assist.AssistContent;
    108 import android.app.assist.AssistStructure;
    109 import android.app.backup.IBackupManager;
    110 import android.app.usage.UsageEvents;
    111 import android.app.usage.UsageStatsManagerInternal;
    112 import android.appwidget.AppWidgetManager;
    113 import android.content.ActivityNotFoundException;
    114 import android.content.BroadcastReceiver;
    115 import android.content.ClipData;
    116 import android.content.ComponentCallbacks2;
    117 import android.content.ComponentName;
    118 import android.content.ContentProvider;
    119 import android.content.ContentResolver;
    120 import android.content.Context;
    121 import android.content.DialogInterface;
    122 import android.content.IContentProvider;
    123 import android.content.IIntentReceiver;
    124 import android.content.IIntentSender;
    125 import android.content.Intent;
    126 import android.content.IntentFilter;
    127 import android.content.IntentSender;
    128 import android.content.pm.ActivityInfo;
    129 import android.content.pm.ApplicationInfo;
    130 import android.content.pm.ConfigurationInfo;
    131 import android.content.pm.IPackageDataObserver;
    132 import android.content.pm.IPackageManager;
    133 import android.content.pm.InstrumentationInfo;
    134 import android.content.pm.PackageInfo;
    135 import android.content.pm.PackageManager;
    136 import android.content.pm.PackageManager.NameNotFoundException;
    137 import android.content.pm.PackageManagerInternal;
    138 import android.content.pm.ParceledListSlice;
    139 import android.content.pm.PathPermission;
    140 import android.content.pm.PermissionInfo;
    141 import android.content.pm.ProviderInfo;
    142 import android.content.pm.ResolveInfo;
    143 import android.content.pm.ServiceInfo;
    144 import android.content.pm.UserInfo;
    145 import android.content.res.CompatibilityInfo;
    146 import android.content.res.Configuration;
    147 import android.content.res.Resources;
    148 import android.database.ContentObserver;
    149 import android.graphics.Bitmap;
    150 import android.graphics.Point;
    151 import android.graphics.Rect;
    152 import android.location.LocationManager;
    153 import android.net.Proxy;
    154 import android.net.ProxyInfo;
    155 import android.net.Uri;
    156 import android.os.BatteryStats;
    157 import android.os.Binder;
    158 import android.os.Build;
    159 import android.os.Bundle;
    160 import android.os.Debug;
    161 import android.os.DropBoxManager;
    162 import android.os.Environment;
    163 import android.os.FactoryTest;
    164 import android.os.FileObserver;
    165 import android.os.FileUtils;
    166 import android.os.Handler;
    167 import android.os.IBinder;
    168 import android.os.IPermissionController;
    169 import android.os.IProcessInfoService;
    170 import android.os.IProgressListener;
    171 import android.os.LocaleList;
    172 import android.os.Looper;
    173 import android.os.Message;
    174 import android.os.Parcel;
    175 import android.os.ParcelFileDescriptor;
    176 import android.os.PersistableBundle;
    177 import android.os.PowerManager;
    178 import android.os.PowerManagerInternal;
    179 import android.os.Process;
    180 import android.os.RemoteCallbackList;
    181 import android.os.RemoteException;
    182 import android.os.ResultReceiver;
    183 import android.os.ServiceManager;
    184 import android.os.StrictMode;
    185 import android.os.SystemClock;
    186 import android.os.SystemProperties;
    187 import android.os.Trace;
    188 import android.os.TransactionTooLargeException;
    189 import android.os.UpdateLock;
    190 import android.os.UserHandle;
    191 import android.os.UserManager;
    192 import android.os.WorkSource;
    193 import android.os.storage.IMountService;
    194 import android.os.storage.MountServiceInternal;
    195 import android.os.storage.StorageManager;
    196 import android.provider.Settings;
    197 import android.service.voice.IVoiceInteractionSession;
    198 import android.service.voice.VoiceInteractionManagerInternal;
    199 import android.service.voice.VoiceInteractionSession;
    200 import android.telecom.TelecomManager;
    201 import android.text.format.DateUtils;
    202 import android.text.format.Time;
    203 import android.text.style.SuggestionSpan;
    204 import android.util.ArrayMap;
    205 import android.util.ArraySet;
    206 import android.util.AtomicFile;
    207 import android.util.DebugUtils;
    208 import android.util.DisplayMetrics;
    209 import android.util.EventLog;
    210 import android.util.Log;
    211 import android.util.Pair;
    212 import android.util.PrintWriterPrinter;
    213 import android.util.Slog;
    214 import android.util.SparseArray;
    215 import android.util.TimeUtils;
    216 import android.util.Xml;
    217 import android.view.Display;
    218 import android.view.Gravity;
    219 import android.view.LayoutInflater;
    220 import android.view.View;
    221 import android.view.WindowManager;
    222 
    223 import java.io.File;
    224 import java.io.FileDescriptor;
    225 import java.io.FileInputStream;
    226 import java.io.FileNotFoundException;
    227 import java.io.FileOutputStream;
    228 import java.io.IOException;
    229 import java.io.InputStreamReader;
    230 import java.io.PrintWriter;
    231 import java.io.StringWriter;
    232 import java.lang.ref.WeakReference;
    233 import java.nio.charset.StandardCharsets;
    234 import java.util.ArrayList;
    235 import java.util.Arrays;
    236 import java.util.Collections;
    237 import java.util.Comparator;
    238 import java.util.HashMap;
    239 import java.util.HashSet;
    240 import java.util.Iterator;
    241 import java.util.List;
    242 import java.util.Locale;
    243 import java.util.Map;
    244 import java.util.Objects;
    245 import java.util.Set;
    246 import java.util.concurrent.atomic.AtomicBoolean;
    247 import java.util.concurrent.atomic.AtomicLong;
    248 
    249 import dalvik.system.VMRuntime;
    250 
    251 import libcore.io.IoUtils;
    252 import libcore.util.EmptyArray;
    253 
    254 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
    255 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
    256 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
    257 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
    258 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
    259 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
    260 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
    261 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
    262 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
    263 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
    264 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
    265 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
    266 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
    267 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
    268 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
    269 import static android.content.pm.PackageManager.GET_PROVIDERS;
    270 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
    271 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
    272 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
    273 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
    274 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
    275 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
    276 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
    277 import static android.os.Process.PROC_CHAR;
    278 import static android.os.Process.PROC_OUT_LONG;
    279 import static android.os.Process.PROC_PARENS;
    280 import static android.os.Process.PROC_SPACE_TERM;
    281 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
    282 import static android.provider.Settings.Global.DEBUG_APP;
    283 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
    284 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
    285 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
    286 import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
    287 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
    288 import static android.provider.Settings.System.FONT_SCALE;
    289 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
    290 import static com.android.internal.util.XmlUtils.readIntAttribute;
    291 import static com.android.internal.util.XmlUtils.readLongAttribute;
    292 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
    293 import static com.android.internal.util.XmlUtils.writeIntAttribute;
    294 import static com.android.internal.util.XmlUtils.writeLongAttribute;
    295 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
    296 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
    297 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
    298 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
    299 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
    300 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
    301 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
    302 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
    303 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
    304 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
    305 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
    306 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
    307 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
    308 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
    309 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
    310 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
    311 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
    312 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
    313 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
    314 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
    315 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
    316 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
    317 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
    318 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
    319 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
    320 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
    321 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
    322 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
    323 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
    324 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
    325 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
    326 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
    327 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
    328 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
    329 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
    330 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
    331 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
    332 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
    333 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
    334 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
    335 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
    336 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
    337 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
    338 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
    339 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
    340 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
    341 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
    342 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
    343 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
    344 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
    345 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
    346 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
    347 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
    348 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
    349 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
    350 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
    351 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
    352 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
    353 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
    354 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
    355 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
    356 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
    357 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
    358 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
    359 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
    360 import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
    361 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
    362 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
    363 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
    364 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
    365 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
    366 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
    367 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
    368 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
    369 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
    370 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
    371 import static org.xmlpull.v1.XmlPullParser.START_TAG;
    372 
    373 public final class ActivityManagerService extends ActivityManagerNative
    374         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    375 
    376     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
    377     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
    378     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
    379     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
    380     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
    381     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
    382     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
    383     private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
    384     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
    385     private static final String TAG_LRU = TAG + POSTFIX_LRU;
    386     private static final String TAG_MU = TAG + POSTFIX_MU;
    387     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
    388     private static final String TAG_POWER = TAG + POSTFIX_POWER;
    389     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
    390     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
    391     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
    392     private static final String TAG_PSS = TAG + POSTFIX_PSS;
    393     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
    394     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
    395     private static final String TAG_STACK = TAG + POSTFIX_STACK;
    396     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
    397     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
    398     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
    399     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
    400     private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
    401 
    402     // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
    403     // here so that while the job scheduler can depend on AMS, the other way around
    404     // need not be the case.
    405     public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
    406 
    407     /** Control over CPU and battery monitoring */
    408     // write battery stats every 30 minutes.
    409     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
    410     static final boolean MONITOR_CPU_USAGE = true;
    411     // don't sample cpu less than every 5 seconds.
    412     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
    413     // wait possibly forever for next cpu sample.
    414     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
    415     static final boolean MONITOR_THREAD_CPU_USAGE = false;
    416 
    417     // The flags that are set for all calls we make to the package manager.
    418     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
    419 
    420     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
    421 
    422     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
    423 
    424     // Amount of time after a call to stopAppSwitches() during which we will
    425     // prevent further untrusted switches from happening.
    426     static final long APP_SWITCH_DELAY_TIME = 5*1000;
    427 
    428     // How long we wait for a launched process to attach to the activity manager
    429     // before we decide it's never going to come up for real.
    430     static final int PROC_START_TIMEOUT = 10*1000;
    431     // How long we wait for an attached process to publish its content providers
    432     // before we decide it must be hung.
    433     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
    434 
    435     // How long we will retain processes hosting content providers in the "last activity"
    436     // state before allowing them to drop down to the regular cached LRU list.  This is
    437     // to avoid thrashing of provider processes under low memory situations.
    438     static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
    439 
    440     // How long we wait for a launched process to attach to the activity manager
    441     // before we decide it's never going to come up for real, when the process was
    442     // started with a wrapper for instrumentation (such as Valgrind) because it
    443     // could take much longer than usual.
    444     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
    445 
    446     // How long to wait after going idle before forcing apps to GC.
    447     static final int GC_TIMEOUT = 5*1000;
    448 
    449     // The minimum amount of time between successive GC requests for a process.
    450     static final int GC_MIN_INTERVAL = 60*1000;
    451 
    452     // The minimum amount of time between successive PSS requests for a process.
    453     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
    454 
    455     // The minimum amount of time between successive PSS requests for a process
    456     // when the request is due to the memory state being lowered.
    457     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
    458 
    459     // The rate at which we check for apps using excessive power -- 15 mins.
    460     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
    461 
    462     // The minimum sample duration we will allow before deciding we have
    463     // enough data on wake locks to start killing things.
    464     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    465 
    466     // The minimum sample duration we will allow before deciding we have
    467     // enough data on CPU usage to start killing things.
    468     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    469 
    470     // How long we allow a receiver to run before giving up on it.
    471     static final int BROADCAST_FG_TIMEOUT = 10*1000;
    472     static final int BROADCAST_BG_TIMEOUT = 60*1000;
    473 
    474     // How long we wait until we timeout on key dispatching.
    475     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
    476 
    477     // How long we wait until we timeout on key dispatching during instrumentation.
    478     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
    479 
    480     // This is the amount of time an app needs to be running a foreground service before
    481     // we will consider it to be doing interaction for usage stats.
    482     static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
    483 
    484     // Maximum amount of time we will allow to elapse before re-reporting usage stats
    485     // interaction with foreground processes.
    486     static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
    487 
    488     // This is the amount of time we allow an app to settle after it goes into the background,
    489     // before we start restricting what it can do.
    490     static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
    491 
    492     // How long to wait in getAssistContextExtras for the activity and foreground services
    493     // to respond with the result.
    494     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
    495 
    496     // How long top wait when going through the modern assist (which doesn't need to block
    497     // on getting this result before starting to launch its UI).
    498     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
    499 
    500     // Maximum number of persisted Uri grants a package is allowed
    501     static final int MAX_PERSISTED_URI_GRANTS = 128;
    502 
    503     static final int MY_PID = Process.myPid();
    504 
    505     static final String[] EMPTY_STRING_ARRAY = new String[0];
    506 
    507     // How many bytes to write into the dropbox log before truncating
    508     static final int DROPBOX_MAX_SIZE = 192 * 1024;
    509     // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
    510     // as one line, but close enough for now.
    511     static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
    512 
    513     // Access modes for handleIncomingUser.
    514     static final int ALLOW_NON_FULL = 0;
    515     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
    516     static final int ALLOW_FULL_ONLY = 2;
    517 
    518     // Delay in notifying task stack change listeners (in millis)
    519     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
    520 
    521     // Necessary ApplicationInfo flags to mark an app as persistent
    522     private static final int PERSISTENT_MASK =
    523             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
    524 
    525     // Intent sent when remote bugreport collection has been completed
    526     private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
    527             "android.intent.action.REMOTE_BUGREPORT_FINISHED";
    528 
    529     // Delay to disable app launch boost
    530     static final int APP_BOOST_MESSAGE_DELAY = 3000;
    531     // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
    532     static final int APP_BOOST_TIMEOUT = 2500;
    533 
    534     // Used to indicate that a task is removed it should also be removed from recents.
    535     private static final boolean REMOVE_FROM_RECENTS = true;
    536     // Used to indicate that an app transition should be animated.
    537     static final boolean ANIMATE = true;
    538 
    539     // Determines whether to take full screen screenshots
    540     static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
    541     public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
    542 
    543     private static native int nativeMigrateToBoost();
    544     private static native int nativeMigrateFromBoost();
    545     private boolean mIsBoosted = false;
    546     private long mBoostStartTime = 0;
    547 
    548     /** All system services */
    549     SystemServiceManager mSystemServiceManager;
    550 
    551     private Installer mInstaller;
    552 
    553     /** Run all ActivityStacks through this */
    554     final ActivityStackSupervisor mStackSupervisor;
    555 
    556     final ActivityStarter mActivityStarter;
    557 
    558     /** Task stack change listeners. */
    559     private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
    560             new RemoteCallbackList<ITaskStackListener>();
    561 
    562     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
    563 
    564     public IntentFirewall mIntentFirewall;
    565 
    566     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
    567     // default actuion automatically.  Important for devices without direct input
    568     // devices.
    569     private boolean mShowDialogs = true;
    570     private boolean mInVrMode = false;
    571 
    572     // Whether we should use SCHED_FIFO for UI and RenderThreads.
    573     private boolean mUseFifoUiScheduling = false;
    574 
    575     BroadcastQueue mFgBroadcastQueue;
    576     BroadcastQueue mBgBroadcastQueue;
    577     // Convenient for easy iteration over the queues. Foreground is first
    578     // so that dispatch of foreground broadcasts gets precedence.
    579     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
    580 
    581     BroadcastStats mLastBroadcastStats;
    582     BroadcastStats mCurBroadcastStats;
    583 
    584     BroadcastQueue broadcastQueueForIntent(Intent intent) {
    585         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
    586         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
    587                 "Broadcast intent " + intent + " on "
    588                 + (isFg ? "foreground" : "background") + " queue");
    589         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
    590     }
    591 
    592     /**
    593      * Activity we have told the window manager to have key focus.
    594      */
    595     ActivityRecord mFocusedActivity = null;
    596 
    597     /**
    598      * User id of the last activity mFocusedActivity was set to.
    599      */
    600     private int mLastFocusedUserId;
    601 
    602     /**
    603      * If non-null, we are tracking the time the user spends in the currently focused app.
    604      */
    605     private AppTimeTracker mCurAppTimeTracker;
    606 
    607     /**
    608      * List of intents that were used to start the most recent tasks.
    609      */
    610     final RecentTasks mRecentTasks;
    611 
    612     /**
    613      * For addAppTask: cached of the last activity component that was added.
    614      */
    615     ComponentName mLastAddedTaskComponent;
    616 
    617     /**
    618      * For addAppTask: cached of the last activity uid that was added.
    619      */
    620     int mLastAddedTaskUid;
    621 
    622     /**
    623      * For addAppTask: cached of the last ActivityInfo that was added.
    624      */
    625     ActivityInfo mLastAddedTaskActivity;
    626 
    627     /**
    628      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
    629      */
    630     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
    631 
    632     /**
    633      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
    634      */
    635     String mDeviceOwnerName;
    636 
    637     final UserController mUserController;
    638 
    639     final AppErrors mAppErrors;
    640 
    641     boolean mDoingSetFocusedActivity;
    642 
    643     public boolean canShowErrorDialogs() {
    644         return mShowDialogs && !mSleeping && !mShuttingDown;
    645     }
    646 
    647     private static final class PriorityState {
    648         // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
    649         // the current thread is currently in. When it drops down to zero, we will no longer boost
    650         // the thread's priority.
    651         private int regionCounter = 0;
    652 
    653         // The thread's previous priority before boosting.
    654         private int prevPriority = Integer.MIN_VALUE;
    655     }
    656 
    657     static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
    658         @Override protected PriorityState initialValue() {
    659             return new PriorityState();
    660         }
    661     };
    662 
    663     static void boostPriorityForLockedSection() {
    664         int tid = Process.myTid();
    665         int prevPriority = Process.getThreadPriority(tid);
    666         PriorityState state = sThreadPriorityState.get();
    667         if (state.regionCounter == 0 && prevPriority > -2) {
    668             state.prevPriority = prevPriority;
    669             Process.setThreadPriority(tid, -2);
    670         }
    671         state.regionCounter++;
    672     }
    673 
    674     static void resetPriorityAfterLockedSection() {
    675         PriorityState state = sThreadPriorityState.get();
    676         state.regionCounter--;
    677         if (state.regionCounter == 0 && state.prevPriority > -2) {
    678             Process.setThreadPriority(Process.myTid(), state.prevPriority);
    679         }
    680     }
    681 
    682     public class PendingAssistExtras extends Binder implements Runnable {
    683         public final ActivityRecord activity;
    684         public final Bundle extras;
    685         public final Intent intent;
    686         public final String hint;
    687         public final IResultReceiver receiver;
    688         public final int userHandle;
    689         public boolean haveResult = false;
    690         public Bundle result = null;
    691         public AssistStructure structure = null;
    692         public AssistContent content = null;
    693         public Bundle receiverExtras;
    694 
    695         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
    696                 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
    697             activity = _activity;
    698             extras = _extras;
    699             intent = _intent;
    700             hint = _hint;
    701             receiver = _receiver;
    702             receiverExtras = _receiverExtras;
    703             userHandle = _userHandle;
    704         }
    705         @Override
    706         public void run() {
    707             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
    708             synchronized (this) {
    709                 haveResult = true;
    710                 notifyAll();
    711             }
    712             pendingAssistExtrasTimedOut(this);
    713         }
    714     }
    715 
    716     final ArrayList<PendingAssistExtras> mPendingAssistExtras
    717             = new ArrayList<PendingAssistExtras>();
    718 
    719     /**
    720      * Process management.
    721      */
    722     final ProcessList mProcessList = new ProcessList();
    723 
    724     /**
    725      * All of the applications we currently have running organized by name.
    726      * The keys are strings of the application package name (as
    727      * returned by the package manager), and the keys are ApplicationRecord
    728      * objects.
    729      */
    730     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
    731 
    732     /**
    733      * Tracking long-term execution of processes to look for abuse and other
    734      * bad app behavior.
    735      */
    736     final ProcessStatsService mProcessStats;
    737 
    738     /**
    739      * The currently running isolated processes.
    740      */
    741     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
    742 
    743     /**
    744      * Counter for assigning isolated process uids, to avoid frequently reusing the
    745      * same ones.
    746      */
    747     int mNextIsolatedProcessUid = 0;
    748 
    749     /**
    750      * The currently running heavy-weight process, if any.
    751      */
    752     ProcessRecord mHeavyWeightProcess = null;
    753 
    754     /**
    755      * All of the processes we currently have running organized by pid.
    756      * The keys are the pid running the application.
    757      *
    758      * <p>NOTE: This object is protected by its own lock, NOT the global
    759      * activity manager lock!
    760      */
    761     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
    762 
    763     /**
    764      * All of the processes that have been forced to be foreground.  The key
    765      * is the pid of the caller who requested it (we hold a death
    766      * link on it).
    767      */
    768     abstract class ForegroundToken implements IBinder.DeathRecipient {
    769         int pid;
    770         IBinder token;
    771     }
    772     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
    773 
    774     /**
    775      * List of records for processes that someone had tried to start before the
    776      * system was ready.  We don't start them at that point, but ensure they
    777      * are started by the time booting is complete.
    778      */
    779     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
    780 
    781     /**
    782      * List of persistent applications that are in the process
    783      * of being started.
    784      */
    785     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
    786 
    787     /**
    788      * Processes that are being forcibly torn down.
    789      */
    790     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
    791 
    792     /**
    793      * List of running applications, sorted by recent usage.
    794      * The first entry in the list is the least recently used.
    795      */
    796     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
    797 
    798     /**
    799      * Where in mLruProcesses that the processes hosting activities start.
    800      */
    801     int mLruProcessActivityStart = 0;
    802 
    803     /**
    804      * Where in mLruProcesses that the processes hosting services start.
    805      * This is after (lower index) than mLruProcessesActivityStart.
    806      */
    807     int mLruProcessServiceStart = 0;
    808 
    809     /**
    810      * List of processes that should gc as soon as things are idle.
    811      */
    812     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
    813 
    814     /**
    815      * Processes we want to collect PSS data from.
    816      */
    817     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
    818 
    819     private boolean mBinderTransactionTrackingEnabled = false;
    820 
    821     /**
    822      * Last time we requested PSS data of all processes.
    823      */
    824     long mLastFullPssTime = SystemClock.uptimeMillis();
    825 
    826     /**
    827      * If set, the next time we collect PSS data we should do a full collection
    828      * with data from native processes and the kernel.
    829      */
    830     boolean mFullPssPending = false;
    831 
    832     /**
    833      * This is the process holding what we currently consider to be
    834      * the "home" activity.
    835      */
    836     ProcessRecord mHomeProcess;
    837 
    838     /**
    839      * This is the process holding the activity the user last visited that
    840      * is in a different process from the one they are currently in.
    841      */
    842     ProcessRecord mPreviousProcess;
    843 
    844     /**
    845      * The time at which the previous process was last visible.
    846      */
    847     long mPreviousProcessVisibleTime;
    848 
    849     /**
    850      * Track all uids that have actively running processes.
    851      */
    852     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
    853 
    854     /**
    855      * This is for verifying the UID report flow.
    856      */
    857     static final boolean VALIDATE_UID_STATES = true;
    858     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
    859 
    860     /**
    861      * Packages that the user has asked to have run in screen size
    862      * compatibility mode instead of filling the screen.
    863      */
    864     final CompatModePackages mCompatModePackages;
    865 
    866     /**
    867      * Set of IntentSenderRecord objects that are currently active.
    868      */
    869     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
    870             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
    871 
    872     /**
    873      * Fingerprints (hashCode()) of stack traces that we've
    874      * already logged DropBox entries for.  Guarded by itself.  If
    875      * something (rogue user app) forces this over
    876      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
    877      */
    878     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
    879     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
    880 
    881     /**
    882      * Strict Mode background batched logging state.
    883      *
    884      * The string buffer is guarded by itself, and its lock is also
    885      * used to determine if another batched write is already
    886      * in-flight.
    887      */
    888     private final StringBuilder mStrictModeBuffer = new StringBuilder();
    889 
    890     /**
    891      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
    892      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
    893      */
    894     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
    895 
    896     /**
    897      * Resolver for broadcast intents to registered receivers.
    898      * Holds BroadcastFilter (subclass of IntentFilter).
    899      */
    900     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
    901             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
    902         @Override
    903         protected boolean allowFilterResult(
    904                 BroadcastFilter filter, List<BroadcastFilter> dest) {
    905             IBinder target = filter.receiverList.receiver.asBinder();
    906             for (int i = dest.size() - 1; i >= 0; i--) {
    907                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
    908                     return false;
    909                 }
    910             }
    911             return true;
    912         }
    913 
    914         @Override
    915         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
    916             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
    917                     || userId == filter.owningUserId) {
    918                 return super.newResult(filter, match, userId);
    919             }
    920             return null;
    921         }
    922 
    923         @Override
    924         protected BroadcastFilter[] newArray(int size) {
    925             return new BroadcastFilter[size];
    926         }
    927 
    928         @Override
    929         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
    930             return packageName.equals(filter.packageName);
    931         }
    932     };
    933 
    934     /**
    935      * State of all active sticky broadcasts per user.  Keys are the action of the
    936      * sticky Intent, values are an ArrayList of all broadcasted intents with
    937      * that action (which should usually be one).  The SparseArray is keyed
    938      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
    939      * for stickies that are sent to all users.
    940      */
    941     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
    942             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
    943 
    944     final ActiveServices mServices;
    945 
    946     final static class Association {
    947         final int mSourceUid;
    948         final String mSourceProcess;
    949         final int mTargetUid;
    950         final ComponentName mTargetComponent;
    951         final String mTargetProcess;
    952 
    953         int mCount;
    954         long mTime;
    955 
    956         int mNesting;
    957         long mStartTime;
    958 
    959         // states of the source process when the bind occurred.
    960         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
    961         long mLastStateUptime;
    962         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
    963                 - ActivityManager.MIN_PROCESS_STATE+1];
    964 
    965         Association(int sourceUid, String sourceProcess, int targetUid,
    966                 ComponentName targetComponent, String targetProcess) {
    967             mSourceUid = sourceUid;
    968             mSourceProcess = sourceProcess;
    969             mTargetUid = targetUid;
    970             mTargetComponent = targetComponent;
    971             mTargetProcess = targetProcess;
    972         }
    973     }
    974 
    975     /**
    976      * When service association tracking is enabled, this is all of the associations we
    977      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
    978      * -> association data.
    979      */
    980     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
    981             mAssociations = new SparseArray<>();
    982     boolean mTrackingAssociations;
    983 
    984     /**
    985      * Backup/restore process management
    986      */
    987     String mBackupAppName = null;
    988     BackupRecord mBackupTarget = null;
    989 
    990     final ProviderMap mProviderMap;
    991 
    992     /**
    993      * List of content providers who have clients waiting for them.  The
    994      * application is currently being launched and the provider will be
    995      * removed from this list once it is published.
    996      */
    997     final ArrayList<ContentProviderRecord> mLaunchingProviders
    998             = new ArrayList<ContentProviderRecord>();
    999 
   1000     /**
   1001      * File storing persisted {@link #mGrantedUriPermissions}.
   1002      */
   1003     private final AtomicFile mGrantFile;
   1004 
   1005     /** XML constants used in {@link #mGrantFile} */
   1006     private static final String TAG_URI_GRANTS = "uri-grants";
   1007     private static final String TAG_URI_GRANT = "uri-grant";
   1008     private static final String ATTR_USER_HANDLE = "userHandle";
   1009     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
   1010     private static final String ATTR_TARGET_USER_ID = "targetUserId";
   1011     private static final String ATTR_SOURCE_PKG = "sourcePkg";
   1012     private static final String ATTR_TARGET_PKG = "targetPkg";
   1013     private static final String ATTR_URI = "uri";
   1014     private static final String ATTR_MODE_FLAGS = "modeFlags";
   1015     private static final String ATTR_CREATED_TIME = "createdTime";
   1016     private static final String ATTR_PREFIX = "prefix";
   1017 
   1018     /**
   1019      * Global set of specific {@link Uri} permissions that have been granted.
   1020      * This optimized lookup structure maps from {@link UriPermission#targetUid}
   1021      * to {@link UriPermission#uri} to {@link UriPermission}.
   1022      */
   1023     @GuardedBy("this")
   1024     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
   1025             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
   1026 
   1027     public static class GrantUri {
   1028         public final int sourceUserId;
   1029         public final Uri uri;
   1030         public boolean prefix;
   1031 
   1032         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
   1033             this.sourceUserId = sourceUserId;
   1034             this.uri = uri;
   1035             this.prefix = prefix;
   1036         }
   1037 
   1038         @Override
   1039         public int hashCode() {
   1040             int hashCode = 1;
   1041             hashCode = 31 * hashCode + sourceUserId;
   1042             hashCode = 31 * hashCode + uri.hashCode();
   1043             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
   1044             return hashCode;
   1045         }
   1046 
   1047         @Override
   1048         public boolean equals(Object o) {
   1049             if (o instanceof GrantUri) {
   1050                 GrantUri other = (GrantUri) o;
   1051                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
   1052                         && prefix == other.prefix;
   1053             }
   1054             return false;
   1055         }
   1056 
   1057         @Override
   1058         public String toString() {
   1059             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
   1060             if (prefix) result += " [prefix]";
   1061             return result;
   1062         }
   1063 
   1064         public String toSafeString() {
   1065             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
   1066             if (prefix) result += " [prefix]";
   1067             return result;
   1068         }
   1069 
   1070         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
   1071             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
   1072                     ContentProvider.getUriWithoutUserId(uri), false);
   1073         }
   1074     }
   1075 
   1076     CoreSettingsObserver mCoreSettingsObserver;
   1077 
   1078     FontScaleSettingObserver mFontScaleSettingObserver;
   1079 
   1080     private final class FontScaleSettingObserver extends ContentObserver {
   1081         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
   1082 
   1083         public FontScaleSettingObserver() {
   1084             super(mHandler);
   1085             ContentResolver resolver = mContext.getContentResolver();
   1086             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
   1087         }
   1088 
   1089         @Override
   1090         public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
   1091             if (mFontScaleUri.equals(uri)) {
   1092                 updateFontScaleIfNeeded(userId);
   1093             }
   1094         }
   1095     }
   1096 
   1097     /**
   1098      * Thread-local storage used to carry caller permissions over through
   1099      * indirect content-provider access.
   1100      */
   1101     private class Identity {
   1102         public final IBinder token;
   1103         public final int pid;
   1104         public final int uid;
   1105 
   1106         Identity(IBinder _token, int _pid, int _uid) {
   1107             token = _token;
   1108             pid = _pid;
   1109             uid = _uid;
   1110         }
   1111     }
   1112 
   1113     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
   1114 
   1115     /**
   1116      * All information we have collected about the runtime performance of
   1117      * any user id that can impact battery performance.
   1118      */
   1119     final BatteryStatsService mBatteryStatsService;
   1120 
   1121     /**
   1122      * Information about component usage
   1123      */
   1124     UsageStatsManagerInternal mUsageStatsService;
   1125 
   1126     /**
   1127      * Access to DeviceIdleController service.
   1128      */
   1129     DeviceIdleController.LocalService mLocalDeviceIdleController;
   1130 
   1131     /**
   1132      * Information about and control over application operations
   1133      */
   1134     final AppOpsService mAppOpsService;
   1135 
   1136     /**
   1137      * Current configuration information.  HistoryRecord objects are given
   1138      * a reference to this object to indicate which configuration they are
   1139      * currently running in, so this object must be kept immutable.
   1140      */
   1141     Configuration mConfiguration = new Configuration();
   1142 
   1143     /**
   1144      * Current sequencing integer of the configuration, for skipping old
   1145      * configurations.
   1146      */
   1147     int mConfigurationSeq = 0;
   1148 
   1149     boolean mSuppressResizeConfigChanges = false;
   1150 
   1151     /**
   1152      * Hardware-reported OpenGLES version.
   1153      */
   1154     final int GL_ES_VERSION;
   1155 
   1156     /**
   1157      * List of initialization arguments to pass to all processes when binding applications to them.
   1158      * For example, references to the commonly used services.
   1159      */
   1160     HashMap<String, IBinder> mAppBindArgs;
   1161 
   1162     /**
   1163      * Temporary to avoid allocations.  Protected by main lock.
   1164      */
   1165     final StringBuilder mStringBuilder = new StringBuilder(256);
   1166 
   1167     /**
   1168      * Used to control how we initialize the service.
   1169      */
   1170     ComponentName mTopComponent;
   1171     String mTopAction = Intent.ACTION_MAIN;
   1172     String mTopData;
   1173 
   1174     volatile boolean mProcessesReady = false;
   1175     volatile boolean mSystemReady = false;
   1176     volatile boolean mOnBattery = false;
   1177     volatile int mFactoryTest;
   1178 
   1179     @GuardedBy("this") boolean mBooting = false;
   1180     @GuardedBy("this") boolean mCallFinishBooting = false;
   1181     @GuardedBy("this") boolean mBootAnimationComplete = false;
   1182     @GuardedBy("this") boolean mLaunchWarningShown = false;
   1183     @GuardedBy("this") boolean mCheckedForSetup = false;
   1184 
   1185     Context mContext;
   1186 
   1187     /**
   1188      * The time at which we will allow normal application switches again,
   1189      * after a call to {@link #stopAppSwitches()}.
   1190      */
   1191     long mAppSwitchesAllowedTime;
   1192 
   1193     /**
   1194      * This is set to true after the first switch after mAppSwitchesAllowedTime
   1195      * is set; any switches after that will clear the time.
   1196      */
   1197     boolean mDidAppSwitch;
   1198 
   1199     /**
   1200      * Last time (in realtime) at which we checked for power usage.
   1201      */
   1202     long mLastPowerCheckRealtime;
   1203 
   1204     /**
   1205      * Last time (in uptime) at which we checked for power usage.
   1206      */
   1207     long mLastPowerCheckUptime;
   1208 
   1209     /**
   1210      * Set while we are wanting to sleep, to prevent any
   1211      * activities from being started/resumed.
   1212      */
   1213     private boolean mSleeping = false;
   1214 
   1215     /**
   1216      * The process state used for processes that are running the top activities.
   1217      * This changes between TOP and TOP_SLEEPING to following mSleeping.
   1218      */
   1219     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
   1220 
   1221     /**
   1222      * Set while we are running a voice interaction.  This overrides
   1223      * sleeping while it is active.
   1224      */
   1225     private IVoiceInteractionSession mRunningVoice;
   1226 
   1227     /**
   1228      * For some direct access we need to power manager.
   1229      */
   1230     PowerManagerInternal mLocalPowerManager;
   1231 
   1232     /**
   1233      * We want to hold a wake lock while running a voice interaction session, since
   1234      * this may happen with the screen off and we need to keep the CPU running to
   1235      * be able to continue to interact with the user.
   1236      */
   1237     PowerManager.WakeLock mVoiceWakeLock;
   1238 
   1239     /**
   1240      * State of external calls telling us if the device is awake or asleep.
   1241      */
   1242     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
   1243 
   1244     /**
   1245      * A list of tokens that cause the top activity to be put to sleep.
   1246      * They are used by components that may hide and block interaction with underlying
   1247      * activities.
   1248      */
   1249     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
   1250 
   1251     static final int LOCK_SCREEN_HIDDEN = 0;
   1252     static final int LOCK_SCREEN_LEAVING = 1;
   1253     static final int LOCK_SCREEN_SHOWN = 2;
   1254     /**
   1255      * State of external call telling us if the lock screen is shown.
   1256      */
   1257     int mLockScreenShown = LOCK_SCREEN_HIDDEN;
   1258 
   1259     /**
   1260      * Set if we are shutting down the system, similar to sleeping.
   1261      */
   1262     boolean mShuttingDown = false;
   1263 
   1264     /**
   1265      * Current sequence id for oom_adj computation traversal.
   1266      */
   1267     int mAdjSeq = 0;
   1268 
   1269     /**
   1270      * Current sequence id for process LRU updating.
   1271      */
   1272     int mLruSeq = 0;
   1273 
   1274     /**
   1275      * Keep track of the non-cached/empty process we last found, to help
   1276      * determine how to distribute cached/empty processes next time.
   1277      */
   1278     int mNumNonCachedProcs = 0;
   1279 
   1280     /**
   1281      * Keep track of the number of cached hidden procs, to balance oom adj
   1282      * distribution between those and empty procs.
   1283      */
   1284     int mNumCachedHiddenProcs = 0;
   1285 
   1286     /**
   1287      * Keep track of the number of service processes we last found, to
   1288      * determine on the next iteration which should be B services.
   1289      */
   1290     int mNumServiceProcs = 0;
   1291     int mNewNumAServiceProcs = 0;
   1292     int mNewNumServiceProcs = 0;
   1293 
   1294     /**
   1295      * Allow the current computed overall memory level of the system to go down?
   1296      * This is set to false when we are killing processes for reasons other than
   1297      * memory management, so that the now smaller process list will not be taken as
   1298      * an indication that memory is tighter.
   1299      */
   1300     boolean mAllowLowerMemLevel = false;
   1301 
   1302     /**
   1303      * The last computed memory level, for holding when we are in a state that
   1304      * processes are going away for other reasons.
   1305      */
   1306     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
   1307 
   1308     /**
   1309      * The last total number of process we have, to determine if changes actually look
   1310      * like a shrinking number of process due to lower RAM.
   1311      */
   1312     int mLastNumProcesses;
   1313 
   1314     /**
   1315      * The uptime of the last time we performed idle maintenance.
   1316      */
   1317     long mLastIdleTime = SystemClock.uptimeMillis();
   1318 
   1319     /**
   1320      * Total time spent with RAM that has been added in the past since the last idle time.
   1321      */
   1322     long mLowRamTimeSinceLastIdle = 0;
   1323 
   1324     /**
   1325      * If RAM is currently low, when that horrible situation started.
   1326      */
   1327     long mLowRamStartTime = 0;
   1328 
   1329     /**
   1330      * For reporting to battery stats the current top application.
   1331      */
   1332     private String mCurResumedPackage = null;
   1333     private int mCurResumedUid = -1;
   1334 
   1335     /**
   1336      * For reporting to battery stats the apps currently running foreground
   1337      * service.  The ProcessMap is package/uid tuples; each of these contain
   1338      * an array of the currently foreground processes.
   1339      */
   1340     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
   1341             = new ProcessMap<ArrayList<ProcessRecord>>();
   1342 
   1343     /**
   1344      * This is set if we had to do a delayed dexopt of an app before launching
   1345      * it, to increase the ANR timeouts in that case.
   1346      */
   1347     boolean mDidDexOpt;
   1348 
   1349     /**
   1350      * Set if the systemServer made a call to enterSafeMode.
   1351      */
   1352     boolean mSafeMode;
   1353 
   1354     /**
   1355      * If true, we are running under a test environment so will sample PSS from processes
   1356      * much more rapidly to try to collect better data when the tests are rapidly
   1357      * running through apps.
   1358      */
   1359     boolean mTestPssMode = false;
   1360 
   1361     String mDebugApp = null;
   1362     boolean mWaitForDebugger = false;
   1363     boolean mDebugTransient = false;
   1364     String mOrigDebugApp = null;
   1365     boolean mOrigWaitForDebugger = false;
   1366     boolean mAlwaysFinishActivities = false;
   1367     boolean mLenientBackgroundCheck = false;
   1368     boolean mForceResizableActivities;
   1369     boolean mSupportsMultiWindow;
   1370     boolean mSupportsFreeformWindowManagement;
   1371     boolean mSupportsPictureInPicture;
   1372     boolean mSupportsLeanbackOnly;
   1373     Rect mDefaultPinnedStackBounds;
   1374     IActivityController mController = null;
   1375     boolean mControllerIsAMonkey = false;
   1376     String mProfileApp = null;
   1377     ProcessRecord mProfileProc = null;
   1378     String mProfileFile;
   1379     ParcelFileDescriptor mProfileFd;
   1380     int mSamplingInterval = 0;
   1381     boolean mAutoStopProfiler = false;
   1382     int mProfileType = 0;
   1383     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
   1384     String mMemWatchDumpProcName;
   1385     String mMemWatchDumpFile;
   1386     int mMemWatchDumpPid;
   1387     int mMemWatchDumpUid;
   1388     String mTrackAllocationApp = null;
   1389     String mNativeDebuggingApp = null;
   1390 
   1391     final long[] mTmpLong = new long[2];
   1392 
   1393     static final class ProcessChangeItem {
   1394         static final int CHANGE_ACTIVITIES = 1<<0;
   1395         static final int CHANGE_PROCESS_STATE = 1<<1;
   1396         int changes;
   1397         int uid;
   1398         int pid;
   1399         int processState;
   1400         boolean foregroundActivities;
   1401     }
   1402 
   1403     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
   1404     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
   1405 
   1406     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
   1407     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
   1408 
   1409     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
   1410     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
   1411 
   1412     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
   1413     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
   1414 
   1415     /**
   1416      * Runtime CPU use collection thread.  This object's lock is used to
   1417      * perform synchronization with the thread (notifying it to run).
   1418      */
   1419     final Thread mProcessCpuThread;
   1420 
   1421     /**
   1422      * Used to collect per-process CPU use for ANRs, battery stats, etc.
   1423      * Must acquire this object's lock when accessing it.
   1424      * NOTE: this lock will be held while doing long operations (trawling
   1425      * through all processes in /proc), so it should never be acquired by
   1426      * any critical paths such as when holding the main activity manager lock.
   1427      */
   1428     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
   1429             MONITOR_THREAD_CPU_USAGE);
   1430     final AtomicLong mLastCpuTime = new AtomicLong(0);
   1431     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
   1432 
   1433     long mLastWriteTime = 0;
   1434 
   1435     /**
   1436      * Used to retain an update lock when the foreground activity is in
   1437      * immersive mode.
   1438      */
   1439     final UpdateLock mUpdateLock = new UpdateLock("immersive");
   1440 
   1441     /**
   1442      * Set to true after the system has finished booting.
   1443      */
   1444     boolean mBooted = false;
   1445 
   1446     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
   1447     int mProcessLimitOverride = -1;
   1448 
   1449     WindowManagerService mWindowManager;
   1450     final ActivityThread mSystemThread;
   1451 
   1452     private final class AppDeathRecipient implements IBinder.DeathRecipient {
   1453         final ProcessRecord mApp;
   1454         final int mPid;
   1455         final IApplicationThread mAppThread;
   1456 
   1457         AppDeathRecipient(ProcessRecord app, int pid,
   1458                 IApplicationThread thread) {
   1459             if (DEBUG_ALL) Slog.v(
   1460                 TAG, "New death recipient " + this
   1461                 + " for thread " + thread.asBinder());
   1462             mApp = app;
   1463             mPid = pid;
   1464             mAppThread = thread;
   1465         }
   1466 
   1467         @Override
   1468         public void binderDied() {
   1469             if (DEBUG_ALL) Slog.v(
   1470                 TAG, "Death received in " + this
   1471                 + " for thread " + mAppThread.asBinder());
   1472             synchronized(ActivityManagerService.this) {
   1473                 appDiedLocked(mApp, mPid, mAppThread, true);
   1474             }
   1475         }
   1476     }
   1477 
   1478     static final int SHOW_ERROR_UI_MSG = 1;
   1479     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
   1480     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
   1481     static final int UPDATE_CONFIGURATION_MSG = 4;
   1482     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
   1483     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
   1484     static final int SERVICE_TIMEOUT_MSG = 12;
   1485     static final int UPDATE_TIME_ZONE = 13;
   1486     static final int SHOW_UID_ERROR_UI_MSG = 14;
   1487     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
   1488     static final int PROC_START_TIMEOUT_MSG = 20;
   1489     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
   1490     static final int KILL_APPLICATION_MSG = 22;
   1491     static final int FINALIZE_PENDING_INTENT_MSG = 23;
   1492     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
   1493     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
   1494     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
   1495     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
   1496     static final int CLEAR_DNS_CACHE_MSG = 28;
   1497     static final int UPDATE_HTTP_PROXY_MSG = 29;
   1498     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
   1499     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
   1500     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
   1501     static final int REPORT_MEM_USAGE_MSG = 33;
   1502     static final int REPORT_USER_SWITCH_MSG = 34;
   1503     static final int CONTINUE_USER_SWITCH_MSG = 35;
   1504     static final int USER_SWITCH_TIMEOUT_MSG = 36;
   1505     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
   1506     static final int PERSIST_URI_GRANTS_MSG = 38;
   1507     static final int REQUEST_ALL_PSS_MSG = 39;
   1508     static final int START_PROFILES_MSG = 40;
   1509     static final int UPDATE_TIME = 41;
   1510     static final int SYSTEM_USER_START_MSG = 42;
   1511     static final int SYSTEM_USER_CURRENT_MSG = 43;
   1512     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
   1513     static final int FINISH_BOOTING_MSG = 45;
   1514     static final int START_USER_SWITCH_UI_MSG = 46;
   1515     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
   1516     static final int DISMISS_DIALOG_UI_MSG = 48;
   1517     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
   1518     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
   1519     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
   1520     static final int DELETE_DUMPHEAP_MSG = 52;
   1521     static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
   1522     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
   1523     static final int REPORT_TIME_TRACKER_MSG = 55;
   1524     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
   1525     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
   1526     static final int APP_BOOST_DEACTIVATE_MSG = 58;
   1527     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
   1528     static final int IDLE_UIDS_MSG = 60;
   1529     static final int SYSTEM_USER_UNLOCK_MSG = 61;
   1530     static final int LOG_STACK_STATE = 62;
   1531     static final int VR_MODE_CHANGE_MSG = 63;
   1532     static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
   1533     static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
   1534     static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
   1535     static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
   1536     static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
   1537     static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
   1538     static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
   1539 
   1540     static final int FIRST_ACTIVITY_STACK_MSG = 100;
   1541     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
   1542     static final int FIRST_COMPAT_MODE_MSG = 300;
   1543     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
   1544 
   1545     static ServiceThread sKillThread = null;
   1546     static KillHandler sKillHandler = null;
   1547 
   1548     CompatModeDialog mCompatModeDialog;
   1549     UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
   1550     long mLastMemUsageReportTime = 0;
   1551 
   1552     /**
   1553      * Flag whether the current user is a "monkey", i.e. whether
   1554      * the UI is driven by a UI automation tool.
   1555      */
   1556     private boolean mUserIsMonkey;
   1557 
   1558     /** Flag whether the device has a Recents UI */
   1559     boolean mHasRecents;
   1560 
   1561     /** The dimensions of the thumbnails in the Recents UI. */
   1562     int mThumbnailWidth;
   1563     int mThumbnailHeight;
   1564     float mFullscreenThumbnailScale;
   1565 
   1566     final ServiceThread mHandlerThread;
   1567     final MainHandler mHandler;
   1568     final UiHandler mUiHandler;
   1569 
   1570     PackageManagerInternal mPackageManagerInt;
   1571 
   1572     // VoiceInteraction session ID that changes for each new request except when
   1573     // being called for multiwindow assist in a single session.
   1574     private int mViSessionId = 1000;
   1575 
   1576     final class KillHandler extends Handler {
   1577         static final int KILL_PROCESS_GROUP_MSG = 4000;
   1578 
   1579         public KillHandler(Looper looper) {
   1580             super(looper, null, true);
   1581         }
   1582 
   1583         @Override
   1584         public void handleMessage(Message msg) {
   1585             switch (msg.what) {
   1586                 case KILL_PROCESS_GROUP_MSG:
   1587                 {
   1588                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
   1589                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
   1590                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   1591                 }
   1592                 break;
   1593 
   1594                 default:
   1595                     super.handleMessage(msg);
   1596             }
   1597         }
   1598     }
   1599 
   1600     final class UiHandler extends Handler {
   1601         public UiHandler() {
   1602             super(com.android.server.UiThread.get().getLooper(), null, true);
   1603         }
   1604 
   1605         @Override
   1606         public void handleMessage(Message msg) {
   1607             switch (msg.what) {
   1608             case SHOW_ERROR_UI_MSG: {
   1609                 mAppErrors.handleShowAppErrorUi(msg);
   1610                 ensureBootCompleted();
   1611             } break;
   1612             case SHOW_NOT_RESPONDING_UI_MSG: {
   1613                 mAppErrors.handleShowAnrUi(msg);
   1614                 ensureBootCompleted();
   1615             } break;
   1616             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
   1617                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
   1618                 synchronized (ActivityManagerService.this) {
   1619                     ProcessRecord proc = (ProcessRecord) data.get("app");
   1620                     if (proc == null) {
   1621                         Slog.e(TAG, "App not found when showing strict mode dialog.");
   1622                         break;
   1623                     }
   1624                     if (proc.crashDialog != null) {
   1625                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
   1626                         return;
   1627                     }
   1628                     AppErrorResult res = (AppErrorResult) data.get("result");
   1629                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
   1630                         Dialog d = new StrictModeViolationDialog(mContext,
   1631                                 ActivityManagerService.this, res, proc);
   1632                         d.show();
   1633                         proc.crashDialog = d;
   1634                     } else {
   1635                         // The device is asleep, so just pretend that the user
   1636                         // saw a crash dialog and hit "force quit".
   1637                         res.set(0);
   1638                     }
   1639                 }
   1640                 ensureBootCompleted();
   1641             } break;
   1642             case SHOW_FACTORY_ERROR_UI_MSG: {
   1643                 Dialog d = new FactoryErrorDialog(
   1644                     mContext, msg.getData().getCharSequence("msg"));
   1645                 d.show();
   1646                 ensureBootCompleted();
   1647             } break;
   1648             case WAIT_FOR_DEBUGGER_UI_MSG: {
   1649                 synchronized (ActivityManagerService.this) {
   1650                     ProcessRecord app = (ProcessRecord)msg.obj;
   1651                     if (msg.arg1 != 0) {
   1652                         if (!app.waitedForDebugger) {
   1653                             Dialog d = new AppWaitingForDebuggerDialog(
   1654                                     ActivityManagerService.this,
   1655                                     mContext, app);
   1656                             app.waitDialog = d;
   1657                             app.waitedForDebugger = true;
   1658                             d.show();
   1659                         }
   1660                     } else {
   1661                         if (app.waitDialog != null) {
   1662                             app.waitDialog.dismiss();
   1663                             app.waitDialog = null;
   1664                         }
   1665                     }
   1666                 }
   1667             } break;
   1668             case SHOW_UID_ERROR_UI_MSG: {
   1669                 if (mShowDialogs) {
   1670                     AlertDialog d = new BaseErrorDialog(mContext);
   1671                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   1672                     d.setCancelable(false);
   1673                     d.setTitle(mContext.getText(R.string.android_system_label));
   1674                     d.setMessage(mContext.getText(R.string.system_error_wipe_data));
   1675                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
   1676                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
   1677                     d.show();
   1678                 }
   1679             } break;
   1680             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
   1681                 if (mShowDialogs) {
   1682                     AlertDialog d = new BaseErrorDialog(mContext);
   1683                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   1684                     d.setCancelable(false);
   1685                     d.setTitle(mContext.getText(R.string.android_system_label));
   1686                     d.setMessage(mContext.getText(R.string.system_error_manufacturer));
   1687                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
   1688                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
   1689                     d.show();
   1690                 }
   1691             } break;
   1692             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
   1693                 synchronized (ActivityManagerService.this) {
   1694                     ActivityRecord ar = (ActivityRecord) msg.obj;
   1695                     if (mCompatModeDialog != null) {
   1696                         if (mCompatModeDialog.mAppInfo.packageName.equals(
   1697                                 ar.info.applicationInfo.packageName)) {
   1698                             return;
   1699                         }
   1700                         mCompatModeDialog.dismiss();
   1701                         mCompatModeDialog = null;
   1702                     }
   1703                     if (ar != null && false) {
   1704                         if (mCompatModePackages.getPackageAskCompatModeLocked(
   1705                                 ar.packageName)) {
   1706                             int mode = mCompatModePackages.computeCompatModeLocked(
   1707                                     ar.info.applicationInfo);
   1708                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
   1709                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
   1710                                 mCompatModeDialog = new CompatModeDialog(
   1711                                         ActivityManagerService.this, mContext,
   1712                                         ar.info.applicationInfo);
   1713                                 mCompatModeDialog.show();
   1714                             }
   1715                         }
   1716                     }
   1717                 }
   1718                 break;
   1719             }
   1720             case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
   1721                 synchronized (ActivityManagerService.this) {
   1722                     final ActivityRecord ar = (ActivityRecord) msg.obj;
   1723                     if (mUnsupportedDisplaySizeDialog != null) {
   1724                         mUnsupportedDisplaySizeDialog.dismiss();
   1725                         mUnsupportedDisplaySizeDialog = null;
   1726                     }
   1727                     if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
   1728                             ar.packageName)) {
   1729                         mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
   1730                                 ActivityManagerService.this, mContext, ar.info.applicationInfo);
   1731                         mUnsupportedDisplaySizeDialog.show();
   1732                     }
   1733                 }
   1734                 break;
   1735             }
   1736             case START_USER_SWITCH_UI_MSG: {
   1737                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
   1738                 break;
   1739             }
   1740             case DISMISS_DIALOG_UI_MSG: {
   1741                 final Dialog d = (Dialog) msg.obj;
   1742                 d.dismiss();
   1743                 break;
   1744             }
   1745             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
   1746                 dispatchProcessesChanged();
   1747                 break;
   1748             }
   1749             case DISPATCH_PROCESS_DIED_UI_MSG: {
   1750                 final int pid = msg.arg1;
   1751                 final int uid = msg.arg2;
   1752                 dispatchProcessDied(pid, uid);
   1753                 break;
   1754             }
   1755             case DISPATCH_UIDS_CHANGED_UI_MSG: {
   1756                 dispatchUidsChanged();
   1757             } break;
   1758             }
   1759         }
   1760     }
   1761 
   1762     final class MainHandler extends Handler {
   1763         public MainHandler(Looper looper) {
   1764             super(looper, null, true);
   1765         }
   1766 
   1767         @Override
   1768         public void handleMessage(Message msg) {
   1769             switch (msg.what) {
   1770             case UPDATE_CONFIGURATION_MSG: {
   1771                 final ContentResolver resolver = mContext.getContentResolver();
   1772                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
   1773                         msg.arg1);
   1774             } break;
   1775             case GC_BACKGROUND_PROCESSES_MSG: {
   1776                 synchronized (ActivityManagerService.this) {
   1777                     performAppGcsIfAppropriateLocked();
   1778                 }
   1779             } break;
   1780             case SERVICE_TIMEOUT_MSG: {
   1781                 if (mDidDexOpt) {
   1782                     mDidDexOpt = false;
   1783                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   1784                     nmsg.obj = msg.obj;
   1785                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
   1786                     return;
   1787                 }
   1788                 mServices.serviceTimeout((ProcessRecord)msg.obj);
   1789             } break;
   1790             case UPDATE_TIME_ZONE: {
   1791                 synchronized (ActivityManagerService.this) {
   1792                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1793                         ProcessRecord r = mLruProcesses.get(i);
   1794                         if (r.thread != null) {
   1795                             try {
   1796                                 r.thread.updateTimeZone();
   1797                             } catch (RemoteException ex) {
   1798                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
   1799                             }
   1800                         }
   1801                     }
   1802                 }
   1803             } break;
   1804             case CLEAR_DNS_CACHE_MSG: {
   1805                 synchronized (ActivityManagerService.this) {
   1806                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1807                         ProcessRecord r = mLruProcesses.get(i);
   1808                         if (r.thread != null) {
   1809                             try {
   1810                                 r.thread.clearDnsCache();
   1811                             } catch (RemoteException ex) {
   1812                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
   1813                             }
   1814                         }
   1815                     }
   1816                 }
   1817             } break;
   1818             case UPDATE_HTTP_PROXY_MSG: {
   1819                 ProxyInfo proxy = (ProxyInfo)msg.obj;
   1820                 String host = "";
   1821                 String port = "";
   1822                 String exclList = "";
   1823                 Uri pacFileUrl = Uri.EMPTY;
   1824                 if (proxy != null) {
   1825                     host = proxy.getHost();
   1826                     port = Integer.toString(proxy.getPort());
   1827                     exclList = proxy.getExclusionListAsString();
   1828                     pacFileUrl = proxy.getPacFileUrl();
   1829                 }
   1830                 synchronized (ActivityManagerService.this) {
   1831                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1832                         ProcessRecord r = mLruProcesses.get(i);
   1833                         if (r.thread != null) {
   1834                             try {
   1835                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
   1836                             } catch (RemoteException ex) {
   1837                                 Slog.w(TAG, "Failed to update http proxy for: " +
   1838                                         r.info.processName);
   1839                             }
   1840                         }
   1841                     }
   1842                 }
   1843             } break;
   1844             case PROC_START_TIMEOUT_MSG: {
   1845                 if (mDidDexOpt) {
   1846                     mDidDexOpt = false;
   1847                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   1848                     nmsg.obj = msg.obj;
   1849                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
   1850                     return;
   1851                 }
   1852                 ProcessRecord app = (ProcessRecord)msg.obj;
   1853                 synchronized (ActivityManagerService.this) {
   1854                     processStartTimedOutLocked(app);
   1855                 }
   1856             } break;
   1857             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
   1858                 ProcessRecord app = (ProcessRecord)msg.obj;
   1859                 synchronized (ActivityManagerService.this) {
   1860                     processContentProviderPublishTimedOutLocked(app);
   1861                 }
   1862             } break;
   1863             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
   1864                 synchronized (ActivityManagerService.this) {
   1865                     mActivityStarter.doPendingActivityLaunchesLocked(true);
   1866                 }
   1867             } break;
   1868             case KILL_APPLICATION_MSG: {
   1869                 synchronized (ActivityManagerService.this) {
   1870                     final int appId = msg.arg1;
   1871                     final int userId = msg.arg2;
   1872                     Bundle bundle = (Bundle)msg.obj;
   1873                     String pkg = bundle.getString("pkg");
   1874                     String reason = bundle.getString("reason");
   1875                     forceStopPackageLocked(pkg, appId, false, false, true, false,
   1876                             false, userId, reason);
   1877                 }
   1878             } break;
   1879             case FINALIZE_PENDING_INTENT_MSG: {
   1880                 ((PendingIntentRecord)msg.obj).completeFinalize();
   1881             } break;
   1882             case POST_HEAVY_NOTIFICATION_MSG: {
   1883                 INotificationManager inm = NotificationManager.getService();
   1884                 if (inm == null) {
   1885                     return;
   1886                 }
   1887 
   1888                 ActivityRecord root = (ActivityRecord)msg.obj;
   1889                 ProcessRecord process = root.app;
   1890                 if (process == null) {
   1891                     return;
   1892                 }
   1893 
   1894                 try {
   1895                     Context context = mContext.createPackageContext(process.info.packageName, 0);
   1896                     String text = mContext.getString(R.string.heavy_weight_notification,
   1897                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
   1898                     Notification notification = new Notification.Builder(context)
   1899                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
   1900                             .setWhen(0)
   1901                             .setOngoing(true)
   1902                             .setTicker(text)
   1903                             .setColor(mContext.getColor(
   1904                                     com.android.internal.R.color.system_notification_accent_color))
   1905                             .setContentTitle(text)
   1906                             .setContentText(
   1907                                     mContext.getText(R.string.heavy_weight_notification_detail))
   1908                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
   1909                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
   1910                                     new UserHandle(root.userId)))
   1911                             .build();
   1912                     try {
   1913                         int[] outId = new int[1];
   1914                         inm.enqueueNotificationWithTag("android", "android", null,
   1915                                 R.string.heavy_weight_notification,
   1916                                 notification, outId, root.userId);
   1917                     } catch (RuntimeException e) {
   1918                         Slog.w(ActivityManagerService.TAG,
   1919                                 "Error showing notification for heavy-weight app", e);
   1920                     } catch (RemoteException e) {
   1921                     }
   1922                 } catch (NameNotFoundException e) {
   1923                     Slog.w(TAG, "Unable to create context for heavy notification", e);
   1924                 }
   1925             } break;
   1926             case CANCEL_HEAVY_NOTIFICATION_MSG: {
   1927                 INotificationManager inm = NotificationManager.getService();
   1928                 if (inm == null) {
   1929                     return;
   1930                 }
   1931                 try {
   1932                     inm.cancelNotificationWithTag("android", null,
   1933                             R.string.heavy_weight_notification,  msg.arg1);
   1934                 } catch (RuntimeException e) {
   1935                     Slog.w(ActivityManagerService.TAG,
   1936                             "Error canceling notification for service", e);
   1937                 } catch (RemoteException e) {
   1938                 }
   1939             } break;
   1940             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
   1941                 synchronized (ActivityManagerService.this) {
   1942                     checkExcessivePowerUsageLocked(true);
   1943                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1944                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1945                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   1946                 }
   1947             } break;
   1948             case REPORT_MEM_USAGE_MSG: {
   1949                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
   1950                 Thread thread = new Thread() {
   1951                     @Override public void run() {
   1952                         reportMemUsage(memInfos);
   1953                     }
   1954                 };
   1955                 thread.start();
   1956                 break;
   1957             }
   1958             case REPORT_USER_SWITCH_MSG: {
   1959                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
   1960                 break;
   1961             }
   1962             case CONTINUE_USER_SWITCH_MSG: {
   1963                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
   1964                 break;
   1965             }
   1966             case USER_SWITCH_TIMEOUT_MSG: {
   1967                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
   1968                 break;
   1969             }
   1970             case IMMERSIVE_MODE_LOCK_MSG: {
   1971                 final boolean nextState = (msg.arg1 != 0);
   1972                 if (mUpdateLock.isHeld() != nextState) {
   1973                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
   1974                             "Applying new update lock state '" + nextState
   1975                             + "' for " + (ActivityRecord)msg.obj);
   1976                     if (nextState) {
   1977                         mUpdateLock.acquire();
   1978                     } else {
   1979                         mUpdateLock.release();
   1980                     }
   1981                 }
   1982                 break;
   1983             }
   1984             case PERSIST_URI_GRANTS_MSG: {
   1985                 writeGrantedUriPermissions();
   1986                 break;
   1987             }
   1988             case REQUEST_ALL_PSS_MSG: {
   1989                 synchronized (ActivityManagerService.this) {
   1990                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
   1991                 }
   1992                 break;
   1993             }
   1994             case START_PROFILES_MSG: {
   1995                 synchronized (ActivityManagerService.this) {
   1996                     mUserController.startProfilesLocked();
   1997                 }
   1998                 break;
   1999             }
   2000             case UPDATE_TIME: {
   2001                 synchronized (ActivityManagerService.this) {
   2002                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   2003                         ProcessRecord r = mLruProcesses.get(i);
   2004                         if (r.thread != null) {
   2005                             try {
   2006                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
   2007                             } catch (RemoteException ex) {
   2008                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
   2009                             }
   2010                         }
   2011                     }
   2012                 }
   2013                 break;
   2014             }
   2015             case SYSTEM_USER_START_MSG: {
   2016                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
   2017                         Integer.toString(msg.arg1), msg.arg1);
   2018                 mSystemServiceManager.startUser(msg.arg1);
   2019                 break;
   2020             }
   2021             case SYSTEM_USER_UNLOCK_MSG: {
   2022                 final int userId = msg.arg1;
   2023                 mSystemServiceManager.unlockUser(userId);
   2024                 synchronized (ActivityManagerService.this) {
   2025                     mRecentTasks.loadUserRecentsLocked(userId);
   2026                 }
   2027                 if (userId == UserHandle.USER_SYSTEM) {
   2028                     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
   2029                 }
   2030                 installEncryptionUnawareProviders(userId);
   2031                 mUserController.finishUserUnlocked((UserState) msg.obj);
   2032                 break;
   2033             }
   2034             case SYSTEM_USER_CURRENT_MSG: {
   2035                 mBatteryStatsService.noteEvent(
   2036                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
   2037                         Integer.toString(msg.arg2), msg.arg2);
   2038                 mBatteryStatsService.noteEvent(
   2039                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
   2040                         Integer.toString(msg.arg1), msg.arg1);
   2041                 mSystemServiceManager.switchUser(msg.arg1);
   2042                 break;
   2043             }
   2044             case ENTER_ANIMATION_COMPLETE_MSG: {
   2045                 synchronized (ActivityManagerService.this) {
   2046                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
   2047                     if (r != null && r.app != null && r.app.thread != null) {
   2048                         try {
   2049                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
   2050                         } catch (RemoteException e) {
   2051                         }
   2052                     }
   2053                 }
   2054                 break;
   2055             }
   2056             case FINISH_BOOTING_MSG: {
   2057                 if (msg.arg1 != 0) {
   2058                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
   2059                     finishBooting();
   2060                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   2061                 }
   2062                 if (msg.arg2 != 0) {
   2063                     enableScreenAfterBoot();
   2064                 }
   2065                 break;
   2066             }
   2067             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
   2068                 try {
   2069                     Locale l = (Locale) msg.obj;
   2070                     IBinder service = ServiceManager.getService("mount");
   2071                     IMountService mountService = IMountService.Stub.asInterface(service);
   2072                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
   2073                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
   2074                 } catch (RemoteException e) {
   2075                     Log.e(TAG, "Error storing locale for decryption UI", e);
   2076                 }
   2077                 break;
   2078             }
   2079             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
   2080                 synchronized (ActivityManagerService.this) {
   2081                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
   2082                         try {
   2083                             // Make a one-way callback to the listener
   2084                             mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
   2085                         } catch (RemoteException e){
   2086                             // Handled by the RemoteCallbackList
   2087                         }
   2088                     }
   2089                     mTaskStackListeners.finishBroadcast();
   2090                 }
   2091                 break;
   2092             }
   2093             case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
   2094                 synchronized (ActivityManagerService.this) {
   2095                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
   2096                         try {
   2097                             // Make a one-way callback to the listener
   2098                             mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
   2099                         } catch (RemoteException e){
   2100                             // Handled by the RemoteCallbackList
   2101                         }
   2102                     }
   2103                     mTaskStackListeners.finishBroadcast();
   2104                 }
   2105                 break;
   2106             }
   2107             case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
   2108                 synchronized (ActivityManagerService.this) {
   2109                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
   2110                         try {
   2111                             // Make a one-way callback to the listener
   2112                             mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
   2113                         } catch (RemoteException e){
   2114                             // Handled by the RemoteCallbackList
   2115                         }
   2116                     }
   2117                     mTaskStackListeners.finishBroadcast();
   2118                 }
   2119                 break;
   2120             }
   2121             case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
   2122                 synchronized (ActivityManagerService.this) {
   2123                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
   2124                         try {
   2125                             // Make a one-way callback to the listener
   2126                             mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
   2127                         } catch (RemoteException e){
   2128                             // Handled by the RemoteCallbackList
   2129                         }
   2130                     }
   2131                     mTaskStackListeners.finishBroadcast();
   2132                 }
   2133                 break;
   2134             }
   2135             case NOTIFY_FORCED_RESIZABLE_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).onActivityForcedResizable(
   2141                                     (String) msg.obj, msg.arg1);
   2142                         } catch (RemoteException e){
   2143                             // Handled by the RemoteCallbackList
   2144                         }
   2145                     }
   2146                     mTaskStackListeners.finishBroadcast();
   2147                 }
   2148                 break;
   2149             }
   2150                 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
   2151                     synchronized (ActivityManagerService.this) {
   2152                         for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
   2153                             try {
   2154                                 // Make a one-way callback to the listener
   2155                                 mTaskStackListeners.getBroadcastItem(i)
   2156                                         .onActivityDismissingDockedStack();
   2157                             } catch (RemoteException e){
   2158                                 // Handled by the RemoteCallbackList
   2159                             }
   2160                         }
   2161                         mTaskStackListeners.finishBroadcast();
   2162                     }
   2163                     break;
   2164                 }
   2165             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
   2166                 final int uid = msg.arg1;
   2167                 final byte[] firstPacket = (byte[]) msg.obj;
   2168 
   2169                 synchronized (mPidsSelfLocked) {
   2170                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
   2171                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
   2172                         if (p.uid == uid) {
   2173                             try {
   2174                                 p.thread.notifyCleartextNetwork(firstPacket);
   2175                             } catch (RemoteException ignored) {
   2176                             }
   2177                         }
   2178                     }
   2179                 }
   2180                 break;
   2181             }
   2182             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
   2183                 final String procName;
   2184                 final int uid;
   2185                 final long memLimit;
   2186                 final String reportPackage;
   2187                 synchronized (ActivityManagerService.this) {
   2188                     procName = mMemWatchDumpProcName;
   2189                     uid = mMemWatchDumpUid;
   2190                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
   2191                     if (val == null) {
   2192                         val = mMemWatchProcesses.get(procName, 0);
   2193                     }
   2194                     if (val != null) {
   2195                         memLimit = val.first;
   2196                         reportPackage = val.second;
   2197                     } else {
   2198                         memLimit = 0;
   2199                         reportPackage = null;
   2200                     }
   2201                 }
   2202                 if (procName == null) {
   2203                     return;
   2204                 }
   2205 
   2206                 if (DEBUG_PSS) Slog.d(TAG_PSS,
   2207                         "Showing dump heap notification from " + procName + "/" + uid);
   2208 
   2209                 INotificationManager inm = NotificationManager.getService();
   2210                 if (inm == null) {
   2211                     return;
   2212                 }
   2213 
   2214                 String text = mContext.getString(R.string.dump_heap_notification, procName);
   2215 
   2216 
   2217                 Intent deleteIntent = new Intent();
   2218                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
   2219                 Intent intent = new Intent();
   2220                 intent.setClassName("android", DumpHeapActivity.class.getName());
   2221                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
   2222                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
   2223                 if (reportPackage != null) {
   2224                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
   2225                 }
   2226                 int userId = UserHandle.getUserId(uid);
   2227                 Notification notification = new Notification.Builder(mContext)
   2228                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
   2229                         .setWhen(0)
   2230                         .setOngoing(true)
   2231                         .setAutoCancel(true)
   2232                         .setTicker(text)
   2233                         .setColor(mContext.getColor(
   2234                                 com.android.internal.R.color.system_notification_accent_color))
   2235                         .setContentTitle(text)
   2236                         .setContentText(
   2237                                 mContext.getText(R.string.dump_heap_notification_detail))
   2238                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
   2239                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
   2240                                 new UserHandle(userId)))
   2241                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
   2242                                 deleteIntent, 0, UserHandle.SYSTEM))
   2243                         .build();
   2244 
   2245                 try {
   2246                     int[] outId = new int[1];
   2247                     inm.enqueueNotificationWithTag("android", "android", null,
   2248                             R.string.dump_heap_notification,
   2249                             notification, outId, userId);
   2250                 } catch (RuntimeException e) {
   2251                     Slog.w(ActivityManagerService.TAG,
   2252                             "Error showing notification for dump heap", e);
   2253                 } catch (RemoteException e) {
   2254                 }
   2255             } break;
   2256             case DELETE_DUMPHEAP_MSG: {
   2257                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
   2258                         DumpHeapActivity.JAVA_URI,
   2259                         Intent.FLAG_GRANT_READ_URI_PERMISSION
   2260                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
   2261                         UserHandle.myUserId());
   2262                 synchronized (ActivityManagerService.this) {
   2263                     mMemWatchDumpFile = null;
   2264                     mMemWatchDumpProcName = null;
   2265                     mMemWatchDumpPid = -1;
   2266                     mMemWatchDumpUid = -1;
   2267                 }
   2268             } break;
   2269             case FOREGROUND_PROFILE_CHANGED_MSG: {
   2270                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
   2271             } break;
   2272             case REPORT_TIME_TRACKER_MSG: {
   2273                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
   2274                 tracker.deliverResult(mContext);
   2275             } break;
   2276             case REPORT_USER_SWITCH_COMPLETE_MSG: {
   2277                 mUserController.dispatchUserSwitchComplete(msg.arg1);
   2278             } break;
   2279             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
   2280                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
   2281                 try {
   2282                     connection.shutdown();
   2283                 } catch (RemoteException e) {
   2284                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
   2285                 }
   2286                 // Only a UiAutomation can set this flag and now that
   2287                 // it is finished we make sure it is reset to its default.
   2288                 mUserIsMonkey = false;
   2289             } break;
   2290             case APP_BOOST_DEACTIVATE_MSG: {
   2291                 synchronized(ActivityManagerService.this) {
   2292                     if (mIsBoosted) {
   2293                         if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
   2294                             nativeMigrateFromBoost();
   2295                             mIsBoosted = false;
   2296                             mBoostStartTime = 0;
   2297                         } else {
   2298                             Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
   2299                             mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
   2300                         }
   2301                     }
   2302                 }
   2303             } break;
   2304             case IDLE_UIDS_MSG: {
   2305                 idleUids();
   2306             } break;
   2307             case LOG_STACK_STATE: {
   2308                 synchronized (ActivityManagerService.this) {
   2309                     mStackSupervisor.logStackState();
   2310                 }
   2311             } break;
   2312             case VR_MODE_CHANGE_MSG: {
   2313                 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
   2314                 final ActivityRecord r = (ActivityRecord) msg.obj;
   2315                 boolean vrMode;
   2316                 ComponentName requestedPackage;
   2317                 ComponentName callingPackage;
   2318                 int userId;
   2319                 synchronized (ActivityManagerService.this) {
   2320                     vrMode = r.requestedVrComponent != null;
   2321                     requestedPackage = r.requestedVrComponent;
   2322                     userId = r.userId;
   2323                     callingPackage = r.info.getComponentName();
   2324                     if (mInVrMode != vrMode) {
   2325                         mInVrMode = vrMode;
   2326                         mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
   2327                         if (r.app != null) {
   2328                             ProcessRecord proc = r.app;
   2329                             if (proc.vrThreadTid > 0) {
   2330                                 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
   2331                                     try {
   2332                                         if (mInVrMode == true) {
   2333                                             Process.setThreadScheduler(proc.vrThreadTid,
   2334                                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
   2335                                         } else {
   2336                                             Process.setThreadScheduler(proc.vrThreadTid,
   2337                                                 Process.SCHED_OTHER, 0);
   2338                                         }
   2339                                     } catch (IllegalArgumentException e) {
   2340                                         Slog.w(TAG, "Failed to set scheduling policy, thread does"
   2341                                                 + " not exist:\n" + e);
   2342                                     }
   2343                                 }
   2344                             }
   2345                         }
   2346                     }
   2347                 }
   2348                 vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
   2349             } break;
   2350             case VR_MODE_APPLY_IF_NEEDED_MSG: {
   2351                 final ActivityRecord r = (ActivityRecord) msg.obj;
   2352                 final boolean needsVrMode = r != null && r.requestedVrComponent != null;
   2353                 if (needsVrMode) {
   2354                     applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
   2355                             r.info.getComponentName(), false);
   2356                 }
   2357             } break;
   2358             }
   2359         }
   2360     };
   2361 
   2362     static final int COLLECT_PSS_BG_MSG = 1;
   2363 
   2364     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
   2365         @Override
   2366         public void handleMessage(Message msg) {
   2367             switch (msg.what) {
   2368             case COLLECT_PSS_BG_MSG: {
   2369                 long start = SystemClock.uptimeMillis();
   2370                 MemInfoReader memInfo = null;
   2371                 synchronized (ActivityManagerService.this) {
   2372                     if (mFullPssPending) {
   2373                         mFullPssPending = false;
   2374                         memInfo = new MemInfoReader();
   2375                     }
   2376                 }
   2377                 if (memInfo != null) {
   2378                     updateCpuStatsNow();
   2379                     long nativeTotalPss = 0;
   2380                     synchronized (mProcessCpuTracker) {
   2381                         final int N = mProcessCpuTracker.countStats();
   2382                         for (int j=0; j<N; j++) {
   2383                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
   2384                             if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
   2385                                 // This is definitely an application process; skip it.
   2386                                 continue;
   2387                             }
   2388                             synchronized (mPidsSelfLocked) {
   2389                                 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
   2390                                     // This is one of our own processes; skip it.
   2391                                     continue;
   2392                                 }
   2393                             }
   2394                             nativeTotalPss += Debug.getPss(st.pid, null, null);
   2395                         }
   2396                     }
   2397                     memInfo.readMemInfo();
   2398                     synchronized (ActivityManagerService.this) {
   2399                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
   2400                                 + (SystemClock.uptimeMillis()-start) + "ms");
   2401                         final long cachedKb = memInfo.getCachedSizeKb();
   2402                         final long freeKb = memInfo.getFreeSizeKb();
   2403                         final long zramKb = memInfo.getZramTotalSizeKb();
   2404                         final long kernelKb = memInfo.getKernelUsedSizeKb();
   2405                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
   2406                                 kernelKb*1024, nativeTotalPss*1024);
   2407                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
   2408                                 nativeTotalPss);
   2409                     }
   2410                 }
   2411 
   2412                 int num = 0;
   2413                 long[] tmp = new long[2];
   2414                 do {
   2415                     ProcessRecord proc;
   2416                     int procState;
   2417                     int pid;
   2418                     long lastPssTime;
   2419                     synchronized (ActivityManagerService.this) {
   2420                         if (mPendingPssProcesses.size() <= 0) {
   2421                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
   2422                                     "Collected PSS of " + num + " processes in "
   2423                                     + (SystemClock.uptimeMillis() - start) + "ms");
   2424                             mPendingPssProcesses.clear();
   2425                             return;
   2426                         }
   2427                         proc = mPendingPssProcesses.remove(0);
   2428                         procState = proc.pssProcState;
   2429                         lastPssTime = proc.lastPssTime;
   2430                         if (proc.thread != null && procState == proc.setProcState
   2431                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
   2432                                         < SystemClock.uptimeMillis()) {
   2433                             pid = proc.pid;
   2434                         } else {
   2435                             proc = null;
   2436                             pid = 0;
   2437                         }
   2438                     }
   2439                     if (proc != null) {
   2440                         long pss = Debug.getPss(pid, tmp, null);
   2441                         synchronized (ActivityManagerService.this) {
   2442                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
   2443                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
   2444                                 num++;
   2445                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
   2446                                         SystemClock.uptimeMillis());
   2447                             }
   2448                         }
   2449                     }
   2450                 } while (true);
   2451             }
   2452             }
   2453         }
   2454     };
   2455 
   2456     public void setSystemProcess() {
   2457         try {
   2458             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
   2459             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
   2460             ServiceManager.addService("meminfo", new MemBinder(this));
   2461             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
   2462             ServiceManager.addService("dbinfo", new DbBinder(this));
   2463             if (MONITOR_CPU_USAGE) {
   2464                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
   2465             }
   2466             ServiceManager.addService("permission", new PermissionController(this));
   2467             ServiceManager.addService("processinfo", new ProcessInfoService(this));
   2468 
   2469             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
   2470                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
   2471             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
   2472 
   2473             synchronized (this) {
   2474                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
   2475                 app.persistent = true;
   2476                 app.pid = MY_PID;
   2477                 app.maxAdj = ProcessList.SYSTEM_ADJ;
   2478                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
   2479                 synchronized (mPidsSelfLocked) {
   2480                     mPidsSelfLocked.put(app.pid, app);
   2481                 }
   2482                 updateLruProcessLocked(app, false, null);
   2483                 updateOomAdjLocked();
   2484             }
   2485         } catch (PackageManager.NameNotFoundException e) {
   2486             throw new RuntimeException(
   2487                     "Unable to find android system package", e);
   2488         }
   2489     }
   2490 
   2491     public void setWindowManager(WindowManagerService wm) {
   2492         mWindowManager = wm;
   2493         mStackSupervisor.setWindowManager(wm);
   2494         mActivityStarter.setWindowManager(wm);
   2495     }
   2496 
   2497     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
   2498         mUsageStatsService = usageStatsManager;
   2499     }
   2500 
   2501     public void startObservingNativeCrashes() {
   2502         final NativeCrashListener ncl = new NativeCrashListener(this);
   2503         ncl.start();
   2504     }
   2505 
   2506     public IAppOpsService getAppOpsService() {
   2507         return mAppOpsService;
   2508     }
   2509 
   2510     static class MemBinder extends Binder {
   2511         ActivityManagerService mActivityManagerService;
   2512         MemBinder(ActivityManagerService activityManagerService) {
   2513             mActivityManagerService = activityManagerService;
   2514         }
   2515 
   2516         @Override
   2517         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2518             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   2519                     != PackageManager.PERMISSION_GRANTED) {
   2520                 pw.println("Permission Denial: can't dump meminfo from from pid="
   2521                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   2522                         + " without permission " + android.Manifest.permission.DUMP);
   2523                 return;
   2524             }
   2525 
   2526             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
   2527         }
   2528     }
   2529 
   2530     static class GraphicsBinder extends Binder {
   2531         ActivityManagerService mActivityManagerService;
   2532         GraphicsBinder(ActivityManagerService activityManagerService) {
   2533             mActivityManagerService = activityManagerService;
   2534         }
   2535 
   2536         @Override
   2537         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2538             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   2539                     != PackageManager.PERMISSION_GRANTED) {
   2540                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
   2541                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   2542                         + " without permission " + android.Manifest.permission.DUMP);
   2543                 return;
   2544             }
   2545 
   2546             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
   2547         }
   2548     }
   2549 
   2550     static class DbBinder extends Binder {
   2551         ActivityManagerService mActivityManagerService;
   2552         DbBinder(ActivityManagerService activityManagerService) {
   2553             mActivityManagerService = activityManagerService;
   2554         }
   2555 
   2556         @Override
   2557         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2558             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   2559                     != PackageManager.PERMISSION_GRANTED) {
   2560                 pw.println("Permission Denial: can't dump dbinfo from from pid="
   2561                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   2562                         + " without permission " + android.Manifest.permission.DUMP);
   2563                 return;
   2564             }
   2565 
   2566             mActivityManagerService.dumpDbInfo(fd, pw, args);
   2567         }
   2568     }
   2569 
   2570     static class CpuBinder extends Binder {
   2571         ActivityManagerService mActivityManagerService;
   2572         CpuBinder(ActivityManagerService activityManagerService) {
   2573             mActivityManagerService = activityManagerService;
   2574         }
   2575 
   2576         @Override
   2577         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2578             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   2579                     != PackageManager.PERMISSION_GRANTED) {
   2580                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
   2581                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   2582                         + " without permission " + android.Manifest.permission.DUMP);
   2583                 return;
   2584             }
   2585 
   2586             synchronized (mActivityManagerService.mProcessCpuTracker) {
   2587                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
   2588                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
   2589                         SystemClock.uptimeMillis()));
   2590             }
   2591         }
   2592     }
   2593 
   2594     public static final class Lifecycle extends SystemService {
   2595         private final ActivityManagerService mService;
   2596 
   2597         public Lifecycle(Context context) {
   2598             super(context);
   2599             mService = new ActivityManagerService(context);
   2600         }
   2601 
   2602         @Override
   2603         public void onStart() {
   2604             mService.start();
   2605         }
   2606 
   2607         public ActivityManagerService getService() {
   2608             return mService;
   2609         }
   2610     }
   2611 
   2612     // Note: This method is invoked on the main thread but may need to attach various
   2613     // handlers to other threads.  So take care to be explicit about the looper.
   2614     public ActivityManagerService(Context systemContext) {
   2615         mContext = systemContext;
   2616         mFactoryTest = FactoryTest.getMode();
   2617         mSystemThread = ActivityThread.currentActivityThread();
   2618 
   2619         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
   2620 
   2621         mHandlerThread = new ServiceThread(TAG,
   2622                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
   2623         mHandlerThread.start();
   2624         mHandler = new MainHandler(mHandlerThread.getLooper());
   2625         mUiHandler = new UiHandler();
   2626 
   2627         /* static; one-time init here */
   2628         if (sKillHandler == null) {
   2629             sKillThread = new ServiceThread(TAG + ":kill",
   2630                     android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
   2631             sKillThread.start();
   2632             sKillHandler = new KillHandler(sKillThread.getLooper());
   2633         }
   2634 
   2635         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
   2636                 "foreground", BROADCAST_FG_TIMEOUT, false);
   2637         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
   2638                 "background", BROADCAST_BG_TIMEOUT, true);
   2639         mBroadcastQueues[0] = mFgBroadcastQueue;
   2640         mBroadcastQueues[1] = mBgBroadcastQueue;
   2641 
   2642         mServices = new ActiveServices(this);
   2643         mProviderMap = new ProviderMap(this);
   2644         mAppErrors = new AppErrors(mContext, this);
   2645 
   2646         // TODO: Move creation of battery stats service outside of activity manager service.
   2647         File dataDir = Environment.getDataDirectory();
   2648         File systemDir = new File(dataDir, "system");
   2649         systemDir.mkdirs();
   2650         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
   2651         mBatteryStatsService.getActiveStatistics().readLocked();
   2652         mBatteryStatsService.scheduleWriteToDisk();
   2653         mOnBattery = DEBUG_POWER ? true
   2654                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
   2655         mBatteryStatsService.getActiveStatistics().setCallback(this);
   2656 
   2657         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
   2658 
   2659         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
   2660         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
   2661                 new IAppOpsCallback.Stub() {
   2662                     @Override public void opChanged(int op, int uid, String packageName) {
   2663                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
   2664                             if (mAppOpsService.checkOperation(op, uid, packageName)
   2665                                     != AppOpsManager.MODE_ALLOWED) {
   2666                                 runInBackgroundDisabled(uid);
   2667                             }
   2668                         }
   2669                     }
   2670                 });
   2671 
   2672         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
   2673 
   2674         mUserController = new UserController(this);
   2675 
   2676         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
   2677             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
   2678 
   2679         if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
   2680             mUseFifoUiScheduling = true;
   2681         }
   2682 
   2683         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
   2684 
   2685         mConfiguration.setToDefaults();
   2686         mConfiguration.setLocales(LocaleList.getDefault());
   2687 
   2688         mConfigurationSeq = mConfiguration.seq = 1;
   2689         mProcessCpuTracker.init();
   2690 
   2691         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
   2692         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
   2693         mStackSupervisor = new ActivityStackSupervisor(this);
   2694         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
   2695         mRecentTasks = new RecentTasks(this, mStackSupervisor);
   2696 
   2697         mProcessCpuThread = new Thread("CpuTracker") {
   2698             @Override
   2699             public void run() {
   2700                 while (true) {
   2701                     try {
   2702                         try {
   2703                             synchronized(this) {
   2704                                 final long now = SystemClock.uptimeMillis();
   2705                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
   2706                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
   2707                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
   2708                                 //        + ", write delay=" + nextWriteDelay);
   2709                                 if (nextWriteDelay < nextCpuDelay) {
   2710                                     nextCpuDelay = nextWriteDelay;
   2711                                 }
   2712                                 if (nextCpuDelay > 0) {
   2713                                     mProcessCpuMutexFree.set(true);
   2714                                     this.wait(nextCpuDelay);
   2715                                 }
   2716                             }
   2717                         } catch (InterruptedException e) {
   2718                         }
   2719                         updateCpuStatsNow();
   2720                     } catch (Exception e) {
   2721                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
   2722                     }
   2723                 }
   2724             }
   2725         };
   2726 
   2727         Watchdog.getInstance().addMonitor(this);
   2728         Watchdog.getInstance().addThread(mHandler);
   2729     }
   2730 
   2731     public void setSystemServiceManager(SystemServiceManager mgr) {
   2732         mSystemServiceManager = mgr;
   2733     }
   2734 
   2735     public void setInstaller(Installer installer) {
   2736         mInstaller = installer;
   2737     }
   2738 
   2739     private void start() {
   2740         Process.removeAllProcessGroups();
   2741         mProcessCpuThread.start();
   2742 
   2743         mBatteryStatsService.publish(mContext);
   2744         mAppOpsService.publish(mContext);
   2745         Slog.d("AppOps", "AppOpsService published");
   2746         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
   2747     }
   2748 
   2749     void onUserStoppedLocked(int userId) {
   2750         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
   2751     }
   2752 
   2753     public void initPowerManagement() {
   2754         mStackSupervisor.initPowerManagement();
   2755         mBatteryStatsService.initPowerManagement();
   2756         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
   2757         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
   2758         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
   2759         mVoiceWakeLock.setReferenceCounted(false);
   2760     }
   2761 
   2762     @Override
   2763     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   2764             throws RemoteException {
   2765         if (code == SYSPROPS_TRANSACTION) {
   2766             // We need to tell all apps about the system property change.
   2767             ArrayList<IBinder> procs = new ArrayList<IBinder>();
   2768             synchronized(this) {
   2769                 final int NP = mProcessNames.getMap().size();
   2770                 for (int ip=0; ip<NP; ip++) {
   2771                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   2772                     final int NA = apps.size();
   2773                     for (int ia=0; ia<NA; ia++) {
   2774                         ProcessRecord app = apps.valueAt(ia);
   2775                         if (app.thread != null) {
   2776                             procs.add(app.thread.asBinder());
   2777                         }
   2778                     }
   2779                 }
   2780             }
   2781 
   2782             int N = procs.size();
   2783             for (int i=0; i<N; i++) {
   2784                 Parcel data2 = Parcel.obtain();
   2785                 try {
   2786                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
   2787                 } catch (RemoteException e) {
   2788                 }
   2789                 data2.recycle();
   2790             }
   2791         }
   2792         try {
   2793             return super.onTransact(code, data, reply, flags);
   2794         } catch (RuntimeException e) {
   2795             // The activity manager only throws security exceptions, so let's
   2796             // log all others.
   2797             if (!(e instanceof SecurityException)) {
   2798                 Slog.wtf(TAG, "Activity Manager Crash", e);
   2799             }
   2800             throw e;
   2801         }
   2802     }
   2803 
   2804     void updateCpuStats() {
   2805         final long now = SystemClock.uptimeMillis();
   2806         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
   2807             return;
   2808         }
   2809         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
   2810             synchronized (mProcessCpuThread) {
   2811                 mProcessCpuThread.notify();
   2812             }
   2813         }
   2814     }
   2815 
   2816     void updateCpuStatsNow() {
   2817         synchronized (mProcessCpuTracker) {
   2818             mProcessCpuMutexFree.set(false);
   2819             final long now = SystemClock.uptimeMillis();
   2820             boolean haveNewCpuStats = false;
   2821 
   2822             if (MONITOR_CPU_USAGE &&
   2823                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
   2824                 mLastCpuTime.set(now);
   2825                 mProcessCpuTracker.update();
   2826                 if (mProcessCpuTracker.hasGoodLastStats()) {
   2827                     haveNewCpuStats = true;
   2828                     //Slog.i(TAG, mProcessCpu.printCurrentState());
   2829                     //Slog.i(TAG, "Total CPU usage: "
   2830                     //        + mProcessCpu.getTotalCpuPercent() + "%");
   2831 
   2832                     // Slog the cpu usage if the property is set.
   2833                     if ("true".equals(SystemProperties.get("events.cpu"))) {
   2834                         int user = mProcessCpuTracker.getLastUserTime();
   2835                         int system = mProcessCpuTracker.getLastSystemTime();
   2836                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
   2837                         int irq = mProcessCpuTracker.getLastIrqTime();
   2838                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
   2839                         int idle = mProcessCpuTracker.getLastIdleTime();
   2840 
   2841                         int total = user + system + iowait + irq + softIrq + idle;
   2842                         if (total == 0) total = 1;
   2843 
   2844                         EventLog.writeEvent(EventLogTags.CPU,
   2845                                 ((user+system+iowait+irq+softIrq) * 100) / total,
   2846                                 (user * 100) / total,
   2847                                 (system * 100) / total,
   2848                                 (iowait * 100) / total,
   2849                                 (irq * 100) / total,
   2850                                 (softIrq * 100) / total);
   2851                     }
   2852                 }
   2853             }
   2854 
   2855             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
   2856             synchronized(bstats) {
   2857                 synchronized(mPidsSelfLocked) {
   2858                     if (haveNewCpuStats) {
   2859                         if (bstats.startAddingCpuLocked()) {
   2860                             int totalUTime = 0;
   2861                             int totalSTime = 0;
   2862                             final int N = mProcessCpuTracker.countStats();
   2863                             for (int i=0; i<N; i++) {
   2864                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   2865                                 if (!st.working) {
   2866                                     continue;
   2867                                 }
   2868                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
   2869                                 totalUTime += st.rel_utime;
   2870                                 totalSTime += st.rel_stime;
   2871                                 if (pr != null) {
   2872                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
   2873                                     if (ps == null || !ps.isActive()) {
   2874                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
   2875                                                 pr.info.uid, pr.processName);
   2876                                     }
   2877                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
   2878                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
   2879                                 } else {
   2880                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
   2881                                     if (ps == null || !ps.isActive()) {
   2882                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
   2883                                                 bstats.mapUid(st.uid), st.name);
   2884                                     }
   2885                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
   2886                                 }
   2887                             }
   2888                             final int userTime = mProcessCpuTracker.getLastUserTime();
   2889                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
   2890                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
   2891                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
   2892                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
   2893                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
   2894                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
   2895                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
   2896                         }
   2897                     }
   2898                 }
   2899 
   2900                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
   2901                     mLastWriteTime = now;
   2902                     mBatteryStatsService.scheduleWriteToDisk();
   2903                 }
   2904             }
   2905         }
   2906     }
   2907 
   2908     @Override
   2909     public void batteryNeedsCpuUpdate() {
   2910         updateCpuStatsNow();
   2911     }
   2912 
   2913     @Override
   2914     public void batteryPowerChanged(boolean onBattery) {
   2915         // When plugging in, update the CPU stats first before changing
   2916         // the plug state.
   2917         updateCpuStatsNow();
   2918         synchronized (this) {
   2919             synchronized(mPidsSelfLocked) {
   2920                 mOnBattery = DEBUG_POWER ? true : onBattery;
   2921             }
   2922         }
   2923     }
   2924 
   2925     @Override
   2926     public void batterySendBroadcast(Intent intent) {
   2927         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
   2928                 AppOpsManager.OP_NONE, null, false, false,
   2929                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
   2930     }
   2931 
   2932     /**
   2933      * Initialize the application bind args. These are passed to each
   2934      * process when the bindApplication() IPC is sent to the process. They're
   2935      * lazily setup to make sure the services are running when they're asked for.
   2936      */
   2937     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
   2938         if (mAppBindArgs == null) {
   2939             mAppBindArgs = new HashMap<>();
   2940 
   2941             // Isolated processes won't get this optimization, so that we don't
   2942             // violate the rules about which services they have access to.
   2943             if (!isolated) {
   2944                 // Setup the application init args
   2945                 mAppBindArgs.put("package", ServiceManager.getService("package"));
   2946                 mAppBindArgs.put("window", ServiceManager.getService("window"));
   2947                 mAppBindArgs.put(Context.ALARM_SERVICE,
   2948                         ServiceManager.getService(Context.ALARM_SERVICE));
   2949             }
   2950         }
   2951         return mAppBindArgs;
   2952     }
   2953 
   2954     boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
   2955         if (r == null || mFocusedActivity == r) {
   2956             return false;
   2957         }
   2958 
   2959         if (!r.isFocusable()) {
   2960             if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
   2961             return false;
   2962         }
   2963 
   2964         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
   2965 
   2966         final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
   2967         if (wasDoingSetFocusedActivity) Slog.w(TAG,
   2968                 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
   2969         mDoingSetFocusedActivity = true;
   2970 
   2971         final ActivityRecord last = mFocusedActivity;
   2972         mFocusedActivity = r;
   2973         if (r.task.isApplicationTask()) {
   2974             if (mCurAppTimeTracker != r.appTimeTracker) {
   2975                 // We are switching app tracking.  Complete the current one.
   2976                 if (mCurAppTimeTracker != null) {
   2977                     mCurAppTimeTracker.stop();
   2978                     mHandler.obtainMessage(
   2979                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
   2980                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
   2981                     mCurAppTimeTracker = null;
   2982                 }
   2983                 if (r.appTimeTracker != null) {
   2984                     mCurAppTimeTracker = r.appTimeTracker;
   2985                     startTimeTrackingFocusedActivityLocked();
   2986                 }
   2987             } else {
   2988                 startTimeTrackingFocusedActivityLocked();
   2989             }
   2990         } else {
   2991             r.appTimeTracker = null;
   2992         }
   2993         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
   2994         // TODO: Probably not, because we don't want to resume voice on switching
   2995         // back to this activity
   2996         if (r.task.voiceInteractor != null) {
   2997             startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
   2998         } else {
   2999             finishRunningVoiceLocked();
   3000             IVoiceInteractionSession session;
   3001             if (last != null && ((session = last.task.voiceSession) != null
   3002                     || (session = last.voiceSession) != null)) {
   3003                 // We had been in a voice interaction session, but now focused has
   3004                 // move to something different.  Just finish the session, we can't
   3005                 // return to it and retain the proper state and synchronization with
   3006                 // the voice interaction service.
   3007                 finishVoiceTask(session);
   3008             }
   3009         }
   3010         if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
   3011             mWindowManager.setFocusedApp(r.appToken, true);
   3012         }
   3013         applyUpdateLockStateLocked(r);
   3014         applyUpdateVrModeLocked(r);
   3015         if (mFocusedActivity.userId != mLastFocusedUserId) {
   3016             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
   3017             mHandler.obtainMessage(
   3018                     FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
   3019             mLastFocusedUserId = mFocusedActivity.userId;
   3020         }
   3021 
   3022         // Log a warning if the focused app is changed during the process. This could
   3023         // indicate a problem of the focus setting logic!
   3024         if (mFocusedActivity != r) Slog.w(TAG,
   3025                 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
   3026         mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
   3027 
   3028         EventLogTags.writeAmFocusedActivity(
   3029                 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
   3030                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
   3031                 reason);
   3032         return true;
   3033     }
   3034 
   3035     final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
   3036         if (mFocusedActivity != goingAway) {
   3037             return;
   3038         }
   3039 
   3040         final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
   3041         if (focusedStack != null) {
   3042             final ActivityRecord top = focusedStack.topActivity();
   3043             if (top != null && top.userId != mLastFocusedUserId) {
   3044                 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
   3045                 mHandler.sendMessage(
   3046                         mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
   3047                 mLastFocusedUserId = top.userId;
   3048             }
   3049         }
   3050 
   3051         // Try to move focus to another activity if possible.
   3052         if (setFocusedActivityLocked(
   3053                 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
   3054             return;
   3055         }
   3056 
   3057         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
   3058                 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
   3059         mFocusedActivity = null;
   3060         EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
   3061     }
   3062 
   3063     @Override
   3064     public void setFocusedStack(int stackId) {
   3065         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
   3066         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
   3067         final long callingId = Binder.clearCallingIdentity();
   3068         try {
   3069             synchronized (this) {
   3070                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
   3071                 if (stack == null) {
   3072                     return;
   3073                 }
   3074                 final ActivityRecord r = stack.topRunningActivityLocked();
   3075                 if (setFocusedActivityLocked(r, "setFocusedStack")) {
   3076                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
   3077                 }
   3078             }
   3079         } finally {
   3080             Binder.restoreCallingIdentity(callingId);
   3081         }
   3082     }
   3083 
   3084     @Override
   3085     public void setFocusedTask(int taskId) {
   3086         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
   3087         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
   3088         final long callingId = Binder.clearCallingIdentity();
   3089         try {
   3090             synchronized (this) {
   3091                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   3092                 if (task == null) {
   3093                     return;
   3094                 }
   3095                 final ActivityRecord r = task.topRunningActivityLocked();
   3096                 if (setFocusedActivityLocked(r, "setFocusedTask")) {
   3097                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
   3098                 }
   3099             }
   3100         } finally {
   3101             Binder.restoreCallingIdentity(callingId);
   3102         }
   3103     }
   3104 
   3105     /** Sets the task stack listener that gets callbacks when a task stack changes. */
   3106     @Override
   3107     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
   3108         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
   3109         synchronized (this) {
   3110             if (listener != null) {
   3111                 mTaskStackListeners.register(listener);
   3112             }
   3113         }
   3114     }
   3115 
   3116     @Override
   3117     public void notifyActivityDrawn(IBinder token) {
   3118         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
   3119         synchronized (this) {
   3120             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
   3121             if (r != null) {
   3122                 r.task.stack.notifyActivityDrawnLocked(r);
   3123             }
   3124         }
   3125     }
   3126 
   3127     final void applyUpdateLockStateLocked(ActivityRecord r) {
   3128         // Modifications to the UpdateLock state are done on our handler, outside
   3129         // the activity manager's locks.  The new state is determined based on the
   3130         // state *now* of the relevant activity record.  The object is passed to
   3131         // the handler solely for logging detail, not to be consulted/modified.
   3132         final boolean nextState = r != null && r.immersive;
   3133         mHandler.sendMessage(
   3134                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
   3135     }
   3136 
   3137     final void applyUpdateVrModeLocked(ActivityRecord r) {
   3138         mHandler.sendMessage(
   3139                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
   3140     }
   3141 
   3142     private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
   3143         mHandler.sendMessage(
   3144                 mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
   3145     }
   3146 
   3147     private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
   3148             ComponentName callingPackage, boolean immediate) {
   3149         VrManagerInternal vrService =
   3150                 LocalServices.getService(VrManagerInternal.class);
   3151         if (immediate) {
   3152             vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
   3153         } else {
   3154             vrService.setVrMode(enabled, packageName, userId, callingPackage);
   3155         }
   3156     }
   3157 
   3158     final void showAskCompatModeDialogLocked(ActivityRecord r) {
   3159         Message msg = Message.obtain();
   3160         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
   3161         msg.obj = r.task.askedCompatMode ? null : r;
   3162         mUiHandler.sendMessage(msg);
   3163     }
   3164 
   3165     final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
   3166         if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
   3167                 && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
   3168             final Message msg = Message.obtain();
   3169             msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
   3170             msg.obj = r;
   3171             mUiHandler.sendMessage(msg);
   3172         }
   3173     }
   3174 
   3175     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
   3176             String what, Object obj, ProcessRecord srcApp) {
   3177         app.lastActivityTime = now;
   3178 
   3179         if (app.activities.size() > 0) {
   3180             // Don't want to touch dependent processes that are hosting activities.
   3181             return index;
   3182         }
   3183 
   3184         int lrui = mLruProcesses.lastIndexOf(app);
   3185         if (lrui < 0) {
   3186             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
   3187                     + what + " " + obj + " from " + srcApp);
   3188             return index;
   3189         }
   3190 
   3191         if (lrui >= index) {
   3192             // Don't want to cause this to move dependent processes *back* in the
   3193             // list as if they were less frequently used.
   3194             return index;
   3195         }
   3196 
   3197         if (lrui >= mLruProcessActivityStart) {
   3198             // Don't want to touch dependent processes that are hosting activities.
   3199             return index;
   3200         }
   3201 
   3202         mLruProcesses.remove(lrui);
   3203         if (index > 0) {
   3204             index--;
   3205         }
   3206         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
   3207                 + " in LRU list: " + app);
   3208         mLruProcesses.add(index, app);
   3209         return index;
   3210     }
   3211 
   3212     static void killProcessGroup(int uid, int pid) {
   3213         if (sKillHandler != null) {
   3214             sKillHandler.sendMessage(
   3215                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
   3216         } else {
   3217             Slog.w(TAG, "Asked to kill process group before system bringup!");
   3218             Process.killProcessGroup(uid, pid);
   3219         }
   3220     }
   3221 
   3222     final void removeLruProcessLocked(ProcessRecord app) {
   3223         int lrui = mLruProcesses.lastIndexOf(app);
   3224         if (lrui >= 0) {
   3225             if (!app.killed) {
   3226                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
   3227                 Process.killProcessQuiet(app.pid);
   3228                 killProcessGroup(app.uid, app.pid);
   3229             }
   3230             if (lrui <= mLruProcessActivityStart) {
   3231                 mLruProcessActivityStart--;
   3232             }
   3233             if (lrui <= mLruProcessServiceStart) {
   3234                 mLruProcessServiceStart--;
   3235             }
   3236             mLruProcesses.remove(lrui);
   3237         }
   3238     }
   3239 
   3240     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
   3241             ProcessRecord client) {
   3242         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
   3243                 || app.treatLikeActivity;
   3244         final boolean hasService = false; // not impl yet. app.services.size() > 0;
   3245         if (!activityChange && hasActivity) {
   3246             // The process has activities, so we are only allowing activity-based adjustments
   3247             // to move it.  It should be kept in the front of the list with other
   3248             // processes that have activities, and we don't want those to change their
   3249             // order except due to activity operations.
   3250             return;
   3251         }
   3252 
   3253         mLruSeq++;
   3254         final long now = SystemClock.uptimeMillis();
   3255         app.lastActivityTime = now;
   3256 
   3257         // First a quick reject: if the app is already at the position we will
   3258         // put it, then there is nothing to do.
   3259         if (hasActivity) {
   3260             final int N = mLruProcesses.size();
   3261             if (N > 0 && mLruProcesses.get(N-1) == app) {
   3262                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
   3263                 return;
   3264             }
   3265         } else {
   3266             if (mLruProcessServiceStart > 0
   3267                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
   3268                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
   3269                 return;
   3270             }
   3271         }
   3272 
   3273         int lrui = mLruProcesses.lastIndexOf(app);
   3274 
   3275         if (app.persistent && lrui >= 0) {
   3276             // We don't care about the position of persistent processes, as long as
   3277             // they are in the list.
   3278             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
   3279             return;
   3280         }
   3281 
   3282         /* In progress: compute new position first, so we can avoid doing work
   3283            if the process is not actually going to move.  Not yet working.
   3284         int addIndex;
   3285         int nextIndex;
   3286         boolean inActivity = false, inService = false;
   3287         if (hasActivity) {
   3288             // Process has activities, put it at the very tipsy-top.
   3289             addIndex = mLruProcesses.size();
   3290             nextIndex = mLruProcessServiceStart;
   3291             inActivity = true;
   3292         } else if (hasService) {
   3293             // Process has services, put it at the top of the service list.
   3294             addIndex = mLruProcessActivityStart;
   3295             nextIndex = mLruProcessServiceStart;
   3296             inActivity = true;
   3297             inService = true;
   3298         } else  {
   3299             // Process not otherwise of interest, it goes to the top of the non-service area.
   3300             addIndex = mLruProcessServiceStart;
   3301             if (client != null) {
   3302                 int clientIndex = mLruProcesses.lastIndexOf(client);
   3303                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
   3304                         + app);
   3305                 if (clientIndex >= 0 && addIndex > clientIndex) {
   3306                     addIndex = clientIndex;
   3307                 }
   3308             }
   3309             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
   3310         }
   3311 
   3312         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
   3313                 + mLruProcessActivityStart + "): " + app);
   3314         */
   3315 
   3316         if (lrui >= 0) {
   3317             if (lrui < mLruProcessActivityStart) {
   3318                 mLruProcessActivityStart--;
   3319             }
   3320             if (lrui < mLruProcessServiceStart) {
   3321                 mLruProcessServiceStart--;
   3322             }
   3323             /*
   3324             if (addIndex > lrui) {
   3325                 addIndex--;
   3326             }
   3327             if (nextIndex > lrui) {
   3328                 nextIndex--;
   3329             }
   3330             */
   3331             mLruProcesses.remove(lrui);
   3332         }
   3333 
   3334         /*
   3335         mLruProcesses.add(addIndex, app);
   3336         if (inActivity) {
   3337             mLruProcessActivityStart++;
   3338         }
   3339         if (inService) {
   3340             mLruProcessActivityStart++;
   3341         }
   3342         */
   3343 
   3344         int nextIndex;
   3345         if (hasActivity) {
   3346             final int N = mLruProcesses.size();
   3347             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
   3348                 // Process doesn't have activities, but has clients with
   3349                 // activities...  move it up, but one below the top (the top
   3350                 // should always have a real activity).
   3351                 if (DEBUG_LRU) Slog.d(TAG_LRU,
   3352                         "Adding to second-top of LRU activity list: " + app);
   3353                 mLruProcesses.add(N - 1, app);
   3354                 // To keep it from spamming the LRU list (by making a bunch of clients),
   3355                 // we will push down any other entries owned by the app.
   3356                 final int uid = app.info.uid;
   3357                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
   3358                     ProcessRecord subProc = mLruProcesses.get(i);
   3359                     if (subProc.info.uid == uid) {
   3360                         // We want to push this one down the list.  If the process after
   3361                         // it is for the same uid, however, don't do so, because we don't
   3362                         // want them internally to be re-ordered.
   3363                         if (mLruProcesses.get(i - 1).info.uid != uid) {
   3364                             if (DEBUG_LRU) Slog.d(TAG_LRU,
   3365                                     "Pushing uid " + uid + " swapping at " + i + ": "
   3366                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
   3367                             ProcessRecord tmp = mLruProcesses.get(i);
   3368                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
   3369                             mLruProcesses.set(i - 1, tmp);
   3370                             i--;
   3371                         }
   3372                     } else {
   3373                         // A gap, we can stop here.
   3374                         break;
   3375                     }
   3376                 }
   3377             } else {
   3378                 // Process has activities, put it at the very tipsy-top.
   3379                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
   3380                 mLruProcesses.add(app);
   3381             }
   3382             nextIndex = mLruProcessServiceStart;
   3383         } else if (hasService) {
   3384             // Process has services, put it at the top of the service list.
   3385             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
   3386             mLruProcesses.add(mLruProcessActivityStart, app);
   3387             nextIndex = mLruProcessServiceStart;
   3388             mLruProcessActivityStart++;
   3389         } else  {
   3390             // Process not otherwise of interest, it goes to the top of the non-service area.
   3391             int index = mLruProcessServiceStart;
   3392             if (client != null) {
   3393                 // If there is a client, don't allow the process to be moved up higher
   3394                 // in the list than that client.
   3395                 int clientIndex = mLruProcesses.lastIndexOf(client);
   3396                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
   3397                         + " when updating " + app);
   3398                 if (clientIndex <= lrui) {
   3399                     // Don't allow the client index restriction to push it down farther in the
   3400                     // list than it already is.
   3401                     clientIndex = lrui;
   3402                 }
   3403                 if (clientIndex >= 0 && index > clientIndex) {
   3404                     index = clientIndex;
   3405                 }
   3406             }
   3407             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
   3408             mLruProcesses.add(index, app);
   3409             nextIndex = index-1;
   3410             mLruProcessActivityStart++;
   3411             mLruProcessServiceStart++;
   3412         }
   3413 
   3414         // If the app is currently using a content provider or service,
   3415         // bump those processes as well.
   3416         for (int j=app.connections.size()-1; j>=0; j--) {
   3417             ConnectionRecord cr = app.connections.valueAt(j);
   3418             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
   3419                     && cr.binding.service.app != null
   3420                     && cr.binding.service.app.lruSeq != mLruSeq
   3421                     && !cr.binding.service.app.persistent) {
   3422                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
   3423                         "service connection", cr, app);
   3424             }
   3425         }
   3426         for (int j=app.conProviders.size()-1; j>=0; j--) {
   3427             ContentProviderRecord cpr = app.conProviders.get(j).provider;
   3428             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
   3429                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
   3430                         "provider reference", cpr, app);
   3431             }
   3432         }
   3433     }
   3434 
   3435     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
   3436         if (uid == Process.SYSTEM_UID) {
   3437             // The system gets to run in any process.  If there are multiple
   3438             // processes with the same uid, just pick the first (this
   3439             // should never happen).
   3440             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
   3441             if (procs == null) return null;
   3442             final int procCount = procs.size();
   3443             for (int i = 0; i < procCount; i++) {
   3444                 final int procUid = procs.keyAt(i);
   3445                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
   3446                     // Don't use an app process or different user process for system component.
   3447                     continue;
   3448                 }
   3449                 return procs.valueAt(i);
   3450             }
   3451         }
   3452         ProcessRecord proc = mProcessNames.get(processName, uid);
   3453         if (false && proc != null && !keepIfLarge
   3454                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
   3455                 && proc.lastCachedPss >= 4000) {
   3456             // Turn this condition on to cause killing to happen regularly, for testing.
   3457             if (proc.baseProcessTracker != null) {
   3458                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
   3459             }
   3460             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
   3461         } else if (proc != null && !keepIfLarge
   3462                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
   3463                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
   3464             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
   3465             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
   3466                 if (proc.baseProcessTracker != null) {
   3467                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
   3468                 }
   3469                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
   3470             }
   3471         }
   3472         return proc;
   3473     }
   3474 
   3475     void notifyPackageUse(String packageName, int reason) {
   3476         IPackageManager pm = AppGlobals.getPackageManager();
   3477         try {
   3478             pm.notifyPackageUse(packageName, reason);
   3479         } catch (RemoteException e) {
   3480         }
   3481     }
   3482 
   3483     boolean isNextTransitionForward() {
   3484         int transit = mWindowManager.getPendingAppTransition();
   3485         return transit == TRANSIT_ACTIVITY_OPEN
   3486                 || transit == TRANSIT_TASK_OPEN
   3487                 || transit == TRANSIT_TASK_TO_FRONT;
   3488     }
   3489 
   3490     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
   3491             String processName, String abiOverride, int uid, Runnable crashHandler) {
   3492         synchronized(this) {
   3493             ApplicationInfo info = new ApplicationInfo();
   3494             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
   3495             // For isolated processes, the former contains the parent's uid and the latter the
   3496             // actual uid of the isolated process.
   3497             // In the special case introduced by this method (which is, starting an isolated
   3498             // process directly from the SystemServer without an actual parent app process) the
   3499             // closest thing to a parent's uid is SYSTEM_UID.
   3500             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
   3501             // the |isolated| logic in the ProcessRecord constructor.
   3502             info.uid = Process.SYSTEM_UID;
   3503             info.processName = processName;
   3504             info.className = entryPoint;
   3505             info.packageName = "android";
   3506             ProcessRecord proc = startProcessLocked(processName, info /* info */,
   3507                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
   3508                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
   3509                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
   3510                     crashHandler);
   3511             return proc != null ? proc.pid : 0;
   3512         }
   3513     }
   3514 
   3515     final ProcessRecord startProcessLocked(String processName,
   3516             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
   3517             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
   3518             boolean isolated, boolean keepIfLarge) {
   3519         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
   3520                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
   3521                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
   3522                 null /* crashHandler */);
   3523     }
   3524 
   3525     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
   3526             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
   3527             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
   3528             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
   3529         long startTime = SystemClock.elapsedRealtime();
   3530         ProcessRecord app;
   3531         if (!isolated) {
   3532             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
   3533             checkTime(startTime, "startProcess: after getProcessRecord");
   3534 
   3535             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
   3536                 // If we are in the background, then check to see if this process
   3537                 // is bad.  If so, we will just silently fail.
   3538                 if (mAppErrors.isBadProcessLocked(info)) {
   3539                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
   3540                             + "/" + info.processName);
   3541                     return null;
   3542                 }
   3543             } else {
   3544                 // When the user is explicitly starting a process, then clear its
   3545                 // crash count so that we won't make it bad until they see at
   3546                 // least one crash dialog again, and make the process good again
   3547                 // if it had been bad.
   3548                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
   3549                         + "/" + info.processName);
   3550                 mAppErrors.resetProcessCrashTimeLocked(info);
   3551                 if (mAppErrors.isBadProcessLocked(info)) {
   3552                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
   3553                             UserHandle.getUserId(info.uid), info.uid,
   3554                             info.processName);
   3555                     mAppErrors.clearBadProcessLocked(info);
   3556                     if (app != null) {
   3557                         app.bad = false;
   3558                     }
   3559                 }
   3560             }
   3561         } else {
   3562             // If this is an isolated process, it can't re-use an existing process.
   3563             app = null;
   3564         }
   3565 
   3566         // app launch boost for big.little configurations
   3567         // use cpusets to migrate freshly launched tasks to big cores
   3568         nativeMigrateToBoost();
   3569         mIsBoosted = true;
   3570         mBoostStartTime = SystemClock.uptimeMillis();
   3571         Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
   3572         mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
   3573 
   3574         // We don't have to do anything more if:
   3575         // (1) There is an existing application record; and
   3576         // (2) The caller doesn't think it is dead, OR there is no thread
   3577         //     object attached to it so we know it couldn't have crashed; and
   3578         // (3) There is a pid assigned to it, so it is either starting or
   3579         //     already running.
   3580         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
   3581                 + " app=" + app + " knownToBeDead=" + knownToBeDead
   3582                 + " thread=" + (app != null ? app.thread : null)
   3583                 + " pid=" + (app != null ? app.pid : -1));
   3584         if (app != null && app.pid > 0) {
   3585             if ((!knownToBeDead && !app.killed) || app.thread == null) {
   3586                 // We already have the app running, or are waiting for it to
   3587                 // come up (we have a pid but not yet its thread), so keep it.
   3588                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
   3589                 // If this is a new package in the process, add the package to the list
   3590                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
   3591                 checkTime(startTime, "startProcess: done, added package to proc");
   3592                 return app;
   3593             }
   3594 
   3595             // An application record is attached to a previous process,
   3596             // clean it up now.
   3597             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
   3598             checkTime(startTime, "startProcess: bad proc running, killing");
   3599             killProcessGroup(app.uid, app.pid);
   3600             handleAppDiedLocked(app, true, true);
   3601             checkTime(startTime, "startProcess: done killing old proc");
   3602         }
   3603 
   3604         String hostingNameStr = hostingName != null
   3605                 ? hostingName.flattenToShortString() : null;
   3606 
   3607         if (app == null) {
   3608             checkTime(startTime, "startProcess: creating new process record");
   3609             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
   3610             if (app == null) {
   3611                 Slog.w(TAG, "Failed making new process record for "
   3612                         + processName + "/" + info.uid + " isolated=" + isolated);
   3613                 return null;
   3614             }
   3615             app.crashHandler = crashHandler;
   3616             checkTime(startTime, "startProcess: done creating new process record");
   3617         } else {
   3618             // If this is a new package in the process, add the package to the list
   3619             app.addPackage(info.packageName, info.versionCode, mProcessStats);
   3620             checkTime(startTime, "startProcess: added package to existing proc");
   3621         }
   3622 
   3623         // If the system is not ready yet, then hold off on starting this
   3624         // process until it is.
   3625         if (!mProcessesReady
   3626                 && !isAllowedWhileBooting(info)
   3627                 && !allowWhileBooting) {
   3628             if (!mProcessesOnHold.contains(app)) {
   3629                 mProcessesOnHold.add(app);
   3630             }
   3631             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
   3632                     "System not ready, putting on hold: " + app);
   3633             checkTime(startTime, "startProcess: returning with proc on hold");
   3634             return app;
   3635         }
   3636 
   3637         checkTime(startTime, "startProcess: stepping in to startProcess");
   3638         startProcessLocked(
   3639                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
   3640         checkTime(startTime, "startProcess: done starting proc!");
   3641         return (app.pid != 0) ? app : null;
   3642     }
   3643 
   3644     boolean isAllowedWhileBooting(ApplicationInfo ai) {
   3645         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
   3646     }
   3647 
   3648     private final void startProcessLocked(ProcessRecord app,
   3649             String hostingType, String hostingNameStr) {
   3650         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
   3651                 null /* entryPoint */, null /* entryPointArgs */);
   3652     }
   3653 
   3654     private final void startProcessLocked(ProcessRecord app, String hostingType,
   3655             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
   3656         long startTime = SystemClock.elapsedRealtime();
   3657         if (app.pid > 0 && app.pid != MY_PID) {
   3658             checkTime(startTime, "startProcess: removing from pids map");
   3659             synchronized (mPidsSelfLocked) {
   3660                 mPidsSelfLocked.remove(app.pid);
   3661                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   3662             }
   3663             checkTime(startTime, "startProcess: done removing from pids map");
   3664             app.setPid(0);
   3665         }
   3666 
   3667         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
   3668                 "startProcessLocked removing on hold: " + app);
   3669         mProcessesOnHold.remove(app);
   3670 
   3671         checkTime(startTime, "startProcess: starting to update cpu stats");
   3672         updateCpuStats();
   3673         checkTime(startTime, "startProcess: done updating cpu stats");
   3674 
   3675         try {
   3676             try {
   3677                 final int userId = UserHandle.getUserId(app.uid);
   3678                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
   3679             } catch (RemoteException e) {
   3680                 throw e.rethrowAsRuntimeException();
   3681             }
   3682 
   3683             int uid = app.uid;
   3684             int[] gids = null;
   3685             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
   3686             if (!app.isolated) {
   3687                 int[] permGids = null;
   3688                 try {
   3689                     checkTime(startTime, "startProcess: getting gids from package manager");
   3690                     final IPackageManager pm = AppGlobals.getPackageManager();
   3691                     permGids = pm.getPackageGids(app.info.packageName,
   3692                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
   3693                     MountServiceInternal mountServiceInternal = LocalServices.getService(
   3694                             MountServiceInternal.class);
   3695                     mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
   3696                             app.info.packageName);
   3697                 } catch (RemoteException e) {
   3698                     throw e.rethrowAsRuntimeException();
   3699                 }
   3700 
   3701                 /*
   3702                  * Add shared application and profile GIDs so applications can share some
   3703                  * resources like shared libraries and access user-wide resources
   3704                  */
   3705                 if (ArrayUtils.isEmpty(permGids)) {
   3706                     gids = new int[2];
   3707                 } else {
   3708                     gids = new int[permGids.length + 2];
   3709                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
   3710                 }
   3711                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
   3712                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
   3713             }
   3714             checkTime(startTime, "startProcess: building args");
   3715             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
   3716                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
   3717                         && mTopComponent != null
   3718                         && app.processName.equals(mTopComponent.getPackageName())) {
   3719                     uid = 0;
   3720                 }
   3721                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
   3722                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
   3723                     uid = 0;
   3724                 }
   3725             }
   3726             int debugFlags = 0;
   3727             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   3728                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
   3729                 // Also turn on CheckJNI for debuggable apps. It's quite
   3730                 // awkward to turn on otherwise.
   3731                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   3732             }
   3733             // Run the app in safe mode if its manifest requests so or the
   3734             // system is booted in safe mode.
   3735             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
   3736                 mSafeMode == true) {
   3737                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
   3738             }
   3739             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
   3740                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   3741             }
   3742             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
   3743             if ("true".equals(genDebugInfoProperty)) {
   3744                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
   3745             }
   3746             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
   3747                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
   3748             }
   3749             if ("1".equals(SystemProperties.get("debug.assert"))) {
   3750                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
   3751             }
   3752             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
   3753                 // Enable all debug flags required by the native debugger.
   3754                 debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
   3755                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
   3756                 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
   3757                 mNativeDebuggingApp = null;
   3758             }
   3759 
   3760             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
   3761             if (requiredAbi == null) {
   3762                 requiredAbi = Build.SUPPORTED_ABIS[0];
   3763             }
   3764 
   3765             String instructionSet = null;
   3766             if (app.info.primaryCpuAbi != null) {
   3767                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
   3768             }
   3769 
   3770             app.gids = gids;
   3771             app.requiredAbi = requiredAbi;
   3772             app.instructionSet = instructionSet;
   3773 
   3774             // Start the process.  It will either succeed and return a result containing
   3775             // the PID of the new process, or else throw a RuntimeException.
   3776             boolean isActivityProcess = (entryPoint == null);
   3777             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
   3778             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
   3779                     app.processName);
   3780             checkTime(startTime, "startProcess: asking zygote to start proc");
   3781             Process.ProcessStartResult startResult = Process.start(entryPoint,
   3782                     app.processName, uid, uid, gids, debugFlags, mountExternal,
   3783                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
   3784                     app.info.dataDir, entryPointArgs);
   3785             checkTime(startTime, "startProcess: returned from zygote!");
   3786             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   3787 
   3788             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
   3789             checkTime(startTime, "startProcess: done updating battery stats");
   3790 
   3791             EventLog.writeEvent(EventLogTags.AM_PROC_START,
   3792                     UserHandle.getUserId(uid), startResult.pid, uid,
   3793                     app.processName, hostingType,
   3794                     hostingNameStr != null ? hostingNameStr : "");
   3795 
   3796             try {
   3797                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
   3798                         app.info.seinfo, app.info.sourceDir, startResult.pid);
   3799             } catch (RemoteException ex) {
   3800                 // Ignore
   3801             }
   3802 
   3803             if (app.persistent) {
   3804                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
   3805             }
   3806 
   3807             checkTime(startTime, "startProcess: building log message");
   3808             StringBuilder buf = mStringBuilder;
   3809             buf.setLength(0);
   3810             buf.append("Start proc ");
   3811             buf.append(startResult.pid);
   3812             buf.append(':');
   3813             buf.append(app.processName);
   3814             buf.append('/');
   3815             UserHandle.formatUid(buf, uid);
   3816             if (!isActivityProcess) {
   3817                 buf.append(" [");
   3818                 buf.append(entryPoint);
   3819                 buf.append("]");
   3820             }
   3821             buf.append(" for ");
   3822             buf.append(hostingType);
   3823             if (hostingNameStr != null) {
   3824                 buf.append(" ");
   3825                 buf.append(hostingNameStr);
   3826             }
   3827             Slog.i(TAG, buf.toString());
   3828             app.setPid(startResult.pid);
   3829             app.usingWrapper = startResult.usingWrapper;
   3830             app.removed = false;
   3831             app.killed = false;
   3832             app.killedByAm = false;
   3833             checkTime(startTime, "startProcess: starting to update pids map");
   3834             synchronized (mPidsSelfLocked) {
   3835                 ProcessRecord oldApp;
   3836                 // If there is already an app occupying that pid that hasn't been cleaned up
   3837                 if ((oldApp = mPidsSelfLocked.get(startResult.pid)) != null && !app.isolated) {
   3838                     // Clean up anything relating to this pid first
   3839                     Slog.w(TAG, "Reusing pid " + startResult.pid
   3840                             + " while app is still mapped to it");
   3841                     cleanUpApplicationRecordLocked(oldApp, false, false, -1,
   3842                             true /*replacingPid*/);
   3843                 }
   3844                 this.mPidsSelfLocked.put(startResult.pid, app);
   3845                 if (isActivityProcess) {
   3846                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   3847                     msg.obj = app;
   3848                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
   3849                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
   3850                 }
   3851             }
   3852             checkTime(startTime, "startProcess: done updating pids map");
   3853         } catch (RuntimeException e) {
   3854             Slog.e(TAG, "Failure starting process " + app.processName, e);
   3855 
   3856             // Something went very wrong while trying to start this process; one
   3857             // common case is when the package is frozen due to an active
   3858             // upgrade. To recover, clean up any active bookkeeping related to
   3859             // starting this process. (We already invoked this method once when
   3860             // the package was initially frozen through KILL_APPLICATION_MSG, so
   3861             // it doesn't hurt to use it again.)
   3862             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
   3863                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
   3864         }
   3865     }
   3866 
   3867     void updateUsageStats(ActivityRecord component, boolean resumed) {
   3868         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
   3869                 "updateUsageStats: comp=" + component + "res=" + resumed);
   3870         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   3871         if (resumed) {
   3872             if (mUsageStatsService != null) {
   3873                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
   3874                         UsageEvents.Event.MOVE_TO_FOREGROUND);
   3875             }
   3876             synchronized (stats) {
   3877                 stats.noteActivityResumedLocked(component.app.uid);
   3878             }
   3879         } else {
   3880             if (mUsageStatsService != null) {
   3881                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
   3882                         UsageEvents.Event.MOVE_TO_BACKGROUND);
   3883             }
   3884             synchronized (stats) {
   3885                 stats.noteActivityPausedLocked(component.app.uid);
   3886             }
   3887         }
   3888     }
   3889 
   3890     Intent getHomeIntent() {
   3891         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
   3892         intent.setComponent(mTopComponent);
   3893         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
   3894         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   3895             intent.addCategory(Intent.CATEGORY_HOME);
   3896         }
   3897         return intent;
   3898     }
   3899 
   3900     boolean startHomeActivityLocked(int userId, String reason) {
   3901         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
   3902                 && mTopAction == null) {
   3903             // We are running in factory test mode, but unable to find
   3904             // the factory test app, so just sit around displaying the
   3905             // error message and don't try to start anything.
   3906             return false;
   3907         }
   3908         Intent intent = getHomeIntent();
   3909         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
   3910         if (aInfo != null) {
   3911             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
   3912             // Don't do this if the home app is currently being
   3913             // instrumented.
   3914             aInfo = new ActivityInfo(aInfo);
   3915             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
   3916             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
   3917                     aInfo.applicationInfo.uid, true);
   3918             if (app == null || app.instrumentationClass == null) {
   3919                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
   3920                 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
   3921             }
   3922         } else {
   3923             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
   3924         }
   3925 
   3926         return true;
   3927     }
   3928 
   3929     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
   3930         ActivityInfo ai = null;
   3931         ComponentName comp = intent.getComponent();
   3932         try {
   3933             if (comp != null) {
   3934                 // Factory test.
   3935                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
   3936             } else {
   3937                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
   3938                         intent,
   3939                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
   3940                         flags, userId);
   3941 
   3942                 if (info != null) {
   3943                     ai = info.activityInfo;
   3944                 }
   3945             }
   3946         } catch (RemoteException e) {
   3947             // ignore
   3948         }
   3949 
   3950         return ai;
   3951     }
   3952 
   3953     /**
   3954      * Starts the "new version setup screen" if appropriate.
   3955      */
   3956     void startSetupActivityLocked() {
   3957         // Only do this once per boot.
   3958         if (mCheckedForSetup) {
   3959             return;
   3960         }
   3961 
   3962         // We will show this screen if the current one is a different
   3963         // version than the last one shown, and we are not running in
   3964         // low-level factory test mode.
   3965         final ContentResolver resolver = mContext.getContentResolver();
   3966         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
   3967                 Settings.Global.getInt(resolver,
   3968                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
   3969             mCheckedForSetup = true;
   3970 
   3971             // See if we should be showing the platform update setup UI.
   3972             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
   3973             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
   3974                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
   3975             if (!ris.isEmpty()) {
   3976                 final ResolveInfo ri = ris.get(0);
   3977                 String vers = ri.activityInfo.metaData != null
   3978                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
   3979                         : null;
   3980                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
   3981                     vers = ri.activityInfo.applicationInfo.metaData.getString(
   3982                             Intent.METADATA_SETUP_VERSION);
   3983                 }
   3984                 String lastVers = Settings.Secure.getString(
   3985                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
   3986                 if (vers != null && !vers.equals(lastVers)) {
   3987                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   3988                     intent.setComponent(new ComponentName(
   3989                             ri.activityInfo.packageName, ri.activityInfo.name));
   3990                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
   3991                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
   3992                             null, 0, 0, 0, null, false, false, null, null, null);
   3993                 }
   3994             }
   3995         }
   3996     }
   3997 
   3998     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
   3999         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
   4000     }
   4001 
   4002     void enforceNotIsolatedCaller(String caller) {
   4003         if (UserHandle.isIsolated(Binder.getCallingUid())) {
   4004             throw new SecurityException("Isolated process not allowed to call " + caller);
   4005         }
   4006     }
   4007 
   4008     void enforceShellRestriction(String restriction, int userHandle) {
   4009         if (Binder.getCallingUid() == Process.SHELL_UID) {
   4010             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
   4011                 throw new SecurityException("Shell does not have permission to access user "
   4012                         + userHandle);
   4013             }
   4014         }
   4015     }
   4016 
   4017     @Override
   4018     public int getFrontActivityScreenCompatMode() {
   4019         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
   4020         synchronized (this) {
   4021             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
   4022         }
   4023     }
   4024 
   4025     @Override
   4026     public void setFrontActivityScreenCompatMode(int mode) {
   4027         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   4028                 "setFrontActivityScreenCompatMode");
   4029         synchronized (this) {
   4030             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
   4031         }
   4032     }
   4033 
   4034     @Override
   4035     public int getPackageScreenCompatMode(String packageName) {
   4036         enforceNotIsolatedCaller("getPackageScreenCompatMode");
   4037         synchronized (this) {
   4038             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
   4039         }
   4040     }
   4041 
   4042     @Override
   4043     public void setPackageScreenCompatMode(String packageName, int mode) {
   4044         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   4045                 "setPackageScreenCompatMode");
   4046         synchronized (this) {
   4047             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
   4048         }
   4049     }
   4050 
   4051     @Override
   4052     public boolean getPackageAskScreenCompat(String packageName) {
   4053         enforceNotIsolatedCaller("getPackageAskScreenCompat");
   4054         synchronized (this) {
   4055             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
   4056         }
   4057     }
   4058 
   4059     @Override
   4060     public void setPackageAskScreenCompat(String packageName, boolean ask) {
   4061         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   4062                 "setPackageAskScreenCompat");
   4063         synchronized (this) {
   4064             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
   4065         }
   4066     }
   4067 
   4068     private boolean hasUsageStatsPermission(String callingPackage) {
   4069         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
   4070                 Binder.getCallingUid(), callingPackage);
   4071         if (mode == AppOpsManager.MODE_DEFAULT) {
   4072             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
   4073                     == PackageManager.PERMISSION_GRANTED;
   4074         }
   4075         return mode == AppOpsManager.MODE_ALLOWED;
   4076     }
   4077 
   4078     @Override
   4079     public int getPackageProcessState(String packageName, String callingPackage) {
   4080         if (!hasUsageStatsPermission(callingPackage)) {
   4081             enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
   4082                     "getPackageProcessState");
   4083         }
   4084 
   4085         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
   4086         synchronized (this) {
   4087             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   4088                 final ProcessRecord proc = mLruProcesses.get(i);
   4089                 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
   4090                         || procState > proc.setProcState) {
   4091                     boolean found = false;
   4092                     for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
   4093                         if (proc.pkgList.keyAt(j).equals(packageName)) {
   4094                             procState = proc.setProcState;
   4095                             found = true;
   4096                         }
   4097                     }
   4098                     if (proc.pkgDeps != null && !found) {
   4099                         for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
   4100                             if (proc.pkgDeps.valueAt(j).equals(packageName)) {
   4101                                 procState = proc.setProcState;
   4102                                 break;
   4103                             }
   4104                         }
   4105                     }
   4106                 }
   4107             }
   4108         }
   4109         return procState;
   4110     }
   4111 
   4112     @Override
   4113     public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
   4114         synchronized (this) {
   4115             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
   4116             if (app == null) {
   4117                 return false;
   4118             }
   4119             if (app.trimMemoryLevel < level && app.thread != null &&
   4120                     (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
   4121                             app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
   4122                 try {
   4123                     app.thread.scheduleTrimMemory(level);
   4124                     app.trimMemoryLevel = level;
   4125                     return true;
   4126                 } catch (RemoteException e) {
   4127                     // Fallthrough to failure case.
   4128                 }
   4129             }
   4130         }
   4131         return false;
   4132     }
   4133 
   4134     private void dispatchProcessesChanged() {
   4135         int N;
   4136         synchronized (this) {
   4137             N = mPendingProcessChanges.size();
   4138             if (mActiveProcessChanges.length < N) {
   4139                 mActiveProcessChanges = new ProcessChangeItem[N];
   4140             }
   4141             mPendingProcessChanges.toArray(mActiveProcessChanges);
   4142             mPendingProcessChanges.clear();
   4143             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   4144                     "*** Delivering " + N + " process changes");
   4145         }
   4146 
   4147         int i = mProcessObservers.beginBroadcast();
   4148         while (i > 0) {
   4149             i--;
   4150             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   4151             if (observer != null) {
   4152                 try {
   4153                     for (int j=0; j<N; j++) {
   4154                         ProcessChangeItem item = mActiveProcessChanges[j];
   4155                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
   4156                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   4157                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
   4158                                     + item.uid + ": " + item.foregroundActivities);
   4159                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
   4160                                     item.foregroundActivities);
   4161                         }
   4162                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
   4163                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   4164                                     "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
   4165                                     + ": " + item.processState);
   4166                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
   4167                         }
   4168                     }
   4169                 } catch (RemoteException e) {
   4170                 }
   4171             }
   4172         }
   4173         mProcessObservers.finishBroadcast();
   4174 
   4175         synchronized (this) {
   4176             for (int j=0; j<N; j++) {
   4177                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
   4178             }
   4179         }
   4180     }
   4181 
   4182     private void dispatchProcessDied(int pid, int uid) {
   4183         int i = mProcessObservers.beginBroadcast();
   4184         while (i > 0) {
   4185             i--;
   4186             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   4187             if (observer != null) {
   4188                 try {
   4189                     observer.onProcessDied(pid, uid);
   4190                 } catch (RemoteException e) {
   4191                 }
   4192             }
   4193         }
   4194         mProcessObservers.finishBroadcast();
   4195     }
   4196 
   4197     private void dispatchUidsChanged() {
   4198         int N;
   4199         synchronized (this) {
   4200             N = mPendingUidChanges.size();
   4201             if (mActiveUidChanges.length < N) {
   4202                 mActiveUidChanges = new UidRecord.ChangeItem[N];
   4203             }
   4204             for (int i=0; i<N; i++) {
   4205                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
   4206                 mActiveUidChanges[i] = change;
   4207                 if (change.uidRecord != null) {
   4208                     change.uidRecord.pendingChange = null;
   4209                     change.uidRecord = null;
   4210                 }
   4211             }
   4212             mPendingUidChanges.clear();
   4213             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4214                     "*** Delivering " + N + " uid changes");
   4215         }
   4216 
   4217         if (mLocalPowerManager != null) {
   4218             for (int j=0; j<N; j++) {
   4219                 UidRecord.ChangeItem item = mActiveUidChanges[j];
   4220                 if (item.change == UidRecord.CHANGE_GONE
   4221                         || item.change == UidRecord.CHANGE_GONE_IDLE) {
   4222                     mLocalPowerManager.uidGone(item.uid);
   4223                 } else {
   4224                     mLocalPowerManager.updateUidProcState(item.uid, item.processState);
   4225                 }
   4226             }
   4227         }
   4228 
   4229         int i = mUidObservers.beginBroadcast();
   4230         while (i > 0) {
   4231             i--;
   4232             final IUidObserver observer = mUidObservers.getBroadcastItem(i);
   4233             final int which = (Integer)mUidObservers.getBroadcastCookie(i);
   4234             if (observer != null) {
   4235                 try {
   4236                     for (int j=0; j<N; j++) {
   4237                         UidRecord.ChangeItem item = mActiveUidChanges[j];
   4238                         final int change = item.change;
   4239                         UidRecord validateUid = null;
   4240                         if (VALIDATE_UID_STATES && i == 0) {
   4241                             validateUid = mValidateUids.get(item.uid);
   4242                             if (validateUid == null && change != UidRecord.CHANGE_GONE
   4243                                     && change != UidRecord.CHANGE_GONE_IDLE) {
   4244                                 validateUid = new UidRecord(item.uid);
   4245                                 mValidateUids.put(item.uid, validateUid);
   4246                             }
   4247                         }
   4248                         if (change == UidRecord.CHANGE_IDLE
   4249                                 || change == UidRecord.CHANGE_GONE_IDLE) {
   4250                             if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
   4251                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4252                                         "UID idle uid=" + item.uid);
   4253                                 observer.onUidIdle(item.uid);
   4254                             }
   4255                             if (VALIDATE_UID_STATES && i == 0) {
   4256                                 if (validateUid != null) {
   4257                                     validateUid.idle = true;
   4258                                 }
   4259                             }
   4260                         } else if (change == UidRecord.CHANGE_ACTIVE) {
   4261                             if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
   4262                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4263                                         "UID active uid=" + item.uid);
   4264                                 observer.onUidActive(item.uid);
   4265                             }
   4266                             if (VALIDATE_UID_STATES && i == 0) {
   4267                                 validateUid.idle = false;
   4268                             }
   4269                         }
   4270                         if (change == UidRecord.CHANGE_GONE
   4271                                 || change == UidRecord.CHANGE_GONE_IDLE) {
   4272                             if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
   4273                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4274                                         "UID gone uid=" + item.uid);
   4275                                 observer.onUidGone(item.uid);
   4276                             }
   4277                             if (VALIDATE_UID_STATES && i == 0) {
   4278                                 if (validateUid != null) {
   4279                                     mValidateUids.remove(item.uid);
   4280                                 }
   4281                             }
   4282                         } else {
   4283                             if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
   4284                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4285                                         "UID CHANGED uid=" + item.uid
   4286                                                 + ": " + item.processState);
   4287                                 observer.onUidStateChanged(item.uid, item.processState);
   4288                             }
   4289                             if (VALIDATE_UID_STATES && i == 0) {
   4290                                 validateUid.curProcState = validateUid.setProcState
   4291                                         = item.processState;
   4292                             }
   4293                         }
   4294                     }
   4295                 } catch (RemoteException e) {
   4296                 }
   4297             }
   4298         }
   4299         mUidObservers.finishBroadcast();
   4300 
   4301         synchronized (this) {
   4302             for (int j=0; j<N; j++) {
   4303                 mAvailUidChanges.add(mActiveUidChanges[j]);
   4304             }
   4305         }
   4306     }
   4307 
   4308     @Override
   4309     public final int startActivity(IApplicationThread caller, String callingPackage,
   4310             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   4311             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
   4312         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
   4313                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
   4314                 UserHandle.getCallingUserId());
   4315     }
   4316 
   4317     final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
   4318         enforceNotIsolatedCaller("ActivityContainer.startActivity");
   4319         final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
   4320                 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
   4321                 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
   4322 
   4323         // TODO: Switch to user app stacks here.
   4324         String mimeType = intent.getType();
   4325         final Uri data = intent.getData();
   4326         if (mimeType == null && data != null && "content".equals(data.getScheme())) {
   4327             mimeType = getProviderMimeType(data, userId);
   4328         }
   4329         container.checkEmbeddedAllowedInner(userId, intent, mimeType);
   4330 
   4331         intent.addFlags(FORCE_NEW_TASK_FLAGS);
   4332         return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
   4333                 null, 0, 0, null, null, null, null, false, userId, container, null);
   4334     }
   4335 
   4336     @Override
   4337     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
   4338             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   4339             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
   4340         enforceNotIsolatedCaller("startActivity");
   4341         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4342                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
   4343         // TODO: Switch to user app stacks here.
   4344         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
   4345                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
   4346                 profilerInfo, null, null, bOptions, false, userId, null, null);
   4347     }
   4348 
   4349     @Override
   4350     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
   4351             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   4352             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
   4353             int userId) {
   4354 
   4355         // This is very dangerous -- it allows you to perform a start activity (including
   4356         // permission grants) as any app that may launch one of your own activities.  So
   4357         // we will only allow this to be done from activities that are part of the core framework,
   4358         // and then only when they are running as the system.
   4359         final ActivityRecord sourceRecord;
   4360         final int targetUid;
   4361         final String targetPackage;
   4362         synchronized (this) {
   4363             if (resultTo == null) {
   4364                 throw new SecurityException("Must be called from an activity");
   4365             }
   4366             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
   4367             if (sourceRecord == null) {
   4368                 throw new SecurityException("Called with bad activity token: " + resultTo);
   4369             }
   4370             if (!sourceRecord.info.packageName.equals("android")) {
   4371                 throw new SecurityException(
   4372                         "Must be called from an activity that is declared in the android package");
   4373             }
   4374             if (sourceRecord.app == null) {
   4375                 throw new SecurityException("Called without a process attached to activity");
   4376             }
   4377             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
   4378                 // This is still okay, as long as this activity is running under the
   4379                 // uid of the original calling activity.
   4380                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
   4381                     throw new SecurityException(
   4382                             "Calling activity in uid " + sourceRecord.app.uid
   4383                                     + " must be system uid or original calling uid "
   4384                                     + sourceRecord.launchedFromUid);
   4385                 }
   4386             }
   4387             if (ignoreTargetSecurity) {
   4388                 if (intent.getComponent() == null) {
   4389                     throw new SecurityException(
   4390                             "Component must be specified with ignoreTargetSecurity");
   4391                 }
   4392                 if (intent.getSelector() != null) {
   4393                     throw new SecurityException(
   4394                             "Selector not allowed with ignoreTargetSecurity");
   4395                 }
   4396             }
   4397             targetUid = sourceRecord.launchedFromUid;
   4398             targetPackage = sourceRecord.launchedFromPackage;
   4399         }
   4400 
   4401         if (userId == UserHandle.USER_NULL) {
   4402             userId = UserHandle.getUserId(sourceRecord.app.uid);
   4403         }
   4404 
   4405         // TODO: Switch to user app stacks here.
   4406         try {
   4407             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
   4408                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
   4409                     null, null, bOptions, ignoreTargetSecurity, userId, null, null);
   4410             return ret;
   4411         } catch (SecurityException e) {
   4412             // XXX need to figure out how to propagate to original app.
   4413             // A SecurityException here is generally actually a fault of the original
   4414             // calling activity (such as a fairly granting permissions), so propagate it
   4415             // back to them.
   4416             /*
   4417             StringBuilder msg = new StringBuilder();
   4418             msg.append("While launching");
   4419             msg.append(intent.toString());
   4420             msg.append(": ");
   4421             msg.append(e.getMessage());
   4422             */
   4423             throw e;
   4424         }
   4425     }
   4426 
   4427     @Override
   4428     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
   4429             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   4430             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
   4431         enforceNotIsolatedCaller("startActivityAndWait");
   4432         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4433                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
   4434         WaitResult res = new WaitResult();
   4435         // TODO: Switch to user app stacks here.
   4436         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
   4437                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
   4438                 bOptions, false, userId, null, null);
   4439         return res;
   4440     }
   4441 
   4442     @Override
   4443     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
   4444             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   4445             int startFlags, Configuration config, Bundle bOptions, int userId) {
   4446         enforceNotIsolatedCaller("startActivityWithConfig");
   4447         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4448                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
   4449         // TODO: Switch to user app stacks here.
   4450         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
   4451                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
   4452                 null, null, config, bOptions, false, userId, null, null);
   4453         return ret;
   4454     }
   4455 
   4456     @Override
   4457     public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
   4458             Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
   4459             int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
   4460             throws TransactionTooLargeException {
   4461         enforceNotIsolatedCaller("startActivityIntentSender");
   4462         // Refuse possible leaked file descriptors
   4463         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
   4464             throw new IllegalArgumentException("File descriptors passed in Intent");
   4465         }
   4466 
   4467         IIntentSender sender = intent.getTarget();
   4468         if (!(sender instanceof PendingIntentRecord)) {
   4469             throw new IllegalArgumentException("Bad PendingIntent object");
   4470         }
   4471 
   4472         PendingIntentRecord pir = (PendingIntentRecord)sender;
   4473 
   4474         synchronized (this) {
   4475             // If this is coming from the currently resumed activity, it is
   4476             // effectively saying that app switches are allowed at this point.
   4477             final ActivityStack stack = getFocusedStack();
   4478             if (stack.mResumedActivity != null &&
   4479                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
   4480                 mAppSwitchesAllowedTime = 0;
   4481             }
   4482         }
   4483         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
   4484                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
   4485         return ret;
   4486     }
   4487 
   4488     @Override
   4489     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
   4490             Intent intent, String resolvedType, IVoiceInteractionSession session,
   4491             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
   4492             Bundle bOptions, int userId) {
   4493         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
   4494                 != PackageManager.PERMISSION_GRANTED) {
   4495             String msg = "Permission Denial: startVoiceActivity() from pid="
   4496                     + Binder.getCallingPid()
   4497                     + ", uid=" + Binder.getCallingUid()
   4498                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
   4499             Slog.w(TAG, msg);
   4500             throw new SecurityException(msg);
   4501         }
   4502         if (session == null || interactor == null) {
   4503             throw new NullPointerException("null session or interactor");
   4504         }
   4505         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
   4506                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
   4507         // TODO: Switch to user app stacks here.
   4508         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
   4509                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
   4510                 null, bOptions, false, userId, null, null);
   4511     }
   4512 
   4513     @Override
   4514     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
   4515             throws RemoteException {
   4516         Slog.i(TAG, "Activity tried to startVoiceInteraction");
   4517         synchronized (this) {
   4518             ActivityRecord activity = getFocusedStack().topActivity();
   4519             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
   4520                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
   4521             }
   4522             if (mRunningVoice != null || activity.task.voiceSession != null
   4523                     || activity.voiceSession != null) {
   4524                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
   4525                 return;
   4526             }
   4527             if (activity.pendingVoiceInteractionStart) {
   4528                 Slog.w(TAG, "Pending start of voice interaction already.");
   4529                 return;
   4530             }
   4531             activity.pendingVoiceInteractionStart = true;
   4532         }
   4533         LocalServices.getService(VoiceInteractionManagerInternal.class)
   4534                 .startLocalVoiceInteraction(callingActivity, options);
   4535     }
   4536 
   4537     @Override
   4538     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
   4539         LocalServices.getService(VoiceInteractionManagerInternal.class)
   4540                 .stopLocalVoiceInteraction(callingActivity);
   4541     }
   4542 
   4543     @Override
   4544     public boolean supportsLocalVoiceInteraction() throws RemoteException {
   4545         return LocalServices.getService(VoiceInteractionManagerInternal.class)
   4546                 .supportsLocalVoiceInteraction();
   4547     }
   4548 
   4549     void onLocalVoiceInteractionStartedLocked(IBinder activity,
   4550             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
   4551         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
   4552         if (activityToCallback == null) return;
   4553         activityToCallback.setVoiceSessionLocked(voiceSession);
   4554 
   4555         // Inform the activity
   4556         try {
   4557             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
   4558                     voiceInteractor);
   4559             long token = Binder.clearCallingIdentity();
   4560             try {
   4561                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
   4562             } finally {
   4563                 Binder.restoreCallingIdentity(token);
   4564             }
   4565             // TODO: VI Should we cache the activity so that it's easier to find later
   4566             // rather than scan through all the stacks and activities?
   4567         } catch (RemoteException re) {
   4568             activityToCallback.clearVoiceSessionLocked();
   4569             // TODO: VI Should this terminate the voice session?
   4570         }
   4571     }
   4572 
   4573     @Override
   4574     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
   4575         synchronized (this) {
   4576             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
   4577                 if (keepAwake) {
   4578                     mVoiceWakeLock.acquire();
   4579                 } else {
   4580                     mVoiceWakeLock.release();
   4581                 }
   4582             }
   4583         }
   4584     }
   4585 
   4586     @Override
   4587     public boolean startNextMatchingActivity(IBinder callingActivity,
   4588             Intent intent, Bundle bOptions) {
   4589         // Refuse possible leaked file descriptors
   4590         if (intent != null && intent.hasFileDescriptors() == true) {
   4591             throw new IllegalArgumentException("File descriptors passed in Intent");
   4592         }
   4593         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
   4594 
   4595         synchronized (this) {
   4596             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
   4597             if (r == null) {
   4598                 ActivityOptions.abort(options);
   4599                 return false;
   4600             }
   4601             if (r.app == null || r.app.thread == null) {
   4602                 // The caller is not running...  d'oh!
   4603                 ActivityOptions.abort(options);
   4604                 return false;
   4605             }
   4606             intent = new Intent(intent);
   4607             // The caller is not allowed to change the data.
   4608             intent.setDataAndType(r.intent.getData(), r.intent.getType());
   4609             // And we are resetting to find the next component...
   4610             intent.setComponent(null);
   4611 
   4612             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
   4613 
   4614             ActivityInfo aInfo = null;
   4615             try {
   4616                 List<ResolveInfo> resolves =
   4617                     AppGlobals.getPackageManager().queryIntentActivities(
   4618                             intent, r.resolvedType,
   4619                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
   4620                             UserHandle.getCallingUserId()).getList();
   4621 
   4622                 // Look for the original activity in the list...
   4623                 final int N = resolves != null ? resolves.size() : 0;
   4624                 for (int i=0; i<N; i++) {
   4625                     ResolveInfo rInfo = resolves.get(i);
   4626                     if (rInfo.activityInfo.packageName.equals(r.packageName)
   4627                             && rInfo.activityInfo.name.equals(r.info.name)) {
   4628                         // We found the current one...  the next matching is
   4629                         // after it.
   4630                         i++;
   4631                         if (i<N) {
   4632                             aInfo = resolves.get(i).activityInfo;
   4633                         }
   4634                         if (debug) {
   4635                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
   4636                                     + "/" + r.info.name);
   4637                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
   4638                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
   4639                         }
   4640                         break;
   4641                     }
   4642                 }
   4643             } catch (RemoteException e) {
   4644             }
   4645 
   4646             if (aInfo == null) {
   4647                 // Nobody who is next!
   4648                 ActivityOptions.abort(options);
   4649                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
   4650                 return false;
   4651             }
   4652 
   4653             intent.setComponent(new ComponentName(
   4654                     aInfo.applicationInfo.packageName, aInfo.name));
   4655             intent.setFlags(intent.getFlags()&~(
   4656                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
   4657                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
   4658                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
   4659                     Intent.FLAG_ACTIVITY_NEW_TASK));
   4660 
   4661             // Okay now we need to start the new activity, replacing the
   4662             // currently running activity.  This is a little tricky because
   4663             // we want to start the new one as if the current one is finished,
   4664             // but not finish the current one first so that there is no flicker.
   4665             // And thus...
   4666             final boolean wasFinishing = r.finishing;
   4667             r.finishing = true;
   4668 
   4669             // Propagate reply information over to the new activity.
   4670             final ActivityRecord resultTo = r.resultTo;
   4671             final String resultWho = r.resultWho;
   4672             final int requestCode = r.requestCode;
   4673             r.resultTo = null;
   4674             if (resultTo != null) {
   4675                 resultTo.removeResultsLocked(r, resultWho, requestCode);
   4676             }
   4677 
   4678             final long origId = Binder.clearCallingIdentity();
   4679             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
   4680                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
   4681                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
   4682                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
   4683                     false, false, null, null, null);
   4684             Binder.restoreCallingIdentity(origId);
   4685 
   4686             r.finishing = wasFinishing;
   4687             if (res != ActivityManager.START_SUCCESS) {
   4688                 return false;
   4689             }
   4690             return true;
   4691         }
   4692     }
   4693 
   4694     @Override
   4695     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
   4696         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
   4697             String msg = "Permission Denial: startActivityFromRecents called without " +
   4698                     START_TASKS_FROM_RECENTS;
   4699             Slog.w(TAG, msg);
   4700             throw new SecurityException(msg);
   4701         }
   4702         final long origId = Binder.clearCallingIdentity();
   4703         try {
   4704             synchronized (this) {
   4705                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
   4706             }
   4707         } finally {
   4708             Binder.restoreCallingIdentity(origId);
   4709         }
   4710     }
   4711 
   4712     final int startActivityInPackage(int uid, String callingPackage,
   4713             Intent intent, String resolvedType, IBinder resultTo,
   4714             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
   4715             IActivityContainer container, TaskRecord inTask) {
   4716 
   4717         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4718                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
   4719 
   4720         // TODO: Switch to user app stacks here.
   4721         int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
   4722                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
   4723                 null, null, null, bOptions, false, userId, container, inTask);
   4724         return ret;
   4725     }
   4726 
   4727     @Override
   4728     public final int startActivities(IApplicationThread caller, String callingPackage,
   4729             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
   4730             int userId) {
   4731         enforceNotIsolatedCaller("startActivities");
   4732         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4733                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
   4734         // TODO: Switch to user app stacks here.
   4735         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
   4736                 resolvedTypes, resultTo, bOptions, userId);
   4737         return ret;
   4738     }
   4739 
   4740     final int startActivitiesInPackage(int uid, String callingPackage,
   4741             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
   4742             Bundle bOptions, int userId) {
   4743 
   4744         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4745                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
   4746         // TODO: Switch to user app stacks here.
   4747         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
   4748                 resultTo, bOptions, userId);
   4749         return ret;
   4750     }
   4751 
   4752     @Override
   4753     public void reportActivityFullyDrawn(IBinder token) {
   4754         synchronized (this) {
   4755             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4756             if (r == null) {
   4757                 return;
   4758             }
   4759             r.reportFullyDrawnLocked();
   4760         }
   4761     }
   4762 
   4763     @Override
   4764     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
   4765         synchronized (this) {
   4766             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4767             if (r == null) {
   4768                 return;
   4769             }
   4770             TaskRecord task = r.task;
   4771             if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
   4772                 // Fixed screen orientation isn't supported when activities aren't in full screen
   4773                 // mode.
   4774                 return;
   4775             }
   4776             final long origId = Binder.clearCallingIdentity();
   4777             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
   4778             Configuration config = mWindowManager.updateOrientationFromAppTokens(
   4779                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
   4780             if (config != null) {
   4781                 r.frozenBeforeDestroy = true;
   4782                 if (!updateConfigurationLocked(config, r, false)) {
   4783                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
   4784                 }
   4785             }
   4786             Binder.restoreCallingIdentity(origId);
   4787         }
   4788     }
   4789 
   4790     @Override
   4791     public int getRequestedOrientation(IBinder token) {
   4792         synchronized (this) {
   4793             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4794             if (r == null) {
   4795                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
   4796             }
   4797             return mWindowManager.getAppOrientation(r.appToken);
   4798         }
   4799     }
   4800 
   4801     /**
   4802      * This is the internal entry point for handling Activity.finish().
   4803      *
   4804      * @param token The Binder token referencing the Activity we want to finish.
   4805      * @param resultCode Result code, if any, from this Activity.
   4806      * @param resultData Result data (Intent), if any, from this Activity.
   4807      * @param finishTask Whether to finish the task associated with this Activity.
   4808      *
   4809      * @return Returns true if the activity successfully finished, or false if it is still running.
   4810      */
   4811     @Override
   4812     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
   4813             int finishTask) {
   4814         // Refuse possible leaked file descriptors
   4815         if (resultData != null && resultData.hasFileDescriptors() == true) {
   4816             throw new IllegalArgumentException("File descriptors passed in Intent");
   4817         }
   4818 
   4819         synchronized(this) {
   4820             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4821             if (r == null) {
   4822                 return true;
   4823             }
   4824             // Keep track of the root activity of the task before we finish it
   4825             TaskRecord tr = r.task;
   4826             ActivityRecord rootR = tr.getRootActivity();
   4827             if (rootR == null) {
   4828                 Slog.w(TAG, "Finishing task with all activities already finished");
   4829             }
   4830             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
   4831             // finish.
   4832             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
   4833                     mStackSupervisor.isLastLockedTask(tr)) {
   4834                 Slog.i(TAG, "Not finishing task in lock task mode");
   4835                 mStackSupervisor.showLockTaskToast();
   4836                 return false;
   4837             }
   4838             if (mController != null) {
   4839                 // Find the first activity that is not finishing.
   4840                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
   4841                 if (next != null) {
   4842                     // ask watcher if this is allowed
   4843                     boolean resumeOK = true;
   4844                     try {
   4845                         resumeOK = mController.activityResuming(next.packageName);
   4846                     } catch (RemoteException e) {
   4847                         mController = null;
   4848                         Watchdog.getInstance().setActivityController(null);
   4849                     }
   4850 
   4851                     if (!resumeOK) {
   4852                         Slog.i(TAG, "Not finishing activity because controller resumed");
   4853                         return false;
   4854                     }
   4855                 }
   4856             }
   4857             final long origId = Binder.clearCallingIdentity();
   4858             try {
   4859                 boolean res;
   4860                 final boolean finishWithRootActivity =
   4861                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
   4862                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
   4863                         || (finishWithRootActivity && r == rootR)) {
   4864                     // If requested, remove the task that is associated to this activity only if it
   4865                     // was the root activity in the task. The result code and data is ignored
   4866                     // because we don't support returning them across task boundaries. Also, to
   4867                     // keep backwards compatibility we remove the task from recents when finishing
   4868                     // task with root activity.
   4869                     res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
   4870                     if (!res) {
   4871                         Slog.i(TAG, "Removing task failed to finish activity");
   4872                     }
   4873                 } else {
   4874                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
   4875                             resultData, "app-request", true);
   4876                     if (!res) {
   4877                         Slog.i(TAG, "Failed to finish by app-request");
   4878                     }
   4879                 }
   4880                 return res;
   4881             } finally {
   4882                 Binder.restoreCallingIdentity(origId);
   4883             }
   4884         }
   4885     }
   4886 
   4887     @Override
   4888     public final void finishHeavyWeightApp() {
   4889         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   4890                 != PackageManager.PERMISSION_GRANTED) {
   4891             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
   4892                     + Binder.getCallingPid()
   4893                     + ", uid=" + Binder.getCallingUid()
   4894                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   4895             Slog.w(TAG, msg);
   4896             throw new SecurityException(msg);
   4897         }
   4898 
   4899         synchronized(this) {
   4900             if (mHeavyWeightProcess == null) {
   4901                 return;
   4902             }
   4903 
   4904             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
   4905             for (int i = 0; i < activities.size(); i++) {
   4906                 ActivityRecord r = activities.get(i);
   4907                 if (!r.finishing && r.isInStackLocked()) {
   4908                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
   4909                             null, "finish-heavy", true);
   4910                 }
   4911             }
   4912 
   4913             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   4914                     mHeavyWeightProcess.userId, 0));
   4915             mHeavyWeightProcess = null;
   4916         }
   4917     }
   4918 
   4919     @Override
   4920     public void crashApplication(int uid, int initialPid, String packageName,
   4921             String message) {
   4922         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   4923                 != PackageManager.PERMISSION_GRANTED) {
   4924             String msg = "Permission Denial: crashApplication() from pid="
   4925                     + Binder.getCallingPid()
   4926                     + ", uid=" + Binder.getCallingUid()
   4927                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   4928             Slog.w(TAG, msg);
   4929             throw new SecurityException(msg);
   4930         }
   4931 
   4932         synchronized(this) {
   4933             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
   4934         }
   4935     }
   4936 
   4937     @Override
   4938     public final void finishSubActivity(IBinder token, String resultWho,
   4939             int requestCode) {
   4940         synchronized(this) {
   4941             final long origId = Binder.clearCallingIdentity();
   4942             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4943             if (r != null) {
   4944                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
   4945             }
   4946             Binder.restoreCallingIdentity(origId);
   4947         }
   4948     }
   4949 
   4950     @Override
   4951     public boolean finishActivityAffinity(IBinder token) {
   4952         synchronized(this) {
   4953             final long origId = Binder.clearCallingIdentity();
   4954             try {
   4955                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4956                 if (r == null) {
   4957                     return false;
   4958                 }
   4959 
   4960                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
   4961                 // can finish.
   4962                 final TaskRecord task = r.task;
   4963                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
   4964                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
   4965                     mStackSupervisor.showLockTaskToast();
   4966                     return false;
   4967                 }
   4968                 return task.stack.finishActivityAffinityLocked(r);
   4969             } finally {
   4970                 Binder.restoreCallingIdentity(origId);
   4971             }
   4972         }
   4973     }
   4974 
   4975     @Override
   4976     public void finishVoiceTask(IVoiceInteractionSession session) {
   4977         synchronized (this) {
   4978             final long origId = Binder.clearCallingIdentity();
   4979             try {
   4980                 // TODO: VI Consider treating local voice interactions and voice tasks
   4981                 // differently here
   4982                 mStackSupervisor.finishVoiceTask(session);
   4983             } finally {
   4984                 Binder.restoreCallingIdentity(origId);
   4985             }
   4986         }
   4987 
   4988     }
   4989 
   4990     @Override
   4991     public boolean releaseActivityInstance(IBinder token) {
   4992         synchronized(this) {
   4993             final long origId = Binder.clearCallingIdentity();
   4994             try {
   4995                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4996                 if (r == null) {
   4997                     return false;
   4998                 }
   4999                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
   5000             } finally {
   5001                 Binder.restoreCallingIdentity(origId);
   5002             }
   5003         }
   5004     }
   5005 
   5006     @Override
   5007     public void releaseSomeActivities(IApplicationThread appInt) {
   5008         synchronized(this) {
   5009             final long origId = Binder.clearCallingIdentity();
   5010             try {
   5011                 ProcessRecord app = getRecordForAppLocked(appInt);
   5012                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
   5013             } finally {
   5014                 Binder.restoreCallingIdentity(origId);
   5015             }
   5016         }
   5017     }
   5018 
   5019     @Override
   5020     public boolean willActivityBeVisible(IBinder token) {
   5021         synchronized(this) {
   5022             ActivityStack stack = ActivityRecord.getStackLocked(token);
   5023             if (stack != null) {
   5024                 return stack.willActivityBeVisibleLocked(token);
   5025             }
   5026             return false;
   5027         }
   5028     }
   5029 
   5030     @Override
   5031     public void overridePendingTransition(IBinder token, String packageName,
   5032             int enterAnim, int exitAnim) {
   5033         synchronized(this) {
   5034             ActivityRecord self = ActivityRecord.isInStackLocked(token);
   5035             if (self == null) {
   5036                 return;
   5037             }
   5038 
   5039             final long origId = Binder.clearCallingIdentity();
   5040 
   5041             if (self.state == ActivityState.RESUMED
   5042                     || self.state == ActivityState.PAUSING) {
   5043                 mWindowManager.overridePendingAppTransition(packageName,
   5044                         enterAnim, exitAnim, null);
   5045             }
   5046 
   5047             Binder.restoreCallingIdentity(origId);
   5048         }
   5049     }
   5050 
   5051     /**
   5052      * Main function for removing an existing process from the activity manager
   5053      * as a result of that process going away.  Clears out all connections
   5054      * to the process.
   5055      */
   5056     private final void handleAppDiedLocked(ProcessRecord app,
   5057             boolean restarting, boolean allowRestart) {
   5058         int pid = app.pid;
   5059         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
   5060                 false /*replacingPid*/);
   5061         if (!kept && !restarting) {
   5062             removeLruProcessLocked(app);
   5063             if (pid > 0) {
   5064                 ProcessList.remove(pid);
   5065             }
   5066         }
   5067 
   5068         if (mProfileProc == app) {
   5069             clearProfilerLocked();
   5070         }
   5071 
   5072         // Remove this application's activities from active lists.
   5073         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
   5074 
   5075         app.activities.clear();
   5076 
   5077         if (app.instrumentationClass != null) {
   5078             Slog.w(TAG, "Crash of app " + app.processName
   5079                   + " running instrumentation " + app.instrumentationClass);
   5080             Bundle info = new Bundle();
   5081             info.putString("shortMsg", "Process crashed.");
   5082             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
   5083         }
   5084 
   5085         if (!restarting && hasVisibleActivities
   5086                 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
   5087             // If there was nothing to resume, and we are not already restarting this process, but
   5088             // there is a visible activity that is hosted by the process...  then make sure all
   5089             // visible activities are running, taking care of restarting this process.
   5090             mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   5091         }
   5092     }
   5093 
   5094     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
   5095         IBinder threadBinder = thread.asBinder();
   5096         // Find the application record.
   5097         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   5098             ProcessRecord rec = mLruProcesses.get(i);
   5099             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
   5100                 return i;
   5101             }
   5102         }
   5103         return -1;
   5104     }
   5105 
   5106     final ProcessRecord getRecordForAppLocked(
   5107             IApplicationThread thread) {
   5108         if (thread == null) {
   5109             return null;
   5110         }
   5111 
   5112         int appIndex = getLRURecordIndexForAppLocked(thread);
   5113         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
   5114     }
   5115 
   5116     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
   5117         // If there are no longer any background processes running,
   5118         // and the app that died was not running instrumentation,
   5119         // then tell everyone we are now low on memory.
   5120         boolean haveBg = false;
   5121         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   5122             ProcessRecord rec = mLruProcesses.get(i);
   5123             if (rec.thread != null
   5124                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   5125                 haveBg = true;
   5126                 break;
   5127             }
   5128         }
   5129 
   5130         if (!haveBg) {
   5131             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   5132             if (doReport) {
   5133                 long now = SystemClock.uptimeMillis();
   5134                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
   5135                     doReport = false;
   5136                 } else {
   5137                     mLastMemUsageReportTime = now;
   5138                 }
   5139             }
   5140             final ArrayList<ProcessMemInfo> memInfos
   5141                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
   5142             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
   5143             long now = SystemClock.uptimeMillis();
   5144             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   5145                 ProcessRecord rec = mLruProcesses.get(i);
   5146                 if (rec == dyingProc || rec.thread == null) {
   5147                     continue;
   5148                 }
   5149                 if (doReport) {
   5150                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
   5151                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
   5152                 }
   5153                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
   5154                     // The low memory report is overriding any current
   5155                     // state for a GC request.  Make sure to do
   5156                     // heavy/important/visible/foreground processes first.
   5157                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   5158                         rec.lastRequestedGc = 0;
   5159                     } else {
   5160                         rec.lastRequestedGc = rec.lastLowMemory;
   5161                     }
   5162                     rec.reportLowMemory = true;
   5163                     rec.lastLowMemory = now;
   5164                     mProcessesToGc.remove(rec);
   5165                     addProcessToGcListLocked(rec);
   5166                 }
   5167             }
   5168             if (doReport) {
   5169                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
   5170                 mHandler.sendMessage(msg);
   5171             }
   5172             scheduleAppGcsLocked();
   5173         }
   5174     }
   5175 
   5176     final void appDiedLocked(ProcessRecord app) {
   5177        appDiedLocked(app, app.pid, app.thread, false);
   5178     }
   5179 
   5180     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
   5181             boolean fromBinderDied) {
   5182         // First check if this ProcessRecord is actually active for the pid.
   5183         synchronized (mPidsSelfLocked) {
   5184             ProcessRecord curProc = mPidsSelfLocked.get(pid);
   5185             if (curProc != app) {
   5186                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
   5187                 return;
   5188             }
   5189         }
   5190 
   5191         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   5192         synchronized (stats) {
   5193             stats.noteProcessDiedLocked(app.info.uid, pid);
   5194         }
   5195 
   5196         if (!app.killed) {
   5197             if (!fromBinderDied) {
   5198                 Process.killProcessQuiet(pid);
   5199             }
   5200             killProcessGroup(app.uid, pid);
   5201             app.killed = true;
   5202         }
   5203 
   5204         // Clean up already done if the process has been re-started.
   5205         if (app.pid == pid && app.thread != null &&
   5206                 app.thread.asBinder() == thread.asBinder()) {
   5207             boolean doLowMem = app.instrumentationClass == null;
   5208             boolean doOomAdj = doLowMem;
   5209             if (!app.killedByAm) {
   5210                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   5211                         + ") has died");
   5212                 mAllowLowerMemLevel = true;
   5213             } else {
   5214                 // Note that we always want to do oom adj to update our state with the
   5215                 // new number of procs.
   5216                 mAllowLowerMemLevel = false;
   5217                 doLowMem = false;
   5218             }
   5219             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   5220             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
   5221                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
   5222             handleAppDiedLocked(app, false, true);
   5223 
   5224             if (doOomAdj) {
   5225                 updateOomAdjLocked();
   5226             }
   5227             if (doLowMem) {
   5228                 doLowMemReportIfNeededLocked(app);
   5229             }
   5230         } else if (app.pid != pid) {
   5231             // A new process has already been started.
   5232             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   5233                     + ") has died and restarted (pid " + app.pid + ").");
   5234             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   5235         } else if (DEBUG_PROCESSES) {
   5236             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
   5237                     + thread.asBinder());
   5238         }
   5239     }
   5240 
   5241     /**
   5242      * If a stack trace dump file is configured, dump process stack traces.
   5243      * @param clearTraces causes the dump file to be erased prior to the new
   5244      *    traces being written, if true; when false, the new traces will be
   5245      *    appended to any existing file content.
   5246      * @param firstPids of dalvik VM processes to dump stack traces for first
   5247      * @param lastPids of dalvik VM processes to dump stack traces for last
   5248      * @param nativeProcs optional list of native process names to dump stack crawls
   5249      * @return file containing stack traces, or null if no dump file is configured
   5250      */
   5251     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
   5252             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   5253         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   5254         if (tracesPath == null || tracesPath.length() == 0) {
   5255             return null;
   5256         }
   5257 
   5258         File tracesFile = new File(tracesPath);
   5259         try {
   5260             if (clearTraces && tracesFile.exists()) tracesFile.delete();
   5261             tracesFile.createNewFile();
   5262             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   5263         } catch (IOException e) {
   5264             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
   5265             return null;
   5266         }
   5267 
   5268         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
   5269         return tracesFile;
   5270     }
   5271 
   5272     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
   5273             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   5274         // Use a FileObserver to detect when traces finish writing.
   5275         // The order of traces is considered important to maintain for legibility.
   5276         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
   5277             @Override
   5278             public synchronized void onEvent(int event, String path) { notify(); }
   5279         };
   5280 
   5281         try {
   5282             observer.startWatching();
   5283 
   5284             // First collect all of the stacks of the most important pids.
   5285             if (firstPids != null) {
   5286                 try {
   5287                     int num = firstPids.size();
   5288                     for (int i = 0; i < num; i++) {
   5289                         synchronized (observer) {
   5290                             if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
   5291                                     + firstPids.get(i));
   5292                             final long sime = SystemClock.elapsedRealtime();
   5293                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
   5294                             observer.wait(1000);  // Wait for write-close, give up after 1 sec
   5295                             if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
   5296                                     + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
   5297                         }
   5298                     }
   5299                 } catch (InterruptedException e) {
   5300                     Slog.wtf(TAG, e);
   5301                 }
   5302             }
   5303 
   5304             // Next collect the stacks of the native pids
   5305             if (nativeProcs != null) {
   5306                 int[] pids = Process.getPidsForCommands(nativeProcs);
   5307                 if (pids != null) {
   5308                     for (int pid : pids) {
   5309                         if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
   5310                         final long sime = SystemClock.elapsedRealtime();
   5311                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
   5312                         if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
   5313                                 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
   5314                     }
   5315                 }
   5316             }
   5317 
   5318             // Lastly, measure CPU usage.
   5319             if (processCpuTracker != null) {
   5320                 processCpuTracker.init();
   5321                 System.gc();
   5322                 processCpuTracker.update();
   5323                 try {
   5324                     synchronized (processCpuTracker) {
   5325                         processCpuTracker.wait(500); // measure over 1/2 second.
   5326                     }
   5327                 } catch (InterruptedException e) {
   5328                 }
   5329                 processCpuTracker.update();
   5330 
   5331                 // We'll take the stack crawls of just the top apps using CPU.
   5332                 final int N = processCpuTracker.countWorkingStats();
   5333                 int numProcs = 0;
   5334                 for (int i=0; i<N && numProcs<5; i++) {
   5335                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
   5336                     if (lastPids.indexOfKey(stats.pid) >= 0) {
   5337                         numProcs++;
   5338                         try {
   5339                             synchronized (observer) {
   5340                                 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
   5341                                         + stats.pid);
   5342                                 final long stime = SystemClock.elapsedRealtime();
   5343                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
   5344                                 observer.wait(1000);  // Wait for write-close, give up after 1 sec
   5345                                 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
   5346                                         + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
   5347                             }
   5348                         } catch (InterruptedException e) {
   5349                             Slog.wtf(TAG, e);
   5350                         }
   5351                     } else if (DEBUG_ANR) {
   5352                         Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
   5353                                 + stats.pid);
   5354                     }
   5355                 }
   5356             }
   5357         } finally {
   5358             observer.stopWatching();
   5359         }
   5360     }
   5361 
   5362     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
   5363         if (true || IS_USER_BUILD) {
   5364             return;
   5365         }
   5366         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   5367         if (tracesPath == null || tracesPath.length() == 0) {
   5368             return;
   5369         }
   5370 
   5371         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
   5372         StrictMode.allowThreadDiskWrites();
   5373         try {
   5374             final File tracesFile = new File(tracesPath);
   5375             final File tracesDir = tracesFile.getParentFile();
   5376             final File tracesTmp = new File(tracesDir, "__tmp__");
   5377             try {
   5378                 if (tracesFile.exists()) {
   5379                     tracesTmp.delete();
   5380                     tracesFile.renameTo(tracesTmp);
   5381                 }
   5382                 StringBuilder sb = new StringBuilder();
   5383                 Time tobj = new Time();
   5384                 tobj.set(System.currentTimeMillis());
   5385                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
   5386                 sb.append(": ");
   5387                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
   5388                 sb.append(" since ");
   5389                 sb.append(msg);
   5390                 FileOutputStream fos = new FileOutputStream(tracesFile);
   5391                 fos.write(sb.toString().getBytes());
   5392                 if (app == null) {
   5393                     fos.write("\n*** No application process!".getBytes());
   5394                 }
   5395                 fos.close();
   5396                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   5397             } catch (IOException e) {
   5398                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
   5399                 return;
   5400             }
   5401 
   5402             if (app != null) {
   5403                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
   5404                 firstPids.add(app.pid);
   5405                 dumpStackTraces(tracesPath, firstPids, null, null, null);
   5406             }
   5407 
   5408             File lastTracesFile = null;
   5409             File curTracesFile = null;
   5410             for (int i=9; i>=0; i--) {
   5411                 String name = String.format(Locale.US, "slow%02d.txt", i);
   5412                 curTracesFile = new File(tracesDir, name);
   5413                 if (curTracesFile.exists()) {
   5414                     if (lastTracesFile != null) {
   5415                         curTracesFile.renameTo(lastTracesFile);
   5416                     } else {
   5417                         curTracesFile.delete();
   5418                     }
   5419                 }
   5420                 lastTracesFile = curTracesFile;
   5421             }
   5422             tracesFile.renameTo(curTracesFile);
   5423             if (tracesTmp.exists()) {
   5424                 tracesTmp.renameTo(tracesFile);
   5425             }
   5426         } finally {
   5427             StrictMode.setThreadPolicy(oldPolicy);
   5428         }
   5429     }
   5430 
   5431     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
   5432         if (!mLaunchWarningShown) {
   5433             mLaunchWarningShown = true;
   5434             mUiHandler.post(new Runnable() {
   5435                 @Override
   5436                 public void run() {
   5437                     synchronized (ActivityManagerService.this) {
   5438                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
   5439                         d.show();
   5440                         mUiHandler.postDelayed(new Runnable() {
   5441                             @Override
   5442                             public void run() {
   5443                                 synchronized (ActivityManagerService.this) {
   5444                                     d.dismiss();
   5445                                     mLaunchWarningShown = false;
   5446                                 }
   5447                             }
   5448                         }, 4000);
   5449                     }
   5450                 }
   5451             });
   5452         }
   5453     }
   5454 
   5455     @Override
   5456     public boolean clearApplicationUserData(final String packageName,
   5457             final IPackageDataObserver observer, int userId) {
   5458         enforceNotIsolatedCaller("clearApplicationUserData");
   5459         int uid = Binder.getCallingUid();
   5460         int pid = Binder.getCallingPid();
   5461         userId = mUserController.handleIncomingUser(pid, uid, userId, false,
   5462                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
   5463 
   5464 
   5465         long callingId = Binder.clearCallingIdentity();
   5466         try {
   5467             IPackageManager pm = AppGlobals.getPackageManager();
   5468             int pkgUid = -1;
   5469             synchronized(this) {
   5470                 if (getPackageManagerInternalLocked().isPackageDataProtected(
   5471                         userId, packageName)) {
   5472                     throw new SecurityException(
   5473                             "Cannot clear data for a protected package: " + packageName);
   5474                 }
   5475 
   5476                 try {
   5477                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
   5478                 } catch (RemoteException e) {
   5479                 }
   5480                 if (pkgUid == -1) {
   5481                     Slog.w(TAG, "Invalid packageName: " + packageName);
   5482                     if (observer != null) {
   5483                         try {
   5484                             observer.onRemoveCompleted(packageName, false);
   5485                         } catch (RemoteException e) {
   5486                             Slog.i(TAG, "Observer no longer exists.");
   5487                         }
   5488                     }
   5489                     return false;
   5490                 }
   5491                 if (uid == pkgUid || checkComponentPermission(
   5492                         android.Manifest.permission.CLEAR_APP_USER_DATA,
   5493                         pid, uid, -1, true)
   5494                         == PackageManager.PERMISSION_GRANTED) {
   5495                     forceStopPackageLocked(packageName, pkgUid, "clear data");
   5496                 } else {
   5497                     throw new SecurityException("PID " + pid + " does not have permission "
   5498                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
   5499                                     + " of package " + packageName);
   5500                 }
   5501 
   5502                 // Remove all tasks match the cleared application package and user
   5503                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
   5504                     final TaskRecord tr = mRecentTasks.get(i);
   5505                     final String taskPackageName =
   5506                             tr.getBaseIntent().getComponent().getPackageName();
   5507                     if (tr.userId != userId) continue;
   5508                     if (!taskPackageName.equals(packageName)) continue;
   5509                     removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
   5510                 }
   5511             }
   5512 
   5513             final int pkgUidF = pkgUid;
   5514             final int userIdF = userId;
   5515             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
   5516                 @Override
   5517                 public void onRemoveCompleted(String packageName, boolean succeeded)
   5518                         throws RemoteException {
   5519                     synchronized (ActivityManagerService.this) {
   5520                         finishForceStopPackageLocked(packageName, pkgUidF);
   5521                     }
   5522 
   5523                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
   5524                             Uri.fromParts("package", packageName, null));
   5525                     intent.putExtra(Intent.EXTRA_UID, pkgUidF);
   5526                     intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
   5527                     broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
   5528                             null, null, 0, null, null, null, null, false, false, userIdF);
   5529 
   5530                     if (observer != null) {
   5531                         observer.onRemoveCompleted(packageName, succeeded);
   5532                     }
   5533                 }
   5534             };
   5535 
   5536             try {
   5537                 // Clear application user data
   5538                 pm.clearApplicationUserData(packageName, localObserver, userId);
   5539 
   5540                 synchronized(this) {
   5541                     // Remove all permissions granted from/to this package
   5542                     removeUriPermissionsForPackageLocked(packageName, userId, true);
   5543                 }
   5544 
   5545                 // Remove all zen rules created by this package; revoke it's zen access.
   5546                 INotificationManager inm = NotificationManager.getService();
   5547                 inm.removeAutomaticZenRules(packageName);
   5548                 inm.setNotificationPolicyAccessGranted(packageName, false);
   5549 
   5550             } catch (RemoteException e) {
   5551             }
   5552         } finally {
   5553             Binder.restoreCallingIdentity(callingId);
   5554         }
   5555         return true;
   5556     }
   5557 
   5558     @Override
   5559     public void killBackgroundProcesses(final String packageName, int userId) {
   5560         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   5561                 != PackageManager.PERMISSION_GRANTED &&
   5562                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
   5563                         != PackageManager.PERMISSION_GRANTED) {
   5564             String msg = "Permission Denial: killBackgroundProcesses() from pid="
   5565                     + Binder.getCallingPid()
   5566                     + ", uid=" + Binder.getCallingUid()
   5567                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   5568             Slog.w(TAG, msg);
   5569             throw new SecurityException(msg);
   5570         }
   5571 
   5572         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   5573                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
   5574         long callingId = Binder.clearCallingIdentity();
   5575         try {
   5576             IPackageManager pm = AppGlobals.getPackageManager();
   5577             synchronized(this) {
   5578                 int appId = -1;
   5579                 try {
   5580                     appId = UserHandle.getAppId(
   5581                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
   5582                 } catch (RemoteException e) {
   5583                 }
   5584                 if (appId == -1) {
   5585                     Slog.w(TAG, "Invalid packageName: " + packageName);
   5586                     return;
   5587                 }
   5588                 killPackageProcessesLocked(packageName, appId, userId,
   5589                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
   5590             }
   5591         } finally {
   5592             Binder.restoreCallingIdentity(callingId);
   5593         }
   5594     }
   5595 
   5596     @Override
   5597     public void killAllBackgroundProcesses() {
   5598         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   5599                 != PackageManager.PERMISSION_GRANTED) {
   5600             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
   5601                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   5602                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   5603             Slog.w(TAG, msg);
   5604             throw new SecurityException(msg);
   5605         }
   5606 
   5607         final long callingId = Binder.clearCallingIdentity();
   5608         try {
   5609             synchronized (this) {
   5610                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
   5611                 final int NP = mProcessNames.getMap().size();
   5612                 for (int ip = 0; ip < NP; ip++) {
   5613                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   5614                     final int NA = apps.size();
   5615                     for (int ia = 0; ia < NA; ia++) {
   5616                         final ProcessRecord app = apps.valueAt(ia);
   5617                         if (app.persistent) {
   5618                             // We don't kill persistent processes.
   5619                             continue;
   5620                         }
   5621                         if (app.removed) {
   5622                             procs.add(app);
   5623                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   5624                             app.removed = true;
   5625                             procs.add(app);
   5626                         }
   5627                     }
   5628                 }
   5629 
   5630                 final int N = procs.size();
   5631                 for (int i = 0; i < N; i++) {
   5632                     removeProcessLocked(procs.get(i), false, true, "kill all background");
   5633                 }
   5634 
   5635                 mAllowLowerMemLevel = true;
   5636 
   5637                 updateOomAdjLocked();
   5638                 doLowMemReportIfNeededLocked(null);
   5639             }
   5640         } finally {
   5641             Binder.restoreCallingIdentity(callingId);
   5642         }
   5643     }
   5644 
   5645     /**
   5646      * Kills all background processes, except those matching any of the
   5647      * specified properties.
   5648      *
   5649      * @param minTargetSdk the target SDK version at or above which to preserve
   5650      *                     processes, or {@code -1} to ignore the target SDK
   5651      * @param maxProcState the process state at or below which to preserve
   5652      *                     processes, or {@code -1} to ignore the process state
   5653      */
   5654     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
   5655         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   5656                 != PackageManager.PERMISSION_GRANTED) {
   5657             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
   5658                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   5659                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   5660             Slog.w(TAG, msg);
   5661             throw new SecurityException(msg);
   5662         }
   5663 
   5664         final long callingId = Binder.clearCallingIdentity();
   5665         try {
   5666             synchronized (this) {
   5667                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
   5668                 final int NP = mProcessNames.getMap().size();
   5669                 for (int ip = 0; ip < NP; ip++) {
   5670                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   5671                     final int NA = apps.size();
   5672                     for (int ia = 0; ia < NA; ia++) {
   5673                         final ProcessRecord app = apps.valueAt(ia);
   5674                         if (app.removed) {
   5675                             procs.add(app);
   5676                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
   5677                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
   5678                             app.removed = true;
   5679                             procs.add(app);
   5680                         }
   5681                     }
   5682                 }
   5683 
   5684                 final int N = procs.size();
   5685                 for (int i = 0; i < N; i++) {
   5686                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
   5687                 }
   5688             }
   5689         } finally {
   5690             Binder.restoreCallingIdentity(callingId);
   5691         }
   5692     }
   5693 
   5694     @Override
   5695     public void forceStopPackage(final String packageName, int userId) {
   5696         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   5697                 != PackageManager.PERMISSION_GRANTED) {
   5698             String msg = "Permission Denial: forceStopPackage() from pid="
   5699                     + Binder.getCallingPid()
   5700                     + ", uid=" + Binder.getCallingUid()
   5701                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   5702             Slog.w(TAG, msg);
   5703             throw new SecurityException(msg);
   5704         }
   5705         final int callingPid = Binder.getCallingPid();
   5706         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
   5707                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
   5708         long callingId = Binder.clearCallingIdentity();
   5709         try {
   5710             IPackageManager pm = AppGlobals.getPackageManager();
   5711             synchronized(this) {
   5712                 int[] users = userId == UserHandle.USER_ALL
   5713                         ? mUserController.getUsers() : new int[] { userId };
   5714                 for (int user : users) {
   5715                     int pkgUid = -1;
   5716                     try {
   5717                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
   5718                                 user);
   5719                     } catch (RemoteException e) {
   5720                     }
   5721                     if (pkgUid == -1) {
   5722                         Slog.w(TAG, "Invalid packageName: " + packageName);
   5723                         continue;
   5724                     }
   5725                     try {
   5726                         pm.setPackageStoppedState(packageName, true, user);
   5727                     } catch (RemoteException e) {
   5728                     } catch (IllegalArgumentException e) {
   5729                         Slog.w(TAG, "Failed trying to unstop package "
   5730                                 + packageName + ": " + e);
   5731                     }
   5732                     if (mUserController.isUserRunningLocked(user, 0)) {
   5733                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
   5734                         finishForceStopPackageLocked(packageName, pkgUid);
   5735                     }
   5736                 }
   5737             }
   5738         } finally {
   5739             Binder.restoreCallingIdentity(callingId);
   5740         }
   5741     }
   5742 
   5743     @Override
   5744     public void addPackageDependency(String packageName) {
   5745         synchronized (this) {
   5746             int callingPid = Binder.getCallingPid();
   5747             if (callingPid == Process.myPid()) {
   5748                 //  Yeah, um, no.
   5749                 return;
   5750             }
   5751             ProcessRecord proc;
   5752             synchronized (mPidsSelfLocked) {
   5753                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   5754             }
   5755             if (proc != null) {
   5756                 if (proc.pkgDeps == null) {
   5757                     proc.pkgDeps = new ArraySet<String>(1);
   5758                 }
   5759                 proc.pkgDeps.add(packageName);
   5760             }
   5761         }
   5762     }
   5763 
   5764     /*
   5765      * The pkg name and app id have to be specified.
   5766      */
   5767     @Override
   5768     public void killApplication(String pkg, int appId, int userId, String reason) {
   5769         if (pkg == null) {
   5770             return;
   5771         }
   5772         // Make sure the uid is valid.
   5773         if (appId < 0) {
   5774             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
   5775             return;
   5776         }
   5777         int callerUid = Binder.getCallingUid();
   5778         // Only the system server can kill an application
   5779         if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
   5780             // Post an aysnc message to kill the application
   5781             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
   5782             msg.arg1 = appId;
   5783             msg.arg2 = userId;
   5784             Bundle bundle = new Bundle();
   5785             bundle.putString("pkg", pkg);
   5786             bundle.putString("reason", reason);
   5787             msg.obj = bundle;
   5788             mHandler.sendMessage(msg);
   5789         } else {
   5790             throw new SecurityException(callerUid + " cannot kill pkg: " +
   5791                     pkg);
   5792         }
   5793     }
   5794 
   5795     @Override
   5796     public void closeSystemDialogs(String reason) {
   5797         enforceNotIsolatedCaller("closeSystemDialogs");
   5798 
   5799         final int pid = Binder.getCallingPid();
   5800         final int uid = Binder.getCallingUid();
   5801         final long origId = Binder.clearCallingIdentity();
   5802         try {
   5803             synchronized (this) {
   5804                 // Only allow this from foreground processes, so that background
   5805                 // applications can't abuse it to prevent system UI from being shown.
   5806                 if (uid >= Process.FIRST_APPLICATION_UID) {
   5807                     ProcessRecord proc;
   5808                     synchronized (mPidsSelfLocked) {
   5809                         proc = mPidsSelfLocked.get(pid);
   5810                     }
   5811                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   5812                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
   5813                                 + " from background process " + proc);
   5814                         return;
   5815                     }
   5816                 }
   5817                 closeSystemDialogsLocked(reason);
   5818             }
   5819         } finally {
   5820             Binder.restoreCallingIdentity(origId);
   5821         }
   5822     }
   5823 
   5824     void closeSystemDialogsLocked(String reason) {
   5825         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
   5826         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   5827                 | Intent.FLAG_RECEIVER_FOREGROUND);
   5828         if (reason != null) {
   5829             intent.putExtra("reason", reason);
   5830         }
   5831         mWindowManager.closeSystemDialogs(reason);
   5832 
   5833         mStackSupervisor.closeSystemDialogsLocked();
   5834 
   5835         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
   5836                 AppOpsManager.OP_NONE, null, false, false,
   5837                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
   5838     }
   5839 
   5840     @Override
   5841     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
   5842         enforceNotIsolatedCaller("getProcessMemoryInfo");
   5843         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
   5844         for (int i=pids.length-1; i>=0; i--) {
   5845             ProcessRecord proc;
   5846             int oomAdj;
   5847             synchronized (this) {
   5848                 synchronized (mPidsSelfLocked) {
   5849                     proc = mPidsSelfLocked.get(pids[i]);
   5850                     oomAdj = proc != null ? proc.setAdj : 0;
   5851                 }
   5852             }
   5853             infos[i] = new Debug.MemoryInfo();
   5854             Debug.getMemoryInfo(pids[i], infos[i]);
   5855             if (proc != null) {
   5856                 synchronized (this) {
   5857                     if (proc.thread != null && proc.setAdj == oomAdj) {
   5858                         // Record this for posterity if the process has been stable.
   5859                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
   5860                                 infos[i].getTotalUss(), false, proc.pkgList);
   5861                     }
   5862                 }
   5863             }
   5864         }
   5865         return infos;
   5866     }
   5867 
   5868     @Override
   5869     public long[] getProcessPss(int[] pids) {
   5870         enforceNotIsolatedCaller("getProcessPss");
   5871         long[] pss = new long[pids.length];
   5872         for (int i=pids.length-1; i>=0; i--) {
   5873             ProcessRecord proc;
   5874             int oomAdj;
   5875             synchronized (this) {
   5876                 synchronized (mPidsSelfLocked) {
   5877                     proc = mPidsSelfLocked.get(pids[i]);
   5878                     oomAdj = proc != null ? proc.setAdj : 0;
   5879                 }
   5880             }
   5881             long[] tmpUss = new long[1];
   5882             pss[i] = Debug.getPss(pids[i], tmpUss, null);
   5883             if (proc != null) {
   5884                 synchronized (this) {
   5885                     if (proc.thread != null && proc.setAdj == oomAdj) {
   5886                         // Record this for posterity if the process has been stable.
   5887                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
   5888                     }
   5889                 }
   5890             }
   5891         }
   5892         return pss;
   5893     }
   5894 
   5895     @Override
   5896     public void killApplicationProcess(String processName, int uid) {
   5897         if (processName == null) {
   5898             return;
   5899         }
   5900 
   5901         int callerUid = Binder.getCallingUid();
   5902         // Only the system server can kill an application
   5903         if (callerUid == Process.SYSTEM_UID) {
   5904             synchronized (this) {
   5905                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
   5906                 if (app != null && app.thread != null) {
   5907                     try {
   5908                         app.thread.scheduleSuicide();
   5909                     } catch (RemoteException e) {
   5910                         // If the other end already died, then our work here is done.
   5911                     }
   5912                 } else {
   5913                     Slog.w(TAG, "Process/uid not found attempting kill of "
   5914                             + processName + " / " + uid);
   5915                 }
   5916             }
   5917         } else {
   5918             throw new SecurityException(callerUid + " cannot kill app process: " +
   5919                     processName);
   5920         }
   5921     }
   5922 
   5923     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
   5924         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
   5925                 false, true, false, false, UserHandle.getUserId(uid), reason);
   5926     }
   5927 
   5928     private void finishForceStopPackageLocked(final String packageName, int uid) {
   5929         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
   5930                 Uri.fromParts("package", packageName, null));
   5931         if (!mProcessesReady) {
   5932             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   5933                     | Intent.FLAG_RECEIVER_FOREGROUND);
   5934         }
   5935         intent.putExtra(Intent.EXTRA_UID, uid);
   5936         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
   5937         broadcastIntentLocked(null, null, intent,
   5938                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   5939                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
   5940     }
   5941 
   5942 
   5943     private final boolean killPackageProcessesLocked(String packageName, int appId,
   5944             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
   5945             boolean doit, boolean evenPersistent, String reason) {
   5946         ArrayList<ProcessRecord> procs = new ArrayList<>();
   5947 
   5948         // Remove all processes this package may have touched: all with the
   5949         // same UID (except for the system or root user), and all whose name
   5950         // matches the package name.
   5951         final int NP = mProcessNames.getMap().size();
   5952         for (int ip=0; ip<NP; ip++) {
   5953             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   5954             final int NA = apps.size();
   5955             for (int ia=0; ia<NA; ia++) {
   5956                 ProcessRecord app = apps.valueAt(ia);
   5957                 if (app.persistent && !evenPersistent) {
   5958                     // we don't kill persistent processes
   5959                     continue;
   5960                 }
   5961                 if (app.removed) {
   5962                     if (doit) {
   5963                         procs.add(app);
   5964                     }
   5965                     continue;
   5966                 }
   5967 
   5968                 // Skip process if it doesn't meet our oom adj requirement.
   5969                 if (app.setAdj < minOomAdj) {
   5970                     continue;
   5971                 }
   5972 
   5973                 // If no package is specified, we call all processes under the
   5974                 // give user id.
   5975                 if (packageName == null) {
   5976                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
   5977                         continue;
   5978                     }
   5979                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
   5980                         continue;
   5981                     }
   5982                 // Package has been specified, we want to hit all processes
   5983                 // that match it.  We need to qualify this by the processes
   5984                 // that are running under the specified app and user ID.
   5985                 } else {
   5986                     final boolean isDep = app.pkgDeps != null
   5987                             && app.pkgDeps.contains(packageName);
   5988                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
   5989                         continue;
   5990                     }
   5991                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
   5992                         continue;
   5993                     }
   5994                     if (!app.pkgList.containsKey(packageName) && !isDep) {
   5995                         continue;
   5996                     }
   5997                 }
   5998 
   5999                 // Process has passed all conditions, kill it!
   6000                 if (!doit) {
   6001                     return true;
   6002                 }
   6003                 app.removed = true;
   6004                 procs.add(app);
   6005             }
   6006         }
   6007 
   6008         int N = procs.size();
   6009         for (int i=0; i<N; i++) {
   6010             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
   6011         }
   6012         updateOomAdjLocked();
   6013         return N > 0;
   6014     }
   6015 
   6016     private void cleanupDisabledPackageComponentsLocked(
   6017             String packageName, int userId, boolean killProcess, String[] changedClasses) {
   6018 
   6019         Set<String> disabledClasses = null;
   6020         boolean packageDisabled = false;
   6021         IPackageManager pm = AppGlobals.getPackageManager();
   6022 
   6023         if (changedClasses == null) {
   6024             // Nothing changed...
   6025             return;
   6026         }
   6027 
   6028         // Determine enable/disable state of the package and its components.
   6029         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
   6030         for (int i = changedClasses.length - 1; i >= 0; i--) {
   6031             final String changedClass = changedClasses[i];
   6032 
   6033             if (changedClass.equals(packageName)) {
   6034                 try {
   6035                     // Entire package setting changed
   6036                     enabled = pm.getApplicationEnabledSetting(packageName,
   6037                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
   6038                 } catch (Exception e) {
   6039                     // No such package/component; probably racing with uninstall.  In any
   6040                     // event it means we have nothing further to do here.
   6041                     return;
   6042                 }
   6043                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
   6044                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
   6045                 if (packageDisabled) {
   6046                     // Entire package is disabled.
   6047                     // No need to continue to check component states.
   6048                     disabledClasses = null;
   6049                     break;
   6050                 }
   6051             } else {
   6052                 try {
   6053                     enabled = pm.getComponentEnabledSetting(
   6054                             new ComponentName(packageName, changedClass),
   6055                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
   6056                 } catch (Exception e) {
   6057                     // As above, probably racing with uninstall.
   6058                     return;
   6059                 }
   6060                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
   6061                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
   6062                     if (disabledClasses == null) {
   6063                         disabledClasses = new ArraySet<>(changedClasses.length);
   6064                     }
   6065                     disabledClasses.add(changedClass);
   6066                 }
   6067             }
   6068         }
   6069 
   6070         if (!packageDisabled && disabledClasses == null) {
   6071             // Nothing to do here...
   6072             return;
   6073         }
   6074 
   6075         // Clean-up disabled activities.
   6076         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
   6077                 packageName, disabledClasses, true, false, userId) && mBooted) {
   6078             mStackSupervisor.resumeFocusedStackTopActivityLocked();
   6079             mStackSupervisor.scheduleIdleLocked();
   6080         }
   6081 
   6082         // Clean-up disabled tasks
   6083         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
   6084 
   6085         // Clean-up disabled services.
   6086         mServices.bringDownDisabledPackageServicesLocked(
   6087                 packageName, disabledClasses, userId, false, killProcess, true);
   6088 
   6089         // Clean-up disabled providers.
   6090         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
   6091         mProviderMap.collectPackageProvidersLocked(
   6092                 packageName, disabledClasses, true, false, userId, providers);
   6093         for (int i = providers.size() - 1; i >= 0; i--) {
   6094             removeDyingProviderLocked(null, providers.get(i), true);
   6095         }
   6096 
   6097         // Clean-up disabled broadcast receivers.
   6098         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
   6099             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
   6100                     packageName, disabledClasses, userId, true);
   6101         }
   6102 
   6103     }
   6104 
   6105     final boolean clearBroadcastQueueForUserLocked(int userId) {
   6106         boolean didSomething = false;
   6107         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
   6108             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
   6109                     null, null, userId, true);
   6110         }
   6111         return didSomething;
   6112     }
   6113 
   6114     final boolean forceStopPackageLocked(String packageName, int appId,
   6115             boolean callerWillRestart, boolean purgeCache, boolean doit,
   6116             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
   6117         int i;
   6118 
   6119         if (userId == UserHandle.USER_ALL && packageName == null) {
   6120             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
   6121         }
   6122 
   6123         if (appId < 0 && packageName != null) {
   6124             try {
   6125                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
   6126                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
   6127             } catch (RemoteException e) {
   6128             }
   6129         }
   6130 
   6131         if (doit) {
   6132             if (packageName != null) {
   6133                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
   6134                         + " user=" + userId + ": " + reason);
   6135             } else {
   6136                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
   6137             }
   6138 
   6139             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
   6140         }
   6141 
   6142         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
   6143                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
   6144                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
   6145 
   6146         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
   6147                 packageName, null, doit, evenPersistent, userId)) {
   6148             if (!doit) {
   6149                 return true;
   6150             }
   6151             didSomething = true;
   6152         }
   6153 
   6154         if (mServices.bringDownDisabledPackageServicesLocked(
   6155                 packageName, null, userId, evenPersistent, true, doit)) {
   6156             if (!doit) {
   6157                 return true;
   6158             }
   6159             didSomething = true;
   6160         }
   6161 
   6162         if (packageName == null) {
   6163             // Remove all sticky broadcasts from this user.
   6164             mStickyBroadcasts.remove(userId);
   6165         }
   6166 
   6167         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
   6168         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
   6169                 userId, providers)) {
   6170             if (!doit) {
   6171                 return true;
   6172             }
   6173             didSomething = true;
   6174         }
   6175         for (i = providers.size() - 1; i >= 0; i--) {
   6176             removeDyingProviderLocked(null, providers.get(i), true);
   6177         }
   6178 
   6179         // Remove transient permissions granted from/to this package/user
   6180         removeUriPermissionsForPackageLocked(packageName, userId, false);
   6181 
   6182         if (doit) {
   6183             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
   6184                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
   6185                         packageName, null, userId, doit);
   6186             }
   6187         }
   6188 
   6189         if (packageName == null || uninstalling) {
   6190             // Remove pending intents.  For now we only do this when force
   6191             // stopping users, because we have some problems when doing this
   6192             // for packages -- app widgets are not currently cleaned up for
   6193             // such packages, so they can be left with bad pending intents.
   6194             if (mIntentSenderRecords.size() > 0) {
   6195                 Iterator<WeakReference<PendingIntentRecord>> it
   6196                         = mIntentSenderRecords.values().iterator();
   6197                 while (it.hasNext()) {
   6198                     WeakReference<PendingIntentRecord> wpir = it.next();
   6199                     if (wpir == null) {
   6200                         it.remove();
   6201                         continue;
   6202                     }
   6203                     PendingIntentRecord pir = wpir.get();
   6204                     if (pir == null) {
   6205                         it.remove();
   6206                         continue;
   6207                     }
   6208                     if (packageName == null) {
   6209                         // Stopping user, remove all objects for the user.
   6210                         if (pir.key.userId != userId) {
   6211                             // Not the same user, skip it.
   6212                             continue;
   6213                         }
   6214                     } else {
   6215                         if (UserHandle.getAppId(pir.uid) != appId) {
   6216                             // Different app id, skip it.
   6217                             continue;
   6218                         }
   6219                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
   6220                             // Different user, skip it.
   6221                             continue;
   6222                         }
   6223                         if (!pir.key.packageName.equals(packageName)) {
   6224                             // Different package, skip it.
   6225                             continue;
   6226                         }
   6227                     }
   6228                     if (!doit) {
   6229                         return true;
   6230                     }
   6231                     didSomething = true;
   6232                     it.remove();
   6233                     pir.canceled = true;
   6234                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
   6235                         pir.key.activity.pendingResults.remove(pir.ref);
   6236                     }
   6237                 }
   6238             }
   6239         }
   6240 
   6241         if (doit) {
   6242             if (purgeCache && packageName != null) {
   6243                 AttributeCache ac = AttributeCache.instance();
   6244                 if (ac != null) {
   6245                     ac.removePackage(packageName);
   6246                 }
   6247             }
   6248             if (mBooted) {
   6249                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
   6250                 mStackSupervisor.scheduleIdleLocked();
   6251             }
   6252         }
   6253 
   6254         return didSomething;
   6255     }
   6256 
   6257     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
   6258         ProcessRecord old = mProcessNames.remove(name, uid);
   6259         if (old != null) {
   6260             old.uidRecord.numProcs--;
   6261             if (old.uidRecord.numProcs == 0) {
   6262                 // No more processes using this uid, tell clients it is gone.
   6263                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   6264                         "No more processes in " + old.uidRecord);
   6265                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
   6266                 mActiveUids.remove(uid);
   6267                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
   6268             }
   6269             old.uidRecord = null;
   6270         }
   6271         mIsolatedProcesses.remove(uid);
   6272         return old;
   6273     }
   6274 
   6275     private final void addProcessNameLocked(ProcessRecord proc) {
   6276         // We shouldn't already have a process under this name, but just in case we
   6277         // need to clean up whatever may be there now.
   6278         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
   6279         if (old == proc && proc.persistent) {
   6280             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
   6281             Slog.w(TAG, "Re-adding persistent process " + proc);
   6282         } else if (old != null) {
   6283             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
   6284         }
   6285         UidRecord uidRec = mActiveUids.get(proc.uid);
   6286         if (uidRec == null) {
   6287             uidRec = new UidRecord(proc.uid);
   6288             // This is the first appearance of the uid, report it now!
   6289             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   6290                     "Creating new process uid: " + uidRec);
   6291             mActiveUids.put(proc.uid, uidRec);
   6292             noteUidProcessState(uidRec.uid, uidRec.curProcState);
   6293             enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
   6294         }
   6295         proc.uidRecord = uidRec;
   6296 
   6297         // Reset render thread tid if it was already set, so new process can set it again.
   6298         proc.renderThreadTid = 0;
   6299         uidRec.numProcs++;
   6300         mProcessNames.put(proc.processName, proc.uid, proc);
   6301         if (proc.isolated) {
   6302             mIsolatedProcesses.put(proc.uid, proc);
   6303         }
   6304     }
   6305 
   6306     boolean removeProcessLocked(ProcessRecord app,
   6307             boolean callerWillRestart, boolean allowRestart, String reason) {
   6308         final String name = app.processName;
   6309         final int uid = app.uid;
   6310         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
   6311             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
   6312 
   6313         ProcessRecord old = mProcessNames.get(name, uid);
   6314         if (old != app) {
   6315             // This process is no longer active, so nothing to do.
   6316             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
   6317             return false;
   6318         }
   6319         removeProcessNameLocked(name, uid);
   6320         if (mHeavyWeightProcess == app) {
   6321             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   6322                     mHeavyWeightProcess.userId, 0));
   6323             mHeavyWeightProcess = null;
   6324         }
   6325         boolean needRestart = false;
   6326         if (app.pid > 0 && app.pid != MY_PID) {
   6327             int pid = app.pid;
   6328             synchronized (mPidsSelfLocked) {
   6329                 mPidsSelfLocked.remove(pid);
   6330                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   6331             }
   6332             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   6333             if (app.isolated) {
   6334                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   6335             }
   6336             boolean willRestart = false;
   6337             if (app.persistent && !app.isolated) {
   6338                 if (!callerWillRestart) {
   6339                     willRestart = true;
   6340                 } else {
   6341                     needRestart = true;
   6342                 }
   6343             }
   6344             app.kill(reason, true);
   6345             handleAppDiedLocked(app, willRestart, allowRestart);
   6346             if (willRestart) {
   6347                 removeLruProcessLocked(app);
   6348                 addAppLocked(app.info, false, null /* ABI override */);
   6349             }
   6350         } else {
   6351             mRemovedProcesses.add(app);
   6352         }
   6353 
   6354         return needRestart;
   6355     }
   6356 
   6357     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
   6358         cleanupAppInLaunchingProvidersLocked(app, true);
   6359         removeProcessLocked(app, false, true, "timeout publishing content providers");
   6360     }
   6361 
   6362     private final void processStartTimedOutLocked(ProcessRecord app) {
   6363         final int pid = app.pid;
   6364         boolean gone = false;
   6365         synchronized (mPidsSelfLocked) {
   6366             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
   6367             if (knownApp != null && knownApp.thread == null) {
   6368                 mPidsSelfLocked.remove(pid);
   6369                 gone = true;
   6370             }
   6371         }
   6372 
   6373         if (gone) {
   6374             Slog.w(TAG, "Process " + app + " failed to attach");
   6375             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
   6376                     pid, app.uid, app.processName);
   6377             removeProcessNameLocked(app.processName, app.uid);
   6378             if (mHeavyWeightProcess == app) {
   6379                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   6380                         mHeavyWeightProcess.userId, 0));
   6381                 mHeavyWeightProcess = null;
   6382             }
   6383             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   6384             if (app.isolated) {
   6385                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   6386             }
   6387             // Take care of any launching providers waiting for this process.
   6388             cleanupAppInLaunchingProvidersLocked(app, true);
   6389             // Take care of any services that are waiting for the process.
   6390             mServices.processStartTimedOutLocked(app);
   6391             app.kill("start timeout", true);
   6392             removeLruProcessLocked(app);
   6393             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
   6394                 Slog.w(TAG, "Unattached app died before backup, skipping");
   6395                 try {
   6396                     IBackupManager bm = IBackupManager.Stub.asInterface(
   6397                             ServiceManager.getService(Context.BACKUP_SERVICE));
   6398                     bm.agentDisconnected(app.info.packageName);
   6399                 } catch (RemoteException e) {
   6400                     // Can't happen; the backup manager is local
   6401                 }
   6402             }
   6403             if (isPendingBroadcastProcessLocked(pid)) {
   6404                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   6405                 skipPendingBroadcastLocked(pid);
   6406             }
   6407         } else {
   6408             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
   6409         }
   6410     }
   6411 
   6412     private final boolean attachApplicationLocked(IApplicationThread thread,
   6413             int pid) {
   6414 
   6415         // Find the application record that is being attached...  either via
   6416         // the pid if we are running in multiple processes, or just pull the
   6417         // next app record if we are emulating process with anonymous threads.
   6418         ProcessRecord app;
   6419         if (pid != MY_PID && pid >= 0) {
   6420             synchronized (mPidsSelfLocked) {
   6421                 app = mPidsSelfLocked.get(pid);
   6422             }
   6423         } else {
   6424             app = null;
   6425         }
   6426 
   6427         if (app == null) {
   6428             Slog.w(TAG, "No pending application record for pid " + pid
   6429                     + " (IApplicationThread " + thread + "); dropping process");
   6430             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
   6431             if (pid > 0 && pid != MY_PID) {
   6432                 Process.killProcessQuiet(pid);
   6433                 //TODO: killProcessGroup(app.info.uid, pid);
   6434             } else {
   6435                 try {
   6436                     thread.scheduleExit();
   6437                 } catch (Exception e) {
   6438                     // Ignore exceptions.
   6439                 }
   6440             }
   6441             return false;
   6442         }
   6443 
   6444         // If this application record is still attached to a previous
   6445         // process, clean it up now.
   6446         if (app.thread != null) {
   6447             handleAppDiedLocked(app, true, true);
   6448         }
   6449 
   6450         // Tell the process all about itself.
   6451 
   6452         if (DEBUG_ALL) Slog.v(
   6453                 TAG, "Binding process pid " + pid + " to record " + app);
   6454 
   6455         final String processName = app.processName;
   6456         try {
   6457             AppDeathRecipient adr = new AppDeathRecipient(
   6458                     app, pid, thread);
   6459             thread.asBinder().linkToDeath(adr, 0);
   6460             app.deathRecipient = adr;
   6461         } catch (RemoteException e) {
   6462             app.resetPackageList(mProcessStats);
   6463             startProcessLocked(app, "link fail", processName);
   6464             return false;
   6465         }
   6466 
   6467         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
   6468 
   6469         app.makeActive(thread, mProcessStats);
   6470         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
   6471         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   6472         app.forcingToForeground = null;
   6473         updateProcessForegroundLocked(app, false, false);
   6474         app.hasShownUi = false;
   6475         app.debugging = false;
   6476         app.cached = false;
   6477         app.killedByAm = false;
   6478 
   6479         // We carefully use the same state that PackageManager uses for
   6480         // filtering, since we use this flag to decide if we need to install
   6481         // providers when user is unlocked later
   6482         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
   6483 
   6484         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   6485 
   6486         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
   6487         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
   6488 
   6489         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
   6490             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
   6491             msg.obj = app;
   6492             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
   6493         }
   6494 
   6495         if (!normalMode) {
   6496             Slog.i(TAG, "Launching preboot mode app: " + app);
   6497         }
   6498 
   6499         if (DEBUG_ALL) Slog.v(
   6500             TAG, "New app record " + app
   6501             + " thread=" + thread.asBinder() + " pid=" + pid);
   6502         try {
   6503             int testMode = IApplicationThread.DEBUG_OFF;
   6504             if (mDebugApp != null && mDebugApp.equals(processName)) {
   6505                 testMode = mWaitForDebugger
   6506                     ? IApplicationThread.DEBUG_WAIT
   6507                     : IApplicationThread.DEBUG_ON;
   6508                 app.debugging = true;
   6509                 if (mDebugTransient) {
   6510                     mDebugApp = mOrigDebugApp;
   6511                     mWaitForDebugger = mOrigWaitForDebugger;
   6512                 }
   6513             }
   6514             String profileFile = app.instrumentationProfileFile;
   6515             ParcelFileDescriptor profileFd = null;
   6516             int samplingInterval = 0;
   6517             boolean profileAutoStop = false;
   6518             if (mProfileApp != null && mProfileApp.equals(processName)) {
   6519                 mProfileProc = app;
   6520                 profileFile = mProfileFile;
   6521                 profileFd = mProfileFd;
   6522                 samplingInterval = mSamplingInterval;
   6523                 profileAutoStop = mAutoStopProfiler;
   6524             }
   6525             boolean enableTrackAllocation = false;
   6526             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
   6527                 enableTrackAllocation = true;
   6528                 mTrackAllocationApp = null;
   6529             }
   6530 
   6531             // If the app is being launched for restore or full backup, set it up specially
   6532             boolean isRestrictedBackupMode = false;
   6533             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
   6534                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
   6535                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
   6536                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
   6537                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
   6538             }
   6539 
   6540             if (app.instrumentationClass != null) {
   6541                 notifyPackageUse(app.instrumentationClass.getPackageName(),
   6542                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
   6543             }
   6544             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
   6545                     + processName + " with config " + mConfiguration);
   6546             ApplicationInfo appInfo = app.instrumentationInfo != null
   6547                     ? app.instrumentationInfo : app.info;
   6548             app.compat = compatibilityInfoForPackageLocked(appInfo);
   6549             if (profileFd != null) {
   6550                 profileFd = profileFd.dup();
   6551             }
   6552             ProfilerInfo profilerInfo = profileFile == null ? null
   6553                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
   6554             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
   6555                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
   6556                     app.instrumentationUiAutomationConnection, testMode,
   6557                     mBinderTransactionTrackingEnabled, enableTrackAllocation,
   6558                     isRestrictedBackupMode || !normalMode, app.persistent,
   6559                     new Configuration(mConfiguration), app.compat,
   6560                     getCommonServicesLocked(app.isolated),
   6561                     mCoreSettingsObserver.getCoreSettingsLocked());
   6562             updateLruProcessLocked(app, false, null);
   6563             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
   6564         } catch (Exception e) {
   6565             // todo: Yikes!  What should we do?  For now we will try to
   6566             // start another process, but that could easily get us in
   6567             // an infinite loop of restarting processes...
   6568             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
   6569 
   6570             app.resetPackageList(mProcessStats);
   6571             app.unlinkDeathRecipient();
   6572             startProcessLocked(app, "bind fail", processName);
   6573             return false;
   6574         }
   6575 
   6576         // Remove this record from the list of starting applications.
   6577         mPersistentStartingProcesses.remove(app);
   6578         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
   6579                 "Attach application locked removing on hold: " + app);
   6580         mProcessesOnHold.remove(app);
   6581 
   6582         boolean badApp = false;
   6583         boolean didSomething = false;
   6584 
   6585         // See if the top visible activity is waiting to run in this process...
   6586         if (normalMode) {
   6587             try {
   6588                 if (mStackSupervisor.attachApplicationLocked(app)) {
   6589                     didSomething = true;
   6590                 }
   6591             } catch (Exception e) {
   6592                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
   6593                 badApp = true;
   6594             }
   6595         }
   6596 
   6597         // Find any services that should be running in this process...
   6598         if (!badApp) {
   6599             try {
   6600                 didSomething |= mServices.attachApplicationLocked(app, processName);
   6601             } catch (Exception e) {
   6602                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
   6603                 badApp = true;
   6604             }
   6605         }
   6606 
   6607         // Check if a next-broadcast receiver is in this process...
   6608         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
   6609             try {
   6610                 didSomething |= sendPendingBroadcastsLocked(app);
   6611             } catch (Exception e) {
   6612                 // If the app died trying to launch the receiver we declare it 'bad'
   6613                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
   6614                 badApp = true;
   6615             }
   6616         }
   6617 
   6618         // Check whether the next backup agent is in this process...
   6619         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
   6620             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
   6621                     "New app is backup target, launching agent for " + app);
   6622             notifyPackageUse(mBackupTarget.appInfo.packageName,
   6623                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
   6624             try {
   6625                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
   6626                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
   6627                         mBackupTarget.backupMode);
   6628             } catch (Exception e) {
   6629                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
   6630                 badApp = true;
   6631             }
   6632         }
   6633 
   6634         if (badApp) {
   6635             app.kill("error during init", true);
   6636             handleAppDiedLocked(app, false, true);
   6637             return false;
   6638         }
   6639 
   6640         if (!didSomething) {
   6641             updateOomAdjLocked();
   6642         }
   6643 
   6644         return true;
   6645     }
   6646 
   6647     @Override
   6648     public final void attachApplication(IApplicationThread thread) {
   6649         synchronized (this) {
   6650             int callingPid = Binder.getCallingPid();
   6651             final long origId = Binder.clearCallingIdentity();
   6652             attachApplicationLocked(thread, callingPid);
   6653             Binder.restoreCallingIdentity(origId);
   6654         }
   6655     }
   6656 
   6657     @Override
   6658     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
   6659         final long origId = Binder.clearCallingIdentity();
   6660         synchronized (this) {
   6661             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6662             if (stack != null) {
   6663                 ActivityRecord r =
   6664                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
   6665                 if (stopProfiling) {
   6666                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
   6667                         try {
   6668                             mProfileFd.close();
   6669                         } catch (IOException e) {
   6670                         }
   6671                         clearProfilerLocked();
   6672                     }
   6673                 }
   6674             }
   6675         }
   6676         Binder.restoreCallingIdentity(origId);
   6677     }
   6678 
   6679     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
   6680         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
   6681                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
   6682     }
   6683 
   6684     void enableScreenAfterBoot() {
   6685         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
   6686                 SystemClock.uptimeMillis());
   6687         mWindowManager.enableScreenAfterBoot();
   6688 
   6689         synchronized (this) {
   6690             updateEventDispatchingLocked();
   6691         }
   6692     }
   6693 
   6694     @Override
   6695     public void showBootMessage(final CharSequence msg, final boolean always) {
   6696         if (Binder.getCallingUid() != Process.myUid()) {
   6697             throw new SecurityException();
   6698         }
   6699         mWindowManager.showBootMessage(msg, always);
   6700     }
   6701 
   6702     @Override
   6703     public void keyguardWaitingForActivityDrawn() {
   6704         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
   6705         final long token = Binder.clearCallingIdentity();
   6706         try {
   6707             synchronized (this) {
   6708                 if (DEBUG_LOCKSCREEN) logLockScreen("");
   6709                 mWindowManager.keyguardWaitingForActivityDrawn();
   6710                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
   6711                     mLockScreenShown = LOCK_SCREEN_LEAVING;
   6712                     updateSleepIfNeededLocked();
   6713                 }
   6714             }
   6715         } finally {
   6716             Binder.restoreCallingIdentity(token);
   6717         }
   6718     }
   6719 
   6720     @Override
   6721     public void keyguardGoingAway(int flags) {
   6722         enforceNotIsolatedCaller("keyguardGoingAway");
   6723         final long token = Binder.clearCallingIdentity();
   6724         try {
   6725             synchronized (this) {
   6726                 if (DEBUG_LOCKSCREEN) logLockScreen("");
   6727                 mWindowManager.keyguardGoingAway(flags);
   6728                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
   6729                     mLockScreenShown = LOCK_SCREEN_HIDDEN;
   6730                     updateSleepIfNeededLocked();
   6731 
   6732                     // Some stack visibility might change (e.g. docked stack)
   6733                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   6734                     applyVrModeIfNeededLocked(mFocusedActivity, true);
   6735                 }
   6736             }
   6737         } finally {
   6738             Binder.restoreCallingIdentity(token);
   6739         }
   6740     }
   6741 
   6742     final void finishBooting() {
   6743         synchronized (this) {
   6744             if (!mBootAnimationComplete) {
   6745                 mCallFinishBooting = true;
   6746                 return;
   6747             }
   6748             mCallFinishBooting = false;
   6749         }
   6750 
   6751         ArraySet<String> completedIsas = new ArraySet<String>();
   6752         for (String abi : Build.SUPPORTED_ABIS) {
   6753             Process.establishZygoteConnectionForAbi(abi);
   6754             final String instructionSet = VMRuntime.getInstructionSet(abi);
   6755             if (!completedIsas.contains(instructionSet)) {
   6756                 try {
   6757                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
   6758                 } catch (InstallerException e) {
   6759                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
   6760                             e.getMessage() +")");
   6761                 }
   6762                 completedIsas.add(instructionSet);
   6763             }
   6764         }
   6765 
   6766         IntentFilter pkgFilter = new IntentFilter();
   6767         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
   6768         pkgFilter.addDataScheme("package");
   6769         mContext.registerReceiver(new BroadcastReceiver() {
   6770             @Override
   6771             public void onReceive(Context context, Intent intent) {
   6772                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
   6773                 if (pkgs != null) {
   6774                     for (String pkg : pkgs) {
   6775                         synchronized (ActivityManagerService.this) {
   6776                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
   6777                                     0, "query restart")) {
   6778                                 setResultCode(Activity.RESULT_OK);
   6779                                 return;
   6780                             }
   6781                         }
   6782                     }
   6783                 }
   6784             }
   6785         }, pkgFilter);
   6786 
   6787         IntentFilter dumpheapFilter = new IntentFilter();
   6788         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
   6789         mContext.registerReceiver(new BroadcastReceiver() {
   6790             @Override
   6791             public void onReceive(Context context, Intent intent) {
   6792                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
   6793                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
   6794                 } else {
   6795                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
   6796                 }
   6797             }
   6798         }, dumpheapFilter);
   6799 
   6800         // Let system services know.
   6801         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
   6802 
   6803         synchronized (this) {
   6804             // Ensure that any processes we had put on hold are now started
   6805             // up.
   6806             final int NP = mProcessesOnHold.size();
   6807             if (NP > 0) {
   6808                 ArrayList<ProcessRecord> procs =
   6809                     new ArrayList<ProcessRecord>(mProcessesOnHold);
   6810                 for (int ip=0; ip<NP; ip++) {
   6811                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
   6812                             + procs.get(ip));
   6813                     startProcessLocked(procs.get(ip), "on-hold", null);
   6814                 }
   6815             }
   6816 
   6817             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   6818                 // Start looking for apps that are abusing wake locks.
   6819                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   6820                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   6821                 // Tell anyone interested that we are done booting!
   6822                 SystemProperties.set("sys.boot_completed", "1");
   6823 
   6824                 // And trigger dev.bootcomplete if we are not showing encryption progress
   6825                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
   6826                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
   6827                     SystemProperties.set("dev.bootcomplete", "1");
   6828                 }
   6829                 mUserController.sendBootCompletedLocked(
   6830                         new IIntentReceiver.Stub() {
   6831                             @Override
   6832                             public void performReceive(Intent intent, int resultCode,
   6833                                     String data, Bundle extras, boolean ordered,
   6834                                     boolean sticky, int sendingUser) {
   6835                                 synchronized (ActivityManagerService.this) {
   6836                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
   6837                                             true, false);
   6838                                 }
   6839                             }
   6840                         });
   6841                 scheduleStartProfilesLocked();
   6842             }
   6843         }
   6844     }
   6845 
   6846     @Override
   6847     public void bootAnimationComplete() {
   6848         final boolean callFinishBooting;
   6849         synchronized (this) {
   6850             callFinishBooting = mCallFinishBooting;
   6851             mBootAnimationComplete = true;
   6852         }
   6853         if (callFinishBooting) {
   6854             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
   6855             finishBooting();
   6856             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   6857         }
   6858     }
   6859 
   6860     final void ensureBootCompleted() {
   6861         boolean booting;
   6862         boolean enableScreen;
   6863         synchronized (this) {
   6864             booting = mBooting;
   6865             mBooting = false;
   6866             enableScreen = !mBooted;
   6867             mBooted = true;
   6868         }
   6869 
   6870         if (booting) {
   6871             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
   6872             finishBooting();
   6873             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   6874         }
   6875 
   6876         if (enableScreen) {
   6877             enableScreenAfterBoot();
   6878         }
   6879     }
   6880 
   6881     @Override
   6882     public final void activityResumed(IBinder token) {
   6883         final long origId = Binder.clearCallingIdentity();
   6884         synchronized(this) {
   6885             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6886             if (stack != null) {
   6887                 stack.activityResumedLocked(token);
   6888             }
   6889         }
   6890         Binder.restoreCallingIdentity(origId);
   6891     }
   6892 
   6893     @Override
   6894     public final void activityPaused(IBinder token) {
   6895         final long origId = Binder.clearCallingIdentity();
   6896         synchronized(this) {
   6897             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6898             if (stack != null) {
   6899                 stack.activityPausedLocked(token, false);
   6900             }
   6901         }
   6902         Binder.restoreCallingIdentity(origId);
   6903     }
   6904 
   6905     @Override
   6906     public final void activityStopped(IBinder token, Bundle icicle,
   6907             PersistableBundle persistentState, CharSequence description) {
   6908         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
   6909 
   6910         // Refuse possible leaked file descriptors
   6911         if (icicle != null && icicle.hasFileDescriptors()) {
   6912             throw new IllegalArgumentException("File descriptors passed in Bundle");
   6913         }
   6914 
   6915         final long origId = Binder.clearCallingIdentity();
   6916 
   6917         synchronized (this) {
   6918             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   6919             if (r != null) {
   6920                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
   6921             }
   6922         }
   6923 
   6924         trimApplications();
   6925 
   6926         Binder.restoreCallingIdentity(origId);
   6927     }
   6928 
   6929     @Override
   6930     public final void activityDestroyed(IBinder token) {
   6931         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
   6932         synchronized (this) {
   6933             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6934             if (stack != null) {
   6935                 stack.activityDestroyedLocked(token, "activityDestroyed");
   6936             }
   6937         }
   6938     }
   6939 
   6940     @Override
   6941     public final void activityRelaunched(IBinder token) {
   6942         final long origId = Binder.clearCallingIdentity();
   6943         synchronized (this) {
   6944             mStackSupervisor.activityRelaunchedLocked(token);
   6945         }
   6946         Binder.restoreCallingIdentity(origId);
   6947     }
   6948 
   6949     @Override
   6950     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
   6951             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
   6952         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
   6953                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
   6954         synchronized (this) {
   6955             ActivityRecord record = ActivityRecord.isInStackLocked(token);
   6956             if (record == null) {
   6957                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
   6958                         + "found for: " + token);
   6959             }
   6960             record.setSizeConfigurations(horizontalSizeConfiguration,
   6961                     verticalSizeConfigurations, smallestSizeConfigurations);
   6962         }
   6963     }
   6964 
   6965     @Override
   6966     public final void backgroundResourcesReleased(IBinder token) {
   6967         final long origId = Binder.clearCallingIdentity();
   6968         try {
   6969             synchronized (this) {
   6970                 ActivityStack stack = ActivityRecord.getStackLocked(token);
   6971                 if (stack != null) {
   6972                     stack.backgroundResourcesReleased();
   6973                 }
   6974             }
   6975         } finally {
   6976             Binder.restoreCallingIdentity(origId);
   6977         }
   6978     }
   6979 
   6980     @Override
   6981     public final void notifyLaunchTaskBehindComplete(IBinder token) {
   6982         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
   6983     }
   6984 
   6985     @Override
   6986     public final void notifyEnterAnimationComplete(IBinder token) {
   6987         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
   6988     }
   6989 
   6990     @Override
   6991     public String getCallingPackage(IBinder token) {
   6992         synchronized (this) {
   6993             ActivityRecord r = getCallingRecordLocked(token);
   6994             return r != null ? r.info.packageName : null;
   6995         }
   6996     }
   6997 
   6998     @Override
   6999     public ComponentName getCallingActivity(IBinder token) {
   7000         synchronized (this) {
   7001             ActivityRecord r = getCallingRecordLocked(token);
   7002             return r != null ? r.intent.getComponent() : null;
   7003         }
   7004     }
   7005 
   7006     private ActivityRecord getCallingRecordLocked(IBinder token) {
   7007         ActivityRecord r = ActivityRecord.isInStackLocked(token);
   7008         if (r == null) {
   7009             return null;
   7010         }
   7011         return r.resultTo;
   7012     }
   7013 
   7014     @Override
   7015     public ComponentName getActivityClassForToken(IBinder token) {
   7016         synchronized(this) {
   7017             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   7018             if (r == null) {
   7019                 return null;
   7020             }
   7021             return r.intent.getComponent();
   7022         }
   7023     }
   7024 
   7025     @Override
   7026     public String getPackageForToken(IBinder token) {
   7027         synchronized(this) {
   7028             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   7029             if (r == null) {
   7030                 return null;
   7031             }
   7032             return r.packageName;
   7033         }
   7034     }
   7035 
   7036     @Override
   7037     public boolean isRootVoiceInteraction(IBinder token) {
   7038         synchronized(this) {
   7039             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   7040             if (r == null) {
   7041                 return false;
   7042             }
   7043             return r.rootVoiceInteraction;
   7044         }
   7045     }
   7046 
   7047     @Override
   7048     public IIntentSender getIntentSender(int type,
   7049             String packageName, IBinder token, String resultWho,
   7050             int requestCode, Intent[] intents, String[] resolvedTypes,
   7051             int flags, Bundle bOptions, int userId) {
   7052         enforceNotIsolatedCaller("getIntentSender");
   7053         // Refuse possible leaked file descriptors
   7054         if (intents != null) {
   7055             if (intents.length < 1) {
   7056                 throw new IllegalArgumentException("Intents array length must be >= 1");
   7057             }
   7058             for (int i=0; i<intents.length; i++) {
   7059                 Intent intent = intents[i];
   7060                 if (intent != null) {
   7061                     if (intent.hasFileDescriptors()) {
   7062                         throw new IllegalArgumentException("File descriptors passed in Intent");
   7063                     }
   7064                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
   7065                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   7066                         throw new IllegalArgumentException(
   7067                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   7068                     }
   7069                     intents[i] = new Intent(intent);
   7070                 }
   7071             }
   7072             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
   7073                 throw new IllegalArgumentException(
   7074                         "Intent array length does not match resolvedTypes length");
   7075             }
   7076         }
   7077         if (bOptions != null) {
   7078             if (bOptions.hasFileDescriptors()) {
   7079                 throw new IllegalArgumentException("File descriptors passed in options");
   7080             }
   7081         }
   7082 
   7083         synchronized(this) {
   7084             int callingUid = Binder.getCallingUid();
   7085             int origUserId = userId;
   7086             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
   7087                     type == ActivityManager.INTENT_SENDER_BROADCAST,
   7088                     ALLOW_NON_FULL, "getIntentSender", null);
   7089             if (origUserId == UserHandle.USER_CURRENT) {
   7090                 // We don't want to evaluate this until the pending intent is
   7091                 // actually executed.  However, we do want to always do the
   7092                 // security checking for it above.
   7093                 userId = UserHandle.USER_CURRENT;
   7094             }
   7095             try {
   7096                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   7097                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
   7098                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
   7099                     if (!UserHandle.isSameApp(callingUid, uid)) {
   7100                         String msg = "Permission Denial: getIntentSender() from pid="
   7101                             + Binder.getCallingPid()
   7102                             + ", uid=" + Binder.getCallingUid()
   7103                             + ", (need uid=" + uid + ")"
   7104                             + " is not allowed to send as package " + packageName;
   7105                         Slog.w(TAG, msg);
   7106                         throw new SecurityException(msg);
   7107                     }
   7108                 }
   7109 
   7110                 return getIntentSenderLocked(type, packageName, callingUid, userId,
   7111                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
   7112 
   7113             } catch (RemoteException e) {
   7114                 throw new SecurityException(e);
   7115             }
   7116         }
   7117     }
   7118 
   7119     IIntentSender getIntentSenderLocked(int type, String packageName,
   7120             int callingUid, int userId, IBinder token, String resultWho,
   7121             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
   7122             Bundle bOptions) {
   7123         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
   7124         ActivityRecord activity = null;
   7125         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   7126             activity = ActivityRecord.isInStackLocked(token);
   7127             if (activity == null) {
   7128                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
   7129                 return null;
   7130             }
   7131             if (activity.finishing) {
   7132                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
   7133                 return null;
   7134             }
   7135         }
   7136 
   7137         // We're going to be splicing together extras before sending, so we're
   7138         // okay poking into any contained extras.
   7139         if (intents != null) {
   7140             for (int i = 0; i < intents.length; i++) {
   7141                 intents[i].setDefusable(true);
   7142             }
   7143         }
   7144         Bundle.setDefusable(bOptions, true);
   7145 
   7146         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
   7147         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
   7148         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
   7149         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
   7150                 |PendingIntent.FLAG_UPDATE_CURRENT);
   7151 
   7152         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
   7153                 type, packageName, activity, resultWho,
   7154                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
   7155         WeakReference<PendingIntentRecord> ref;
   7156         ref = mIntentSenderRecords.get(key);
   7157         PendingIntentRecord rec = ref != null ? ref.get() : null;
   7158         if (rec != null) {
   7159             if (!cancelCurrent) {
   7160                 if (updateCurrent) {
   7161                     if (rec.key.requestIntent != null) {
   7162                         rec.key.requestIntent.replaceExtras(intents != null ?
   7163                                 intents[intents.length - 1] : null);
   7164                     }
   7165                     if (intents != null) {
   7166                         intents[intents.length-1] = rec.key.requestIntent;
   7167                         rec.key.allIntents = intents;
   7168                         rec.key.allResolvedTypes = resolvedTypes;
   7169                     } else {
   7170                         rec.key.allIntents = null;
   7171                         rec.key.allResolvedTypes = null;
   7172                     }
   7173                 }
   7174                 return rec;
   7175             }
   7176             rec.canceled = true;
   7177             mIntentSenderRecords.remove(key);
   7178         }
   7179         if (noCreate) {
   7180             return rec;
   7181         }
   7182         rec = new PendingIntentRecord(this, key, callingUid);
   7183         mIntentSenderRecords.put(key, rec.ref);
   7184         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   7185             if (activity.pendingResults == null) {
   7186                 activity.pendingResults
   7187                         = new HashSet<WeakReference<PendingIntentRecord>>();
   7188             }
   7189             activity.pendingResults.add(rec.ref);
   7190         }
   7191         return rec;
   7192     }
   7193 
   7194     @Override
   7195     public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
   7196             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
   7197         if (target instanceof PendingIntentRecord) {
   7198             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
   7199                     finishedReceiver, requiredPermission, options);
   7200         } else {
   7201             if (intent == null) {
   7202                 // Weird case: someone has given us their own custom IIntentSender, and now
   7203                 // they have someone else trying to send to it but of course this isn't
   7204                 // really a PendingIntent, so there is no base Intent, and the caller isn't
   7205                 // supplying an Intent... but we never want to dispatch a null Intent to
   7206                 // a receiver, so um...  let's make something up.
   7207                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
   7208                 intent = new Intent(Intent.ACTION_MAIN);
   7209             }
   7210             try {
   7211                 target.send(code, intent, resolvedType, null, requiredPermission, options);
   7212             } catch (RemoteException e) {
   7213             }
   7214             // Platform code can rely on getting a result back when the send is done, but if
   7215             // this intent sender is from outside of the system we can't rely on it doing that.
   7216             // So instead we don't give it the result receiver, and instead just directly
   7217             // report the finish immediately.
   7218             if (finishedReceiver != null) {
   7219                 try {
   7220                     finishedReceiver.performReceive(intent, 0,
   7221                             null, null, false, false, UserHandle.getCallingUserId());
   7222                 } catch (RemoteException e) {
   7223                 }
   7224             }
   7225             return 0;
   7226         }
   7227     }
   7228 
   7229     /**
   7230      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
   7231      *
   7232      * <p>{@code callerUid} must be allowed to request such whitelist by calling
   7233      * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
   7234      */
   7235     void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
   7236         if (DEBUG_WHITELISTS) {
   7237             Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
   7238                     + targetUid + ", " + duration + ")");
   7239         }
   7240         synchronized (mPidsSelfLocked) {
   7241             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
   7242             if (pr == null) {
   7243                 Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
   7244                 return;
   7245             }
   7246             if (!pr.whitelistManager) {
   7247                 if (DEBUG_WHITELISTS) {
   7248                     Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
   7249                             + callerPid + " is not allowed");
   7250                 }
   7251                 return;
   7252             }
   7253         }
   7254 
   7255         final long token = Binder.clearCallingIdentity();
   7256         try {
   7257             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
   7258                     true, "pe from uid:" + callerUid);
   7259         } finally {
   7260             Binder.restoreCallingIdentity(token);
   7261         }
   7262     }
   7263 
   7264     @Override
   7265     public void cancelIntentSender(IIntentSender sender) {
   7266         if (!(sender instanceof PendingIntentRecord)) {
   7267             return;
   7268         }
   7269         synchronized(this) {
   7270             PendingIntentRecord rec = (PendingIntentRecord)sender;
   7271             try {
   7272                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
   7273                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
   7274                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
   7275                     String msg = "Permission Denial: cancelIntentSender() from pid="
   7276                         + Binder.getCallingPid()
   7277                         + ", uid=" + Binder.getCallingUid()
   7278                         + " is not allowed to cancel packges "
   7279                         + rec.key.packageName;
   7280                     Slog.w(TAG, msg);
   7281                     throw new SecurityException(msg);
   7282                 }
   7283             } catch (RemoteException e) {
   7284                 throw new SecurityException(e);
   7285             }
   7286             cancelIntentSenderLocked(rec, true);
   7287         }
   7288     }
   7289 
   7290     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
   7291         rec.canceled = true;
   7292         mIntentSenderRecords.remove(rec.key);
   7293         if (cleanActivity && rec.key.activity != null) {
   7294             rec.key.activity.pendingResults.remove(rec.ref);
   7295         }
   7296     }
   7297 
   7298     @Override
   7299     public String getPackageForIntentSender(IIntentSender pendingResult) {
   7300         if (!(pendingResult instanceof PendingIntentRecord)) {
   7301             return null;
   7302         }
   7303         try {
   7304             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   7305             return res.key.packageName;
   7306         } catch (ClassCastException e) {
   7307         }
   7308         return null;
   7309     }
   7310 
   7311     @Override
   7312     public int getUidForIntentSender(IIntentSender sender) {
   7313         if (sender instanceof PendingIntentRecord) {
   7314             try {
   7315                 PendingIntentRecord res = (PendingIntentRecord)sender;
   7316                 return res.uid;
   7317             } catch (ClassCastException e) {
   7318             }
   7319         }
   7320         return -1;
   7321     }
   7322 
   7323     @Override
   7324     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
   7325         if (!(pendingResult instanceof PendingIntentRecord)) {
   7326             return false;
   7327         }
   7328         try {
   7329             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   7330             if (res.key.allIntents == null) {
   7331                 return false;
   7332             }
   7333             for (int i=0; i<res.key.allIntents.length; i++) {
   7334                 Intent intent = res.key.allIntents[i];
   7335                 if (intent.getPackage() != null && intent.getComponent() != null) {
   7336                     return false;
   7337                 }
   7338             }
   7339             return true;
   7340         } catch (ClassCastException e) {
   7341         }
   7342         return false;
   7343     }
   7344 
   7345     @Override
   7346     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
   7347         if (!(pendingResult instanceof PendingIntentRecord)) {
   7348             return false;
   7349         }
   7350         try {
   7351             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   7352             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
   7353                 return true;
   7354             }
   7355             return false;
   7356         } catch (ClassCastException e) {
   7357         }
   7358         return false;
   7359     }
   7360 
   7361     @Override
   7362     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
   7363         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
   7364                 "getIntentForIntentSender()");
   7365         if (!(pendingResult instanceof PendingIntentRecord)) {
   7366             return null;
   7367         }
   7368         try {
   7369             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   7370             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
   7371         } catch (ClassCastException e) {
   7372         }
   7373         return null;
   7374     }
   7375 
   7376     @Override
   7377     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
   7378         if (!(pendingResult instanceof PendingIntentRecord)) {
   7379             return null;
   7380         }
   7381         try {
   7382             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   7383             synchronized (this) {
   7384                 return getTagForIntentSenderLocked(res, prefix);
   7385             }
   7386         } catch (ClassCastException e) {
   7387         }
   7388         return null;
   7389     }
   7390 
   7391     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
   7392         final Intent intent = res.key.requestIntent;
   7393         if (intent != null) {
   7394             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
   7395                     || res.lastTagPrefix.equals(prefix))) {
   7396                 return res.lastTag;
   7397             }
   7398             res.lastTagPrefix = prefix;
   7399             final StringBuilder sb = new StringBuilder(128);
   7400             if (prefix != null) {
   7401                 sb.append(prefix);
   7402             }
   7403             if (intent.getAction() != null) {
   7404                 sb.append(intent.getAction());
   7405             } else if (intent.getComponent() != null) {
   7406                 intent.getComponent().appendShortString(sb);
   7407             } else {
   7408                 sb.append("?");
   7409             }
   7410             return res.lastTag = sb.toString();
   7411         }
   7412         return null;
   7413     }
   7414 
   7415     @Override
   7416     public void setProcessLimit(int max) {
   7417         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   7418                 "setProcessLimit()");
   7419         synchronized (this) {
   7420             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
   7421             mProcessLimitOverride = max;
   7422         }
   7423         trimApplications();
   7424     }
   7425 
   7426     @Override
   7427     public int getProcessLimit() {
   7428         synchronized (this) {
   7429             return mProcessLimitOverride;
   7430         }
   7431     }
   7432 
   7433     void foregroundTokenDied(ForegroundToken token) {
   7434         synchronized (ActivityManagerService.this) {
   7435             synchronized (mPidsSelfLocked) {
   7436                 ForegroundToken cur
   7437                     = mForegroundProcesses.get(token.pid);
   7438                 if (cur != token) {
   7439                     return;
   7440                 }
   7441                 mForegroundProcesses.remove(token.pid);
   7442                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
   7443                 if (pr == null) {
   7444                     return;
   7445                 }
   7446                 pr.forcingToForeground = null;
   7447                 updateProcessForegroundLocked(pr, false, false);
   7448             }
   7449             updateOomAdjLocked();
   7450         }
   7451     }
   7452 
   7453     @Override
   7454     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
   7455         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   7456                 "setProcessForeground()");
   7457         synchronized(this) {
   7458             boolean changed = false;
   7459 
   7460             synchronized (mPidsSelfLocked) {
   7461                 ProcessRecord pr = mPidsSelfLocked.get(pid);
   7462                 if (pr == null && isForeground) {
   7463                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
   7464                     return;
   7465                 }
   7466                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
   7467                 if (oldToken != null) {
   7468                     oldToken.token.unlinkToDeath(oldToken, 0);
   7469                     mForegroundProcesses.remove(pid);
   7470                     if (pr != null) {
   7471                         pr.forcingToForeground = null;
   7472                     }
   7473                     changed = true;
   7474                 }
   7475                 if (isForeground && token != null) {
   7476                     ForegroundToken newToken = new ForegroundToken() {
   7477                         @Override
   7478                         public void binderDied() {
   7479                             foregroundTokenDied(this);
   7480                         }
   7481                     };
   7482                     newToken.pid = pid;
   7483                     newToken.token = token;
   7484                     try {
   7485                         token.linkToDeath(newToken, 0);
   7486                         mForegroundProcesses.put(pid, newToken);
   7487                         pr.forcingToForeground = token;
   7488                         changed = true;
   7489                     } catch (RemoteException e) {
   7490                         // If the process died while doing this, we will later
   7491                         // do the cleanup with the process death link.
   7492                     }
   7493                 }
   7494             }
   7495 
   7496             if (changed) {
   7497                 updateOomAdjLocked();
   7498             }
   7499         }
   7500     }
   7501 
   7502     @Override
   7503     public boolean isAppForeground(int uid) throws RemoteException {
   7504         synchronized (this) {
   7505             UidRecord uidRec = mActiveUids.get(uid);
   7506             if (uidRec == null || uidRec.idle) {
   7507                 return false;
   7508             }
   7509             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   7510         }
   7511     }
   7512 
   7513     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
   7514     // be guarded by permission checking.
   7515     int getUidState(int uid) {
   7516         synchronized (this) {
   7517             UidRecord uidRec = mActiveUids.get(uid);
   7518             return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
   7519         }
   7520     }
   7521 
   7522     @Override
   7523     public boolean isInMultiWindowMode(IBinder token) {
   7524         final long origId = Binder.clearCallingIdentity();
   7525         try {
   7526             synchronized(this) {
   7527                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   7528                 if (r == null) {
   7529                     return false;
   7530                 }
   7531                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
   7532                 return !r.task.mFullscreen;
   7533             }
   7534         } finally {
   7535             Binder.restoreCallingIdentity(origId);
   7536         }
   7537     }
   7538 
   7539     @Override
   7540     public boolean isInPictureInPictureMode(IBinder token) {
   7541         final long origId = Binder.clearCallingIdentity();
   7542         try {
   7543             synchronized(this) {
   7544                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
   7545                 if (stack == null) {
   7546                     return false;
   7547                 }
   7548                 return stack.mStackId == PINNED_STACK_ID;
   7549             }
   7550         } finally {
   7551             Binder.restoreCallingIdentity(origId);
   7552         }
   7553     }
   7554 
   7555     @Override
   7556     public void enterPictureInPictureMode(IBinder token) {
   7557         final long origId = Binder.clearCallingIdentity();
   7558         try {
   7559             synchronized(this) {
   7560                 if (!mSupportsPictureInPicture) {
   7561                     throw new IllegalStateException("enterPictureInPictureMode: "
   7562                             + "Device doesn't support picture-in-picture mode.");
   7563                 }
   7564 
   7565                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   7566 
   7567                 if (r == null) {
   7568                     throw new IllegalStateException("enterPictureInPictureMode: "
   7569                             + "Can't find activity for token=" + token);
   7570                 }
   7571 
   7572                 if (!r.supportsPictureInPicture()) {
   7573                     throw new IllegalArgumentException("enterPictureInPictureMode: "
   7574                             + "Picture-In-Picture not supported for r=" + r);
   7575                 }
   7576 
   7577                 // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
   7578                 // current bounds.
   7579                 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
   7580                 final Rect bounds = (pinnedStack != null)
   7581                         ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
   7582 
   7583                 mStackSupervisor.moveActivityToPinnedStackLocked(
   7584                         r, "enterPictureInPictureMode", bounds);
   7585             }
   7586         } finally {
   7587             Binder.restoreCallingIdentity(origId);
   7588         }
   7589     }
   7590 
   7591     // =========================================================
   7592     // PROCESS INFO
   7593     // =========================================================
   7594 
   7595     static class ProcessInfoService extends IProcessInfoService.Stub {
   7596         final ActivityManagerService mActivityManagerService;
   7597         ProcessInfoService(ActivityManagerService activityManagerService) {
   7598             mActivityManagerService = activityManagerService;
   7599         }
   7600 
   7601         @Override
   7602         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
   7603             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
   7604                     /*in*/ pids, /*out*/ states, null);
   7605         }
   7606 
   7607         @Override
   7608         public void getProcessStatesAndOomScoresFromPids(
   7609                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
   7610             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
   7611                     /*in*/ pids, /*out*/ states, /*out*/ scores);
   7612         }
   7613     }
   7614 
   7615     /**
   7616      * For each PID in the given input array, write the current process state
   7617      * for that process into the states array, or -1 to indicate that no
   7618      * process with the given PID exists. If scores array is provided, write
   7619      * the oom score for the process into the scores array, with INVALID_ADJ
   7620      * indicating the PID doesn't exist.
   7621      */
   7622     public void getProcessStatesAndOomScoresForPIDs(
   7623             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
   7624         if (scores != null) {
   7625             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
   7626                     "getProcessStatesAndOomScoresForPIDs()");
   7627         }
   7628 
   7629         if (pids == null) {
   7630             throw new NullPointerException("pids");
   7631         } else if (states == null) {
   7632             throw new NullPointerException("states");
   7633         } else if (pids.length != states.length) {
   7634             throw new IllegalArgumentException("pids and states arrays have different lengths!");
   7635         } else if (scores != null && pids.length != scores.length) {
   7636             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
   7637         }
   7638 
   7639         synchronized (mPidsSelfLocked) {
   7640             for (int i = 0; i < pids.length; i++) {
   7641                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
   7642                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
   7643                         pr.curProcState;
   7644                 if (scores != null) {
   7645                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
   7646                 }
   7647             }
   7648         }
   7649     }
   7650 
   7651     // =========================================================
   7652     // PERMISSIONS
   7653     // =========================================================
   7654 
   7655     static class PermissionController extends IPermissionController.Stub {
   7656         ActivityManagerService mActivityManagerService;
   7657         PermissionController(ActivityManagerService activityManagerService) {
   7658             mActivityManagerService = activityManagerService;
   7659         }
   7660 
   7661         @Override
   7662         public boolean checkPermission(String permission, int pid, int uid) {
   7663             return mActivityManagerService.checkPermission(permission, pid,
   7664                     uid) == PackageManager.PERMISSION_GRANTED;
   7665         }
   7666 
   7667         @Override
   7668         public String[] getPackagesForUid(int uid) {
   7669             return mActivityManagerService.mContext.getPackageManager()
   7670                     .getPackagesForUid(uid);
   7671         }
   7672 
   7673         @Override
   7674         public boolean isRuntimePermission(String permission) {
   7675             try {
   7676                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
   7677                         .getPermissionInfo(permission, 0);
   7678                 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
   7679             } catch (NameNotFoundException nnfe) {
   7680                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
   7681             }
   7682             return false;
   7683         }
   7684     }
   7685 
   7686     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
   7687         @Override
   7688         public int checkComponentPermission(String permission, int pid, int uid,
   7689                 int owningUid, boolean exported) {
   7690             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
   7691                     owningUid, exported);
   7692         }
   7693 
   7694         @Override
   7695         public Object getAMSLock() {
   7696             return ActivityManagerService.this;
   7697         }
   7698     }
   7699 
   7700     /**
   7701      * This can be called with or without the global lock held.
   7702      */
   7703     int checkComponentPermission(String permission, int pid, int uid,
   7704             int owningUid, boolean exported) {
   7705         if (pid == MY_PID) {
   7706             return PackageManager.PERMISSION_GRANTED;
   7707         }
   7708         return ActivityManager.checkComponentPermission(permission, uid,
   7709                 owningUid, exported);
   7710     }
   7711 
   7712     /**
   7713      * As the only public entry point for permissions checking, this method
   7714      * can enforce the semantic that requesting a check on a null global
   7715      * permission is automatically denied.  (Internally a null permission
   7716      * string is used when calling {@link #checkComponentPermission} in cases
   7717      * when only uid-based security is needed.)
   7718      *
   7719      * This can be called with or without the global lock held.
   7720      */
   7721     @Override
   7722     public int checkPermission(String permission, int pid, int uid) {
   7723         if (permission == null) {
   7724             return PackageManager.PERMISSION_DENIED;
   7725         }
   7726         return checkComponentPermission(permission, pid, uid, -1, true);
   7727     }
   7728 
   7729     @Override
   7730     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
   7731         if (permission == null) {
   7732             return PackageManager.PERMISSION_DENIED;
   7733         }
   7734 
   7735         // We might be performing an operation on behalf of an indirect binder
   7736         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
   7737         // client identity accordingly before proceeding.
   7738         Identity tlsIdentity = sCallerIdentity.get();
   7739         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
   7740             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
   7741                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
   7742             uid = tlsIdentity.uid;
   7743             pid = tlsIdentity.pid;
   7744         }
   7745 
   7746         return checkComponentPermission(permission, pid, uid, -1, true);
   7747     }
   7748 
   7749     /**
   7750      * Binder IPC calls go through the public entry point.
   7751      * This can be called with or without the global lock held.
   7752      */
   7753     int checkCallingPermission(String permission) {
   7754         return checkPermission(permission,
   7755                 Binder.getCallingPid(),
   7756                 UserHandle.getAppId(Binder.getCallingUid()));
   7757     }
   7758 
   7759     /**
   7760      * This can be called with or without the global lock held.
   7761      */
   7762     void enforceCallingPermission(String permission, String func) {
   7763         if (checkCallingPermission(permission)
   7764                 == PackageManager.PERMISSION_GRANTED) {
   7765             return;
   7766         }
   7767 
   7768         String msg = "Permission Denial: " + func + " from pid="
   7769                 + Binder.getCallingPid()
   7770                 + ", uid=" + Binder.getCallingUid()
   7771                 + " requires " + permission;
   7772         Slog.w(TAG, msg);
   7773         throw new SecurityException(msg);
   7774     }
   7775 
   7776     /**
   7777      * Determine if UID is holding permissions required to access {@link Uri} in
   7778      * the given {@link ProviderInfo}. Final permission checking is always done
   7779      * in {@link ContentProvider}.
   7780      */
   7781     private final boolean checkHoldingPermissionsLocked(
   7782             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
   7783         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   7784                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
   7785         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
   7786             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
   7787                     != PERMISSION_GRANTED) {
   7788                 return false;
   7789             }
   7790         }
   7791         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
   7792     }
   7793 
   7794     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
   7795             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
   7796         if (pi.applicationInfo.uid == uid) {
   7797             return true;
   7798         } else if (!pi.exported) {
   7799             return false;
   7800         }
   7801 
   7802         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
   7803         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
   7804         try {
   7805             // check if target holds top-level <provider> permissions
   7806             if (!readMet && pi.readPermission != null && considerUidPermissions
   7807                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
   7808                 readMet = true;
   7809             }
   7810             if (!writeMet && pi.writePermission != null && considerUidPermissions
   7811                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
   7812                 writeMet = true;
   7813             }
   7814 
   7815             // track if unprotected read/write is allowed; any denied
   7816             // <path-permission> below removes this ability
   7817             boolean allowDefaultRead = pi.readPermission == null;
   7818             boolean allowDefaultWrite = pi.writePermission == null;
   7819 
   7820             // check if target holds any <path-permission> that match uri
   7821             final PathPermission[] pps = pi.pathPermissions;
   7822             if (pps != null) {
   7823                 final String path = grantUri.uri.getPath();
   7824                 int i = pps.length;
   7825                 while (i > 0 && (!readMet || !writeMet)) {
   7826                     i--;
   7827                     PathPermission pp = pps[i];
   7828                     if (pp.match(path)) {
   7829                         if (!readMet) {
   7830                             final String pprperm = pp.getReadPermission();
   7831                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   7832                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
   7833                                     + ": match=" + pp.match(path)
   7834                                     + " check=" + pm.checkUidPermission(pprperm, uid));
   7835                             if (pprperm != null) {
   7836                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
   7837                                         == PERMISSION_GRANTED) {
   7838                                     readMet = true;
   7839                                 } else {
   7840                                     allowDefaultRead = false;
   7841                                 }
   7842                             }
   7843                         }
   7844                         if (!writeMet) {
   7845                             final String ppwperm = pp.getWritePermission();
   7846                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   7847                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
   7848                                     + ": match=" + pp.match(path)
   7849                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
   7850                             if (ppwperm != null) {
   7851                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
   7852                                         == PERMISSION_GRANTED) {
   7853                                     writeMet = true;
   7854                                 } else {
   7855                                     allowDefaultWrite = false;
   7856                                 }
   7857                             }
   7858                         }
   7859                     }
   7860                 }
   7861             }
   7862 
   7863             // grant unprotected <provider> read/write, if not blocked by
   7864             // <path-permission> above
   7865             if (allowDefaultRead) readMet = true;
   7866             if (allowDefaultWrite) writeMet = true;
   7867 
   7868         } catch (RemoteException e) {
   7869             return false;
   7870         }
   7871 
   7872         return readMet && writeMet;
   7873     }
   7874 
   7875     public int getAppStartMode(int uid, String packageName) {
   7876         synchronized (this) {
   7877             return checkAllowBackgroundLocked(uid, packageName, -1, true);
   7878         }
   7879     }
   7880 
   7881     int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
   7882             boolean allowWhenForeground) {
   7883         UidRecord uidRec = mActiveUids.get(uid);
   7884         if (!mLenientBackgroundCheck) {
   7885             if (!allowWhenForeground || uidRec == null
   7886                     || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   7887                 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
   7888                         packageName) != AppOpsManager.MODE_ALLOWED) {
   7889                     return ActivityManager.APP_START_MODE_DELAYED;
   7890                 }
   7891             }
   7892 
   7893         } else if (uidRec == null || uidRec.idle) {
   7894             if (callingPid >= 0) {
   7895                 ProcessRecord proc;
   7896                 synchronized (mPidsSelfLocked) {
   7897                     proc = mPidsSelfLocked.get(callingPid);
   7898                 }
   7899                 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
   7900                     // Whoever is instigating this is in the foreground, so we will allow it
   7901                     // to go through.
   7902                     return ActivityManager.APP_START_MODE_NORMAL;
   7903                 }
   7904             }
   7905             if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
   7906                     != AppOpsManager.MODE_ALLOWED) {
   7907                 return ActivityManager.APP_START_MODE_DELAYED;
   7908             }
   7909         }
   7910         return ActivityManager.APP_START_MODE_NORMAL;
   7911     }
   7912 
   7913     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
   7914         ProviderInfo pi = null;
   7915         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
   7916         if (cpr != null) {
   7917             pi = cpr.info;
   7918         } else {
   7919             try {
   7920                 pi = AppGlobals.getPackageManager().resolveContentProvider(
   7921                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
   7922                         userHandle);
   7923             } catch (RemoteException ex) {
   7924             }
   7925         }
   7926         return pi;
   7927     }
   7928 
   7929     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
   7930         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
   7931         if (targetUris != null) {
   7932             return targetUris.get(grantUri);
   7933         }
   7934         return null;
   7935     }
   7936 
   7937     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
   7938             String targetPkg, int targetUid, GrantUri grantUri) {
   7939         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
   7940         if (targetUris == null) {
   7941             targetUris = Maps.newArrayMap();
   7942             mGrantedUriPermissions.put(targetUid, targetUris);
   7943         }
   7944 
   7945         UriPermission perm = targetUris.get(grantUri);
   7946         if (perm == null) {
   7947             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
   7948             targetUris.put(grantUri, perm);
   7949         }
   7950 
   7951         return perm;
   7952     }
   7953 
   7954     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
   7955             final int modeFlags) {
   7956         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
   7957         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
   7958                 : UriPermission.STRENGTH_OWNED;
   7959 
   7960         // Root gets to do everything.
   7961         if (uid == 0) {
   7962             return true;
   7963         }
   7964 
   7965         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   7966         if (perms == null) return false;
   7967 
   7968         // First look for exact match
   7969         final UriPermission exactPerm = perms.get(grantUri);
   7970         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
   7971             return true;
   7972         }
   7973 
   7974         // No exact match, look for prefixes
   7975         final int N = perms.size();
   7976         for (int i = 0; i < N; i++) {
   7977             final UriPermission perm = perms.valueAt(i);
   7978             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
   7979                     && perm.getStrength(modeFlags) >= minStrength) {
   7980                 return true;
   7981             }
   7982         }
   7983 
   7984         return false;
   7985     }
   7986 
   7987     /**
   7988      * @param uri This uri must NOT contain an embedded userId.
   7989      * @param userId The userId in which the uri is to be resolved.
   7990      */
   7991     @Override
   7992     public int checkUriPermission(Uri uri, int pid, int uid,
   7993             final int modeFlags, int userId, IBinder callerToken) {
   7994         enforceNotIsolatedCaller("checkUriPermission");
   7995 
   7996         // Another redirected-binder-call permissions check as in
   7997         // {@link checkPermissionWithToken}.
   7998         Identity tlsIdentity = sCallerIdentity.get();
   7999         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
   8000             uid = tlsIdentity.uid;
   8001             pid = tlsIdentity.pid;
   8002         }
   8003 
   8004         // Our own process gets to do everything.
   8005         if (pid == MY_PID) {
   8006             return PackageManager.PERMISSION_GRANTED;
   8007         }
   8008         synchronized (this) {
   8009             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
   8010                     ? PackageManager.PERMISSION_GRANTED
   8011                     : PackageManager.PERMISSION_DENIED;
   8012         }
   8013     }
   8014 
   8015     /**
   8016      * Check if the targetPkg can be granted permission to access uri by
   8017      * the callingUid using the given modeFlags.  Throws a security exception
   8018      * if callingUid is not allowed to do this.  Returns the uid of the target
   8019      * if the URI permission grant should be performed; returns -1 if it is not
   8020      * needed (for example targetPkg already has permission to access the URI).
   8021      * If you already know the uid of the target, you can supply it in
   8022      * lastTargetUid else set that to -1.
   8023      */
   8024     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
   8025             final int modeFlags, int lastTargetUid) {
   8026         if (!Intent.isAccessUriMode(modeFlags)) {
   8027             return -1;
   8028         }
   8029 
   8030         if (targetPkg != null) {
   8031             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8032                     "Checking grant " + targetPkg + " permission to " + grantUri);
   8033         }
   8034 
   8035         final IPackageManager pm = AppGlobals.getPackageManager();
   8036 
   8037         // If this is not a content: uri, we can't do anything with it.
   8038         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
   8039             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8040                     "Can't grant URI permission for non-content URI: " + grantUri);
   8041             return -1;
   8042         }
   8043 
   8044         final String authority = grantUri.uri.getAuthority();
   8045         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
   8046                 MATCH_DEBUG_TRIAGED_MISSING);
   8047         if (pi == null) {
   8048             Slog.w(TAG, "No content provider found for permission check: " +
   8049                     grantUri.uri.toSafeString());
   8050             return -1;
   8051         }
   8052 
   8053         int targetUid = lastTargetUid;
   8054         if (targetUid < 0 && targetPkg != null) {
   8055             try {
   8056                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
   8057                         UserHandle.getUserId(callingUid));
   8058                 if (targetUid < 0) {
   8059                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8060                             "Can't grant URI permission no uid for: " + targetPkg);
   8061                     return -1;
   8062                 }
   8063             } catch (RemoteException ex) {
   8064                 return -1;
   8065             }
   8066         }
   8067 
   8068         if (targetUid >= 0) {
   8069             // First...  does the target actually need this permission?
   8070             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
   8071                 // No need to grant the target this permission.
   8072                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8073                         "Target " + targetPkg + " already has full permission to " + grantUri);
   8074                 return -1;
   8075             }
   8076         } else {
   8077             // First...  there is no target package, so can anyone access it?
   8078             boolean allowed = pi.exported;
   8079             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   8080                 if (pi.readPermission != null) {
   8081                     allowed = false;
   8082                 }
   8083             }
   8084             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   8085                 if (pi.writePermission != null) {
   8086                     allowed = false;
   8087                 }
   8088             }
   8089             if (allowed) {
   8090                 return -1;
   8091             }
   8092         }
   8093 
   8094         /* There is a special cross user grant if:
   8095          * - The target is on another user.
   8096          * - Apps on the current user can access the uri without any uid permissions.
   8097          * In this case, we grant a uri permission, even if the ContentProvider does not normally
   8098          * grant uri permissions.
   8099          */
   8100         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
   8101                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
   8102                 modeFlags, false /*without considering the uid permissions*/);
   8103 
   8104         // Second...  is the provider allowing granting of URI permissions?
   8105         if (!specialCrossUserGrant) {
   8106             if (!pi.grantUriPermissions) {
   8107                 throw new SecurityException("Provider " + pi.packageName
   8108                         + "/" + pi.name
   8109                         + " does not allow granting of Uri permissions (uri "
   8110                         + grantUri + ")");
   8111             }
   8112             if (pi.uriPermissionPatterns != null) {
   8113                 final int N = pi.uriPermissionPatterns.length;
   8114                 boolean allowed = false;
   8115                 for (int i=0; i<N; i++) {
   8116                     if (pi.uriPermissionPatterns[i] != null
   8117                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
   8118                         allowed = true;
   8119                         break;
   8120                     }
   8121                 }
   8122                 if (!allowed) {
   8123                     throw new SecurityException("Provider " + pi.packageName
   8124                             + "/" + pi.name
   8125                             + " does not allow granting of permission to path of Uri "
   8126                             + grantUri);
   8127                 }
   8128             }
   8129         }
   8130 
   8131         // Third...  does the caller itself have permission to access
   8132         // this uri?
   8133         if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
   8134             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
   8135                 // Require they hold a strong enough Uri permission
   8136                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
   8137                     throw new SecurityException("Uid " + callingUid
   8138                             + " does not have permission to uri " + grantUri);
   8139                 }
   8140             }
   8141         }
   8142         return targetUid;
   8143     }
   8144 
   8145     /**
   8146      * @param uri This uri must NOT contain an embedded userId.
   8147      * @param userId The userId in which the uri is to be resolved.
   8148      */
   8149     @Override
   8150     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
   8151             final int modeFlags, int userId) {
   8152         enforceNotIsolatedCaller("checkGrantUriPermission");
   8153         synchronized(this) {
   8154             return checkGrantUriPermissionLocked(callingUid, targetPkg,
   8155                     new GrantUri(userId, uri, false), modeFlags, -1);
   8156         }
   8157     }
   8158 
   8159     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
   8160             final int modeFlags, UriPermissionOwner owner) {
   8161         if (!Intent.isAccessUriMode(modeFlags)) {
   8162             return;
   8163         }
   8164 
   8165         // So here we are: the caller has the assumed permission
   8166         // to the uri, and the target doesn't.  Let's now give this to
   8167         // the target.
   8168 
   8169         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8170                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
   8171 
   8172         final String authority = grantUri.uri.getAuthority();
   8173         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
   8174                 MATCH_DEBUG_TRIAGED_MISSING);
   8175         if (pi == null) {
   8176             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
   8177             return;
   8178         }
   8179 
   8180         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
   8181             grantUri.prefix = true;
   8182         }
   8183         final UriPermission perm = findOrCreateUriPermissionLocked(
   8184                 pi.packageName, targetPkg, targetUid, grantUri);
   8185         perm.grantModes(modeFlags, owner);
   8186     }
   8187 
   8188     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
   8189             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
   8190         if (targetPkg == null) {
   8191             throw new NullPointerException("targetPkg");
   8192         }
   8193         int targetUid;
   8194         final IPackageManager pm = AppGlobals.getPackageManager();
   8195         try {
   8196             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
   8197         } catch (RemoteException ex) {
   8198             return;
   8199         }
   8200 
   8201         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
   8202                 targetUid);
   8203         if (targetUid < 0) {
   8204             return;
   8205         }
   8206 
   8207         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
   8208                 owner);
   8209     }
   8210 
   8211     static class NeededUriGrants extends ArrayList<GrantUri> {
   8212         final String targetPkg;
   8213         final int targetUid;
   8214         final int flags;
   8215 
   8216         NeededUriGrants(String targetPkg, int targetUid, int flags) {
   8217             this.targetPkg = targetPkg;
   8218             this.targetUid = targetUid;
   8219             this.flags = flags;
   8220         }
   8221     }
   8222 
   8223     /**
   8224      * Like checkGrantUriPermissionLocked, but takes an Intent.
   8225      */
   8226     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
   8227             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
   8228         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8229                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
   8230                 + " clip=" + (intent != null ? intent.getClipData() : null)
   8231                 + " from " + intent + "; flags=0x"
   8232                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
   8233 
   8234         if (targetPkg == null) {
   8235             throw new NullPointerException("targetPkg");
   8236         }
   8237 
   8238         if (intent == null) {
   8239             return null;
   8240         }
   8241         Uri data = intent.getData();
   8242         ClipData clip = intent.getClipData();
   8243         if (data == null && clip == null) {
   8244             return null;
   8245         }
   8246         // Default userId for uris in the intent (if they don't specify it themselves)
   8247         int contentUserHint = intent.getContentUserHint();
   8248         if (contentUserHint == UserHandle.USER_CURRENT) {
   8249             contentUserHint = UserHandle.getUserId(callingUid);
   8250         }
   8251         final IPackageManager pm = AppGlobals.getPackageManager();
   8252         int targetUid;
   8253         if (needed != null) {
   8254             targetUid = needed.targetUid;
   8255         } else {
   8256             try {
   8257                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
   8258                         targetUserId);
   8259             } catch (RemoteException ex) {
   8260                 return null;
   8261             }
   8262             if (targetUid < 0) {
   8263                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8264                         "Can't grant URI permission no uid for: " + targetPkg
   8265                         + " on user " + targetUserId);
   8266                 return null;
   8267             }
   8268         }
   8269         if (data != null) {
   8270             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
   8271             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
   8272                     targetUid);
   8273             if (targetUid > 0) {
   8274                 if (needed == null) {
   8275                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
   8276                 }
   8277                 needed.add(grantUri);
   8278             }
   8279         }
   8280         if (clip != null) {
   8281             for (int i=0; i<clip.getItemCount(); i++) {
   8282                 Uri uri = clip.getItemAt(i).getUri();
   8283                 if (uri != null) {
   8284                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
   8285                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
   8286                             targetUid);
   8287                     if (targetUid > 0) {
   8288                         if (needed == null) {
   8289                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
   8290                         }
   8291                         needed.add(grantUri);
   8292                     }
   8293                 } else {
   8294                     Intent clipIntent = clip.getItemAt(i).getIntent();
   8295                     if (clipIntent != null) {
   8296                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
   8297                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
   8298                         if (newNeeded != null) {
   8299                             needed = newNeeded;
   8300                         }
   8301                     }
   8302                 }
   8303             }
   8304         }
   8305 
   8306         return needed;
   8307     }
   8308 
   8309     /**
   8310      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
   8311      */
   8312     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
   8313             UriPermissionOwner owner) {
   8314         if (needed != null) {
   8315             for (int i=0; i<needed.size(); i++) {
   8316                 GrantUri grantUri = needed.get(i);
   8317                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
   8318                         grantUri, needed.flags, owner);
   8319             }
   8320         }
   8321     }
   8322 
   8323     void grantUriPermissionFromIntentLocked(int callingUid,
   8324             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
   8325         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
   8326                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
   8327         if (needed == null) {
   8328             return;
   8329         }
   8330 
   8331         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
   8332     }
   8333 
   8334     /**
   8335      * @param uri This uri must NOT contain an embedded userId.
   8336      * @param userId The userId in which the uri is to be resolved.
   8337      */
   8338     @Override
   8339     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
   8340             final int modeFlags, int userId) {
   8341         enforceNotIsolatedCaller("grantUriPermission");
   8342         GrantUri grantUri = new GrantUri(userId, uri, false);
   8343         synchronized(this) {
   8344             final ProcessRecord r = getRecordForAppLocked(caller);
   8345             if (r == null) {
   8346                 throw new SecurityException("Unable to find app for caller "
   8347                         + caller
   8348                         + " when granting permission to uri " + grantUri);
   8349             }
   8350             if (targetPkg == null) {
   8351                 throw new IllegalArgumentException("null target");
   8352             }
   8353             if (grantUri == null) {
   8354                 throw new IllegalArgumentException("null uri");
   8355             }
   8356 
   8357             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
   8358                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
   8359                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
   8360                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
   8361 
   8362             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
   8363                     UserHandle.getUserId(r.uid));
   8364         }
   8365     }
   8366 
   8367     void removeUriPermissionIfNeededLocked(UriPermission perm) {
   8368         if (perm.modeFlags == 0) {
   8369             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
   8370                     perm.targetUid);
   8371             if (perms != null) {
   8372                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8373                         "Removing " + perm.targetUid + " permission to " + perm.uri);
   8374 
   8375                 perms.remove(perm.uri);
   8376                 if (perms.isEmpty()) {
   8377                     mGrantedUriPermissions.remove(perm.targetUid);
   8378                 }
   8379             }
   8380         }
   8381     }
   8382 
   8383     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
   8384         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8385                 "Revoking all granted permissions to " + grantUri);
   8386 
   8387         final IPackageManager pm = AppGlobals.getPackageManager();
   8388         final String authority = grantUri.uri.getAuthority();
   8389         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
   8390                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
   8391         if (pi == null) {
   8392             Slog.w(TAG, "No content provider found for permission revoke: "
   8393                     + grantUri.toSafeString());
   8394             return;
   8395         }
   8396 
   8397         // Does the caller have this permission on the URI?
   8398         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
   8399             // If they don't have direct access to the URI, then revoke any
   8400             // ownerless URI permissions that have been granted to them.
   8401             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   8402             if (perms != null) {
   8403                 boolean persistChanged = false;
   8404                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
   8405                     final UriPermission perm = it.next();
   8406                     if (perm.uri.sourceUserId == grantUri.sourceUserId
   8407                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
   8408                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8409                                 "Revoking non-owned " + perm.targetUid
   8410                                 + " permission to " + perm.uri);
   8411                         persistChanged |= perm.revokeModes(
   8412                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
   8413                         if (perm.modeFlags == 0) {
   8414                             it.remove();
   8415                         }
   8416                     }
   8417                 }
   8418                 if (perms.isEmpty()) {
   8419                     mGrantedUriPermissions.remove(callingUid);
   8420                 }
   8421                 if (persistChanged) {
   8422                     schedulePersistUriGrants();
   8423                 }
   8424             }
   8425             return;
   8426         }
   8427 
   8428         boolean persistChanged = false;
   8429 
   8430         // Go through all of the permissions and remove any that match.
   8431         int N = mGrantedUriPermissions.size();
   8432         for (int i = 0; i < N; i++) {
   8433             final int targetUid = mGrantedUriPermissions.keyAt(i);
   8434             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   8435 
   8436             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
   8437                 final UriPermission perm = it.next();
   8438                 if (perm.uri.sourceUserId == grantUri.sourceUserId
   8439                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
   8440                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8441                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
   8442                     persistChanged |= perm.revokeModes(
   8443                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
   8444                     if (perm.modeFlags == 0) {
   8445                         it.remove();
   8446                     }
   8447                 }
   8448             }
   8449 
   8450             if (perms.isEmpty()) {
   8451                 mGrantedUriPermissions.remove(targetUid);
   8452                 N--;
   8453                 i--;
   8454             }
   8455         }
   8456 
   8457         if (persistChanged) {
   8458             schedulePersistUriGrants();
   8459         }
   8460     }
   8461 
   8462     /**
   8463      * @param uri This uri must NOT contain an embedded userId.
   8464      * @param userId The userId in which the uri is to be resolved.
   8465      */
   8466     @Override
   8467     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
   8468             int userId) {
   8469         enforceNotIsolatedCaller("revokeUriPermission");
   8470         synchronized(this) {
   8471             final ProcessRecord r = getRecordForAppLocked(caller);
   8472             if (r == null) {
   8473                 throw new SecurityException("Unable to find app for caller "
   8474                         + caller
   8475                         + " when revoking permission to uri " + uri);
   8476             }
   8477             if (uri == null) {
   8478                 Slog.w(TAG, "revokeUriPermission: null uri");
   8479                 return;
   8480             }
   8481 
   8482             if (!Intent.isAccessUriMode(modeFlags)) {
   8483                 return;
   8484             }
   8485 
   8486             final String authority = uri.getAuthority();
   8487             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
   8488                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
   8489             if (pi == null) {
   8490                 Slog.w(TAG, "No content provider found for permission revoke: "
   8491                         + uri.toSafeString());
   8492                 return;
   8493             }
   8494 
   8495             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
   8496         }
   8497     }
   8498 
   8499     /**
   8500      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
   8501      * given package.
   8502      *
   8503      * @param packageName Package name to match, or {@code null} to apply to all
   8504      *            packages.
   8505      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
   8506      *            to all users.
   8507      * @param persistable If persistable grants should be removed.
   8508      */
   8509     private void removeUriPermissionsForPackageLocked(
   8510             String packageName, int userHandle, boolean persistable) {
   8511         if (userHandle == UserHandle.USER_ALL && packageName == null) {
   8512             throw new IllegalArgumentException("Must narrow by either package or user");
   8513         }
   8514 
   8515         boolean persistChanged = false;
   8516 
   8517         int N = mGrantedUriPermissions.size();
   8518         for (int i = 0; i < N; i++) {
   8519             final int targetUid = mGrantedUriPermissions.keyAt(i);
   8520             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   8521 
   8522             // Only inspect grants matching user
   8523             if (userHandle == UserHandle.USER_ALL
   8524                     || userHandle == UserHandle.getUserId(targetUid)) {
   8525                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
   8526                     final UriPermission perm = it.next();
   8527 
   8528                     // Only inspect grants matching package
   8529                     if (packageName == null || perm.sourcePkg.equals(packageName)
   8530                             || perm.targetPkg.equals(packageName)) {
   8531                         persistChanged |= perm.revokeModes(persistable
   8532                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
   8533 
   8534                         // Only remove when no modes remain; any persisted grants
   8535                         // will keep this alive.
   8536                         if (perm.modeFlags == 0) {
   8537                             it.remove();
   8538                         }
   8539                     }
   8540                 }
   8541 
   8542                 if (perms.isEmpty()) {
   8543                     mGrantedUriPermissions.remove(targetUid);
   8544                     N--;
   8545                     i--;
   8546                 }
   8547             }
   8548         }
   8549 
   8550         if (persistChanged) {
   8551             schedulePersistUriGrants();
   8552         }
   8553     }
   8554 
   8555     @Override
   8556     public IBinder newUriPermissionOwner(String name) {
   8557         enforceNotIsolatedCaller("newUriPermissionOwner");
   8558         synchronized(this) {
   8559             UriPermissionOwner owner = new UriPermissionOwner(this, name);
   8560             return owner.getExternalTokenLocked();
   8561         }
   8562     }
   8563 
   8564     @Override
   8565     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
   8566         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
   8567         synchronized(this) {
   8568             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
   8569             if (r == null) {
   8570                 throw new IllegalArgumentException("Activity does not exist; token="
   8571                         + activityToken);
   8572             }
   8573             return r.getUriPermissionsLocked().getExternalTokenLocked();
   8574         }
   8575     }
   8576     /**
   8577      * @param uri This uri must NOT contain an embedded userId.
   8578      * @param sourceUserId The userId in which the uri is to be resolved.
   8579      * @param targetUserId The userId of the app that receives the grant.
   8580      */
   8581     @Override
   8582     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
   8583             final int modeFlags, int sourceUserId, int targetUserId) {
   8584         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
   8585                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
   8586                 "grantUriPermissionFromOwner", null);
   8587         synchronized(this) {
   8588             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   8589             if (owner == null) {
   8590                 throw new IllegalArgumentException("Unknown owner: " + token);
   8591             }
   8592             if (fromUid != Binder.getCallingUid()) {
   8593                 if (Binder.getCallingUid() != Process.myUid()) {
   8594                     // Only system code can grant URI permissions on behalf
   8595                     // of other users.
   8596                     throw new SecurityException("nice try");
   8597                 }
   8598             }
   8599             if (targetPkg == null) {
   8600                 throw new IllegalArgumentException("null target");
   8601             }
   8602             if (uri == null) {
   8603                 throw new IllegalArgumentException("null uri");
   8604             }
   8605 
   8606             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
   8607                     modeFlags, owner, targetUserId);
   8608         }
   8609     }
   8610 
   8611     /**
   8612      * @param uri This uri must NOT contain an embedded userId.
   8613      * @param userId The userId in which the uri is to be resolved.
   8614      */
   8615     @Override
   8616     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
   8617         synchronized(this) {
   8618             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   8619             if (owner == null) {
   8620                 throw new IllegalArgumentException("Unknown owner: " + token);
   8621             }
   8622 
   8623             if (uri == null) {
   8624                 owner.removeUriPermissionsLocked(mode);
   8625             } else {
   8626                 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
   8627                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
   8628             }
   8629         }
   8630     }
   8631 
   8632     private void schedulePersistUriGrants() {
   8633         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
   8634             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
   8635                     10 * DateUtils.SECOND_IN_MILLIS);
   8636         }
   8637     }
   8638 
   8639     private void writeGrantedUriPermissions() {
   8640         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
   8641 
   8642         // Snapshot permissions so we can persist without lock
   8643         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
   8644         synchronized (this) {
   8645             final int size = mGrantedUriPermissions.size();
   8646             for (int i = 0; i < size; i++) {
   8647                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   8648                 for (UriPermission perm : perms.values()) {
   8649                     if (perm.persistedModeFlags != 0) {
   8650                         persist.add(perm.snapshot());
   8651                     }
   8652                 }
   8653             }
   8654         }
   8655 
   8656         FileOutputStream fos = null;
   8657         try {
   8658             fos = mGrantFile.startWrite();
   8659 
   8660             XmlSerializer out = new FastXmlSerializer();
   8661             out.setOutput(fos, StandardCharsets.UTF_8.name());
   8662             out.startDocument(null, true);
   8663             out.startTag(null, TAG_URI_GRANTS);
   8664             for (UriPermission.Snapshot perm : persist) {
   8665                 out.startTag(null, TAG_URI_GRANT);
   8666                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
   8667                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
   8668                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
   8669                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
   8670                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
   8671                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
   8672                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
   8673                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
   8674                 out.endTag(null, TAG_URI_GRANT);
   8675             }
   8676             out.endTag(null, TAG_URI_GRANTS);
   8677             out.endDocument();
   8678 
   8679             mGrantFile.finishWrite(fos);
   8680         } catch (IOException e) {
   8681             if (fos != null) {
   8682                 mGrantFile.failWrite(fos);
   8683             }
   8684         }
   8685     }
   8686 
   8687     private void readGrantedUriPermissionsLocked() {
   8688         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
   8689 
   8690         final long now = System.currentTimeMillis();
   8691 
   8692         FileInputStream fis = null;
   8693         try {
   8694             fis = mGrantFile.openRead();
   8695             final XmlPullParser in = Xml.newPullParser();
   8696             in.setInput(fis, StandardCharsets.UTF_8.name());
   8697 
   8698             int type;
   8699             while ((type = in.next()) != END_DOCUMENT) {
   8700                 final String tag = in.getName();
   8701                 if (type == START_TAG) {
   8702                     if (TAG_URI_GRANT.equals(tag)) {
   8703                         final int sourceUserId;
   8704                         final int targetUserId;
   8705                         final int userHandle = readIntAttribute(in,
   8706                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
   8707                         if (userHandle != UserHandle.USER_NULL) {
   8708                             // For backwards compatibility.
   8709                             sourceUserId = userHandle;
   8710                             targetUserId = userHandle;
   8711                         } else {
   8712                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
   8713                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
   8714                         }
   8715                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
   8716                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
   8717                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
   8718                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
   8719                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
   8720                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
   8721 
   8722                         // Sanity check that provider still belongs to source package
   8723                         // Both direct boot aware and unaware packages are fine as we
   8724                         // will do filtering at query time to avoid multiple parsing.
   8725                         final ProviderInfo pi = getProviderInfoLocked(
   8726                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
   8727                                         | MATCH_DIRECT_BOOT_UNAWARE);
   8728                         if (pi != null && sourcePkg.equals(pi.packageName)) {
   8729                             int targetUid = -1;
   8730                             try {
   8731                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
   8732                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
   8733                             } catch (RemoteException e) {
   8734                             }
   8735                             if (targetUid != -1) {
   8736                                 final UriPermission perm = findOrCreateUriPermissionLocked(
   8737                                         sourcePkg, targetPkg, targetUid,
   8738                                         new GrantUri(sourceUserId, uri, prefix));
   8739                                 perm.initPersistedModes(modeFlags, createdTime);
   8740                             }
   8741                         } else {
   8742                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
   8743                                     + " but instead found " + pi);
   8744                         }
   8745                     }
   8746                 }
   8747             }
   8748         } catch (FileNotFoundException e) {
   8749             // Missing grants is okay
   8750         } catch (IOException e) {
   8751             Slog.wtf(TAG, "Failed reading Uri grants", e);
   8752         } catch (XmlPullParserException e) {
   8753             Slog.wtf(TAG, "Failed reading Uri grants", e);
   8754         } finally {
   8755             IoUtils.closeQuietly(fis);
   8756         }
   8757     }
   8758 
   8759     /**
   8760      * @param uri This uri must NOT contain an embedded userId.
   8761      * @param userId The userId in which the uri is to be resolved.
   8762      */
   8763     @Override
   8764     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
   8765         enforceNotIsolatedCaller("takePersistableUriPermission");
   8766 
   8767         Preconditions.checkFlagsArgument(modeFlags,
   8768                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   8769 
   8770         synchronized (this) {
   8771             final int callingUid = Binder.getCallingUid();
   8772             boolean persistChanged = false;
   8773             GrantUri grantUri = new GrantUri(userId, uri, false);
   8774 
   8775             UriPermission exactPerm = findUriPermissionLocked(callingUid,
   8776                     new GrantUri(userId, uri, false));
   8777             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
   8778                     new GrantUri(userId, uri, true));
   8779 
   8780             final boolean exactValid = (exactPerm != null)
   8781                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
   8782             final boolean prefixValid = (prefixPerm != null)
   8783                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
   8784 
   8785             if (!(exactValid || prefixValid)) {
   8786                 throw new SecurityException("No persistable permission grants found for UID "
   8787                         + callingUid + " and Uri " + grantUri.toSafeString());
   8788             }
   8789 
   8790             if (exactValid) {
   8791                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
   8792             }
   8793             if (prefixValid) {
   8794                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
   8795             }
   8796 
   8797             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
   8798 
   8799             if (persistChanged) {
   8800                 schedulePersistUriGrants();
   8801             }
   8802         }
   8803     }
   8804 
   8805     /**
   8806      * @param uri This uri must NOT contain an embedded userId.
   8807      * @param userId The userId in which the uri is to be resolved.
   8808      */
   8809     @Override
   8810     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
   8811         enforceNotIsolatedCaller("releasePersistableUriPermission");
   8812 
   8813         Preconditions.checkFlagsArgument(modeFlags,
   8814                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   8815 
   8816         synchronized (this) {
   8817             final int callingUid = Binder.getCallingUid();
   8818             boolean persistChanged = false;
   8819 
   8820             UriPermission exactPerm = findUriPermissionLocked(callingUid,
   8821                     new GrantUri(userId, uri, false));
   8822             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
   8823                     new GrantUri(userId, uri, true));
   8824             if (exactPerm == null && prefixPerm == null) {
   8825                 throw new SecurityException("No permission grants found for UID " + callingUid
   8826                         + " and Uri " + uri.toSafeString());
   8827             }
   8828 
   8829             if (exactPerm != null) {
   8830                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
   8831                 removeUriPermissionIfNeededLocked(exactPerm);
   8832             }
   8833             if (prefixPerm != null) {
   8834                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
   8835                 removeUriPermissionIfNeededLocked(prefixPerm);
   8836             }
   8837 
   8838             if (persistChanged) {
   8839                 schedulePersistUriGrants();
   8840             }
   8841         }
   8842     }
   8843 
   8844     /**
   8845      * Prune any older {@link UriPermission} for the given UID until outstanding
   8846      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
   8847      *
   8848      * @return if any mutations occured that require persisting.
   8849      */
   8850     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
   8851         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   8852         if (perms == null) return false;
   8853         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
   8854 
   8855         final ArrayList<UriPermission> persisted = Lists.newArrayList();
   8856         for (UriPermission perm : perms.values()) {
   8857             if (perm.persistedModeFlags != 0) {
   8858                 persisted.add(perm);
   8859             }
   8860         }
   8861 
   8862         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
   8863         if (trimCount <= 0) return false;
   8864 
   8865         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
   8866         for (int i = 0; i < trimCount; i++) {
   8867             final UriPermission perm = persisted.get(i);
   8868 
   8869             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8870                     "Trimming grant created at " + perm.persistedCreateTime);
   8871 
   8872             perm.releasePersistableModes(~0);
   8873             removeUriPermissionIfNeededLocked(perm);
   8874         }
   8875 
   8876         return true;
   8877     }
   8878 
   8879     @Override
   8880     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
   8881             String packageName, boolean incoming) {
   8882         enforceNotIsolatedCaller("getPersistedUriPermissions");
   8883         Preconditions.checkNotNull(packageName, "packageName");
   8884 
   8885         final int callingUid = Binder.getCallingUid();
   8886         final int callingUserId = UserHandle.getUserId(callingUid);
   8887         final IPackageManager pm = AppGlobals.getPackageManager();
   8888         try {
   8889             final int packageUid = pm.getPackageUid(packageName,
   8890                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
   8891             if (packageUid != callingUid) {
   8892                 throw new SecurityException(
   8893                         "Package " + packageName + " does not belong to calling UID " + callingUid);
   8894             }
   8895         } catch (RemoteException e) {
   8896             throw new SecurityException("Failed to verify package name ownership");
   8897         }
   8898 
   8899         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
   8900         synchronized (this) {
   8901             if (incoming) {
   8902                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
   8903                         callingUid);
   8904                 if (perms == null) {
   8905                     Slog.w(TAG, "No permission grants found for " + packageName);
   8906                 } else {
   8907                     for (UriPermission perm : perms.values()) {
   8908                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
   8909                             result.add(perm.buildPersistedPublicApiObject());
   8910                         }
   8911                     }
   8912                 }
   8913             } else {
   8914                 final int size = mGrantedUriPermissions.size();
   8915                 for (int i = 0; i < size; i++) {
   8916                     final ArrayMap<GrantUri, UriPermission> perms =
   8917                             mGrantedUriPermissions.valueAt(i);
   8918                     for (UriPermission perm : perms.values()) {
   8919                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
   8920                             result.add(perm.buildPersistedPublicApiObject());
   8921                         }
   8922                     }
   8923                 }
   8924             }
   8925         }
   8926         return new ParceledListSlice<android.content.UriPermission>(result);
   8927     }
   8928 
   8929     @Override
   8930     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
   8931             String packageName, int userId) {
   8932         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
   8933                 "getGrantedUriPermissions");
   8934 
   8935         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
   8936         synchronized (this) {
   8937             final int size = mGrantedUriPermissions.size();
   8938             for (int i = 0; i < size; i++) {
   8939                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   8940                 for (UriPermission perm : perms.values()) {
   8941                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
   8942                             && perm.persistedModeFlags != 0) {
   8943                         result.add(perm.buildPersistedPublicApiObject());
   8944                     }
   8945                 }
   8946             }
   8947         }
   8948         return new ParceledListSlice<android.content.UriPermission>(result);
   8949     }
   8950 
   8951     @Override
   8952     public void clearGrantedUriPermissions(String packageName, int userId) {
   8953         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
   8954                 "clearGrantedUriPermissions");
   8955         removeUriPermissionsForPackageLocked(packageName, userId, true);
   8956     }
   8957 
   8958     @Override
   8959     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
   8960         synchronized (this) {
   8961             ProcessRecord app =
   8962                 who != null ? getRecordForAppLocked(who) : null;
   8963             if (app == null) return;
   8964 
   8965             Message msg = Message.obtain();
   8966             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
   8967             msg.obj = app;
   8968             msg.arg1 = waiting ? 1 : 0;
   8969             mUiHandler.sendMessage(msg);
   8970         }
   8971     }
   8972 
   8973     @Override
   8974     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
   8975         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
   8976         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
   8977         outInfo.availMem = Process.getFreeMemory();
   8978         outInfo.totalMem = Process.getTotalMemory();
   8979         outInfo.threshold = homeAppMem;
   8980         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
   8981         outInfo.hiddenAppThreshold = cachedAppMem;
   8982         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
   8983                 ProcessList.SERVICE_ADJ);
   8984         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
   8985                 ProcessList.VISIBLE_APP_ADJ);
   8986         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
   8987                 ProcessList.FOREGROUND_APP_ADJ);
   8988     }
   8989 
   8990     // =========================================================
   8991     // TASK MANAGEMENT
   8992     // =========================================================
   8993 
   8994     @Override
   8995     public List<IAppTask> getAppTasks(String callingPackage) {
   8996         int callingUid = Binder.getCallingUid();
   8997         long ident = Binder.clearCallingIdentity();
   8998 
   8999         synchronized(this) {
   9000             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
   9001             try {
   9002                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
   9003 
   9004                 final int N = mRecentTasks.size();
   9005                 for (int i = 0; i < N; i++) {
   9006                     TaskRecord tr = mRecentTasks.get(i);
   9007                     // Skip tasks that do not match the caller.  We don't need to verify
   9008                     // callingPackage, because we are also limiting to callingUid and know
   9009                     // that will limit to the correct security sandbox.
   9010                     if (tr.effectiveUid != callingUid) {
   9011                         continue;
   9012                     }
   9013                     Intent intent = tr.getBaseIntent();
   9014                     if (intent == null ||
   9015                             !callingPackage.equals(intent.getComponent().getPackageName())) {
   9016                         continue;
   9017                     }
   9018                     ActivityManager.RecentTaskInfo taskInfo =
   9019                             createRecentTaskInfoFromTaskRecord(tr);
   9020                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
   9021                     list.add(taskImpl);
   9022                 }
   9023             } finally {
   9024                 Binder.restoreCallingIdentity(ident);
   9025             }
   9026             return list;
   9027         }
   9028     }
   9029 
   9030     @Override
   9031     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
   9032         final int callingUid = Binder.getCallingUid();
   9033         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
   9034 
   9035         synchronized(this) {
   9036             if (DEBUG_ALL) Slog.v(
   9037                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
   9038 
   9039             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
   9040                     callingUid);
   9041 
   9042             // TODO: Improve with MRU list from all ActivityStacks.
   9043             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
   9044         }
   9045 
   9046         return list;
   9047     }
   9048 
   9049     /**
   9050      * Creates a new RecentTaskInfo from a TaskRecord.
   9051      */
   9052     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
   9053         // Update the task description to reflect any changes in the task stack
   9054         tr.updateTaskDescription();
   9055 
   9056         // Compose the recent task info
   9057         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
   9058         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
   9059         rti.persistentId = tr.taskId;
   9060         rti.baseIntent = new Intent(tr.getBaseIntent());
   9061         rti.origActivity = tr.origActivity;
   9062         rti.realActivity = tr.realActivity;
   9063         rti.description = tr.lastDescription;
   9064         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
   9065         rti.userId = tr.userId;
   9066         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
   9067         rti.firstActiveTime = tr.firstActiveTime;
   9068         rti.lastActiveTime = tr.lastActiveTime;
   9069         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
   9070         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
   9071         rti.numActivities = 0;
   9072         if (tr.mBounds != null) {
   9073             rti.bounds = new Rect(tr.mBounds);
   9074         }
   9075         rti.isDockable = tr.canGoInDockedStack();
   9076         rti.resizeMode = tr.mResizeMode;
   9077 
   9078         ActivityRecord base = null;
   9079         ActivityRecord top = null;
   9080         ActivityRecord tmp;
   9081 
   9082         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
   9083             tmp = tr.mActivities.get(i);
   9084             if (tmp.finishing) {
   9085                 continue;
   9086             }
   9087             base = tmp;
   9088             if (top == null || (top.state == ActivityState.INITIALIZING)) {
   9089                 top = base;
   9090             }
   9091             rti.numActivities++;
   9092         }
   9093 
   9094         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
   9095         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
   9096 
   9097         return rti;
   9098     }
   9099 
   9100     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
   9101         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
   9102                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
   9103         if (!allowed) {
   9104             if (checkPermission(android.Manifest.permission.GET_TASKS,
   9105                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
   9106                 // Temporary compatibility: some existing apps on the system image may
   9107                 // still be requesting the old permission and not switched to the new
   9108                 // one; if so, we'll still allow them full access.  This means we need
   9109                 // to see if they are holding the old permission and are a system app.
   9110                 try {
   9111                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
   9112                         allowed = true;
   9113                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
   9114                                 + " is using old GET_TASKS but privileged; allowing");
   9115                     }
   9116                 } catch (RemoteException e) {
   9117                 }
   9118             }
   9119         }
   9120         if (!allowed) {
   9121             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
   9122                     + " does not hold REAL_GET_TASKS; limiting output");
   9123         }
   9124         return allowed;
   9125     }
   9126 
   9127     @Override
   9128     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
   9129             int userId) {
   9130         final int callingUid = Binder.getCallingUid();
   9131         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
   9132                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
   9133 
   9134         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
   9135         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
   9136         synchronized (this) {
   9137             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
   9138                     callingUid);
   9139             final boolean detailed = checkCallingPermission(
   9140                     android.Manifest.permission.GET_DETAILED_TASKS)
   9141                     == PackageManager.PERMISSION_GRANTED;
   9142 
   9143             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
   9144                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
   9145                 return ParceledListSlice.emptyList();
   9146             }
   9147             mRecentTasks.loadUserRecentsLocked(userId);
   9148 
   9149             final int recentsCount = mRecentTasks.size();
   9150             ArrayList<ActivityManager.RecentTaskInfo> res =
   9151                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
   9152 
   9153             final Set<Integer> includedUsers;
   9154             if (includeProfiles) {
   9155                 includedUsers = mUserController.getProfileIds(userId);
   9156             } else {
   9157                 includedUsers = new HashSet<>();
   9158             }
   9159             includedUsers.add(Integer.valueOf(userId));
   9160 
   9161             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
   9162                 TaskRecord tr = mRecentTasks.get(i);
   9163                 // Only add calling user or related users recent tasks
   9164                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
   9165                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
   9166                     continue;
   9167                 }
   9168 
   9169                 if (tr.realActivitySuspended) {
   9170                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
   9171                     continue;
   9172                 }
   9173 
   9174                 // Return the entry if desired by the caller.  We always return
   9175                 // the first entry, because callers always expect this to be the
   9176                 // foreground app.  We may filter others if the caller has
   9177                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
   9178                 // we should exclude the entry.
   9179 
   9180                 if (i == 0
   9181                         || withExcluded
   9182                         || (tr.intent == null)
   9183                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
   9184                                 == 0)) {
   9185                     if (!allowed) {
   9186                         // If the caller doesn't have the GET_TASKS permission, then only
   9187                         // allow them to see a small subset of tasks -- their own and home.
   9188                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
   9189                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
   9190                             continue;
   9191                         }
   9192                     }
   9193                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
   9194                         if (tr.stack != null && tr.stack.isHomeStack()) {
   9195                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9196                                     "Skipping, home stack task: " + tr);
   9197                             continue;
   9198                         }
   9199                     }
   9200                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
   9201                         final ActivityStack stack = tr.stack;
   9202                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
   9203                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9204                                     "Skipping, top task in docked stack: " + tr);
   9205                             continue;
   9206                         }
   9207                     }
   9208                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
   9209                         if (tr.stack != null && tr.stack.isPinnedStack()) {
   9210                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9211                                     "Skipping, pinned stack task: " + tr);
   9212                             continue;
   9213                         }
   9214                     }
   9215                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
   9216                         // Don't include auto remove tasks that are finished or finishing.
   9217                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9218                                 "Skipping, auto-remove without activity: " + tr);
   9219                         continue;
   9220                     }
   9221                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
   9222                             && !tr.isAvailable) {
   9223                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9224                                 "Skipping, unavail real act: " + tr);
   9225                         continue;
   9226                     }
   9227 
   9228                     if (!tr.mUserSetupComplete) {
   9229                         // Don't include task launched while user is not done setting-up.
   9230                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9231                                 "Skipping, user setup not complete: " + tr);
   9232                         continue;
   9233                     }
   9234 
   9235                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
   9236                     if (!detailed) {
   9237                         rti.baseIntent.replaceExtras((Bundle)null);
   9238                     }
   9239 
   9240                     res.add(rti);
   9241                     maxNum--;
   9242                 }
   9243             }
   9244             return new ParceledListSlice<>(res);
   9245         }
   9246     }
   9247 
   9248     @Override
   9249     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
   9250         synchronized (this) {
   9251             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
   9252                     "getTaskThumbnail()");
   9253             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
   9254                     id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
   9255             if (tr != null) {
   9256                 return tr.getTaskThumbnailLocked();
   9257             }
   9258         }
   9259         return null;
   9260     }
   9261 
   9262     @Override
   9263     public int addAppTask(IBinder activityToken, Intent intent,
   9264             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
   9265         final int callingUid = Binder.getCallingUid();
   9266         final long callingIdent = Binder.clearCallingIdentity();
   9267 
   9268         try {
   9269             synchronized (this) {
   9270                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
   9271                 if (r == null) {
   9272                     throw new IllegalArgumentException("Activity does not exist; token="
   9273                             + activityToken);
   9274                 }
   9275                 ComponentName comp = intent.getComponent();
   9276                 if (comp == null) {
   9277                     throw new IllegalArgumentException("Intent " + intent
   9278                             + " must specify explicit component");
   9279                 }
   9280                 if (thumbnail.getWidth() != mThumbnailWidth
   9281                         || thumbnail.getHeight() != mThumbnailHeight) {
   9282                     throw new IllegalArgumentException("Bad thumbnail size: got "
   9283                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
   9284                             + mThumbnailWidth + "x" + mThumbnailHeight);
   9285                 }
   9286                 if (intent.getSelector() != null) {
   9287                     intent.setSelector(null);
   9288                 }
   9289                 if (intent.getSourceBounds() != null) {
   9290                     intent.setSourceBounds(null);
   9291                 }
   9292                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
   9293                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
   9294                         // The caller has added this as an auto-remove task...  that makes no
   9295                         // sense, so turn off auto-remove.
   9296                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
   9297                     }
   9298                 }
   9299                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
   9300                     mLastAddedTaskActivity = null;
   9301                 }
   9302                 ActivityInfo ainfo = mLastAddedTaskActivity;
   9303                 if (ainfo == null) {
   9304                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
   9305                             comp, 0, UserHandle.getUserId(callingUid));
   9306                     if (ainfo.applicationInfo.uid != callingUid) {
   9307                         throw new SecurityException(
   9308                                 "Can't add task for another application: target uid="
   9309                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
   9310                     }
   9311                 }
   9312 
   9313                 // Use the full screen as the context for the task thumbnail
   9314                 final Point displaySize = new Point();
   9315                 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
   9316                 r.task.stack.getDisplaySize(displaySize);
   9317                 thumbnailInfo.taskWidth = displaySize.x;
   9318                 thumbnailInfo.taskHeight = displaySize.y;
   9319                 thumbnailInfo.screenOrientation = mConfiguration.orientation;
   9320 
   9321                 TaskRecord task = new TaskRecord(this,
   9322                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
   9323                         ainfo, intent, description, thumbnailInfo);
   9324 
   9325                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
   9326                 if (trimIdx >= 0) {
   9327                     // If this would have caused a trim, then we'll abort because that
   9328                     // means it would be added at the end of the list but then just removed.
   9329                     return INVALID_TASK_ID;
   9330                 }
   9331 
   9332                 final int N = mRecentTasks.size();
   9333                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
   9334                     final TaskRecord tr = mRecentTasks.remove(N - 1);
   9335                     tr.removedFromRecents();
   9336                 }
   9337 
   9338                 task.inRecents = true;
   9339                 mRecentTasks.add(task);
   9340                 r.task.stack.addTask(task, false, "addAppTask");
   9341 
   9342                 task.setLastThumbnailLocked(thumbnail);
   9343                 task.freeLastThumbnail();
   9344 
   9345                 return task.taskId;
   9346             }
   9347         } finally {
   9348             Binder.restoreCallingIdentity(callingIdent);
   9349         }
   9350     }
   9351 
   9352     @Override
   9353     public Point getAppTaskThumbnailSize() {
   9354         synchronized (this) {
   9355             return new Point(mThumbnailWidth,  mThumbnailHeight);
   9356         }
   9357     }
   9358 
   9359     @Override
   9360     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
   9361         synchronized (this) {
   9362             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   9363             if (r != null) {
   9364                 r.setTaskDescription(td);
   9365                 r.task.updateTaskDescription();
   9366             }
   9367         }
   9368     }
   9369 
   9370     @Override
   9371     public void setTaskResizeable(int taskId, int resizeableMode) {
   9372         synchronized (this) {
   9373             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
   9374                     taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
   9375             if (task == null) {
   9376                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
   9377                 return;
   9378             }
   9379             if (task.mResizeMode != resizeableMode) {
   9380                 task.mResizeMode = resizeableMode;
   9381                 mWindowManager.setTaskResizeable(taskId, resizeableMode);
   9382                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   9383                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
   9384             }
   9385         }
   9386     }
   9387 
   9388     @Override
   9389     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
   9390         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
   9391         long ident = Binder.clearCallingIdentity();
   9392         try {
   9393             synchronized (this) {
   9394                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   9395                 if (task == null) {
   9396                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
   9397                     return;
   9398                 }
   9399                 int stackId = task.stack.mStackId;
   9400                 // We allow the task to scroll instead of resizing if this is a non-resizeable task
   9401                 // in crop windows resize mode or if the task size is affected by the docked stack
   9402                 // changing size. No need to update configuration.
   9403                 if (bounds != null && task.inCropWindowsResizeMode()
   9404                         && mStackSupervisor.isStackDockedInEffect(stackId)) {
   9405                     mWindowManager.scrollTask(task.taskId, bounds);
   9406                     return;
   9407                 }
   9408 
   9409                 // Place the task in the right stack if it isn't there already based on
   9410                 // the requested bounds.
   9411                 // The stack transition logic is:
   9412                 // - a null bounds on a freeform task moves that task to fullscreen
   9413                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
   9414                 //   that task to freeform
   9415                 // - otherwise the task is not moved
   9416                 if (!StackId.isTaskResizeAllowed(stackId)) {
   9417                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
   9418                 }
   9419                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
   9420                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
   9421                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
   9422                     stackId = FREEFORM_WORKSPACE_STACK_ID;
   9423                 }
   9424                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
   9425                 if (stackId != task.stack.mStackId) {
   9426                     mStackSupervisor.moveTaskToStackUncheckedLocked(
   9427                             task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
   9428                     preserveWindow = false;
   9429                 }
   9430 
   9431                 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
   9432                         false /* deferResume */);
   9433             }
   9434         } finally {
   9435             Binder.restoreCallingIdentity(ident);
   9436         }
   9437     }
   9438 
   9439     @Override
   9440     public Rect getTaskBounds(int taskId) {
   9441         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
   9442         long ident = Binder.clearCallingIdentity();
   9443         Rect rect = new Rect();
   9444         try {
   9445             synchronized (this) {
   9446                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
   9447                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
   9448                 if (task == null) {
   9449                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
   9450                     return rect;
   9451                 }
   9452                 if (task.stack != null) {
   9453                     // Return the bounds from window manager since it will be adjusted for various
   9454                     // things like the presense of a docked stack for tasks that aren't resizeable.
   9455                     mWindowManager.getTaskBounds(task.taskId, rect);
   9456                 } else {
   9457                     // Task isn't in window manager yet since it isn't associated with a stack.
   9458                     // Return the persist value from activity manager
   9459                     if (task.mBounds != null) {
   9460                         rect.set(task.mBounds);
   9461                     } else if (task.mLastNonFullscreenBounds != null) {
   9462                         rect.set(task.mLastNonFullscreenBounds);
   9463                     }
   9464                 }
   9465             }
   9466         } finally {
   9467             Binder.restoreCallingIdentity(ident);
   9468         }
   9469         return rect;
   9470     }
   9471 
   9472     @Override
   9473     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
   9474         if (userId != UserHandle.getCallingUserId()) {
   9475             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   9476                     "getTaskDescriptionIcon");
   9477         }
   9478         final File passedIconFile = new File(filePath);
   9479         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
   9480                 passedIconFile.getName());
   9481         if (!legitIconFile.getPath().equals(filePath)
   9482                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
   9483             throw new IllegalArgumentException("Bad file path: " + filePath
   9484                     + " passed for userId " + userId);
   9485         }
   9486         return mRecentTasks.getTaskDescriptionIcon(filePath);
   9487     }
   9488 
   9489     @Override
   9490     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
   9491             throws RemoteException {
   9492         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
   9493                 opts.getCustomInPlaceResId() == 0) {
   9494             throw new IllegalArgumentException("Expected in-place ActivityOption " +
   9495                     "with valid animation");
   9496         }
   9497         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
   9498         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
   9499                 opts.getCustomInPlaceResId());
   9500         mWindowManager.executeAppTransition();
   9501     }
   9502 
   9503     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
   9504             boolean removeFromRecents) {
   9505         if (removeFromRecents) {
   9506             mRecentTasks.remove(tr);
   9507             tr.removedFromRecents();
   9508         }
   9509         ComponentName component = tr.getBaseIntent().getComponent();
   9510         if (component == null) {
   9511             Slog.w(TAG, "No component for base intent of task: " + tr);
   9512             return;
   9513         }
   9514 
   9515         // Find any running services associated with this app and stop if needed.
   9516         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
   9517 
   9518         if (!killProcess) {
   9519             return;
   9520         }
   9521 
   9522         // Determine if the process(es) for this task should be killed.
   9523         final String pkg = component.getPackageName();
   9524         ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
   9525         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
   9526         for (int i = 0; i < pmap.size(); i++) {
   9527 
   9528             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
   9529             for (int j = 0; j < uids.size(); j++) {
   9530                 ProcessRecord proc = uids.valueAt(j);
   9531                 if (proc.userId != tr.userId) {
   9532                     // Don't kill process for a different user.
   9533                     continue;
   9534                 }
   9535                 if (proc == mHomeProcess) {
   9536                     // Don't kill the home process along with tasks from the same package.
   9537                     continue;
   9538                 }
   9539                 if (!proc.pkgList.containsKey(pkg)) {
   9540                     // Don't kill process that is not associated with this task.
   9541                     continue;
   9542                 }
   9543 
   9544                 for (int k = 0; k < proc.activities.size(); k++) {
   9545                     TaskRecord otherTask = proc.activities.get(k).task;
   9546                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
   9547                         // Don't kill process(es) that has an activity in a different task that is
   9548                         // also in recents.
   9549                         return;
   9550                     }
   9551                 }
   9552 
   9553                 if (proc.foregroundServices) {
   9554                     // Don't kill process(es) with foreground service.
   9555                     return;
   9556                 }
   9557 
   9558                 // Add process to kill list.
   9559                 procsToKill.add(proc);
   9560             }
   9561         }
   9562 
   9563         // Kill the running processes.
   9564         for (int i = 0; i < procsToKill.size(); i++) {
   9565             ProcessRecord pr = procsToKill.get(i);
   9566             if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   9567                     && pr.curReceiver == null) {
   9568                 pr.kill("remove task", true);
   9569             } else {
   9570                 // We delay killing processes that are not in the background or running a receiver.
   9571                 pr.waitingToKill = "remove task";
   9572             }
   9573         }
   9574     }
   9575 
   9576     private void removeTasksByPackageNameLocked(String packageName, int userId) {
   9577         // Remove all tasks with activities in the specified package from the list of recent tasks
   9578         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
   9579             TaskRecord tr = mRecentTasks.get(i);
   9580             if (tr.userId != userId) continue;
   9581 
   9582             ComponentName cn = tr.intent.getComponent();
   9583             if (cn != null && cn.getPackageName().equals(packageName)) {
   9584                 // If the package name matches, remove the task.
   9585                 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
   9586             }
   9587         }
   9588     }
   9589 
   9590     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
   9591             int userId) {
   9592 
   9593         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
   9594             TaskRecord tr = mRecentTasks.get(i);
   9595             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
   9596                 continue;
   9597             }
   9598 
   9599             ComponentName cn = tr.intent.getComponent();
   9600             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
   9601                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
   9602             if (sameComponent) {
   9603                 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
   9604             }
   9605         }
   9606     }
   9607 
   9608     /**
   9609      * Removes the task with the specified task id.
   9610      *
   9611      * @param taskId Identifier of the task to be removed.
   9612      * @param killProcess Kill any process associated with the task if possible.
   9613      * @param removeFromRecents Whether to also remove the task from recents.
   9614      * @return Returns true if the given task was found and removed.
   9615      */
   9616     private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
   9617             boolean removeFromRecents) {
   9618         final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
   9619                 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
   9620         if (tr != null) {
   9621             tr.removeTaskActivitiesLocked();
   9622             cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
   9623             if (tr.isPersistable) {
   9624                 notifyTaskPersisterLocked(null, true);
   9625             }
   9626             return true;
   9627         }
   9628         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
   9629         return false;
   9630     }
   9631 
   9632     @Override
   9633     public void removeStack(int stackId) {
   9634         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
   9635         if (stackId == HOME_STACK_ID) {
   9636             throw new IllegalArgumentException("Removing home stack is not allowed.");
   9637         }
   9638 
   9639         synchronized (this) {
   9640             final long ident = Binder.clearCallingIdentity();
   9641             try {
   9642                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
   9643                 if (stack == null) {
   9644                     return;
   9645                 }
   9646                 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
   9647                 for (int i = tasks.size() - 1; i >= 0; i--) {
   9648                     removeTaskByIdLocked(
   9649                             tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
   9650                 }
   9651             } finally {
   9652                 Binder.restoreCallingIdentity(ident);
   9653             }
   9654         }
   9655     }
   9656 
   9657     @Override
   9658     public boolean removeTask(int taskId) {
   9659         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
   9660         synchronized (this) {
   9661             final long ident = Binder.clearCallingIdentity();
   9662             try {
   9663                 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
   9664             } finally {
   9665                 Binder.restoreCallingIdentity(ident);
   9666             }
   9667         }
   9668     }
   9669 
   9670     /**
   9671      * TODO: Add mController hook
   9672      */
   9673     @Override
   9674     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
   9675         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
   9676 
   9677         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
   9678         synchronized(this) {
   9679             moveTaskToFrontLocked(taskId, flags, bOptions);
   9680         }
   9681     }
   9682 
   9683     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
   9684         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
   9685 
   9686         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   9687                 Binder.getCallingUid(), -1, -1, "Task to front")) {
   9688             ActivityOptions.abort(options);
   9689             return;
   9690         }
   9691         final long origId = Binder.clearCallingIdentity();
   9692         try {
   9693             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   9694             if (task == null) {
   9695                 Slog.d(TAG, "Could not find task for id: "+ taskId);
   9696                 return;
   9697             }
   9698             if (mStackSupervisor.isLockTaskModeViolation(task)) {
   9699                 mStackSupervisor.showLockTaskToast();
   9700                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
   9701                 return;
   9702             }
   9703             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
   9704             if (prev != null && prev.isRecentsActivity()) {
   9705                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
   9706             }
   9707             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
   9708                     false /* forceNonResizable */);
   9709         } finally {
   9710             Binder.restoreCallingIdentity(origId);
   9711         }
   9712         ActivityOptions.abort(options);
   9713     }
   9714 
   9715     /**
   9716      * Moves an activity, and all of the other activities within the same task, to the bottom
   9717      * of the history stack.  The activity's order within the task is unchanged.
   9718      *
   9719      * @param token A reference to the activity we wish to move
   9720      * @param nonRoot If false then this only works if the activity is the root
   9721      *                of a task; if true it will work for any activity in a task.
   9722      * @return Returns true if the move completed, false if not.
   9723      */
   9724     @Override
   9725     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
   9726         enforceNotIsolatedCaller("moveActivityTaskToBack");
   9727         synchronized(this) {
   9728             final long origId = Binder.clearCallingIdentity();
   9729             try {
   9730                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
   9731                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   9732                 if (task != null) {
   9733                     if (mStackSupervisor.isLockedTask(task)) {
   9734                         mStackSupervisor.showLockTaskToast();
   9735                         return false;
   9736                     }
   9737                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
   9738                 }
   9739             } finally {
   9740                 Binder.restoreCallingIdentity(origId);
   9741             }
   9742         }
   9743         return false;
   9744     }
   9745 
   9746     @Override
   9747     public void moveTaskBackwards(int task) {
   9748         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   9749                 "moveTaskBackwards()");
   9750 
   9751         synchronized(this) {
   9752             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   9753                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
   9754                 return;
   9755             }
   9756             final long origId = Binder.clearCallingIdentity();
   9757             moveTaskBackwardsLocked(task);
   9758             Binder.restoreCallingIdentity(origId);
   9759         }
   9760     }
   9761 
   9762     private final void moveTaskBackwardsLocked(int task) {
   9763         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
   9764     }
   9765 
   9766     @Override
   9767     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
   9768             IActivityContainerCallback callback) throws RemoteException {
   9769         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
   9770         synchronized (this) {
   9771             if (parentActivityToken == null) {
   9772                 throw new IllegalArgumentException("parent token must not be null");
   9773             }
   9774             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
   9775             if (r == null) {
   9776                 return null;
   9777             }
   9778             if (callback == null) {
   9779                 throw new IllegalArgumentException("callback must not be null");
   9780             }
   9781             return mStackSupervisor.createVirtualActivityContainer(r, callback);
   9782         }
   9783     }
   9784 
   9785     @Override
   9786     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
   9787         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
   9788         synchronized (this) {
   9789             mStackSupervisor.deleteActivityContainer(container);
   9790         }
   9791     }
   9792 
   9793     @Override
   9794     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
   9795         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
   9796         synchronized (this) {
   9797             final int stackId = mStackSupervisor.getNextStackId();
   9798             final ActivityStack stack =
   9799                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
   9800             if (stack == null) {
   9801                 return null;
   9802             }
   9803             return stack.mActivityContainer;
   9804         }
   9805     }
   9806 
   9807     @Override
   9808     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
   9809         synchronized (this) {
   9810             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
   9811             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
   9812                 return stack.mActivityContainer.getDisplayId();
   9813             }
   9814             return Display.DEFAULT_DISPLAY;
   9815         }
   9816     }
   9817 
   9818     @Override
   9819     public int getActivityStackId(IBinder token) throws RemoteException {
   9820         synchronized (this) {
   9821             ActivityStack stack = ActivityRecord.getStackLocked(token);
   9822             if (stack == null) {
   9823                 return INVALID_STACK_ID;
   9824             }
   9825             return stack.mStackId;
   9826         }
   9827     }
   9828 
   9829     @Override
   9830     public void exitFreeformMode(IBinder token) throws RemoteException {
   9831         synchronized (this) {
   9832             long ident = Binder.clearCallingIdentity();
   9833             try {
   9834                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   9835                 if (r == null) {
   9836                     throw new IllegalArgumentException(
   9837                             "exitFreeformMode: No activity record matching token=" + token);
   9838                 }
   9839                 final ActivityStack stack = r.getStackLocked(token);
   9840                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
   9841                     throw new IllegalStateException(
   9842                             "exitFreeformMode: You can only go fullscreen from freeform.");
   9843                 }
   9844                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
   9845                 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
   9846                         ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
   9847             } finally {
   9848                 Binder.restoreCallingIdentity(ident);
   9849             }
   9850         }
   9851     }
   9852 
   9853     @Override
   9854     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
   9855         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
   9856         if (stackId == HOME_STACK_ID) {
   9857             throw new IllegalArgumentException(
   9858                     "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
   9859         }
   9860         synchronized (this) {
   9861             long ident = Binder.clearCallingIdentity();
   9862             try {
   9863                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
   9864                         + " to stackId=" + stackId + " toTop=" + toTop);
   9865                 if (stackId == DOCKED_STACK_ID) {
   9866                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
   9867                             null /* initialBounds */);
   9868                 }
   9869                 boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
   9870                         !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
   9871                 if (result && stackId == DOCKED_STACK_ID) {
   9872                     // If task moved to docked stack - show recents if needed.
   9873                     mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
   9874                             "moveTaskToDockedStack");
   9875                 }
   9876             } finally {
   9877                 Binder.restoreCallingIdentity(ident);
   9878             }
   9879         }
   9880     }
   9881 
   9882     @Override
   9883     public void swapDockedAndFullscreenStack() throws RemoteException {
   9884         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
   9885         synchronized (this) {
   9886             long ident = Binder.clearCallingIdentity();
   9887             try {
   9888                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
   9889                         FULLSCREEN_WORKSPACE_STACK_ID);
   9890                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
   9891                         : null;
   9892                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
   9893                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
   9894                         : null;
   9895                 if (topTask == null || tasks == null || tasks.size() == 0) {
   9896                     Slog.w(TAG,
   9897                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
   9898                     return;
   9899                 }
   9900 
   9901                 // TODO: App transition
   9902                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
   9903 
   9904                 // Defer the resume so resume/pausing while moving stacks is dangerous.
   9905                 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
   9906                         false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
   9907                         ANIMATE, true /* deferResume */);
   9908                 final int size = tasks.size();
   9909                 for (int i = 0; i < size; i++) {
   9910                     final int id = tasks.get(i).taskId;
   9911                     if (id == topTask.taskId) {
   9912                         continue;
   9913                     }
   9914                     mStackSupervisor.moveTaskToStackLocked(id,
   9915                             FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
   9916                             "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
   9917                 }
   9918 
   9919                 // Because we deferred the resume, to avoid conflicts with stack switches while
   9920                 // resuming, we need to do it after all the tasks are moved.
   9921                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   9922                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
   9923 
   9924                 mWindowManager.executeAppTransition();
   9925             } finally {
   9926                 Binder.restoreCallingIdentity(ident);
   9927             }
   9928         }
   9929     }
   9930 
   9931     /**
   9932      * Moves the input task to the docked stack.
   9933      *
   9934      * @param taskId Id of task to move.
   9935      * @param createMode The mode the docked stack should be created in if it doesn't exist
   9936      *                   already. See
   9937      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
   9938      *                   and
   9939      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
   9940      * @param toTop If the task and stack should be moved to the top.
   9941      * @param animate Whether we should play an animation for the moving the task
   9942      * @param initialBounds If the docked stack gets created, it will use these bounds for the
   9943      *                      docked stack. Pass {@code null} to use default bounds.
   9944      */
   9945     @Override
   9946     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
   9947             Rect initialBounds, boolean moveHomeStackFront) {
   9948         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
   9949         synchronized (this) {
   9950             long ident = Binder.clearCallingIdentity();
   9951             try {
   9952                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
   9953                         + " to createMode=" + createMode + " toTop=" + toTop);
   9954                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
   9955                 final boolean moved = mStackSupervisor.moveTaskToStackLocked(
   9956                         taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
   9957                         animate, DEFER_RESUME);
   9958                 if (moved) {
   9959                     if (moveHomeStackFront) {
   9960                         mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
   9961                     }
   9962                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   9963                 }
   9964                 return moved;
   9965             } finally {
   9966                 Binder.restoreCallingIdentity(ident);
   9967             }
   9968         }
   9969     }
   9970 
   9971     /**
   9972      * Moves the top activity in the input stackId to the pinned stack.
   9973      *
   9974      * @param stackId Id of stack to move the top activity to pinned stack.
   9975      * @param bounds Bounds to use for pinned stack.
   9976      *
   9977      * @return True if the top activity of the input stack was successfully moved to the pinned
   9978      *          stack.
   9979      */
   9980     @Override
   9981     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
   9982         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
   9983         synchronized (this) {
   9984             if (!mSupportsPictureInPicture) {
   9985                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
   9986                         + "Device doesn't support picture-in-pciture mode");
   9987             }
   9988 
   9989             long ident = Binder.clearCallingIdentity();
   9990             try {
   9991                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
   9992             } finally {
   9993                 Binder.restoreCallingIdentity(ident);
   9994             }
   9995         }
   9996     }
   9997 
   9998     @Override
   9999     public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
   10000             boolean preserveWindows, boolean animate, int animationDuration) {
   10001         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
   10002         long ident = Binder.clearCallingIdentity();
   10003         try {
   10004             synchronized (this) {
   10005                 if (animate) {
   10006                     if (stackId == PINNED_STACK_ID) {
   10007                         mWindowManager.animateResizePinnedStack(bounds, animationDuration);
   10008                     } else {
   10009                         throw new IllegalArgumentException("Stack: " + stackId
   10010                                 + " doesn't support animated resize.");
   10011                     }
   10012                 } else {
   10013                     mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
   10014                             null /* tempTaskInsetBounds */, preserveWindows,
   10015                             allowResizeInDockedMode, !DEFER_RESUME);
   10016                 }
   10017             }
   10018         } finally {
   10019             Binder.restoreCallingIdentity(ident);
   10020         }
   10021     }
   10022 
   10023     @Override
   10024     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
   10025             Rect tempDockedTaskInsetBounds,
   10026             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
   10027         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   10028                 "resizeDockedStack()");
   10029         long ident = Binder.clearCallingIdentity();
   10030         try {
   10031             synchronized (this) {
   10032                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
   10033                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
   10034                         PRESERVE_WINDOWS);
   10035             }
   10036         } finally {
   10037             Binder.restoreCallingIdentity(ident);
   10038         }
   10039     }
   10040 
   10041     @Override
   10042     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
   10043         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   10044                 "resizePinnedStack()");
   10045         final long ident = Binder.clearCallingIdentity();
   10046         try {
   10047             synchronized (this) {
   10048                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
   10049             }
   10050         } finally {
   10051             Binder.restoreCallingIdentity(ident);
   10052         }
   10053     }
   10054 
   10055     @Override
   10056     public void positionTaskInStack(int taskId, int stackId, int position) {
   10057         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
   10058         if (stackId == HOME_STACK_ID) {
   10059             throw new IllegalArgumentException(
   10060                     "positionTaskInStack: Attempt to change the position of task "
   10061                     + taskId + " in/to home stack");
   10062         }
   10063         synchronized (this) {
   10064             long ident = Binder.clearCallingIdentity();
   10065             try {
   10066                 if (DEBUG_STACK) Slog.d(TAG_STACK,
   10067                         "positionTaskInStack: positioning task=" + taskId
   10068                         + " in stackId=" + stackId + " at position=" + position);
   10069                 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
   10070             } finally {
   10071                 Binder.restoreCallingIdentity(ident);
   10072             }
   10073         }
   10074     }
   10075 
   10076     @Override
   10077     public List<StackInfo> getAllStackInfos() {
   10078         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
   10079         long ident = Binder.clearCallingIdentity();
   10080         try {
   10081             synchronized (this) {
   10082                 return mStackSupervisor.getAllStackInfosLocked();
   10083             }
   10084         } finally {
   10085             Binder.restoreCallingIdentity(ident);
   10086         }
   10087     }
   10088 
   10089     @Override
   10090     public StackInfo getStackInfo(int stackId) {
   10091         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
   10092         long ident = Binder.clearCallingIdentity();
   10093         try {
   10094             synchronized (this) {
   10095                 return mStackSupervisor.getStackInfoLocked(stackId);
   10096             }
   10097         } finally {
   10098             Binder.restoreCallingIdentity(ident);
   10099         }
   10100     }
   10101 
   10102     @Override
   10103     public boolean isInHomeStack(int taskId) {
   10104         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
   10105         long ident = Binder.clearCallingIdentity();
   10106         try {
   10107             synchronized (this) {
   10108                 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
   10109                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
   10110                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
   10111             }
   10112         } finally {
   10113             Binder.restoreCallingIdentity(ident);
   10114         }
   10115     }
   10116 
   10117     @Override
   10118     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
   10119         synchronized(this) {
   10120             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
   10121         }
   10122     }
   10123 
   10124     @Override
   10125     public void updateDeviceOwner(String packageName) {
   10126         final int callingUid = Binder.getCallingUid();
   10127         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   10128             throw new SecurityException("updateDeviceOwner called from non-system process");
   10129         }
   10130         synchronized (this) {
   10131             mDeviceOwnerName = packageName;
   10132         }
   10133     }
   10134 
   10135     @Override
   10136     public void updateLockTaskPackages(int userId, String[] packages) {
   10137         final int callingUid = Binder.getCallingUid();
   10138         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   10139             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
   10140                     "updateLockTaskPackages()");
   10141         }
   10142         synchronized (this) {
   10143             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
   10144                     Arrays.toString(packages));
   10145             mLockTaskPackages.put(userId, packages);
   10146             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
   10147         }
   10148     }
   10149 
   10150 
   10151     void startLockTaskModeLocked(TaskRecord task) {
   10152         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
   10153         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
   10154             return;
   10155         }
   10156 
   10157         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
   10158         // is initiated by system after the pinning request was shown and locked mode is initiated
   10159         // by an authorized app directly
   10160         final int callingUid = Binder.getCallingUid();
   10161         boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
   10162         long ident = Binder.clearCallingIdentity();
   10163         try {
   10164             if (!isSystemInitiated) {
   10165                 task.mLockTaskUid = callingUid;
   10166                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
   10167                     // startLockTask() called by app and task mode is lockTaskModeDefault.
   10168                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
   10169                     StatusBarManagerInternal statusBarManager =
   10170                             LocalServices.getService(StatusBarManagerInternal.class);
   10171                     if (statusBarManager != null) {
   10172                         statusBarManager.showScreenPinningRequest(task.taskId);
   10173                     }
   10174                     return;
   10175                 }
   10176 
   10177                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
   10178                 if (stack == null || task != stack.topTask()) {
   10179                     throw new IllegalArgumentException("Invalid task, not in foreground");
   10180                 }
   10181             }
   10182             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
   10183                     "Locking fully");
   10184             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
   10185                     ActivityManager.LOCK_TASK_MODE_PINNED :
   10186                     ActivityManager.LOCK_TASK_MODE_LOCKED,
   10187                     "startLockTask", true);
   10188         } finally {
   10189             Binder.restoreCallingIdentity(ident);
   10190         }
   10191     }
   10192 
   10193     @Override
   10194     public void startLockTaskMode(int taskId) {
   10195         synchronized (this) {
   10196             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   10197             if (task != null) {
   10198                 startLockTaskModeLocked(task);
   10199             }
   10200         }
   10201     }
   10202 
   10203     @Override
   10204     public void startLockTaskMode(IBinder token) {
   10205         synchronized (this) {
   10206             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   10207             if (r == null) {
   10208                 return;
   10209             }
   10210             final TaskRecord task = r.task;
   10211             if (task != null) {
   10212                 startLockTaskModeLocked(task);
   10213             }
   10214         }
   10215     }
   10216 
   10217     @Override
   10218     public void startSystemLockTaskMode(int taskId) throws RemoteException {
   10219         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
   10220         // This makes inner call to look as if it was initiated by system.
   10221         long ident = Binder.clearCallingIdentity();
   10222         try {
   10223             synchronized (this) {
   10224                 startLockTaskMode(taskId);
   10225             }
   10226         } finally {
   10227             Binder.restoreCallingIdentity(ident);
   10228         }
   10229     }
   10230 
   10231     @Override
   10232     public void stopLockTaskMode() {
   10233         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
   10234         if (lockTask == null) {
   10235             // Our work here is done.
   10236             return;
   10237         }
   10238 
   10239         final int callingUid = Binder.getCallingUid();
   10240         final int lockTaskUid = lockTask.mLockTaskUid;
   10241         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
   10242         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
   10243             // Done.
   10244             return;
   10245         } else {
   10246             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
   10247             // It is possible lockTaskMode was started by the system process because
   10248             // android:lockTaskMode is set to a locking value in the application manifest
   10249             // instead of the app calling startLockTaskMode. In this case
   10250             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
   10251             // {@link TaskRecord.effectiveUid} instead. Also caller with
   10252             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
   10253             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
   10254                     && callingUid != lockTaskUid
   10255                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
   10256                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
   10257                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
   10258             }
   10259         }
   10260         long ident = Binder.clearCallingIdentity();
   10261         try {
   10262             Log.d(TAG, "stopLockTaskMode");
   10263             // Stop lock task
   10264             synchronized (this) {
   10265                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
   10266                         "stopLockTask", true);
   10267             }
   10268             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
   10269             if (tm != null) {
   10270                 tm.showInCallScreen(false);
   10271             }
   10272         } finally {
   10273             Binder.restoreCallingIdentity(ident);
   10274         }
   10275     }
   10276 
   10277     /**
   10278      * This API should be called by SystemUI only when user perform certain action to dismiss
   10279      * lock task mode. We should only dismiss pinned lock task mode in this case.
   10280      */
   10281     @Override
   10282     public void stopSystemLockTaskMode() throws RemoteException {
   10283         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
   10284             stopLockTaskMode();
   10285         } else {
   10286             mStackSupervisor.showLockTaskToast();
   10287         }
   10288     }
   10289 
   10290     @Override
   10291     public boolean isInLockTaskMode() {
   10292         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
   10293     }
   10294 
   10295     @Override
   10296     public int getLockTaskModeState() {
   10297         synchronized (this) {
   10298             return mStackSupervisor.getLockTaskModeState();
   10299         }
   10300     }
   10301 
   10302     @Override
   10303     public void showLockTaskEscapeMessage(IBinder token) {
   10304         synchronized (this) {
   10305             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   10306             if (r == null) {
   10307                 return;
   10308             }
   10309             mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
   10310         }
   10311     }
   10312 
   10313     // =========================================================
   10314     // CONTENT PROVIDERS
   10315     // =========================================================
   10316 
   10317     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
   10318         List<ProviderInfo> providers = null;
   10319         try {
   10320             providers = AppGlobals.getPackageManager()
   10321                     .queryContentProviders(app.processName, app.uid,
   10322                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
   10323                                     | MATCH_DEBUG_TRIAGED_MISSING)
   10324                     .getList();
   10325         } catch (RemoteException ex) {
   10326         }
   10327         if (DEBUG_MU) Slog.v(TAG_MU,
   10328                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
   10329         int userId = app.userId;
   10330         if (providers != null) {
   10331             int N = providers.size();
   10332             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
   10333             for (int i=0; i<N; i++) {
   10334                 // TODO: keep logic in sync with installEncryptionUnawareProviders
   10335                 ProviderInfo cpi =
   10336                     (ProviderInfo)providers.get(i);
   10337                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   10338                         cpi.name, cpi.flags);
   10339                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
   10340                     // This is a singleton provider, but a user besides the
   10341                     // default user is asking to initialize a process it runs
   10342                     // in...  well, no, it doesn't actually run in this process,
   10343                     // it runs in the process of the default user.  Get rid of it.
   10344                     providers.remove(i);
   10345                     N--;
   10346                     i--;
   10347                     continue;
   10348                 }
   10349 
   10350                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   10351                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
   10352                 if (cpr == null) {
   10353                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
   10354                     mProviderMap.putProviderByClass(comp, cpr);
   10355                 }
   10356                 if (DEBUG_MU) Slog.v(TAG_MU,
   10357                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
   10358                 app.pubProviders.put(cpi.name, cpr);
   10359                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
   10360                     // Don't add this if it is a platform component that is marked
   10361                     // to run in multiple processes, because this is actually
   10362                     // part of the framework so doesn't make sense to track as a
   10363                     // separate apk in the process.
   10364                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
   10365                             mProcessStats);
   10366                 }
   10367                 notifyPackageUse(cpi.applicationInfo.packageName,
   10368                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
   10369             }
   10370         }
   10371         return providers;
   10372     }
   10373 
   10374     /**
   10375      * Check if {@link ProcessRecord} has a possible chance at accessing the
   10376      * given {@link ProviderInfo}. Final permission checking is always done
   10377      * in {@link ContentProvider}.
   10378      */
   10379     private final String checkContentProviderPermissionLocked(
   10380             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
   10381         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
   10382         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
   10383         boolean checkedGrants = false;
   10384         if (checkUser) {
   10385             // Looking for cross-user grants before enforcing the typical cross-users permissions
   10386             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
   10387             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
   10388                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
   10389                     return null;
   10390                 }
   10391                 checkedGrants = true;
   10392             }
   10393             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
   10394                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
   10395             if (userId != tmpTargetUserId) {
   10396                 // When we actually went to determine the final targer user ID, this ended
   10397                 // up different than our initial check for the authority.  This is because
   10398                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
   10399                 // SELF.  So we need to re-check the grants again.
   10400                 checkedGrants = false;
   10401             }
   10402         }
   10403         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
   10404                 cpi.applicationInfo.uid, cpi.exported)
   10405                 == PackageManager.PERMISSION_GRANTED) {
   10406             return null;
   10407         }
   10408         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
   10409                 cpi.applicationInfo.uid, cpi.exported)
   10410                 == PackageManager.PERMISSION_GRANTED) {
   10411             return null;
   10412         }
   10413 
   10414         PathPermission[] pps = cpi.pathPermissions;
   10415         if (pps != null) {
   10416             int i = pps.length;
   10417             while (i > 0) {
   10418                 i--;
   10419                 PathPermission pp = pps[i];
   10420                 String pprperm = pp.getReadPermission();
   10421                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
   10422                         cpi.applicationInfo.uid, cpi.exported)
   10423                         == PackageManager.PERMISSION_GRANTED) {
   10424                     return null;
   10425                 }
   10426                 String ppwperm = pp.getWritePermission();
   10427                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
   10428                         cpi.applicationInfo.uid, cpi.exported)
   10429                         == PackageManager.PERMISSION_GRANTED) {
   10430                     return null;
   10431                 }
   10432             }
   10433         }
   10434         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
   10435             return null;
   10436         }
   10437 
   10438         String msg;
   10439         if (!cpi.exported) {
   10440             msg = "Permission Denial: opening provider " + cpi.name
   10441                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   10442                     + ", uid=" + callingUid + ") that is not exported from uid "
   10443                     + cpi.applicationInfo.uid;
   10444         } else {
   10445             msg = "Permission Denial: opening provider " + cpi.name
   10446                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   10447                     + ", uid=" + callingUid + ") requires "
   10448                     + cpi.readPermission + " or " + cpi.writePermission;
   10449         }
   10450         Slog.w(TAG, msg);
   10451         return msg;
   10452     }
   10453 
   10454     /**
   10455      * Returns if the ContentProvider has granted a uri to callingUid
   10456      */
   10457     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
   10458         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   10459         if (perms != null) {
   10460             for (int i=perms.size()-1; i>=0; i--) {
   10461                 GrantUri grantUri = perms.keyAt(i);
   10462                 if (grantUri.sourceUserId == userId || !checkUser) {
   10463                     if (matchesProvider(grantUri.uri, cpi)) {
   10464                         return true;
   10465                     }
   10466                 }
   10467             }
   10468         }
   10469         return false;
   10470     }
   10471 
   10472     /**
   10473      * Returns true if the uri authority is one of the authorities specified in the provider.
   10474      */
   10475     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
   10476         String uriAuth = uri.getAuthority();
   10477         String cpiAuth = cpi.authority;
   10478         if (cpiAuth.indexOf(';') == -1) {
   10479             return cpiAuth.equals(uriAuth);
   10480         }
   10481         String[] cpiAuths = cpiAuth.split(";");
   10482         int length = cpiAuths.length;
   10483         for (int i = 0; i < length; i++) {
   10484             if (cpiAuths[i].equals(uriAuth)) return true;
   10485         }
   10486         return false;
   10487     }
   10488 
   10489     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
   10490             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   10491         if (r != null) {
   10492             for (int i=0; i<r.conProviders.size(); i++) {
   10493                 ContentProviderConnection conn = r.conProviders.get(i);
   10494                 if (conn.provider == cpr) {
   10495                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
   10496                             "Adding provider requested by "
   10497                             + r.processName + " from process "
   10498                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   10499                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   10500                     if (stable) {
   10501                         conn.stableCount++;
   10502                         conn.numStableIncs++;
   10503                     } else {
   10504                         conn.unstableCount++;
   10505                         conn.numUnstableIncs++;
   10506                     }
   10507                     return conn;
   10508                 }
   10509             }
   10510             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
   10511             if (stable) {
   10512                 conn.stableCount = 1;
   10513                 conn.numStableIncs = 1;
   10514             } else {
   10515                 conn.unstableCount = 1;
   10516                 conn.numUnstableIncs = 1;
   10517             }
   10518             cpr.connections.add(conn);
   10519             r.conProviders.add(conn);
   10520             startAssociationLocked(r.uid, r.processName, r.curProcState,
   10521                     cpr.uid, cpr.name, cpr.info.processName);
   10522             return conn;
   10523         }
   10524         cpr.addExternalProcessHandleLocked(externalProcessToken);
   10525         return null;
   10526     }
   10527 
   10528     boolean decProviderCountLocked(ContentProviderConnection conn,
   10529             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   10530         if (conn != null) {
   10531             cpr = conn.provider;
   10532             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
   10533                     "Removing provider requested by "
   10534                     + conn.client.processName + " from process "
   10535                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   10536                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   10537             if (stable) {
   10538                 conn.stableCount--;
   10539             } else {
   10540                 conn.unstableCount--;
   10541             }
   10542             if (conn.stableCount == 0 && conn.unstableCount == 0) {
   10543                 cpr.connections.remove(conn);
   10544                 conn.client.conProviders.remove(conn);
   10545                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   10546                     // The client is more important than last activity -- note the time this
   10547                     // is happening, so we keep the old provider process around a bit as last
   10548                     // activity to avoid thrashing it.
   10549                     if (cpr.proc != null) {
   10550                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
   10551                     }
   10552                 }
   10553                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
   10554                 return true;
   10555             }
   10556             return false;
   10557         }
   10558         cpr.removeExternalProcessHandleLocked(externalProcessToken);
   10559         return false;
   10560     }
   10561 
   10562     private void checkTime(long startTime, String where) {
   10563         long now = SystemClock.uptimeMillis();
   10564         if ((now-startTime) > 50) {
   10565             // If we are taking more than 50ms, log about it.
   10566             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
   10567         }
   10568     }
   10569 
   10570     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
   10571             PROC_SPACE_TERM,
   10572             PROC_SPACE_TERM|PROC_PARENS,
   10573             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
   10574     };
   10575 
   10576     private final long[] mProcessStateStatsLongs = new long[1];
   10577 
   10578     boolean isProcessAliveLocked(ProcessRecord proc) {
   10579         if (proc.procStatFile == null) {
   10580             proc.procStatFile = "/proc/" + proc.pid + "/stat";
   10581         }
   10582         mProcessStateStatsLongs[0] = 0;
   10583         if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
   10584                 mProcessStateStatsLongs, null)) {
   10585             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
   10586             return false;
   10587         }
   10588         final long state = mProcessStateStatsLongs[0];
   10589         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
   10590                 + (char)state);
   10591         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
   10592     }
   10593 
   10594     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
   10595             String name, IBinder token, boolean stable, int userId) {
   10596         ContentProviderRecord cpr;
   10597         ContentProviderConnection conn = null;
   10598         ProviderInfo cpi = null;
   10599 
   10600         synchronized(this) {
   10601             long startTime = SystemClock.uptimeMillis();
   10602 
   10603             ProcessRecord r = null;
   10604             if (caller != null) {
   10605                 r = getRecordForAppLocked(caller);
   10606                 if (r == null) {
   10607                     throw new SecurityException(
   10608                             "Unable to find app for caller " + caller
   10609                           + " (pid=" + Binder.getCallingPid()
   10610                           + ") when getting content provider " + name);
   10611                 }
   10612             }
   10613 
   10614             boolean checkCrossUser = true;
   10615 
   10616             checkTime(startTime, "getContentProviderImpl: getProviderByName");
   10617 
   10618             // First check if this content provider has been published...
   10619             cpr = mProviderMap.getProviderByName(name, userId);
   10620             // If that didn't work, check if it exists for user 0 and then
   10621             // verify that it's a singleton provider before using it.
   10622             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
   10623                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
   10624                 if (cpr != null) {
   10625                     cpi = cpr.info;
   10626                     if (isSingleton(cpi.processName, cpi.applicationInfo,
   10627                             cpi.name, cpi.flags)
   10628                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
   10629                         userId = UserHandle.USER_SYSTEM;
   10630                         checkCrossUser = false;
   10631                     } else {
   10632                         cpr = null;
   10633                         cpi = null;
   10634                     }
   10635                 }
   10636             }
   10637 
   10638             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
   10639             if (providerRunning) {
   10640                 cpi = cpr.info;
   10641                 String msg;
   10642                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
   10643                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
   10644                         != null) {
   10645                     throw new SecurityException(msg);
   10646                 }
   10647                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
   10648 
   10649                 if (r != null && cpr.canRunHere(r)) {
   10650                     // This provider has been published or is in the process
   10651                     // of being published...  but it is also allowed to run
   10652                     // in the caller's process, so don't make a connection
   10653                     // and just let the caller instantiate its own instance.
   10654                     ContentProviderHolder holder = cpr.newHolder(null);
   10655                     // don't give caller the provider object, it needs
   10656                     // to make its own.
   10657                     holder.provider = null;
   10658                     return holder;
   10659                 }
   10660 
   10661                 final long origId = Binder.clearCallingIdentity();
   10662 
   10663                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
   10664 
   10665                 // In this case the provider instance already exists, so we can
   10666                 // return it right away.
   10667                 conn = incProviderCountLocked(r, cpr, token, stable);
   10668                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
   10669                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   10670                         // If this is a perceptible app accessing the provider,
   10671                         // make sure to count it as being accessed and thus
   10672                         // back up on the LRU list.  This is good because
   10673                         // content providers are often expensive to start.
   10674                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
   10675                         updateLruProcessLocked(cpr.proc, false, null);
   10676                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
   10677                     }
   10678                 }
   10679 
   10680                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
   10681                 final int verifiedAdj = cpr.proc.verifiedAdj;
   10682                 boolean success = updateOomAdjLocked(cpr.proc);
   10683                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
   10684                 // if the process has been successfully adjusted.  So to reduce races with
   10685                 // it, we will check whether the process still exists.  Note that this doesn't
   10686                 // completely get rid of races with LMK killing the process, but should make
   10687                 // them much smaller.
   10688                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
   10689                     success = false;
   10690                 }
   10691                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
   10692                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
   10693                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
   10694                 // NOTE: there is still a race here where a signal could be
   10695                 // pending on the process even though we managed to update its
   10696                 // adj level.  Not sure what to do about this, but at least
   10697                 // the race is now smaller.
   10698                 if (!success) {
   10699                     // Uh oh...  it looks like the provider's process
   10700                     // has been killed on us.  We need to wait for a new
   10701                     // process to be started, and make sure its death
   10702                     // doesn't kill our process.
   10703                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
   10704                             + " is crashing; detaching " + r);
   10705                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
   10706                     checkTime(startTime, "getContentProviderImpl: before appDied");
   10707                     appDiedLocked(cpr.proc);
   10708                     checkTime(startTime, "getContentProviderImpl: after appDied");
   10709                     if (!lastRef) {
   10710                         // This wasn't the last ref our process had on
   10711                         // the provider...  we have now been killed, bail.
   10712                         return null;
   10713                     }
   10714                     providerRunning = false;
   10715                     conn = null;
   10716                 } else {
   10717                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
   10718                 }
   10719 
   10720                 Binder.restoreCallingIdentity(origId);
   10721             }
   10722 
   10723             if (!providerRunning) {
   10724                 try {
   10725                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
   10726                     cpi = AppGlobals.getPackageManager().
   10727                         resolveContentProvider(name,
   10728                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
   10729                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
   10730                 } catch (RemoteException ex) {
   10731                 }
   10732                 if (cpi == null) {
   10733                     return null;
   10734                 }
   10735                 // If the provider is a singleton AND
   10736                 // (it's a call within the same user || the provider is a
   10737                 // privileged app)
   10738                 // Then allow connecting to the singleton provider
   10739                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   10740                         cpi.name, cpi.flags)
   10741                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
   10742                 if (singleton) {
   10743                     userId = UserHandle.USER_SYSTEM;
   10744                 }
   10745                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
   10746                 checkTime(startTime, "getContentProviderImpl: got app info for user");
   10747 
   10748                 String msg;
   10749                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
   10750                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
   10751                         != null) {
   10752                     throw new SecurityException(msg);
   10753                 }
   10754                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
   10755 
   10756                 if (!mProcessesReady
   10757                         && !cpi.processName.equals("system")) {
   10758                     // If this content provider does not run in the system
   10759                     // process, and the system is not yet ready to run other
   10760                     // processes, then fail fast instead of hanging.
   10761                     throw new IllegalArgumentException(
   10762                             "Attempt to launch content provider before system ready");
   10763                 }
   10764 
   10765                 // Make sure that the user who owns this provider is running.  If not,
   10766                 // we don't want to allow it to run.
   10767                 if (!mUserController.isUserRunningLocked(userId, 0)) {
   10768                     Slog.w(TAG, "Unable to launch app "
   10769                             + cpi.applicationInfo.packageName + "/"
   10770                             + cpi.applicationInfo.uid + " for provider "
   10771                             + name + ": user " + userId + " is stopped");
   10772                     return null;
   10773                 }
   10774 
   10775                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   10776                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
   10777                 cpr = mProviderMap.getProviderByClass(comp, userId);
   10778                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
   10779                 final boolean firstClass = cpr == null;
   10780                 if (firstClass) {
   10781                     final long ident = Binder.clearCallingIdentity();
   10782 
   10783                     // If permissions need a review before any of the app components can run,
   10784                     // we return no provider and launch a review activity if the calling app
   10785                     // is in the foreground.
   10786                     if (Build.PERMISSIONS_REVIEW_REQUIRED) {
   10787                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
   10788                             return null;
   10789                         }
   10790                     }
   10791 
   10792                     try {
   10793                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
   10794                         ApplicationInfo ai =
   10795                             AppGlobals.getPackageManager().
   10796                                 getApplicationInfo(
   10797                                         cpi.applicationInfo.packageName,
   10798                                         STOCK_PM_FLAGS, userId);
   10799                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
   10800                         if (ai == null) {
   10801                             Slog.w(TAG, "No package info for content provider "
   10802                                     + cpi.name);
   10803                             return null;
   10804                         }
   10805                         ai = getAppInfoForUser(ai, userId);
   10806                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
   10807                     } catch (RemoteException ex) {
   10808                         // pm is in same process, this will never happen.
   10809                     } finally {
   10810                         Binder.restoreCallingIdentity(ident);
   10811                     }
   10812                 }
   10813 
   10814                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
   10815 
   10816                 if (r != null && cpr.canRunHere(r)) {
   10817                     // If this is a multiprocess provider, then just return its
   10818                     // info and allow the caller to instantiate it.  Only do
   10819                     // this if the provider is the same user as the caller's
   10820                     // process, or can run as root (so can be in any process).
   10821                     return cpr.newHolder(null);
   10822                 }
   10823 
   10824                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
   10825                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
   10826                             + cpr.info.name + " callers=" + Debug.getCallers(6));
   10827 
   10828                 // This is single process, and our app is now connecting to it.
   10829                 // See if we are already in the process of launching this
   10830                 // provider.
   10831                 final int N = mLaunchingProviders.size();
   10832                 int i;
   10833                 for (i = 0; i < N; i++) {
   10834                     if (mLaunchingProviders.get(i) == cpr) {
   10835                         break;
   10836                     }
   10837                 }
   10838 
   10839                 // If the provider is not already being launched, then get it
   10840                 // started.
   10841                 if (i >= N) {
   10842                     final long origId = Binder.clearCallingIdentity();
   10843 
   10844                     try {
   10845                         // Content provider is now in use, its package can't be stopped.
   10846                         try {
   10847                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
   10848                             AppGlobals.getPackageManager().setPackageStoppedState(
   10849                                     cpr.appInfo.packageName, false, userId);
   10850                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
   10851                         } catch (RemoteException e) {
   10852                         } catch (IllegalArgumentException e) {
   10853                             Slog.w(TAG, "Failed trying to unstop package "
   10854                                     + cpr.appInfo.packageName + ": " + e);
   10855                         }
   10856 
   10857                         // Use existing process if already started
   10858                         checkTime(startTime, "getContentProviderImpl: looking for process record");
   10859                         ProcessRecord proc = getProcessRecordLocked(
   10860                                 cpi.processName, cpr.appInfo.uid, false);
   10861                         if (proc != null && proc.thread != null && !proc.killed) {
   10862                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
   10863                                     "Installing in existing process " + proc);
   10864                             if (!proc.pubProviders.containsKey(cpi.name)) {
   10865                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
   10866                                 proc.pubProviders.put(cpi.name, cpr);
   10867                                 try {
   10868                                     proc.thread.scheduleInstallProvider(cpi);
   10869                                 } catch (RemoteException e) {
   10870                                 }
   10871                             }
   10872                         } else {
   10873                             checkTime(startTime, "getContentProviderImpl: before start process");
   10874                             proc = startProcessLocked(cpi.processName,
   10875                                     cpr.appInfo, false, 0, "content provider",
   10876                                     new ComponentName(cpi.applicationInfo.packageName,
   10877                                             cpi.name), false, false, false);
   10878                             checkTime(startTime, "getContentProviderImpl: after start process");
   10879                             if (proc == null) {
   10880                                 Slog.w(TAG, "Unable to launch app "
   10881                                         + cpi.applicationInfo.packageName + "/"
   10882                                         + cpi.applicationInfo.uid + " for provider "
   10883                                         + name + ": process is bad");
   10884                                 return null;
   10885                             }
   10886                         }
   10887                         cpr.launchingApp = proc;
   10888                         mLaunchingProviders.add(cpr);
   10889                     } finally {
   10890                         Binder.restoreCallingIdentity(origId);
   10891                     }
   10892                 }
   10893 
   10894                 checkTime(startTime, "getContentProviderImpl: updating data structures");
   10895 
   10896                 // Make sure the provider is published (the same provider class
   10897                 // may be published under multiple names).
   10898                 if (firstClass) {
   10899                     mProviderMap.putProviderByClass(comp, cpr);
   10900                 }
   10901 
   10902                 mProviderMap.putProviderByName(name, cpr);
   10903                 conn = incProviderCountLocked(r, cpr, token, stable);
   10904                 if (conn != null) {
   10905                     conn.waiting = true;
   10906                 }
   10907             }
   10908             checkTime(startTime, "getContentProviderImpl: done!");
   10909         }
   10910 
   10911         // Wait for the provider to be published...
   10912         synchronized (cpr) {
   10913             while (cpr.provider == null) {
   10914                 if (cpr.launchingApp == null) {
   10915                     Slog.w(TAG, "Unable to launch app "
   10916                             + cpi.applicationInfo.packageName + "/"
   10917                             + cpi.applicationInfo.uid + " for provider "
   10918                             + name + ": launching app became null");
   10919                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
   10920                             UserHandle.getUserId(cpi.applicationInfo.uid),
   10921                             cpi.applicationInfo.packageName,
   10922                             cpi.applicationInfo.uid, name);
   10923                     return null;
   10924                 }
   10925                 try {
   10926                     if (DEBUG_MU) Slog.v(TAG_MU,
   10927                             "Waiting to start provider " + cpr
   10928                             + " launchingApp=" + cpr.launchingApp);
   10929                     if (conn != null) {
   10930                         conn.waiting = true;
   10931                     }
   10932                     cpr.wait();
   10933                 } catch (InterruptedException ex) {
   10934                 } finally {
   10935                     if (conn != null) {
   10936                         conn.waiting = false;
   10937                     }
   10938                 }
   10939             }
   10940         }
   10941         return cpr != null ? cpr.newHolder(conn) : null;
   10942     }
   10943 
   10944     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
   10945             ProcessRecord r, final int userId) {
   10946         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
   10947                 cpi.packageName, userId)) {
   10948 
   10949             final boolean callerForeground = r == null || r.setSchedGroup
   10950                     != ProcessList.SCHED_GROUP_BACKGROUND;
   10951 
   10952             // Show a permission review UI only for starting from a foreground app
   10953             if (!callerForeground) {
   10954                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
   10955                         + cpi.packageName + " requires a permissions review");
   10956                 return false;
   10957             }
   10958 
   10959             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
   10960             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
   10961                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
   10962             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
   10963 
   10964             if (DEBUG_PERMISSIONS_REVIEW) {
   10965                 Slog.i(TAG, "u" + userId + " Launching permission review "
   10966                         + "for package " + cpi.packageName);
   10967             }
   10968 
   10969             final UserHandle userHandle = new UserHandle(userId);
   10970             mHandler.post(new Runnable() {
   10971                 @Override
   10972                 public void run() {
   10973                     mContext.startActivityAsUser(intent, userHandle);
   10974                 }
   10975             });
   10976 
   10977             return false;
   10978         }
   10979 
   10980         return true;
   10981     }
   10982 
   10983     PackageManagerInternal getPackageManagerInternalLocked() {
   10984         if (mPackageManagerInt == null) {
   10985             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
   10986         }
   10987         return mPackageManagerInt;
   10988     }
   10989 
   10990     @Override
   10991     public final ContentProviderHolder getContentProvider(
   10992             IApplicationThread caller, String name, int userId, boolean stable) {
   10993         enforceNotIsolatedCaller("getContentProvider");
   10994         if (caller == null) {
   10995             String msg = "null IApplicationThread when getting content provider "
   10996                     + name;
   10997             Slog.w(TAG, msg);
   10998             throw new SecurityException(msg);
   10999         }
   11000         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
   11001         // with cross-user grant.
   11002         return getContentProviderImpl(caller, name, null, stable, userId);
   11003     }
   11004 
   11005     public ContentProviderHolder getContentProviderExternal(
   11006             String name, int userId, IBinder token) {
   11007         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   11008             "Do not have permission in call getContentProviderExternal()");
   11009         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   11010                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
   11011         return getContentProviderExternalUnchecked(name, token, userId);
   11012     }
   11013 
   11014     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
   11015             IBinder token, int userId) {
   11016         return getContentProviderImpl(null, name, token, true, userId);
   11017     }
   11018 
   11019     /**
   11020      * Drop a content provider from a ProcessRecord's bookkeeping
   11021      */
   11022     public void removeContentProvider(IBinder connection, boolean stable) {
   11023         enforceNotIsolatedCaller("removeContentProvider");
   11024         long ident = Binder.clearCallingIdentity();
   11025         try {
   11026             synchronized (this) {
   11027                 ContentProviderConnection conn;
   11028                 try {
   11029                     conn = (ContentProviderConnection)connection;
   11030                 } catch (ClassCastException e) {
   11031                     String msg ="removeContentProvider: " + connection
   11032                             + " not a ContentProviderConnection";
   11033                     Slog.w(TAG, msg);
   11034                     throw new IllegalArgumentException(msg);
   11035                 }
   11036                 if (conn == null) {
   11037                     throw new NullPointerException("connection is null");
   11038                 }
   11039                 if (decProviderCountLocked(conn, null, null, stable)) {
   11040                     updateOomAdjLocked();
   11041                 }
   11042             }
   11043         } finally {
   11044             Binder.restoreCallingIdentity(ident);
   11045         }
   11046     }
   11047 
   11048     public void removeContentProviderExternal(String name, IBinder token) {
   11049         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   11050             "Do not have permission in call removeContentProviderExternal()");
   11051         int userId = UserHandle.getCallingUserId();
   11052         long ident = Binder.clearCallingIdentity();
   11053         try {
   11054             removeContentProviderExternalUnchecked(name, token, userId);
   11055         } finally {
   11056             Binder.restoreCallingIdentity(ident);
   11057         }
   11058     }
   11059 
   11060     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
   11061         synchronized (this) {
   11062             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
   11063             if(cpr == null) {
   11064                 //remove from mProvidersByClass
   11065                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
   11066                 return;
   11067             }
   11068 
   11069             //update content provider record entry info
   11070             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
   11071             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
   11072             if (localCpr.hasExternalProcessHandles()) {
   11073                 if (localCpr.removeExternalProcessHandleLocked(token)) {
   11074                     updateOomAdjLocked();
   11075                 } else {
   11076                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
   11077                             + " with no external reference for token: "
   11078                             + token + ".");
   11079                 }
   11080             } else {
   11081                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
   11082                         + " with no external references.");
   11083             }
   11084         }
   11085     }
   11086 
   11087     public final void publishContentProviders(IApplicationThread caller,
   11088             List<ContentProviderHolder> providers) {
   11089         if (providers == null) {
   11090             return;
   11091         }
   11092 
   11093         enforceNotIsolatedCaller("publishContentProviders");
   11094         synchronized (this) {
   11095             final ProcessRecord r = getRecordForAppLocked(caller);
   11096             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
   11097             if (r == null) {
   11098                 throw new SecurityException(
   11099                         "Unable to find app for caller " + caller
   11100                       + " (pid=" + Binder.getCallingPid()
   11101                       + ") when publishing content providers");
   11102             }
   11103 
   11104             final long origId = Binder.clearCallingIdentity();
   11105 
   11106             final int N = providers.size();
   11107             for (int i = 0; i < N; i++) {
   11108                 ContentProviderHolder src = providers.get(i);
   11109                 if (src == null || src.info == null || src.provider == null) {
   11110                     continue;
   11111                 }
   11112                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
   11113                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
   11114                 if (dst != null) {
   11115                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
   11116                     mProviderMap.putProviderByClass(comp, dst);
   11117                     String names[] = dst.info.authority.split(";");
   11118                     for (int j = 0; j < names.length; j++) {
   11119                         mProviderMap.putProviderByName(names[j], dst);
   11120                     }
   11121 
   11122                     int launchingCount = mLaunchingProviders.size();
   11123                     int j;
   11124                     boolean wasInLaunchingProviders = false;
   11125                     for (j = 0; j < launchingCount; j++) {
   11126                         if (mLaunchingProviders.get(j) == dst) {
   11127                             mLaunchingProviders.remove(j);
   11128                             wasInLaunchingProviders = true;
   11129                             j--;
   11130                             launchingCount--;
   11131                         }
   11132                     }
   11133                     if (wasInLaunchingProviders) {
   11134                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
   11135                     }
   11136                     synchronized (dst) {
   11137                         dst.provider = src.provider;
   11138                         dst.proc = r;
   11139                         dst.notifyAll();
   11140                     }
   11141                     updateOomAdjLocked(r);
   11142                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
   11143                             src.info.authority);
   11144                 }
   11145             }
   11146 
   11147             Binder.restoreCallingIdentity(origId);
   11148         }
   11149     }
   11150 
   11151     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
   11152         ContentProviderConnection conn;
   11153         try {
   11154             conn = (ContentProviderConnection)connection;
   11155         } catch (ClassCastException e) {
   11156             String msg ="refContentProvider: " + connection
   11157                     + " not a ContentProviderConnection";
   11158             Slog.w(TAG, msg);
   11159             throw new IllegalArgumentException(msg);
   11160         }
   11161         if (conn == null) {
   11162             throw new NullPointerException("connection is null");
   11163         }
   11164 
   11165         synchronized (this) {
   11166             if (stable > 0) {
   11167                 conn.numStableIncs += stable;
   11168             }
   11169             stable = conn.stableCount + stable;
   11170             if (stable < 0) {
   11171                 throw new IllegalStateException("stableCount < 0: " + stable);
   11172             }
   11173 
   11174             if (unstable > 0) {
   11175                 conn.numUnstableIncs += unstable;
   11176             }
   11177             unstable = conn.unstableCount + unstable;
   11178             if (unstable < 0) {
   11179                 throw new IllegalStateException("unstableCount < 0: " + unstable);
   11180             }
   11181 
   11182             if ((stable+unstable) <= 0) {
   11183                 throw new IllegalStateException("ref counts can't go to zero here: stable="
   11184                         + stable + " unstable=" + unstable);
   11185             }
   11186             conn.stableCount = stable;
   11187             conn.unstableCount = unstable;
   11188             return !conn.dead;
   11189         }
   11190     }
   11191 
   11192     public void unstableProviderDied(IBinder connection) {
   11193         ContentProviderConnection conn;
   11194         try {
   11195             conn = (ContentProviderConnection)connection;
   11196         } catch (ClassCastException e) {
   11197             String msg ="refContentProvider: " + connection
   11198                     + " not a ContentProviderConnection";
   11199             Slog.w(TAG, msg);
   11200             throw new IllegalArgumentException(msg);
   11201         }
   11202         if (conn == null) {
   11203             throw new NullPointerException("connection is null");
   11204         }
   11205 
   11206         // Safely retrieve the content provider associated with the connection.
   11207         IContentProvider provider;
   11208         synchronized (this) {
   11209             provider = conn.provider.provider;
   11210         }
   11211 
   11212         if (provider == null) {
   11213             // Um, yeah, we're way ahead of you.
   11214             return;
   11215         }
   11216 
   11217         // Make sure the caller is being honest with us.
   11218         if (provider.asBinder().pingBinder()) {
   11219             // Er, no, still looks good to us.
   11220             synchronized (this) {
   11221                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
   11222                         + " says " + conn + " died, but we don't agree");
   11223                 return;
   11224             }
   11225         }
   11226 
   11227         // Well look at that!  It's dead!
   11228         synchronized (this) {
   11229             if (conn.provider.provider != provider) {
   11230                 // But something changed...  good enough.
   11231                 return;
   11232             }
   11233 
   11234             ProcessRecord proc = conn.provider.proc;
   11235             if (proc == null || proc.thread == null) {
   11236                 // Seems like the process is already cleaned up.
   11237                 return;
   11238             }
   11239 
   11240             // As far as we're concerned, this is just like receiving a
   11241             // death notification...  just a bit prematurely.
   11242             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
   11243                     + ") early provider death");
   11244             final long ident = Binder.clearCallingIdentity();
   11245             try {
   11246                 appDiedLocked(proc);
   11247             } finally {
   11248                 Binder.restoreCallingIdentity(ident);
   11249             }
   11250         }
   11251     }
   11252 
   11253     @Override
   11254     public void appNotRespondingViaProvider(IBinder connection) {
   11255         enforceCallingPermission(
   11256                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
   11257 
   11258         final ContentProviderConnection conn = (ContentProviderConnection) connection;
   11259         if (conn == null) {
   11260             Slog.w(TAG, "ContentProviderConnection is null");
   11261             return;
   11262         }
   11263 
   11264         final ProcessRecord host = conn.provider.proc;
   11265         if (host == null) {
   11266             Slog.w(TAG, "Failed to find hosting ProcessRecord");
   11267             return;
   11268         }
   11269 
   11270         mHandler.post(new Runnable() {
   11271             @Override
   11272             public void run() {
   11273                 mAppErrors.appNotResponding(host, null, null, false,
   11274                         "ContentProvider not responding");
   11275             }
   11276         });
   11277     }
   11278 
   11279     public final void installSystemProviders() {
   11280         List<ProviderInfo> providers;
   11281         synchronized (this) {
   11282             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
   11283             providers = generateApplicationProvidersLocked(app);
   11284             if (providers != null) {
   11285                 for (int i=providers.size()-1; i>=0; i--) {
   11286                     ProviderInfo pi = (ProviderInfo)providers.get(i);
   11287                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   11288                         Slog.w(TAG, "Not installing system proc provider " + pi.name
   11289                                 + ": not system .apk");
   11290                         providers.remove(i);
   11291                     }
   11292                 }
   11293             }
   11294         }
   11295         if (providers != null) {
   11296             mSystemThread.installSystemProviders(providers);
   11297         }
   11298 
   11299         mCoreSettingsObserver = new CoreSettingsObserver(this);
   11300         mFontScaleSettingObserver = new FontScaleSettingObserver();
   11301 
   11302         //mUsageStatsService.monitorPackages();
   11303     }
   11304 
   11305     private void startPersistentApps(int matchFlags) {
   11306         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
   11307 
   11308         synchronized (this) {
   11309             try {
   11310                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
   11311                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
   11312                 for (ApplicationInfo app : apps) {
   11313                     if (!"android".equals(app.packageName)) {
   11314                         addAppLocked(app, false, null /* ABI override */);
   11315                     }
   11316                 }
   11317             } catch (RemoteException ex) {
   11318             }
   11319         }
   11320     }
   11321 
   11322     /**
   11323      * When a user is unlocked, we need to install encryption-unaware providers
   11324      * belonging to any running apps.
   11325      */
   11326     private void installEncryptionUnawareProviders(int userId) {
   11327         // We're only interested in providers that are encryption unaware, and
   11328         // we don't care about uninstalled apps, since there's no way they're
   11329         // running at this point.
   11330         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
   11331 
   11332         synchronized (this) {
   11333             final int NP = mProcessNames.getMap().size();
   11334             for (int ip = 0; ip < NP; ip++) {
   11335                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   11336                 final int NA = apps.size();
   11337                 for (int ia = 0; ia < NA; ia++) {
   11338                     final ProcessRecord app = apps.valueAt(ia);
   11339                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
   11340 
   11341                     final int NG = app.pkgList.size();
   11342                     for (int ig = 0; ig < NG; ig++) {
   11343                         try {
   11344                             final String pkgName = app.pkgList.keyAt(ig);
   11345                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
   11346                                     .getPackageInfo(pkgName, matchFlags, userId);
   11347                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
   11348                                 for (ProviderInfo pi : pkgInfo.providers) {
   11349                                     // TODO: keep in sync with generateApplicationProvidersLocked
   11350                                     final boolean processMatch = Objects.equals(pi.processName,
   11351                                             app.processName) || pi.multiprocess;
   11352                                     final boolean userMatch = isSingleton(pi.processName,
   11353                                             pi.applicationInfo, pi.name, pi.flags)
   11354                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
   11355                                     if (processMatch && userMatch) {
   11356                                         Log.v(TAG, "Installing " + pi);
   11357                                         app.thread.scheduleInstallProvider(pi);
   11358                                     } else {
   11359                                         Log.v(TAG, "Skipping " + pi);
   11360                                     }
   11361                                 }
   11362                             }
   11363                         } catch (RemoteException ignored) {
   11364                         }
   11365                     }
   11366                 }
   11367             }
   11368         }
   11369     }
   11370 
   11371     /**
   11372      * Allows apps to retrieve the MIME type of a URI.
   11373      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
   11374      * users, then it does not need permission to access the ContentProvider.
   11375      * Either, it needs cross-user uri grants.
   11376      *
   11377      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
   11378      *
   11379      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
   11380      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
   11381      */
   11382     public String getProviderMimeType(Uri uri, int userId) {
   11383         enforceNotIsolatedCaller("getProviderMimeType");
   11384         final String name = uri.getAuthority();
   11385         int callingUid = Binder.getCallingUid();
   11386         int callingPid = Binder.getCallingPid();
   11387         long ident = 0;
   11388         boolean clearedIdentity = false;
   11389         synchronized (this) {
   11390             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
   11391         }
   11392         if (canClearIdentity(callingPid, callingUid, userId)) {
   11393             clearedIdentity = true;
   11394             ident = Binder.clearCallingIdentity();
   11395         }
   11396         ContentProviderHolder holder = null;
   11397         try {
   11398             holder = getContentProviderExternalUnchecked(name, null, userId);
   11399             if (holder != null) {
   11400                 return holder.provider.getType(uri);
   11401             }
   11402         } catch (RemoteException e) {
   11403             Log.w(TAG, "Content provider dead retrieving " + uri, e);
   11404             return null;
   11405         } catch (Exception e) {
   11406             Log.w(TAG, "Exception while determining type of " + uri, e);
   11407             return null;
   11408         } finally {
   11409             // We need to clear the identity to call removeContentProviderExternalUnchecked
   11410             if (!clearedIdentity) {
   11411                 ident = Binder.clearCallingIdentity();
   11412             }
   11413             try {
   11414                 if (holder != null) {
   11415                     removeContentProviderExternalUnchecked(name, null, userId);
   11416                 }
   11417             } finally {
   11418                 Binder.restoreCallingIdentity(ident);
   11419             }
   11420         }
   11421 
   11422         return null;
   11423     }
   11424 
   11425     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
   11426         if (UserHandle.getUserId(callingUid) == userId) {
   11427             return true;
   11428         }
   11429         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
   11430                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
   11431                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
   11432                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
   11433                 return true;
   11434         }
   11435         return false;
   11436     }
   11437 
   11438     // =========================================================
   11439     // GLOBAL MANAGEMENT
   11440     // =========================================================
   11441 
   11442     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
   11443             boolean isolated, int isolatedUid) {
   11444         String proc = customProcess != null ? customProcess : info.processName;
   11445         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   11446         final int userId = UserHandle.getUserId(info.uid);
   11447         int uid = info.uid;
   11448         if (isolated) {
   11449             if (isolatedUid == 0) {
   11450                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
   11451                 while (true) {
   11452                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
   11453                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
   11454                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
   11455                     }
   11456                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
   11457                     mNextIsolatedProcessUid++;
   11458                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
   11459                         // No process for this uid, use it.
   11460                         break;
   11461                     }
   11462                     stepsLeft--;
   11463                     if (stepsLeft <= 0) {
   11464                         return null;
   11465                     }
   11466                 }
   11467             } else {
   11468                 // Special case for startIsolatedProcess (internal only), where
   11469                 // the uid of the isolated process is specified by the caller.
   11470                 uid = isolatedUid;
   11471             }
   11472 
   11473             // Register the isolated UID with this application so BatteryStats knows to
   11474             // attribute resource usage to the application.
   11475             //
   11476             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
   11477             // about the process state of the isolated UID *before* it is registered with the
   11478             // owning application.
   11479             mBatteryStatsService.addIsolatedUid(uid, info.uid);
   11480         }
   11481         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
   11482         if (!mBooted && !mBooting
   11483                 && userId == UserHandle.USER_SYSTEM
   11484                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
   11485             r.persistent = true;
   11486         }
   11487         addProcessNameLocked(r);
   11488         return r;
   11489     }
   11490 
   11491     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
   11492             String abiOverride) {
   11493         ProcessRecord app;
   11494         if (!isolated) {
   11495             app = getProcessRecordLocked(info.processName, info.uid, true);
   11496         } else {
   11497             app = null;
   11498         }
   11499 
   11500         if (app == null) {
   11501             app = newProcessRecordLocked(info, null, isolated, 0);
   11502             updateLruProcessLocked(app, false, null);
   11503             updateOomAdjLocked();
   11504         }
   11505 
   11506         // This package really, really can not be stopped.
   11507         try {
   11508             AppGlobals.getPackageManager().setPackageStoppedState(
   11509                     info.packageName, false, UserHandle.getUserId(app.uid));
   11510         } catch (RemoteException e) {
   11511         } catch (IllegalArgumentException e) {
   11512             Slog.w(TAG, "Failed trying to unstop package "
   11513                     + info.packageName + ": " + e);
   11514         }
   11515 
   11516         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
   11517             app.persistent = true;
   11518             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
   11519         }
   11520         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
   11521             mPersistentStartingProcesses.add(app);
   11522             startProcessLocked(app, "added application", app.processName, abiOverride,
   11523                     null /* entryPoint */, null /* entryPointArgs */);
   11524         }
   11525 
   11526         return app;
   11527     }
   11528 
   11529     public void unhandledBack() {
   11530         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
   11531                 "unhandledBack()");
   11532 
   11533         synchronized(this) {
   11534             final long origId = Binder.clearCallingIdentity();
   11535             try {
   11536                 getFocusedStack().unhandledBackLocked();
   11537             } finally {
   11538                 Binder.restoreCallingIdentity(origId);
   11539             }
   11540         }
   11541     }
   11542 
   11543     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
   11544         enforceNotIsolatedCaller("openContentUri");
   11545         final int userId = UserHandle.getCallingUserId();
   11546         String name = uri.getAuthority();
   11547         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
   11548         ParcelFileDescriptor pfd = null;
   11549         if (cph != null) {
   11550             // We record the binder invoker's uid in thread-local storage before
   11551             // going to the content provider to open the file.  Later, in the code
   11552             // that handles all permissions checks, we look for this uid and use
   11553             // that rather than the Activity Manager's own uid.  The effect is that
   11554             // we do the check against the caller's permissions even though it looks
   11555             // to the content provider like the Activity Manager itself is making
   11556             // the request.
   11557             Binder token = new Binder();
   11558             sCallerIdentity.set(new Identity(
   11559                     token, Binder.getCallingPid(), Binder.getCallingUid()));
   11560             try {
   11561                 pfd = cph.provider.openFile(null, uri, "r", null, token);
   11562             } catch (FileNotFoundException e) {
   11563                 // do nothing; pfd will be returned null
   11564             } finally {
   11565                 // Ensure that whatever happens, we clean up the identity state
   11566                 sCallerIdentity.remove();
   11567                 // Ensure we're done with the provider.
   11568                 removeContentProviderExternalUnchecked(name, null, userId);
   11569             }
   11570         } else {
   11571             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
   11572         }
   11573         return pfd;
   11574     }
   11575 
   11576     // Actually is sleeping or shutting down or whatever else in the future
   11577     // is an inactive state.
   11578     boolean isSleepingOrShuttingDownLocked() {
   11579         return isSleepingLocked() || mShuttingDown;
   11580     }
   11581 
   11582     boolean isShuttingDownLocked() {
   11583         return mShuttingDown;
   11584     }
   11585 
   11586     boolean isSleepingLocked() {
   11587         return mSleeping;
   11588     }
   11589 
   11590     void onWakefulnessChanged(int wakefulness) {
   11591         synchronized(this) {
   11592             mWakefulness = wakefulness;
   11593             updateSleepIfNeededLocked();
   11594         }
   11595     }
   11596 
   11597     void finishRunningVoiceLocked() {
   11598         if (mRunningVoice != null) {
   11599             mRunningVoice = null;
   11600             mVoiceWakeLock.release();
   11601             updateSleepIfNeededLocked();
   11602         }
   11603     }
   11604 
   11605     void startTimeTrackingFocusedActivityLocked() {
   11606         if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
   11607             mCurAppTimeTracker.start(mFocusedActivity.packageName);
   11608         }
   11609     }
   11610 
   11611     void updateSleepIfNeededLocked() {
   11612         if (mSleeping && !shouldSleepLocked()) {
   11613             mSleeping = false;
   11614             startTimeTrackingFocusedActivityLocked();
   11615             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
   11616             mStackSupervisor.comeOutOfSleepIfNeededLocked();
   11617             updateOomAdjLocked();
   11618         } else if (!mSleeping && shouldSleepLocked()) {
   11619             mSleeping = true;
   11620             if (mCurAppTimeTracker != null) {
   11621                 mCurAppTimeTracker.stop();
   11622             }
   11623             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
   11624             mStackSupervisor.goingToSleepLocked();
   11625             updateOomAdjLocked();
   11626 
   11627             // Initialize the wake times of all processes.
   11628             checkExcessivePowerUsageLocked(false);
   11629             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   11630             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   11631             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   11632         }
   11633     }
   11634 
   11635     private boolean shouldSleepLocked() {
   11636         // Resume applications while running a voice interactor.
   11637         if (mRunningVoice != null) {
   11638             return false;
   11639         }
   11640 
   11641         // TODO: Transform the lock screen state into a sleep token instead.
   11642         switch (mWakefulness) {
   11643             case PowerManagerInternal.WAKEFULNESS_AWAKE:
   11644             case PowerManagerInternal.WAKEFULNESS_DREAMING:
   11645             case PowerManagerInternal.WAKEFULNESS_DOZING:
   11646                 // Pause applications whenever the lock screen is shown or any sleep
   11647                 // tokens have been acquired.
   11648                 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
   11649             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
   11650             default:
   11651                 // If we're asleep then pause applications unconditionally.
   11652                 return true;
   11653         }
   11654     }
   11655 
   11656     /** Pokes the task persister. */
   11657     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
   11658         mRecentTasks.notifyTaskPersisterLocked(task, flush);
   11659     }
   11660 
   11661     /** Notifies all listeners when the task stack has changed. */
   11662     void notifyTaskStackChangedLocked() {
   11663         mHandler.sendEmptyMessage(LOG_STACK_STATE);
   11664         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
   11665         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
   11666         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
   11667     }
   11668 
   11669     /** Notifies all listeners when an Activity is pinned. */
   11670     void notifyActivityPinnedLocked() {
   11671         mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
   11672         mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
   11673     }
   11674 
   11675     /**
   11676      * Notifies all listeners when an attempt was made to start an an activity that is already
   11677      * running in the pinned stack and the activity was not actually started, but the task is
   11678      * either brought to the front or a new Intent is delivered to it.
   11679      */
   11680     void notifyPinnedActivityRestartAttemptLocked() {
   11681         mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
   11682         mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
   11683     }
   11684 
   11685     /** Notifies all listeners when the pinned stack animation ends. */
   11686     @Override
   11687     public void notifyPinnedStackAnimationEnded() {
   11688         synchronized (this) {
   11689             mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
   11690             mHandler.obtainMessage(
   11691                     NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
   11692         }
   11693     }
   11694 
   11695     @Override
   11696     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
   11697         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
   11698     }
   11699 
   11700     @Override
   11701     public boolean shutdown(int timeout) {
   11702         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
   11703                 != PackageManager.PERMISSION_GRANTED) {
   11704             throw new SecurityException("Requires permission "
   11705                     + android.Manifest.permission.SHUTDOWN);
   11706         }
   11707 
   11708         boolean timedout = false;
   11709 
   11710         synchronized(this) {
   11711             mShuttingDown = true;
   11712             updateEventDispatchingLocked();
   11713             timedout = mStackSupervisor.shutdownLocked(timeout);
   11714         }
   11715 
   11716         mAppOpsService.shutdown();
   11717         if (mUsageStatsService != null) {
   11718             mUsageStatsService.prepareShutdown();
   11719         }
   11720         mBatteryStatsService.shutdown();
   11721         synchronized (this) {
   11722             mProcessStats.shutdownLocked();
   11723             notifyTaskPersisterLocked(null, true);
   11724         }
   11725 
   11726         return timedout;
   11727     }
   11728 
   11729     public final void activitySlept(IBinder token) {
   11730         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
   11731 
   11732         final long origId = Binder.clearCallingIdentity();
   11733 
   11734         synchronized (this) {
   11735             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   11736             if (r != null) {
   11737                 mStackSupervisor.activitySleptLocked(r);
   11738             }
   11739         }
   11740 
   11741         Binder.restoreCallingIdentity(origId);
   11742     }
   11743 
   11744     private String lockScreenShownToString() {
   11745         switch (mLockScreenShown) {
   11746             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
   11747             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
   11748             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
   11749             default: return "Unknown=" + mLockScreenShown;
   11750         }
   11751     }
   11752 
   11753     void logLockScreen(String msg) {
   11754         if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
   11755                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
   11756                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
   11757                 + " mSleeping=" + mSleeping);
   11758     }
   11759 
   11760     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
   11761         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
   11762         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
   11763         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
   11764             boolean wasRunningVoice = mRunningVoice != null;
   11765             mRunningVoice = session;
   11766             if (!wasRunningVoice) {
   11767                 mVoiceWakeLock.acquire();
   11768                 updateSleepIfNeededLocked();
   11769             }
   11770         }
   11771     }
   11772 
   11773     private void updateEventDispatchingLocked() {
   11774         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
   11775     }
   11776 
   11777     public void setLockScreenShown(boolean showing, boolean occluded) {
   11778         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   11779                 != PackageManager.PERMISSION_GRANTED) {
   11780             throw new SecurityException("Requires permission "
   11781                     + android.Manifest.permission.DEVICE_POWER);
   11782         }
   11783 
   11784         synchronized(this) {
   11785             long ident = Binder.clearCallingIdentity();
   11786             try {
   11787                 if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
   11788                 mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
   11789                 if (showing && occluded) {
   11790                     // The lock screen is currently showing, but is occluded by a window that can
   11791                     // show on top of the lock screen. In this can we want to dismiss the docked
   11792                     // stack since it will be complicated/risky to try to put the activity on top
   11793                     // of the lock screen in the right fullscreen configuration.
   11794                     mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
   11795                             mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
   11796                 }
   11797 
   11798                 updateSleepIfNeededLocked();
   11799             } finally {
   11800                 Binder.restoreCallingIdentity(ident);
   11801             }
   11802         }
   11803     }
   11804 
   11805     @Override
   11806     public void notifyLockedProfile(@UserIdInt int userId) {
   11807         try {
   11808             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
   11809                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
   11810             }
   11811         } catch (RemoteException ex) {
   11812             throw new SecurityException("Fail to check is caller a privileged app", ex);
   11813         }
   11814 
   11815         synchronized (this) {
   11816             if (mStackSupervisor.isUserLockedProfile(userId)) {
   11817                 final long ident = Binder.clearCallingIdentity();
   11818                 try {
   11819                     final int currentUserId = mUserController.getCurrentUserIdLocked();
   11820                     if (mUserController.isLockScreenDisabled(currentUserId)) {
   11821                         // If there is no device lock, we will show the profile's credential page.
   11822                         mActivityStarter.showConfirmDeviceCredential(userId);
   11823                     } else {
   11824                         // Showing launcher to avoid user entering credential twice.
   11825                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
   11826                     }
   11827                 } finally {
   11828                     Binder.restoreCallingIdentity(ident);
   11829                 }
   11830             }
   11831         }
   11832     }
   11833 
   11834     @Override
   11835     public void startConfirmDeviceCredentialIntent(Intent intent) {
   11836         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
   11837         synchronized (this) {
   11838             final long ident = Binder.clearCallingIdentity();
   11839             try {
   11840                 mActivityStarter.startConfirmCredentialIntent(intent);
   11841             } finally {
   11842                 Binder.restoreCallingIdentity(ident);
   11843             }
   11844         }
   11845     }
   11846 
   11847     @Override
   11848     public void stopAppSwitches() {
   11849         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   11850                 != PackageManager.PERMISSION_GRANTED) {
   11851             throw new SecurityException("viewquires permission "
   11852                     + android.Manifest.permission.STOP_APP_SWITCHES);
   11853         }
   11854 
   11855         synchronized(this) {
   11856             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
   11857                     + APP_SWITCH_DELAY_TIME;
   11858             mDidAppSwitch = false;
   11859             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   11860             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   11861             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
   11862         }
   11863     }
   11864 
   11865     public void resumeAppSwitches() {
   11866         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   11867                 != PackageManager.PERMISSION_GRANTED) {
   11868             throw new SecurityException("Requires permission "
   11869                     + android.Manifest.permission.STOP_APP_SWITCHES);
   11870         }
   11871 
   11872         synchronized(this) {
   11873             // Note that we don't execute any pending app switches... we will
   11874             // let those wait until either the timeout, or the next start
   11875             // activity request.
   11876             mAppSwitchesAllowedTime = 0;
   11877         }
   11878     }
   11879 
   11880     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
   11881             int callingPid, int callingUid, String name) {
   11882         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
   11883             return true;
   11884         }
   11885 
   11886         int perm = checkComponentPermission(
   11887                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
   11888                 sourceUid, -1, true);
   11889         if (perm == PackageManager.PERMISSION_GRANTED) {
   11890             return true;
   11891         }
   11892 
   11893         // If the actual IPC caller is different from the logical source, then
   11894         // also see if they are allowed to control app switches.
   11895         if (callingUid != -1 && callingUid != sourceUid) {
   11896             perm = checkComponentPermission(
   11897                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
   11898                     callingUid, -1, true);
   11899             if (perm == PackageManager.PERMISSION_GRANTED) {
   11900                 return true;
   11901             }
   11902         }
   11903 
   11904         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
   11905         return false;
   11906     }
   11907 
   11908     public void setDebugApp(String packageName, boolean waitForDebugger,
   11909             boolean persistent) {
   11910         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   11911                 "setDebugApp()");
   11912 
   11913         long ident = Binder.clearCallingIdentity();
   11914         try {
   11915             // Note that this is not really thread safe if there are multiple
   11916             // callers into it at the same time, but that's not a situation we
   11917             // care about.
   11918             if (persistent) {
   11919                 final ContentResolver resolver = mContext.getContentResolver();
   11920                 Settings.Global.putString(
   11921                     resolver, Settings.Global.DEBUG_APP,
   11922                     packageName);
   11923                 Settings.Global.putInt(
   11924                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
   11925                     waitForDebugger ? 1 : 0);
   11926             }
   11927 
   11928             synchronized (this) {
   11929                 if (!persistent) {
   11930                     mOrigDebugApp = mDebugApp;
   11931                     mOrigWaitForDebugger = mWaitForDebugger;
   11932                 }
   11933                 mDebugApp = packageName;
   11934                 mWaitForDebugger = waitForDebugger;
   11935                 mDebugTransient = !persistent;
   11936                 if (packageName != null) {
   11937                     forceStopPackageLocked(packageName, -1, false, false, true, true,
   11938                             false, UserHandle.USER_ALL, "set debug app");
   11939                 }
   11940             }
   11941         } finally {
   11942             Binder.restoreCallingIdentity(ident);
   11943         }
   11944     }
   11945 
   11946     void setTrackAllocationApp(ApplicationInfo app, String processName) {
   11947         synchronized (this) {
   11948             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   11949             if (!isDebuggable) {
   11950                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   11951                     throw new SecurityException("Process not debuggable: " + app.packageName);
   11952                 }
   11953             }
   11954 
   11955             mTrackAllocationApp = processName;
   11956         }
   11957     }
   11958 
   11959     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
   11960         synchronized (this) {
   11961             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   11962             if (!isDebuggable) {
   11963                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   11964                     throw new SecurityException("Process not debuggable: " + app.packageName);
   11965                 }
   11966             }
   11967             mProfileApp = processName;
   11968             mProfileFile = profilerInfo.profileFile;
   11969             if (mProfileFd != null) {
   11970                 try {
   11971                     mProfileFd.close();
   11972                 } catch (IOException e) {
   11973                 }
   11974                 mProfileFd = null;
   11975             }
   11976             mProfileFd = profilerInfo.profileFd;
   11977             mSamplingInterval = profilerInfo.samplingInterval;
   11978             mAutoStopProfiler = profilerInfo.autoStopProfiler;
   11979             mProfileType = 0;
   11980         }
   11981     }
   11982 
   11983     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
   11984         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   11985         if (!isDebuggable) {
   11986             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   11987                 throw new SecurityException("Process not debuggable: " + app.packageName);
   11988             }
   11989         }
   11990         mNativeDebuggingApp = processName;
   11991     }
   11992 
   11993     @Override
   11994     public void setAlwaysFinish(boolean enabled) {
   11995         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
   11996                 "setAlwaysFinish()");
   11997 
   11998         long ident = Binder.clearCallingIdentity();
   11999         try {
   12000             Settings.Global.putInt(
   12001                     mContext.getContentResolver(),
   12002                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
   12003 
   12004             synchronized (this) {
   12005                 mAlwaysFinishActivities = enabled;
   12006             }
   12007         } finally {
   12008             Binder.restoreCallingIdentity(ident);
   12009         }
   12010     }
   12011 
   12012     @Override
   12013     public void setLenientBackgroundCheck(boolean enabled) {
   12014         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   12015                 "setLenientBackgroundCheck()");
   12016 
   12017         long ident = Binder.clearCallingIdentity();
   12018         try {
   12019             Settings.Global.putInt(
   12020                     mContext.getContentResolver(),
   12021                     Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
   12022 
   12023             synchronized (this) {
   12024                 mLenientBackgroundCheck = enabled;
   12025             }
   12026         } finally {
   12027             Binder.restoreCallingIdentity(ident);
   12028         }
   12029     }
   12030 
   12031     @Override
   12032     public void setActivityController(IActivityController controller, boolean imAMonkey) {
   12033         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   12034                 "setActivityController()");
   12035         synchronized (this) {
   12036             mController = controller;
   12037             mControllerIsAMonkey = imAMonkey;
   12038             Watchdog.getInstance().setActivityController(controller);
   12039         }
   12040     }
   12041 
   12042     @Override
   12043     public void setUserIsMonkey(boolean userIsMonkey) {
   12044         synchronized (this) {
   12045             synchronized (mPidsSelfLocked) {
   12046                 final int callingPid = Binder.getCallingPid();
   12047                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
   12048                 if (precessRecord == null) {
   12049                     throw new SecurityException("Unknown process: " + callingPid);
   12050                 }
   12051                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
   12052                     throw new SecurityException("Only an instrumentation process "
   12053                             + "with a UiAutomation can call setUserIsMonkey");
   12054                 }
   12055             }
   12056             mUserIsMonkey = userIsMonkey;
   12057         }
   12058     }
   12059 
   12060     @Override
   12061     public boolean isUserAMonkey() {
   12062         synchronized (this) {
   12063             // If there is a controller also implies the user is a monkey.
   12064             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
   12065         }
   12066     }
   12067 
   12068     public void requestBugReport(int bugreportType) {
   12069         String service = null;
   12070         switch (bugreportType) {
   12071             case ActivityManager.BUGREPORT_OPTION_FULL:
   12072                 service = "bugreport";
   12073                 break;
   12074             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
   12075                 service = "bugreportplus";
   12076                 break;
   12077             case ActivityManager.BUGREPORT_OPTION_REMOTE:
   12078                 service = "bugreportremote";
   12079                 break;
   12080             case ActivityManager.BUGREPORT_OPTION_WEAR:
   12081                 service = "bugreportwear";
   12082                 break;
   12083         }
   12084         if (service == null) {
   12085             throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
   12086                     + bugreportType);
   12087         }
   12088         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
   12089         SystemProperties.set("ctl.start", service);
   12090     }
   12091 
   12092     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
   12093         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
   12094     }
   12095 
   12096     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
   12097         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
   12098             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
   12099         }
   12100         return KEY_DISPATCHING_TIMEOUT;
   12101     }
   12102 
   12103     @Override
   12104     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
   12105         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   12106                 != PackageManager.PERMISSION_GRANTED) {
   12107             throw new SecurityException("Requires permission "
   12108                     + android.Manifest.permission.FILTER_EVENTS);
   12109         }
   12110         ProcessRecord proc;
   12111         long timeout;
   12112         synchronized (this) {
   12113             synchronized (mPidsSelfLocked) {
   12114                 proc = mPidsSelfLocked.get(pid);
   12115             }
   12116             timeout = getInputDispatchingTimeoutLocked(proc);
   12117         }
   12118 
   12119         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
   12120             return -1;
   12121         }
   12122 
   12123         return timeout;
   12124     }
   12125 
   12126     /**
   12127      * Handle input dispatching timeouts.
   12128      * Returns whether input dispatching should be aborted or not.
   12129      */
   12130     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
   12131             final ActivityRecord activity, final ActivityRecord parent,
   12132             final boolean aboveSystem, String reason) {
   12133         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   12134                 != PackageManager.PERMISSION_GRANTED) {
   12135             throw new SecurityException("Requires permission "
   12136                     + android.Manifest.permission.FILTER_EVENTS);
   12137         }
   12138 
   12139         final String annotation;
   12140         if (reason == null) {
   12141             annotation = "Input dispatching timed out";
   12142         } else {
   12143             annotation = "Input dispatching timed out (" + reason + ")";
   12144         }
   12145 
   12146         if (proc != null) {
   12147             synchronized (this) {
   12148                 if (proc.debugging) {
   12149                     return false;
   12150                 }
   12151 
   12152                 if (mDidDexOpt) {
   12153                     // Give more time since we were dexopting.
   12154                     mDidDexOpt = false;
   12155                     return false;
   12156                 }
   12157 
   12158                 if (proc.instrumentationClass != null) {
   12159                     Bundle info = new Bundle();
   12160                     info.putString("shortMsg", "keyDispatchingTimedOut");
   12161                     info.putString("longMsg", annotation);
   12162                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
   12163                     return true;
   12164                 }
   12165             }
   12166             mHandler.post(new Runnable() {
   12167                 @Override
   12168                 public void run() {
   12169                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
   12170                 }
   12171             });
   12172         }
   12173 
   12174         return true;
   12175     }
   12176 
   12177     @Override
   12178     public Bundle getAssistContextExtras(int requestType) {
   12179         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
   12180                 null, null, true /* focused */, true /* newSessionId */,
   12181                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
   12182         if (pae == null) {
   12183             return null;
   12184         }
   12185         synchronized (pae) {
   12186             while (!pae.haveResult) {
   12187                 try {
   12188                     pae.wait();
   12189                 } catch (InterruptedException e) {
   12190                 }
   12191             }
   12192         }
   12193         synchronized (this) {
   12194             buildAssistBundleLocked(pae, pae.result);
   12195             mPendingAssistExtras.remove(pae);
   12196             mUiHandler.removeCallbacks(pae);
   12197         }
   12198         return pae.extras;
   12199     }
   12200 
   12201     @Override
   12202     public boolean isAssistDataAllowedOnCurrentActivity() {
   12203         int userId;
   12204         synchronized (this) {
   12205             userId = mUserController.getCurrentUserIdLocked();
   12206             ActivityRecord activity = getFocusedStack().topActivity();
   12207             if (activity == null) {
   12208                 return false;
   12209             }
   12210             userId = activity.userId;
   12211         }
   12212         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
   12213                 Context.DEVICE_POLICY_SERVICE);
   12214         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
   12215     }
   12216 
   12217     @Override
   12218     public boolean showAssistFromActivity(IBinder token, Bundle args) {
   12219         long ident = Binder.clearCallingIdentity();
   12220         try {
   12221             synchronized (this) {
   12222                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
   12223                 ActivityRecord top = getFocusedStack().topActivity();
   12224                 if (top != caller) {
   12225                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
   12226                             + " is not current top " + top);
   12227                     return false;
   12228                 }
   12229                 if (!top.nowVisible) {
   12230                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
   12231                             + " is not visible");
   12232                     return false;
   12233                 }
   12234             }
   12235             AssistUtils utils = new AssistUtils(mContext);
   12236             return utils.showSessionForActiveService(args,
   12237                     VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
   12238         } finally {
   12239             Binder.restoreCallingIdentity(ident);
   12240         }
   12241     }
   12242 
   12243     @Override
   12244     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
   12245             Bundle receiverExtras,
   12246             IBinder activityToken, boolean focused, boolean newSessionId) {
   12247         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
   12248                 activityToken, focused, newSessionId,
   12249                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
   12250                 != null;
   12251     }
   12252 
   12253     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
   12254             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
   12255             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
   12256         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
   12257                 "enqueueAssistContext()");
   12258         synchronized (this) {
   12259             ActivityRecord activity = getFocusedStack().topActivity();
   12260             if (activity == null) {
   12261                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
   12262                 return null;
   12263             }
   12264             if (activity.app == null || activity.app.thread == null) {
   12265                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
   12266                 return null;
   12267             }
   12268             if (focused) {
   12269                 if (activityToken != null) {
   12270                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
   12271                     if (activity != caller) {
   12272                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
   12273                                 + " is not current top " + activity);
   12274                         return null;
   12275                     }
   12276                 }
   12277             } else {
   12278                 activity = ActivityRecord.forTokenLocked(activityToken);
   12279                 if (activity == null) {
   12280                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
   12281                             + " couldn't be found");
   12282                     return null;
   12283                 }
   12284             }
   12285 
   12286             PendingAssistExtras pae;
   12287             Bundle extras = new Bundle();
   12288             if (args != null) {
   12289                 extras.putAll(args);
   12290             }
   12291             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
   12292             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
   12293             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
   12294                     userHandle);
   12295             // Increment the sessionId if necessary
   12296             if (newSessionId) {
   12297                 mViSessionId++;
   12298             }
   12299             try {
   12300                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
   12301                         requestType, mViSessionId);
   12302                 mPendingAssistExtras.add(pae);
   12303                 mUiHandler.postDelayed(pae, timeout);
   12304             } catch (RemoteException e) {
   12305                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
   12306                 return null;
   12307             }
   12308             return pae;
   12309         }
   12310     }
   12311 
   12312     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
   12313         IResultReceiver receiver;
   12314         synchronized (this) {
   12315             mPendingAssistExtras.remove(pae);
   12316             receiver = pae.receiver;
   12317         }
   12318         if (receiver != null) {
   12319             // Caller wants result sent back to them.
   12320             Bundle sendBundle = new Bundle();
   12321             // At least return the receiver extras
   12322             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
   12323                     pae.receiverExtras);
   12324             try {
   12325                 pae.receiver.send(0, sendBundle);
   12326             } catch (RemoteException e) {
   12327             }
   12328         }
   12329     }
   12330 
   12331     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
   12332         if (result != null) {
   12333             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
   12334         }
   12335         if (pae.hint != null) {
   12336             pae.extras.putBoolean(pae.hint, true);
   12337         }
   12338     }
   12339 
   12340     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
   12341             AssistContent content, Uri referrer) {
   12342         PendingAssistExtras pae = (PendingAssistExtras)token;
   12343         synchronized (pae) {
   12344             pae.result = extras;
   12345             pae.structure = structure;
   12346             pae.content = content;
   12347             if (referrer != null) {
   12348                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
   12349             }
   12350             pae.haveResult = true;
   12351             pae.notifyAll();
   12352             if (pae.intent == null && pae.receiver == null) {
   12353                 // Caller is just waiting for the result.
   12354                 return;
   12355             }
   12356         }
   12357 
   12358         // We are now ready to launch the assist activity.
   12359         IResultReceiver sendReceiver = null;
   12360         Bundle sendBundle = null;
   12361         synchronized (this) {
   12362             buildAssistBundleLocked(pae, extras);
   12363             boolean exists = mPendingAssistExtras.remove(pae);
   12364             mUiHandler.removeCallbacks(pae);
   12365             if (!exists) {
   12366                 // Timed out.
   12367                 return;
   12368             }
   12369             if ((sendReceiver=pae.receiver) != null) {
   12370                 // Caller wants result sent back to them.
   12371                 sendBundle = new Bundle();
   12372                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
   12373                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
   12374                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
   12375                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
   12376                         pae.receiverExtras);
   12377             }
   12378         }
   12379         if (sendReceiver != null) {
   12380             try {
   12381                 sendReceiver.send(0, sendBundle);
   12382             } catch (RemoteException e) {
   12383             }
   12384             return;
   12385         }
   12386 
   12387         long ident = Binder.clearCallingIdentity();
   12388         try {
   12389             pae.intent.replaceExtras(pae.extras);
   12390             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
   12391                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
   12392                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
   12393             closeSystemDialogs("assist");
   12394             try {
   12395                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
   12396             } catch (ActivityNotFoundException e) {
   12397                 Slog.w(TAG, "No activity to handle assist action.", e);
   12398             }
   12399         } finally {
   12400             Binder.restoreCallingIdentity(ident);
   12401         }
   12402     }
   12403 
   12404     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
   12405             Bundle args) {
   12406         return enqueueAssistContext(requestType, intent, hint, null, null, null,
   12407                 true /* focused */, true /* newSessionId */,
   12408                 userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
   12409     }
   12410 
   12411     public void registerProcessObserver(IProcessObserver observer) {
   12412         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   12413                 "registerProcessObserver()");
   12414         synchronized (this) {
   12415             mProcessObservers.register(observer);
   12416         }
   12417     }
   12418 
   12419     @Override
   12420     public void unregisterProcessObserver(IProcessObserver observer) {
   12421         synchronized (this) {
   12422             mProcessObservers.unregister(observer);
   12423         }
   12424     }
   12425 
   12426     @Override
   12427     public void registerUidObserver(IUidObserver observer, int which) {
   12428         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   12429                 "registerUidObserver()");
   12430         synchronized (this) {
   12431             mUidObservers.register(observer, which);
   12432         }
   12433     }
   12434 
   12435     @Override
   12436     public void unregisterUidObserver(IUidObserver observer) {
   12437         synchronized (this) {
   12438             mUidObservers.unregister(observer);
   12439         }
   12440     }
   12441 
   12442     @Override
   12443     public boolean convertFromTranslucent(IBinder token) {
   12444         final long origId = Binder.clearCallingIdentity();
   12445         try {
   12446             synchronized (this) {
   12447                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12448                 if (r == null) {
   12449                     return false;
   12450                 }
   12451                 final boolean translucentChanged = r.changeWindowTranslucency(true);
   12452                 if (translucentChanged) {
   12453                     r.task.stack.releaseBackgroundResources(r);
   12454                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   12455                 }
   12456                 mWindowManager.setAppFullscreen(token, true);
   12457                 return translucentChanged;
   12458             }
   12459         } finally {
   12460             Binder.restoreCallingIdentity(origId);
   12461         }
   12462     }
   12463 
   12464     @Override
   12465     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
   12466         final long origId = Binder.clearCallingIdentity();
   12467         try {
   12468             synchronized (this) {
   12469                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12470                 if (r == null) {
   12471                     return false;
   12472                 }
   12473                 int index = r.task.mActivities.lastIndexOf(r);
   12474                 if (index > 0) {
   12475                     ActivityRecord under = r.task.mActivities.get(index - 1);
   12476                     under.returningOptions = options;
   12477                 }
   12478                 final boolean translucentChanged = r.changeWindowTranslucency(false);
   12479                 if (translucentChanged) {
   12480                     r.task.stack.convertActivityToTranslucent(r);
   12481                 }
   12482                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   12483                 mWindowManager.setAppFullscreen(token, false);
   12484                 return translucentChanged;
   12485             }
   12486         } finally {
   12487             Binder.restoreCallingIdentity(origId);
   12488         }
   12489     }
   12490 
   12491     @Override
   12492     public boolean requestVisibleBehind(IBinder token, boolean visible) {
   12493         final long origId = Binder.clearCallingIdentity();
   12494         try {
   12495             synchronized (this) {
   12496                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12497                 if (r != null) {
   12498                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
   12499                 }
   12500             }
   12501             return false;
   12502         } finally {
   12503             Binder.restoreCallingIdentity(origId);
   12504         }
   12505     }
   12506 
   12507     @Override
   12508     public boolean isBackgroundVisibleBehind(IBinder token) {
   12509         final long origId = Binder.clearCallingIdentity();
   12510         try {
   12511             synchronized (this) {
   12512                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
   12513                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
   12514                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
   12515                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
   12516                 return visible;
   12517             }
   12518         } finally {
   12519             Binder.restoreCallingIdentity(origId);
   12520         }
   12521     }
   12522 
   12523     @Override
   12524     public ActivityOptions getActivityOptions(IBinder token) {
   12525         final long origId = Binder.clearCallingIdentity();
   12526         try {
   12527             synchronized (this) {
   12528                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12529                 if (r != null) {
   12530                     final ActivityOptions activityOptions = r.pendingOptions;
   12531                     r.pendingOptions = null;
   12532                     return activityOptions;
   12533                 }
   12534                 return null;
   12535             }
   12536         } finally {
   12537             Binder.restoreCallingIdentity(origId);
   12538         }
   12539     }
   12540 
   12541     @Override
   12542     public void setImmersive(IBinder token, boolean immersive) {
   12543         synchronized(this) {
   12544             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12545             if (r == null) {
   12546                 throw new IllegalArgumentException();
   12547             }
   12548             r.immersive = immersive;
   12549 
   12550             // update associated state if we're frontmost
   12551             if (r == mFocusedActivity) {
   12552                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
   12553                 applyUpdateLockStateLocked(r);
   12554             }
   12555         }
   12556     }
   12557 
   12558     @Override
   12559     public boolean isImmersive(IBinder token) {
   12560         synchronized (this) {
   12561             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12562             if (r == null) {
   12563                 throw new IllegalArgumentException();
   12564             }
   12565             return r.immersive;
   12566         }
   12567     }
   12568 
   12569     public void setVrThread(int tid) {
   12570         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
   12571             throw new UnsupportedOperationException("VR mode not supported on this device!");
   12572         }
   12573 
   12574         synchronized (this) {
   12575             ProcessRecord proc;
   12576             synchronized (mPidsSelfLocked) {
   12577                 final int pid = Binder.getCallingPid();
   12578                 proc = mPidsSelfLocked.get(pid);
   12579 
   12580                 if (proc != null && mInVrMode && tid >= 0) {
   12581                     // ensure the tid belongs to the process
   12582                     if (!Process.isThreadInProcess(pid, tid)) {
   12583                         throw new IllegalArgumentException("VR thread does not belong to process");
   12584                     }
   12585 
   12586                     // reset existing VR thread to CFS if this thread still exists and belongs to
   12587                     // the calling process
   12588                     if (proc.vrThreadTid != 0
   12589                             && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
   12590                         try {
   12591                             Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
   12592                         } catch (IllegalArgumentException e) {
   12593                             // Ignore this.  Only occurs in race condition where previous VR thread
   12594                             // was destroyed during this method call.
   12595                         }
   12596                     }
   12597 
   12598                     proc.vrThreadTid = tid;
   12599 
   12600                     // promote to FIFO now if the tid is non-zero
   12601                     try {
   12602                         if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
   12603                             proc.vrThreadTid > 0) {
   12604                             Process.setThreadScheduler(proc.vrThreadTid,
   12605                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
   12606                         }
   12607                     } catch (IllegalArgumentException e) {
   12608                         Slog.e(TAG, "Failed to set scheduling policy, thread does"
   12609                                + " not exist:\n" + e);
   12610                     }
   12611                 }
   12612             }
   12613         }
   12614     }
   12615 
   12616     @Override
   12617     public void setRenderThread(int tid) {
   12618         synchronized (this) {
   12619             ProcessRecord proc;
   12620             synchronized (mPidsSelfLocked) {
   12621                 int pid = Binder.getCallingPid();
   12622                 proc = mPidsSelfLocked.get(pid);
   12623                 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
   12624                     // ensure the tid belongs to the process
   12625                     if (!Process.isThreadInProcess(pid, tid)) {
   12626                         throw new IllegalArgumentException(
   12627                             "Render thread does not belong to process");
   12628                     }
   12629                     proc.renderThreadTid = tid;
   12630                     if (DEBUG_OOM_ADJ) {
   12631                         Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
   12632                     }
   12633                     // promote to FIFO now
   12634                     if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
   12635                         if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
   12636                         if (mUseFifoUiScheduling) {
   12637                             Process.setThreadScheduler(proc.renderThreadTid,
   12638                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
   12639                         } else {
   12640                             Process.setThreadPriority(proc.renderThreadTid, -10);
   12641                         }
   12642                     }
   12643                 } else {
   12644                     if (DEBUG_OOM_ADJ) {
   12645                         Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
   12646                                "PID: " + pid + ", TID: " + tid + " FIFO: " +
   12647                                mUseFifoUiScheduling);
   12648                     }
   12649                 }
   12650             }
   12651         }
   12652     }
   12653 
   12654     @Override
   12655     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
   12656         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
   12657             throw new UnsupportedOperationException("VR mode not supported on this device!");
   12658         }
   12659 
   12660         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
   12661 
   12662         ActivityRecord r;
   12663         synchronized (this) {
   12664             r = ActivityRecord.isInStackLocked(token);
   12665         }
   12666 
   12667         if (r == null) {
   12668             throw new IllegalArgumentException();
   12669         }
   12670 
   12671         int err;
   12672         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
   12673                 VrManagerInternal.NO_ERROR) {
   12674             return err;
   12675         }
   12676 
   12677         synchronized(this) {
   12678             r.requestedVrComponent = (enabled) ? packageName : null;
   12679 
   12680             // Update associated state if this activity is currently focused
   12681             if (r == mFocusedActivity) {
   12682                 applyUpdateVrModeLocked(r);
   12683             }
   12684             return 0;
   12685         }
   12686     }
   12687 
   12688     @Override
   12689     public boolean isVrModePackageEnabled(ComponentName packageName) {
   12690         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
   12691             throw new UnsupportedOperationException("VR mode not supported on this device!");
   12692         }
   12693 
   12694         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
   12695 
   12696         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
   12697                 VrManagerInternal.NO_ERROR;
   12698     }
   12699 
   12700     public boolean isTopActivityImmersive() {
   12701         enforceNotIsolatedCaller("startActivity");
   12702         synchronized (this) {
   12703             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
   12704             return (r != null) ? r.immersive : false;
   12705         }
   12706     }
   12707 
   12708     @Override
   12709     public boolean isTopOfTask(IBinder token) {
   12710         synchronized (this) {
   12711             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12712             if (r == null) {
   12713                 throw new IllegalArgumentException();
   12714             }
   12715             return r.task.getTopActivity() == r;
   12716         }
   12717     }
   12718 
   12719     @Override
   12720     public void setHasTopUi(boolean hasTopUi) throws RemoteException {
   12721         if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
   12722             String msg = "Permission Denial: setHasTopUi() from pid="
   12723                     + Binder.getCallingPid()
   12724                     + ", uid=" + Binder.getCallingUid()
   12725                     + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
   12726             Slog.w(TAG, msg);
   12727             throw new SecurityException(msg);
   12728         }
   12729         final int pid = Binder.getCallingPid();
   12730         final long origId = Binder.clearCallingIdentity();
   12731         try {
   12732             synchronized (this) {
   12733                 boolean changed = false;
   12734                 ProcessRecord pr;
   12735                 synchronized (mPidsSelfLocked) {
   12736                     pr = mPidsSelfLocked.get(pid);
   12737                     if (pr == null) {
   12738                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
   12739                         return;
   12740                     }
   12741                     if (pr.hasTopUi != hasTopUi) {
   12742                         Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
   12743                         pr.hasTopUi = hasTopUi;
   12744                         changed = true;
   12745                     }
   12746                 }
   12747                 if (changed) {
   12748                     updateOomAdjLocked(pr);
   12749                 }
   12750             }
   12751         } finally {
   12752             Binder.restoreCallingIdentity(origId);
   12753         }
   12754     }
   12755 
   12756     public final void enterSafeMode() {
   12757         synchronized(this) {
   12758             // It only makes sense to do this before the system is ready
   12759             // and started launching other packages.
   12760             if (!mSystemReady) {
   12761                 try {
   12762                     AppGlobals.getPackageManager().enterSafeMode();
   12763                 } catch (RemoteException e) {
   12764                 }
   12765             }
   12766 
   12767             mSafeMode = true;
   12768         }
   12769     }
   12770 
   12771     public final void showSafeModeOverlay() {
   12772         View v = LayoutInflater.from(mContext).inflate(
   12773                 com.android.internal.R.layout.safe_mode, null);
   12774         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
   12775         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
   12776         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
   12777         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
   12778         lp.gravity = Gravity.BOTTOM | Gravity.START;
   12779         lp.format = v.getBackground().getOpacity();
   12780         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
   12781                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
   12782         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
   12783         ((WindowManager)mContext.getSystemService(
   12784                 Context.WINDOW_SERVICE)).addView(v, lp);
   12785     }
   12786 
   12787     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
   12788         if (sender != null && !(sender instanceof PendingIntentRecord)) {
   12789             return;
   12790         }
   12791         final PendingIntentRecord rec = (PendingIntentRecord)sender;
   12792         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   12793         synchronized (stats) {
   12794             if (mBatteryStatsService.isOnBattery()) {
   12795                 mBatteryStatsService.enforceCallingPermission();
   12796                 int MY_UID = Binder.getCallingUid();
   12797                 final int uid;
   12798                 if (sender == null) {
   12799                     uid = sourceUid;
   12800                 } else {
   12801                     uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   12802                 }
   12803                 BatteryStatsImpl.Uid.Pkg pkg =
   12804                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
   12805                             sourcePkg != null ? sourcePkg : rec.key.packageName);
   12806                 pkg.noteWakeupAlarmLocked(tag);
   12807             }
   12808         }
   12809     }
   12810 
   12811     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
   12812         if (sender != null && !(sender instanceof PendingIntentRecord)) {
   12813             return;
   12814         }
   12815         final PendingIntentRecord rec = (PendingIntentRecord)sender;
   12816         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   12817         synchronized (stats) {
   12818             mBatteryStatsService.enforceCallingPermission();
   12819             int MY_UID = Binder.getCallingUid();
   12820             final int uid;
   12821             if (sender == null) {
   12822                 uid = sourceUid;
   12823             } else {
   12824                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   12825             }
   12826             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
   12827         }
   12828     }
   12829 
   12830     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
   12831         if (sender != null && !(sender instanceof PendingIntentRecord)) {
   12832             return;
   12833         }
   12834         final PendingIntentRecord rec = (PendingIntentRecord)sender;
   12835         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   12836         synchronized (stats) {
   12837             mBatteryStatsService.enforceCallingPermission();
   12838             int MY_UID = Binder.getCallingUid();
   12839             final int uid;
   12840             if (sender == null) {
   12841                 uid = sourceUid;
   12842             } else {
   12843                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   12844             }
   12845             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
   12846         }
   12847     }
   12848 
   12849     public boolean killPids(int[] pids, String pReason, boolean secure) {
   12850         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   12851             throw new SecurityException("killPids only available to the system");
   12852         }
   12853         String reason = (pReason == null) ? "Unknown" : pReason;
   12854         // XXX Note: don't acquire main activity lock here, because the window
   12855         // manager calls in with its locks held.
   12856 
   12857         boolean killed = false;
   12858         synchronized (mPidsSelfLocked) {
   12859             int worstType = 0;
   12860             for (int i=0; i<pids.length; i++) {
   12861                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   12862                 if (proc != null) {
   12863                     int type = proc.setAdj;
   12864                     if (type > worstType) {
   12865                         worstType = type;
   12866                     }
   12867                 }
   12868             }
   12869 
   12870             // If the worst oom_adj is somewhere in the cached proc LRU range,
   12871             // then constrain it so we will kill all cached procs.
   12872             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
   12873                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
   12874                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
   12875             }
   12876 
   12877             // If this is not a secure call, don't let it kill processes that
   12878             // are important.
   12879             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
   12880                 worstType = ProcessList.SERVICE_ADJ;
   12881             }
   12882 
   12883             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
   12884             for (int i=0; i<pids.length; i++) {
   12885                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   12886                 if (proc == null) {
   12887                     continue;
   12888                 }
   12889                 int adj = proc.setAdj;
   12890                 if (adj >= worstType && !proc.killedByAm) {
   12891                     proc.kill(reason, true);
   12892                     killed = true;
   12893                 }
   12894             }
   12895         }
   12896         return killed;
   12897     }
   12898 
   12899     @Override
   12900     public void killUid(int appId, int userId, String reason) {
   12901         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
   12902         synchronized (this) {
   12903             final long identity = Binder.clearCallingIdentity();
   12904             try {
   12905                 killPackageProcessesLocked(null, appId, userId,
   12906                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
   12907                         reason != null ? reason : "kill uid");
   12908             } finally {
   12909                 Binder.restoreCallingIdentity(identity);
   12910             }
   12911         }
   12912     }
   12913 
   12914     @Override
   12915     public boolean killProcessesBelowForeground(String reason) {
   12916         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   12917             throw new SecurityException("killProcessesBelowForeground() only available to system");
   12918         }
   12919 
   12920         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
   12921     }
   12922 
   12923     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
   12924         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   12925             throw new SecurityException("killProcessesBelowAdj() only available to system");
   12926         }
   12927 
   12928         boolean killed = false;
   12929         synchronized (mPidsSelfLocked) {
   12930             final int size = mPidsSelfLocked.size();
   12931             for (int i = 0; i < size; i++) {
   12932                 final int pid = mPidsSelfLocked.keyAt(i);
   12933                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   12934                 if (proc == null) continue;
   12935 
   12936                 final int adj = proc.setAdj;
   12937                 if (adj > belowAdj && !proc.killedByAm) {
   12938                     proc.kill(reason, true);
   12939                     killed = true;
   12940                 }
   12941             }
   12942         }
   12943         return killed;
   12944     }
   12945 
   12946     @Override
   12947     public void hang(final IBinder who, boolean allowRestart) {
   12948         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   12949                 != PackageManager.PERMISSION_GRANTED) {
   12950             throw new SecurityException("Requires permission "
   12951                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   12952         }
   12953 
   12954         final IBinder.DeathRecipient death = new DeathRecipient() {
   12955             @Override
   12956             public void binderDied() {
   12957                 synchronized (this) {
   12958                     notifyAll();
   12959                 }
   12960             }
   12961         };
   12962 
   12963         try {
   12964             who.linkToDeath(death, 0);
   12965         } catch (RemoteException e) {
   12966             Slog.w(TAG, "hang: given caller IBinder is already dead.");
   12967             return;
   12968         }
   12969 
   12970         synchronized (this) {
   12971             Watchdog.getInstance().setAllowRestart(allowRestart);
   12972             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
   12973             synchronized (death) {
   12974                 while (who.isBinderAlive()) {
   12975                     try {
   12976                         death.wait();
   12977                     } catch (InterruptedException e) {
   12978                     }
   12979                 }
   12980             }
   12981             Watchdog.getInstance().setAllowRestart(true);
   12982         }
   12983     }
   12984 
   12985     @Override
   12986     public void restart() {
   12987         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   12988                 != PackageManager.PERMISSION_GRANTED) {
   12989             throw new SecurityException("Requires permission "
   12990                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   12991         }
   12992 
   12993         Log.i(TAG, "Sending shutdown broadcast...");
   12994 
   12995         BroadcastReceiver br = new BroadcastReceiver() {
   12996             @Override public void onReceive(Context context, Intent intent) {
   12997                 // Now the broadcast is done, finish up the low-level shutdown.
   12998                 Log.i(TAG, "Shutting down activity manager...");
   12999                 shutdown(10000);
   13000                 Log.i(TAG, "Shutdown complete, restarting!");
   13001                 Process.killProcess(Process.myPid());
   13002                 System.exit(10);
   13003             }
   13004         };
   13005 
   13006         // First send the high-level shut down broadcast.
   13007         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
   13008         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   13009         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
   13010         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
   13011         mContext.sendOrderedBroadcastAsUser(intent,
   13012                 UserHandle.ALL, null, br, mHandler, 0, null, null);
   13013         */
   13014         br.onReceive(mContext, intent);
   13015     }
   13016 
   13017     private long getLowRamTimeSinceIdle(long now) {
   13018         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
   13019     }
   13020 
   13021     @Override
   13022     public void performIdleMaintenance() {
   13023         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   13024                 != PackageManager.PERMISSION_GRANTED) {
   13025             throw new SecurityException("Requires permission "
   13026                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   13027         }
   13028 
   13029         synchronized (this) {
   13030             final long now = SystemClock.uptimeMillis();
   13031             final long timeSinceLastIdle = now - mLastIdleTime;
   13032             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
   13033             mLastIdleTime = now;
   13034             mLowRamTimeSinceLastIdle = 0;
   13035             if (mLowRamStartTime != 0) {
   13036                 mLowRamStartTime = now;
   13037             }
   13038 
   13039             StringBuilder sb = new StringBuilder(128);
   13040             sb.append("Idle maintenance over ");
   13041             TimeUtils.formatDuration(timeSinceLastIdle, sb);
   13042             sb.append(" low RAM for ");
   13043             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
   13044             Slog.i(TAG, sb.toString());
   13045 
   13046             // If at least 1/3 of our time since the last idle period has been spent
   13047             // with RAM low, then we want to kill processes.
   13048             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
   13049 
   13050             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   13051                 ProcessRecord proc = mLruProcesses.get(i);
   13052                 if (proc.notCachedSinceIdle) {
   13053                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
   13054                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
   13055                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
   13056                         if (doKilling && proc.initialIdlePss != 0
   13057                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
   13058                             sb = new StringBuilder(128);
   13059                             sb.append("Kill");
   13060                             sb.append(proc.processName);
   13061                             sb.append(" in idle maint: pss=");
   13062                             sb.append(proc.lastPss);
   13063                             sb.append(", swapPss=");
   13064                             sb.append(proc.lastSwapPss);
   13065                             sb.append(", initialPss=");
   13066                             sb.append(proc.initialIdlePss);
   13067                             sb.append(", period=");
   13068                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
   13069                             sb.append(", lowRamPeriod=");
   13070                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
   13071                             Slog.wtfQuiet(TAG, sb.toString());
   13072                             proc.kill("idle maint (pss " + proc.lastPss
   13073                                     + " from " + proc.initialIdlePss + ")", true);
   13074                         }
   13075                     }
   13076                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
   13077                         && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
   13078                     proc.notCachedSinceIdle = true;
   13079                     proc.initialIdlePss = 0;
   13080                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
   13081                             mTestPssMode, isSleepingLocked(), now);
   13082                 }
   13083             }
   13084 
   13085             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
   13086             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
   13087         }
   13088     }
   13089 
   13090     @Override
   13091     public void sendIdleJobTrigger() {
   13092         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   13093                 != PackageManager.PERMISSION_GRANTED) {
   13094             throw new SecurityException("Requires permission "
   13095                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   13096         }
   13097 
   13098         final long ident = Binder.clearCallingIdentity();
   13099         try {
   13100             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
   13101                     .setPackage("android")
   13102                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   13103             broadcastIntent(null, intent, null, null, 0, null, null, null,
   13104                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
   13105         } finally {
   13106             Binder.restoreCallingIdentity(ident);
   13107         }
   13108     }
   13109 
   13110     private void retrieveSettings() {
   13111         final ContentResolver resolver = mContext.getContentResolver();
   13112         final boolean freeformWindowManagement =
   13113                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
   13114                         || Settings.Global.getInt(
   13115                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
   13116         final boolean supportsPictureInPicture =
   13117                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
   13118 
   13119         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
   13120         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
   13121         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
   13122         final boolean alwaysFinishActivities =
   13123                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
   13124         final boolean lenientBackgroundCheck =
   13125                 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
   13126         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
   13127         final boolean forceResizable = Settings.Global.getInt(
   13128                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
   13129         final boolean supportsLeanbackOnly =
   13130                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
   13131 
   13132         // Transfer any global setting for forcing RTL layout, into a System Property
   13133         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
   13134 
   13135         final Configuration configuration = new Configuration();
   13136         Settings.System.getConfiguration(resolver, configuration);
   13137         if (forceRtl) {
   13138             // This will take care of setting the correct layout direction flags
   13139             configuration.setLayoutDirection(configuration.locale);
   13140         }
   13141 
   13142         synchronized (this) {
   13143             mDebugApp = mOrigDebugApp = debugApp;
   13144             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
   13145             mAlwaysFinishActivities = alwaysFinishActivities;
   13146             mLenientBackgroundCheck = lenientBackgroundCheck;
   13147             mSupportsLeanbackOnly = supportsLeanbackOnly;
   13148             mForceResizableActivities = forceResizable;
   13149             mWindowManager.setForceResizableTasks(mForceResizableActivities);
   13150             if (supportsMultiWindow || forceResizable) {
   13151                 mSupportsMultiWindow = true;
   13152                 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
   13153                 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
   13154             } else {
   13155                 mSupportsMultiWindow = false;
   13156                 mSupportsFreeformWindowManagement = false;
   13157                 mSupportsPictureInPicture = false;
   13158             }
   13159             // This happens before any activities are started, so we can
   13160             // change mConfiguration in-place.
   13161             updateConfigurationLocked(configuration, null, true);
   13162             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
   13163                     "Initial config: " + mConfiguration);
   13164 
   13165             // Load resources only after the current configuration has been set.
   13166             final Resources res = mContext.getResources();
   13167             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
   13168             mThumbnailWidth = res.getDimensionPixelSize(
   13169                     com.android.internal.R.dimen.thumbnail_width);
   13170             mThumbnailHeight = res.getDimensionPixelSize(
   13171                     com.android.internal.R.dimen.thumbnail_height);
   13172             mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
   13173                     com.android.internal.R.string.config_defaultPictureInPictureBounds));
   13174             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
   13175                     com.android.internal.R.string.config_appsNotReportingCrashes));
   13176             if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
   13177                 mFullscreenThumbnailScale = (float) res
   13178                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
   13179                     (float) mConfiguration.screenWidthDp;
   13180             } else {
   13181                 mFullscreenThumbnailScale = res.getFraction(
   13182                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
   13183             }
   13184         }
   13185     }
   13186 
   13187     public boolean testIsSystemReady() {
   13188         // no need to synchronize(this) just to read & return the value
   13189         return mSystemReady;
   13190     }
   13191 
   13192     public void systemReady(final Runnable goingCallback) {
   13193         synchronized(this) {
   13194             if (mSystemReady) {
   13195                 // If we're done calling all the receivers, run the next "boot phase" passed in
   13196                 // by the SystemServer
   13197                 if (goingCallback != null) {
   13198                     goingCallback.run();
   13199                 }
   13200                 return;
   13201             }
   13202 
   13203             mLocalDeviceIdleController
   13204                     = LocalServices.getService(DeviceIdleController.LocalService.class);
   13205 
   13206             // Make sure we have the current profile info, since it is needed for security checks.
   13207             mUserController.onSystemReady();
   13208             mRecentTasks.onSystemReadyLocked();
   13209             mAppOpsService.systemReady();
   13210             mSystemReady = true;
   13211         }
   13212 
   13213         ArrayList<ProcessRecord> procsToKill = null;
   13214         synchronized(mPidsSelfLocked) {
   13215             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
   13216                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   13217                 if (!isAllowedWhileBooting(proc.info)){
   13218                     if (procsToKill == null) {
   13219                         procsToKill = new ArrayList<ProcessRecord>();
   13220                     }
   13221                     procsToKill.add(proc);
   13222                 }
   13223             }
   13224         }
   13225 
   13226         synchronized(this) {
   13227             if (procsToKill != null) {
   13228                 for (int i=procsToKill.size()-1; i>=0; i--) {
   13229                     ProcessRecord proc = procsToKill.get(i);
   13230                     Slog.i(TAG, "Removing system update proc: " + proc);
   13231                     removeProcessLocked(proc, true, false, "system update done");
   13232                 }
   13233             }
   13234 
   13235             // Now that we have cleaned up any update processes, we
   13236             // are ready to start launching real processes and know that
   13237             // we won't trample on them any more.
   13238             mProcessesReady = true;
   13239         }
   13240 
   13241         Slog.i(TAG, "System now ready");
   13242         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
   13243             SystemClock.uptimeMillis());
   13244 
   13245         synchronized(this) {
   13246             // Make sure we have no pre-ready processes sitting around.
   13247 
   13248             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   13249                 ResolveInfo ri = mContext.getPackageManager()
   13250                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
   13251                                 STOCK_PM_FLAGS);
   13252                 CharSequence errorMsg = null;
   13253                 if (ri != null) {
   13254                     ActivityInfo ai = ri.activityInfo;
   13255                     ApplicationInfo app = ai.applicationInfo;
   13256                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   13257                         mTopAction = Intent.ACTION_FACTORY_TEST;
   13258                         mTopData = null;
   13259                         mTopComponent = new ComponentName(app.packageName,
   13260                                 ai.name);
   13261                     } else {
   13262                         errorMsg = mContext.getResources().getText(
   13263                                 com.android.internal.R.string.factorytest_not_system);
   13264                     }
   13265                 } else {
   13266                     errorMsg = mContext.getResources().getText(
   13267                             com.android.internal.R.string.factorytest_no_action);
   13268                 }
   13269                 if (errorMsg != null) {
   13270                     mTopAction = null;
   13271                     mTopData = null;
   13272                     mTopComponent = null;
   13273                     Message msg = Message.obtain();
   13274                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
   13275                     msg.getData().putCharSequence("msg", errorMsg);
   13276                     mUiHandler.sendMessage(msg);
   13277                 }
   13278             }
   13279         }
   13280 
   13281         retrieveSettings();
   13282         final int currentUserId;
   13283         synchronized (this) {
   13284             currentUserId = mUserController.getCurrentUserIdLocked();
   13285             readGrantedUriPermissionsLocked();
   13286         }
   13287 
   13288         if (goingCallback != null) goingCallback.run();
   13289 
   13290         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
   13291                 Integer.toString(currentUserId), currentUserId);
   13292         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
   13293                 Integer.toString(currentUserId), currentUserId);
   13294         mSystemServiceManager.startUser(currentUserId);
   13295 
   13296         synchronized (this) {
   13297             // Only start up encryption-aware persistent apps; once user is
   13298             // unlocked we'll come back around and start unaware apps
   13299             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
   13300 
   13301             // Start up initial activity.
   13302             mBooting = true;
   13303             // Enable home activity for system user, so that the system can always boot
   13304             if (UserManager.isSplitSystemUser()) {
   13305                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
   13306                 try {
   13307                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
   13308                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
   13309                             UserHandle.USER_SYSTEM);
   13310                 } catch (RemoteException e) {
   13311                     throw e.rethrowAsRuntimeException();
   13312                 }
   13313             }
   13314             startHomeActivityLocked(currentUserId, "systemReady");
   13315 
   13316             try {
   13317                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
   13318                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
   13319                             + " data partition or your device will be unstable.");
   13320                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
   13321                 }
   13322             } catch (RemoteException e) {
   13323             }
   13324 
   13325             if (!Build.isBuildConsistent()) {
   13326                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
   13327                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
   13328             }
   13329 
   13330             long ident = Binder.clearCallingIdentity();
   13331             try {
   13332                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
   13333                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   13334                         | Intent.FLAG_RECEIVER_FOREGROUND);
   13335                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
   13336                 broadcastIntentLocked(null, null, intent,
   13337                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   13338                         null, false, false, MY_PID, Process.SYSTEM_UID,
   13339                         currentUserId);
   13340                 intent = new Intent(Intent.ACTION_USER_STARTING);
   13341                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   13342                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
   13343                 broadcastIntentLocked(null, null, intent,
   13344                         null, new IIntentReceiver.Stub() {
   13345                             @Override
   13346                             public void performReceive(Intent intent, int resultCode, String data,
   13347                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
   13348                                     throws RemoteException {
   13349                             }
   13350                         }, 0, null, null,
   13351                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
   13352                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   13353             } catch (Throwable t) {
   13354                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
   13355             } finally {
   13356                 Binder.restoreCallingIdentity(ident);
   13357             }
   13358             mStackSupervisor.resumeFocusedStackTopActivityLocked();
   13359             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
   13360         }
   13361     }
   13362 
   13363     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
   13364         synchronized (this) {
   13365             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
   13366         }
   13367     }
   13368 
   13369     void skipCurrentReceiverLocked(ProcessRecord app) {
   13370         for (BroadcastQueue queue : mBroadcastQueues) {
   13371             queue.skipCurrentReceiverLocked(app);
   13372         }
   13373     }
   13374 
   13375     /**
   13376      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
   13377      * The application process will exit immediately after this call returns.
   13378      * @param app object of the crashing app, null for the system server
   13379      * @param crashInfo describing the exception
   13380      */
   13381     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
   13382         ProcessRecord r = findAppProcess(app, "Crash");
   13383         final String processName = app == null ? "system_server"
   13384                 : (r == null ? "unknown" : r.processName);
   13385 
   13386         handleApplicationCrashInner("crash", r, processName, crashInfo);
   13387     }
   13388 
   13389     /* Native crash reporting uses this inner version because it needs to be somewhat
   13390      * decoupled from the AM-managed cleanup lifecycle
   13391      */
   13392     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
   13393             ApplicationErrorReport.CrashInfo crashInfo) {
   13394         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
   13395                 UserHandle.getUserId(Binder.getCallingUid()), processName,
   13396                 r == null ? -1 : r.info.flags,
   13397                 crashInfo.exceptionClassName,
   13398                 crashInfo.exceptionMessage,
   13399                 crashInfo.throwFileName,
   13400                 crashInfo.throwLineNumber);
   13401 
   13402         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
   13403 
   13404         mAppErrors.crashApplication(r, crashInfo);
   13405     }
   13406 
   13407     public void handleApplicationStrictModeViolation(
   13408             IBinder app,
   13409             int violationMask,
   13410             StrictMode.ViolationInfo info) {
   13411         ProcessRecord r = findAppProcess(app, "StrictMode");
   13412         if (r == null) {
   13413             return;
   13414         }
   13415 
   13416         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
   13417             Integer stackFingerprint = info.hashCode();
   13418             boolean logIt = true;
   13419             synchronized (mAlreadyLoggedViolatedStacks) {
   13420                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
   13421                     logIt = false;
   13422                     // TODO: sub-sample into EventLog for these, with
   13423                     // the info.durationMillis?  Then we'd get
   13424                     // the relative pain numbers, without logging all
   13425                     // the stack traces repeatedly.  We'd want to do
   13426                     // likewise in the client code, which also does
   13427                     // dup suppression, before the Binder call.
   13428                 } else {
   13429                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
   13430                         mAlreadyLoggedViolatedStacks.clear();
   13431                     }
   13432                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
   13433                 }
   13434             }
   13435             if (logIt) {
   13436                 logStrictModeViolationToDropBox(r, info);
   13437             }
   13438         }
   13439 
   13440         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
   13441             AppErrorResult result = new AppErrorResult();
   13442             synchronized (this) {
   13443                 final long origId = Binder.clearCallingIdentity();
   13444 
   13445                 Message msg = Message.obtain();
   13446                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
   13447                 HashMap<String, Object> data = new HashMap<String, Object>();
   13448                 data.put("result", result);
   13449                 data.put("app", r);
   13450                 data.put("violationMask", violationMask);
   13451                 data.put("info", info);
   13452                 msg.obj = data;
   13453                 mUiHandler.sendMessage(msg);
   13454 
   13455                 Binder.restoreCallingIdentity(origId);
   13456             }
   13457             int res = result.get();
   13458             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
   13459         }
   13460     }
   13461 
   13462     // Depending on the policy in effect, there could be a bunch of
   13463     // these in quick succession so we try to batch these together to
   13464     // minimize disk writes, number of dropbox entries, and maximize
   13465     // compression, by having more fewer, larger records.
   13466     private void logStrictModeViolationToDropBox(
   13467             ProcessRecord process,
   13468             StrictMode.ViolationInfo info) {
   13469         if (info == null) {
   13470             return;
   13471         }
   13472         final boolean isSystemApp = process == null ||
   13473                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
   13474                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
   13475         final String processName = process == null ? "unknown" : process.processName;
   13476         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
   13477         final DropBoxManager dbox = (DropBoxManager)
   13478                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   13479 
   13480         // Exit early if the dropbox isn't configured to accept this report type.
   13481         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   13482 
   13483         boolean bufferWasEmpty;
   13484         boolean needsFlush;
   13485         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
   13486         synchronized (sb) {
   13487             bufferWasEmpty = sb.length() == 0;
   13488             appendDropBoxProcessHeaders(process, processName, sb);
   13489             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   13490             sb.append("System-App: ").append(isSystemApp).append("\n");
   13491             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
   13492             if (info.violationNumThisLoop != 0) {
   13493                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
   13494             }
   13495             if (info.numAnimationsRunning != 0) {
   13496                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
   13497             }
   13498             if (info.broadcastIntentAction != null) {
   13499                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
   13500             }
   13501             if (info.durationMillis != -1) {
   13502                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
   13503             }
   13504             if (info.numInstances != -1) {
   13505                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
   13506             }
   13507             if (info.tags != null) {
   13508                 for (String tag : info.tags) {
   13509                     sb.append("Span-Tag: ").append(tag).append("\n");
   13510                 }
   13511             }
   13512             sb.append("\n");
   13513             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
   13514                 sb.append(info.crashInfo.stackTrace);
   13515                 sb.append("\n");
   13516             }
   13517             if (info.message != null) {
   13518                 sb.append(info.message);
   13519                 sb.append("\n");
   13520             }
   13521 
   13522             // Only buffer up to ~64k.  Various logging bits truncate
   13523             // things at 128k.
   13524             needsFlush = (sb.length() > 64 * 1024);
   13525         }
   13526 
   13527         // Flush immediately if the buffer's grown too large, or this
   13528         // is a non-system app.  Non-system apps are isolated with a
   13529         // different tag & policy and not batched.
   13530         //
   13531         // Batching is useful during internal testing with
   13532         // StrictMode settings turned up high.  Without batching,
   13533         // thousands of separate files could be created on boot.
   13534         if (!isSystemApp || needsFlush) {
   13535             new Thread("Error dump: " + dropboxTag) {
   13536                 @Override
   13537                 public void run() {
   13538                     String report;
   13539                     synchronized (sb) {
   13540                         report = sb.toString();
   13541                         sb.delete(0, sb.length());
   13542                         sb.trimToSize();
   13543                     }
   13544                     if (report.length() != 0) {
   13545                         dbox.addText(dropboxTag, report);
   13546                     }
   13547                 }
   13548             }.start();
   13549             return;
   13550         }
   13551 
   13552         // System app batching:
   13553         if (!bufferWasEmpty) {
   13554             // An existing dropbox-writing thread is outstanding, so
   13555             // we don't need to start it up.  The existing thread will
   13556             // catch the buffer appends we just did.
   13557             return;
   13558         }
   13559 
   13560         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
   13561         // (After this point, we shouldn't access AMS internal data structures.)
   13562         new Thread("Error dump: " + dropboxTag) {
   13563             @Override
   13564             public void run() {
   13565                 // 5 second sleep to let stacks arrive and be batched together
   13566                 try {
   13567                     Thread.sleep(5000);  // 5 seconds
   13568                 } catch (InterruptedException e) {}
   13569 
   13570                 String errorReport;
   13571                 synchronized (mStrictModeBuffer) {
   13572                     errorReport = mStrictModeBuffer.toString();
   13573                     if (errorReport.length() == 0) {
   13574                         return;
   13575                     }
   13576                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
   13577                     mStrictModeBuffer.trimToSize();
   13578                 }
   13579                 dbox.addText(dropboxTag, errorReport);
   13580             }
   13581         }.start();
   13582     }
   13583 
   13584     /**
   13585      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
   13586      * @param app object of the crashing app, null for the system server
   13587      * @param tag reported by the caller
   13588      * @param system whether this wtf is coming from the system
   13589      * @param crashInfo describing the context of the error
   13590      * @return true if the process should exit immediately (WTF is fatal)
   13591      */
   13592     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
   13593             final ApplicationErrorReport.CrashInfo crashInfo) {
   13594         final int callingUid = Binder.getCallingUid();
   13595         final int callingPid = Binder.getCallingPid();
   13596 
   13597         if (system) {
   13598             // If this is coming from the system, we could very well have low-level
   13599             // system locks held, so we want to do this all asynchronously.  And we
   13600             // never want this to become fatal, so there is that too.
   13601             mHandler.post(new Runnable() {
   13602                 @Override public void run() {
   13603                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
   13604                 }
   13605             });
   13606             return false;
   13607         }
   13608 
   13609         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
   13610                 crashInfo);
   13611 
   13612         if (r != null && r.pid != Process.myPid() &&
   13613                 Settings.Global.getInt(mContext.getContentResolver(),
   13614                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
   13615             mAppErrors.crashApplication(r, crashInfo);
   13616             return true;
   13617         } else {
   13618             return false;
   13619         }
   13620     }
   13621 
   13622     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
   13623             final ApplicationErrorReport.CrashInfo crashInfo) {
   13624         final ProcessRecord r = findAppProcess(app, "WTF");
   13625         final String processName = app == null ? "system_server"
   13626                 : (r == null ? "unknown" : r.processName);
   13627 
   13628         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
   13629                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
   13630 
   13631         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
   13632 
   13633         return r;
   13634     }
   13635 
   13636     /**
   13637      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
   13638      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
   13639      */
   13640     private ProcessRecord findAppProcess(IBinder app, String reason) {
   13641         if (app == null) {
   13642             return null;
   13643         }
   13644 
   13645         synchronized (this) {
   13646             final int NP = mProcessNames.getMap().size();
   13647             for (int ip=0; ip<NP; ip++) {
   13648                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   13649                 final int NA = apps.size();
   13650                 for (int ia=0; ia<NA; ia++) {
   13651                     ProcessRecord p = apps.valueAt(ia);
   13652                     if (p.thread != null && p.thread.asBinder() == app) {
   13653                         return p;
   13654                     }
   13655                 }
   13656             }
   13657 
   13658             Slog.w(TAG, "Can't find mystery application for " + reason
   13659                     + " from pid=" + Binder.getCallingPid()
   13660                     + " uid=" + Binder.getCallingUid() + ": " + app);
   13661             return null;
   13662         }
   13663     }
   13664 
   13665     /**
   13666      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
   13667      * to append various headers to the dropbox log text.
   13668      */
   13669     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
   13670             StringBuilder sb) {
   13671         // Watchdog thread ends up invoking this function (with
   13672         // a null ProcessRecord) to add the stack file to dropbox.
   13673         // Do not acquire a lock on this (am) in such cases, as it
   13674         // could cause a potential deadlock, if and when watchdog
   13675         // is invoked due to unavailability of lock on am and it
   13676         // would prevent watchdog from killing system_server.
   13677         if (process == null) {
   13678             sb.append("Process: ").append(processName).append("\n");
   13679             return;
   13680         }
   13681         // Note: ProcessRecord 'process' is guarded by the service
   13682         // instance.  (notably process.pkgList, which could otherwise change
   13683         // concurrently during execution of this method)
   13684         synchronized (this) {
   13685             sb.append("Process: ").append(processName).append("\n");
   13686             int flags = process.info.flags;
   13687             IPackageManager pm = AppGlobals.getPackageManager();
   13688             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
   13689             for (int ip=0; ip<process.pkgList.size(); ip++) {
   13690                 String pkg = process.pkgList.keyAt(ip);
   13691                 sb.append("Package: ").append(pkg);
   13692                 try {
   13693                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
   13694                     if (pi != null) {
   13695                         sb.append(" v").append(pi.versionCode);
   13696                         if (pi.versionName != null) {
   13697                             sb.append(" (").append(pi.versionName).append(")");
   13698                         }
   13699                     }
   13700                 } catch (RemoteException e) {
   13701                     Slog.e(TAG, "Error getting package info: " + pkg, e);
   13702                 }
   13703                 sb.append("\n");
   13704             }
   13705         }
   13706     }
   13707 
   13708     private static String processClass(ProcessRecord process) {
   13709         if (process == null || process.pid == MY_PID) {
   13710             return "system_server";
   13711         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   13712             return "system_app";
   13713         } else {
   13714             return "data_app";
   13715         }
   13716     }
   13717 
   13718     private volatile long mWtfClusterStart;
   13719     private volatile int mWtfClusterCount;
   13720 
   13721     /**
   13722      * Write a description of an error (crash, WTF, ANR) to the drop box.
   13723      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
   13724      * @param process which caused the error, null means the system server
   13725      * @param activity which triggered the error, null if unknown
   13726      * @param parent activity related to the error, null if unknown
   13727      * @param subject line related to the error, null if absent
   13728      * @param report in long form describing the error, null if absent
   13729      * @param dataFile text file to include in the report, null if none
   13730      * @param crashInfo giving an application stack trace, null if absent
   13731      */
   13732     public void addErrorToDropBox(String eventType,
   13733             ProcessRecord process, String processName, ActivityRecord activity,
   13734             ActivityRecord parent, String subject,
   13735             final String report, final File dataFile,
   13736             final ApplicationErrorReport.CrashInfo crashInfo) {
   13737         // NOTE -- this must never acquire the ActivityManagerService lock,
   13738         // otherwise the watchdog may be prevented from resetting the system.
   13739 
   13740         final String dropboxTag = processClass(process) + "_" + eventType;
   13741         final DropBoxManager dbox = (DropBoxManager)
   13742                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   13743 
   13744         // Exit early if the dropbox isn't configured to accept this report type.
   13745         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   13746 
   13747         // Rate-limit how often we're willing to do the heavy lifting below to
   13748         // collect and record logs; currently 5 logs per 10 second period.
   13749         final long now = SystemClock.elapsedRealtime();
   13750         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
   13751             mWtfClusterStart = now;
   13752             mWtfClusterCount = 1;
   13753         } else {
   13754             if (mWtfClusterCount++ >= 5) return;
   13755         }
   13756 
   13757         final StringBuilder sb = new StringBuilder(1024);
   13758         appendDropBoxProcessHeaders(process, processName, sb);
   13759         if (process != null) {
   13760             sb.append("Foreground: ")
   13761                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
   13762                     .append("\n");
   13763         }
   13764         if (activity != null) {
   13765             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
   13766         }
   13767         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
   13768             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
   13769         }
   13770         if (parent != null && parent != activity) {
   13771             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
   13772         }
   13773         if (subject != null) {
   13774             sb.append("Subject: ").append(subject).append("\n");
   13775         }
   13776         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   13777         if (Debug.isDebuggerConnected()) {
   13778             sb.append("Debugger: Connected\n");
   13779         }
   13780         sb.append("\n");
   13781 
   13782         // Do the rest in a worker thread to avoid blocking the caller on I/O
   13783         // (After this point, we shouldn't access AMS internal data structures.)
   13784         Thread worker = new Thread("Error dump: " + dropboxTag) {
   13785             @Override
   13786             public void run() {
   13787                 if (report != null) {
   13788                     sb.append(report);
   13789                 }
   13790 
   13791                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
   13792                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
   13793                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
   13794                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
   13795 
   13796                 if (dataFile != null && maxDataFileSize > 0) {
   13797                     try {
   13798                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
   13799                                     "\n\n[[TRUNCATED]]"));
   13800                     } catch (IOException e) {
   13801                         Slog.e(TAG, "Error reading " + dataFile, e);
   13802                     }
   13803                 }
   13804                 if (crashInfo != null && crashInfo.stackTrace != null) {
   13805                     sb.append(crashInfo.stackTrace);
   13806                 }
   13807 
   13808                 if (lines > 0) {
   13809                     sb.append("\n");
   13810 
   13811                     // Merge several logcat streams, and take the last N lines
   13812                     InputStreamReader input = null;
   13813                     try {
   13814                         java.lang.Process logcat = new ProcessBuilder(
   13815                                 "/system/bin/timeout", "-k", "15s", "10s",
   13816                                 "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
   13817                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
   13818                                         .redirectErrorStream(true).start();
   13819 
   13820                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
   13821                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
   13822                         input = new InputStreamReader(logcat.getInputStream());
   13823 
   13824                         int num;
   13825                         char[] buf = new char[8192];
   13826                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
   13827                     } catch (IOException e) {
   13828                         Slog.e(TAG, "Error running logcat", e);
   13829                     } finally {
   13830                         if (input != null) try { input.close(); } catch (IOException e) {}
   13831                     }
   13832                 }
   13833 
   13834                 dbox.addText(dropboxTag, sb.toString());
   13835             }
   13836         };
   13837 
   13838         if (process == null) {
   13839             // If process is null, we are being called from some internal code
   13840             // and may be about to die -- run this synchronously.
   13841             worker.run();
   13842         } else {
   13843             worker.start();
   13844         }
   13845     }
   13846 
   13847     @Override
   13848     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
   13849         enforceNotIsolatedCaller("getProcessesInErrorState");
   13850         // assume our apps are happy - lazy create the list
   13851         List<ActivityManager.ProcessErrorStateInfo> errList = null;
   13852 
   13853         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
   13854                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
   13855         int userId = UserHandle.getUserId(Binder.getCallingUid());
   13856 
   13857         synchronized (this) {
   13858 
   13859             // iterate across all processes
   13860             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   13861                 ProcessRecord app = mLruProcesses.get(i);
   13862                 if (!allUsers && app.userId != userId) {
   13863                     continue;
   13864                 }
   13865                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
   13866                     // This one's in trouble, so we'll generate a report for it
   13867                     // crashes are higher priority (in case there's a crash *and* an anr)
   13868                     ActivityManager.ProcessErrorStateInfo report = null;
   13869                     if (app.crashing) {
   13870                         report = app.crashingReport;
   13871                     } else if (app.notResponding) {
   13872                         report = app.notRespondingReport;
   13873                     }
   13874 
   13875                     if (report != null) {
   13876                         if (errList == null) {
   13877                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
   13878                         }
   13879                         errList.add(report);
   13880                     } else {
   13881                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
   13882                                 " crashing = " + app.crashing +
   13883                                 " notResponding = " + app.notResponding);
   13884                     }
   13885                 }
   13886             }
   13887         }
   13888 
   13889         return errList;
   13890     }
   13891 
   13892     static int procStateToImportance(int procState, int memAdj,
   13893             ActivityManager.RunningAppProcessInfo currApp) {
   13894         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
   13895         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
   13896             currApp.lru = memAdj;
   13897         } else {
   13898             currApp.lru = 0;
   13899         }
   13900         return imp;
   13901     }
   13902 
   13903     private void fillInProcMemInfo(ProcessRecord app,
   13904             ActivityManager.RunningAppProcessInfo outInfo) {
   13905         outInfo.pid = app.pid;
   13906         outInfo.uid = app.info.uid;
   13907         if (mHeavyWeightProcess == app) {
   13908             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
   13909         }
   13910         if (app.persistent) {
   13911             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
   13912         }
   13913         if (app.activities.size() > 0) {
   13914             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
   13915         }
   13916         outInfo.lastTrimLevel = app.trimMemoryLevel;
   13917         int adj = app.curAdj;
   13918         int procState = app.curProcState;
   13919         outInfo.importance = procStateToImportance(procState, adj, outInfo);
   13920         outInfo.importanceReasonCode = app.adjTypeCode;
   13921         outInfo.processState = app.curProcState;
   13922     }
   13923 
   13924     @Override
   13925     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
   13926         enforceNotIsolatedCaller("getRunningAppProcesses");
   13927 
   13928         final int callingUid = Binder.getCallingUid();
   13929 
   13930         // Lazy instantiation of list
   13931         List<ActivityManager.RunningAppProcessInfo> runList = null;
   13932         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
   13933                 callingUid) == PackageManager.PERMISSION_GRANTED;
   13934         final int userId = UserHandle.getUserId(callingUid);
   13935         final boolean allUids = isGetTasksAllowed(
   13936                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
   13937 
   13938         synchronized (this) {
   13939             // Iterate across all processes
   13940             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   13941                 ProcessRecord app = mLruProcesses.get(i);
   13942                 if ((!allUsers && app.userId != userId)
   13943                         || (!allUids && app.uid != callingUid)) {
   13944                     continue;
   13945                 }
   13946                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
   13947                     // Generate process state info for running application
   13948                     ActivityManager.RunningAppProcessInfo currApp =
   13949                         new ActivityManager.RunningAppProcessInfo(app.processName,
   13950                                 app.pid, app.getPackageList());
   13951                     fillInProcMemInfo(app, currApp);
   13952                     if (app.adjSource instanceof ProcessRecord) {
   13953                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
   13954                         currApp.importanceReasonImportance =
   13955                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
   13956                                         app.adjSourceProcState);
   13957                     } else if (app.adjSource instanceof ActivityRecord) {
   13958                         ActivityRecord r = (ActivityRecord)app.adjSource;
   13959                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
   13960                     }
   13961                     if (app.adjTarget instanceof ComponentName) {
   13962                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
   13963                     }
   13964                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
   13965                     //        + " lru=" + currApp.lru);
   13966                     if (runList == null) {
   13967                         runList = new ArrayList<>();
   13968                     }
   13969                     runList.add(currApp);
   13970                 }
   13971             }
   13972         }
   13973         return runList;
   13974     }
   13975 
   13976     @Override
   13977     public List<ApplicationInfo> getRunningExternalApplications() {
   13978         enforceNotIsolatedCaller("getRunningExternalApplications");
   13979         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
   13980         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
   13981         if (runningApps != null && runningApps.size() > 0) {
   13982             Set<String> extList = new HashSet<String>();
   13983             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
   13984                 if (app.pkgList != null) {
   13985                     for (String pkg : app.pkgList) {
   13986                         extList.add(pkg);
   13987                     }
   13988                 }
   13989             }
   13990             IPackageManager pm = AppGlobals.getPackageManager();
   13991             for (String pkg : extList) {
   13992                 try {
   13993                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
   13994                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
   13995                         retList.add(info);
   13996                     }
   13997                 } catch (RemoteException e) {
   13998                 }
   13999             }
   14000         }
   14001         return retList;
   14002     }
   14003 
   14004     @Override
   14005     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
   14006         enforceNotIsolatedCaller("getMyMemoryState");
   14007         synchronized (this) {
   14008             ProcessRecord proc;
   14009             synchronized (mPidsSelfLocked) {
   14010                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   14011             }
   14012             fillInProcMemInfo(proc, outInfo);
   14013         }
   14014     }
   14015 
   14016     @Override
   14017     public int getMemoryTrimLevel() {
   14018         enforceNotIsolatedCaller("getMyMemoryState");
   14019         synchronized (this) {
   14020             return mLastMemoryLevel;
   14021         }
   14022     }
   14023 
   14024     @Override
   14025     public void onShellCommand(FileDescriptor in, FileDescriptor out,
   14026             FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
   14027         (new ActivityManagerShellCommand(this, false)).exec(
   14028                 this, in, out, err, args, resultReceiver);
   14029     }
   14030 
   14031     @Override
   14032     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   14033         if (checkCallingPermission(android.Manifest.permission.DUMP)
   14034                 != PackageManager.PERMISSION_GRANTED) {
   14035             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   14036                     + Binder.getCallingPid()
   14037                     + ", uid=" + Binder.getCallingUid()
   14038                     + " without permission "
   14039                     + android.Manifest.permission.DUMP);
   14040             return;
   14041         }
   14042 
   14043         boolean dumpAll = false;
   14044         boolean dumpClient = false;
   14045         boolean dumpCheckin = false;
   14046         boolean dumpCheckinFormat = false;
   14047         String dumpPackage = null;
   14048 
   14049         int opti = 0;
   14050         while (opti < args.length) {
   14051             String opt = args[opti];
   14052             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   14053                 break;
   14054             }
   14055             opti++;
   14056             if ("-a".equals(opt)) {
   14057                 dumpAll = true;
   14058             } else if ("-c".equals(opt)) {
   14059                 dumpClient = true;
   14060             } else if ("-p".equals(opt)) {
   14061                 if (opti < args.length) {
   14062                     dumpPackage = args[opti];
   14063                     opti++;
   14064                 } else {
   14065                     pw.println("Error: -p option requires package argument");
   14066                     return;
   14067                 }
   14068                 dumpClient = true;
   14069             } else if ("--checkin".equals(opt)) {
   14070                 dumpCheckin = dumpCheckinFormat = true;
   14071             } else if ("-C".equals(opt)) {
   14072                 dumpCheckinFormat = true;
   14073             } else if ("-h".equals(opt)) {
   14074                 ActivityManagerShellCommand.dumpHelp(pw, true);
   14075                 return;
   14076             } else {
   14077                 pw.println("Unknown argument: " + opt + "; use -h for help");
   14078             }
   14079         }
   14080 
   14081         long origId = Binder.clearCallingIdentity();
   14082         boolean more = false;
   14083         // Is the caller requesting to dump a particular piece of data?
   14084         if (opti < args.length) {
   14085             String cmd = args[opti];
   14086             opti++;
   14087             if ("activities".equals(cmd) || "a".equals(cmd)) {
   14088                 synchronized (this) {
   14089                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
   14090                 }
   14091             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
   14092                 synchronized (this) {
   14093                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
   14094                 }
   14095             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
   14096                 String[] newArgs;
   14097                 String name;
   14098                 if (opti >= args.length) {
   14099                     name = null;
   14100                     newArgs = EMPTY_STRING_ARRAY;
   14101                 } else {
   14102                     dumpPackage = args[opti];
   14103                     opti++;
   14104                     newArgs = new String[args.length - opti];
   14105                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   14106                             args.length - opti);
   14107                 }
   14108                 synchronized (this) {
   14109                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
   14110                 }
   14111             } else if ("broadcast-stats".equals(cmd)) {
   14112                 String[] newArgs;
   14113                 String name;
   14114                 if (opti >= args.length) {
   14115                     name = null;
   14116                     newArgs = EMPTY_STRING_ARRAY;
   14117                 } else {
   14118                     dumpPackage = args[opti];
   14119                     opti++;
   14120                     newArgs = new String[args.length - opti];
   14121                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   14122                             args.length - opti);
   14123                 }
   14124                 synchronized (this) {
   14125                     if (dumpCheckinFormat) {
   14126                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
   14127                                 dumpPackage);
   14128                     } else {
   14129                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
   14130                     }
   14131                 }
   14132             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
   14133                 String[] newArgs;
   14134                 String name;
   14135                 if (opti >= args.length) {
   14136                     name = null;
   14137                     newArgs = EMPTY_STRING_ARRAY;
   14138                 } else {
   14139                     dumpPackage = args[opti];
   14140                     opti++;
   14141                     newArgs = new String[args.length - opti];
   14142                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   14143                             args.length - opti);
   14144                 }
   14145                 synchronized (this) {
   14146                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
   14147                 }
   14148             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
   14149                 String[] newArgs;
   14150                 String name;
   14151                 if (opti >= args.length) {
   14152                     name = null;
   14153                     newArgs = EMPTY_STRING_ARRAY;
   14154                 } else {
   14155                     dumpPackage = args[opti];
   14156                     opti++;
   14157                     newArgs = new String[args.length - opti];
   14158                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   14159                             args.length - opti);
   14160                 }
   14161                 synchronized (this) {
   14162                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
   14163                 }
   14164             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
   14165                 synchronized (this) {
   14166                     dumpOomLocked(fd, pw, args, opti, true);
   14167                 }
   14168             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
   14169                 synchronized (this) {
   14170                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
   14171                 }
   14172             } else if ("provider".equals(cmd)) {
   14173                 String[] newArgs;
   14174                 String name;
   14175                 if (opti >= args.length) {
   14176                     name = null;
   14177                     newArgs = EMPTY_STRING_ARRAY;
   14178                 } else {
   14179                     name = args[opti];
   14180                     opti++;
   14181                     newArgs = new String[args.length - opti];
   14182                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   14183                 }
   14184                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
   14185                     pw.println("No providers match: " + name);
   14186                     pw.println("Use -h for help.");
   14187                 }
   14188             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
   14189                 synchronized (this) {
   14190                     dumpProvidersLocked(fd, pw, args, opti, true, null);
   14191                 }
   14192             } else if ("service".equals(cmd)) {
   14193                 String[] newArgs;
   14194                 String name;
   14195                 if (opti >= args.length) {
   14196                     name = null;
   14197                     newArgs = EMPTY_STRING_ARRAY;
   14198                 } else {
   14199                     name = args[opti];
   14200                     opti++;
   14201                     newArgs = new String[args.length - opti];
   14202                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   14203                             args.length - opti);
   14204                 }
   14205                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
   14206                     pw.println("No services match: " + name);
   14207                     pw.println("Use -h for help.");
   14208                 }
   14209             } else if ("package".equals(cmd)) {
   14210                 String[] newArgs;
   14211                 if (opti >= args.length) {
   14212                     pw.println("package: no package name specified");
   14213                     pw.println("Use -h for help.");
   14214                 } else {
   14215                     dumpPackage = args[opti];
   14216                     opti++;
   14217                     newArgs = new String[args.length - opti];
   14218                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   14219                             args.length - opti);
   14220                     args = newArgs;
   14221                     opti = 0;
   14222                     more = true;
   14223                 }
   14224             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
   14225                 synchronized (this) {
   14226                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
   14227                 }
   14228             } else if ("services".equals(cmd) || "s".equals(cmd)) {
   14229                 if (dumpClient) {
   14230                     ActiveServices.ServiceDumper dumper;
   14231                     synchronized (this) {
   14232                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
   14233                                 dumpPackage);
   14234                     }
   14235                     dumper.dumpWithClient();
   14236                 } else {
   14237                     synchronized (this) {
   14238                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
   14239                                 dumpPackage).dumpLocked();
   14240                     }
   14241                 }
   14242             } else if ("locks".equals(cmd)) {
   14243                 LockGuard.dump(fd, pw, args);
   14244             } else {
   14245                 // Dumping a single activity?
   14246                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
   14247                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
   14248                     int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
   14249                     if (res < 0) {
   14250                         pw.println("Bad activity command, or no activities match: " + cmd);
   14251                         pw.println("Use -h for help.");
   14252                     }
   14253                 }
   14254             }
   14255             if (!more) {
   14256                 Binder.restoreCallingIdentity(origId);
   14257                 return;
   14258             }
   14259         }
   14260 
   14261         // No piece of data specified, dump everything.
   14262         if (dumpCheckinFormat) {
   14263             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
   14264         } else if (dumpClient) {
   14265             ActiveServices.ServiceDumper sdumper;
   14266             synchronized (this) {
   14267                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14268                 pw.println();
   14269                 if (dumpAll) {
   14270                     pw.println("-------------------------------------------------------------------------------");
   14271                 }
   14272                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14273                 pw.println();
   14274                 if (dumpAll) {
   14275                     pw.println("-------------------------------------------------------------------------------");
   14276                 }
   14277                 if (dumpAll || dumpPackage != null) {
   14278                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14279                     pw.println();
   14280                     if (dumpAll) {
   14281                         pw.println("-------------------------------------------------------------------------------");
   14282                     }
   14283                 }
   14284                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14285                 pw.println();
   14286                 if (dumpAll) {
   14287                     pw.println("-------------------------------------------------------------------------------");
   14288                 }
   14289                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14290                 pw.println();
   14291                 if (dumpAll) {
   14292                     pw.println("-------------------------------------------------------------------------------");
   14293                 }
   14294                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
   14295                         dumpPackage);
   14296             }
   14297             sdumper.dumpWithClient();
   14298             pw.println();
   14299             synchronized (this) {
   14300                 if (dumpAll) {
   14301                     pw.println("-------------------------------------------------------------------------------");
   14302                 }
   14303                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14304                 pw.println();
   14305                 if (dumpAll) {
   14306                     pw.println("-------------------------------------------------------------------------------");
   14307                 }
   14308                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   14309                 if (mAssociations.size() > 0) {
   14310                     pw.println();
   14311                     if (dumpAll) {
   14312                         pw.println("-------------------------------------------------------------------------------");
   14313                     }
   14314                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   14315                 }
   14316                 pw.println();
   14317                 if (dumpAll) {
   14318                     pw.println("-------------------------------------------------------------------------------");
   14319                 }
   14320                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14321             }
   14322 
   14323         } else {
   14324             synchronized (this) {
   14325                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14326                 pw.println();
   14327                 if (dumpAll) {
   14328                     pw.println("-------------------------------------------------------------------------------");
   14329                 }
   14330                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14331                 pw.println();
   14332                 if (dumpAll) {
   14333                     pw.println("-------------------------------------------------------------------------------");
   14334                 }
   14335                 if (dumpAll || dumpPackage != null) {
   14336                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14337                     pw.println();
   14338                     if (dumpAll) {
   14339                         pw.println("-------------------------------------------------------------------------------");
   14340                     }
   14341                 }
   14342                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14343                 pw.println();
   14344                 if (dumpAll) {
   14345                     pw.println("-------------------------------------------------------------------------------");
   14346                 }
   14347                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14348                 pw.println();
   14349                 if (dumpAll) {
   14350                     pw.println("-------------------------------------------------------------------------------");
   14351                 }
   14352                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
   14353                         .dumpLocked();
   14354                 pw.println();
   14355                 if (dumpAll) {
   14356                     pw.println("-------------------------------------------------------------------------------");
   14357                 }
   14358                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14359                 pw.println();
   14360                 if (dumpAll) {
   14361                     pw.println("-------------------------------------------------------------------------------");
   14362                 }
   14363                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   14364                 if (mAssociations.size() > 0) {
   14365                     pw.println();
   14366                     if (dumpAll) {
   14367                         pw.println("-------------------------------------------------------------------------------");
   14368                     }
   14369                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   14370                 }
   14371                 pw.println();
   14372                 if (dumpAll) {
   14373                     pw.println("-------------------------------------------------------------------------------");
   14374                 }
   14375                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14376             }
   14377         }
   14378         Binder.restoreCallingIdentity(origId);
   14379     }
   14380 
   14381     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   14382             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   14383         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
   14384 
   14385         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
   14386                 dumpPackage);
   14387         boolean needSep = printedAnything;
   14388 
   14389         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
   14390                 dumpPackage, needSep, "  mFocusedActivity: ");
   14391         if (printed) {
   14392             printedAnything = true;
   14393             needSep = false;
   14394         }
   14395 
   14396         if (dumpPackage == null) {
   14397             if (needSep) {
   14398                 pw.println();
   14399             }
   14400             needSep = true;
   14401             printedAnything = true;
   14402             mStackSupervisor.dump(pw, "  ");
   14403         }
   14404 
   14405         if (!printedAnything) {
   14406             pw.println("  (nothing)");
   14407         }
   14408     }
   14409 
   14410     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   14411             int opti, boolean dumpAll, String dumpPackage) {
   14412         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
   14413 
   14414         boolean printedAnything = false;
   14415 
   14416         if (mRecentTasks != null && mRecentTasks.size() > 0) {
   14417             boolean printedHeader = false;
   14418 
   14419             final int N = mRecentTasks.size();
   14420             for (int i=0; i<N; i++) {
   14421                 TaskRecord tr = mRecentTasks.get(i);
   14422                 if (dumpPackage != null) {
   14423                     if (tr.realActivity == null ||
   14424                             !dumpPackage.equals(tr.realActivity)) {
   14425                         continue;
   14426                     }
   14427                 }
   14428                 if (!printedHeader) {
   14429                     pw.println("  Recent tasks:");
   14430                     printedHeader = true;
   14431                     printedAnything = true;
   14432                 }
   14433                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
   14434                         pw.println(tr);
   14435                 if (dumpAll) {
   14436                     mRecentTasks.get(i).dump(pw, "    ");
   14437                 }
   14438             }
   14439         }
   14440 
   14441         if (!printedAnything) {
   14442             pw.println("  (nothing)");
   14443         }
   14444     }
   14445 
   14446     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   14447             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   14448         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
   14449 
   14450         int dumpUid = 0;
   14451         if (dumpPackage != null) {
   14452             IPackageManager pm = AppGlobals.getPackageManager();
   14453             try {
   14454                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
   14455             } catch (RemoteException e) {
   14456             }
   14457         }
   14458 
   14459         boolean printedAnything = false;
   14460 
   14461         final long now = SystemClock.uptimeMillis();
   14462 
   14463         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
   14464             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
   14465                     = mAssociations.valueAt(i1);
   14466             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
   14467                 SparseArray<ArrayMap<String, Association>> sourceUids
   14468                         = targetComponents.valueAt(i2);
   14469                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
   14470                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
   14471                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
   14472                         Association ass = sourceProcesses.valueAt(i4);
   14473                         if (dumpPackage != null) {
   14474                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
   14475                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
   14476                                 continue;
   14477                             }
   14478                         }
   14479                         printedAnything = true;
   14480                         pw.print("  ");
   14481                         pw.print(ass.mTargetProcess);
   14482                         pw.print("/");
   14483                         UserHandle.formatUid(pw, ass.mTargetUid);
   14484                         pw.print(" <- ");
   14485                         pw.print(ass.mSourceProcess);
   14486                         pw.print("/");
   14487                         UserHandle.formatUid(pw, ass.mSourceUid);
   14488                         pw.println();
   14489                         pw.print("    via ");
   14490                         pw.print(ass.mTargetComponent.flattenToShortString());
   14491                         pw.println();
   14492                         pw.print("    ");
   14493                         long dur = ass.mTime;
   14494                         if (ass.mNesting > 0) {
   14495                             dur += now - ass.mStartTime;
   14496                         }
   14497                         TimeUtils.formatDuration(dur, pw);
   14498                         pw.print(" (");
   14499                         pw.print(ass.mCount);
   14500                         pw.print(" times)");
   14501                         pw.print("  ");
   14502                         for (int i=0; i<ass.mStateTimes.length; i++) {
   14503                             long amt = ass.mStateTimes[i];
   14504                             if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
   14505                                 amt += now - ass.mLastStateUptime;
   14506                             }
   14507                             if (amt != 0) {
   14508                                 pw.print(" ");
   14509                                 pw.print(ProcessList.makeProcStateString(
   14510                                             i + ActivityManager.MIN_PROCESS_STATE));
   14511                                 pw.print("=");
   14512                                 TimeUtils.formatDuration(amt, pw);
   14513                                 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
   14514                                     pw.print("*");
   14515                                 }
   14516                             }
   14517                         }
   14518                         pw.println();
   14519                         if (ass.mNesting > 0) {
   14520                             pw.print("    Currently active: ");
   14521                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
   14522                             pw.println();
   14523                         }
   14524                     }
   14525                 }
   14526             }
   14527 
   14528         }
   14529 
   14530         if (!printedAnything) {
   14531             pw.println("  (nothing)");
   14532         }
   14533     }
   14534 
   14535     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
   14536             String header, boolean needSep) {
   14537         boolean printed = false;
   14538         int whichAppId = -1;
   14539         if (dumpPackage != null) {
   14540             try {
   14541                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
   14542                         dumpPackage, 0);
   14543                 whichAppId = UserHandle.getAppId(info.uid);
   14544             } catch (NameNotFoundException e) {
   14545                 e.printStackTrace();
   14546             }
   14547         }
   14548         for (int i=0; i<uids.size(); i++) {
   14549             UidRecord uidRec = uids.valueAt(i);
   14550             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
   14551                 continue;
   14552             }
   14553             if (!printed) {
   14554                 printed = true;
   14555                 if (needSep) {
   14556                     pw.println();
   14557                 }
   14558                 pw.print("  ");
   14559                 pw.println(header);
   14560                 needSep = true;
   14561             }
   14562             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
   14563             pw.print(": "); pw.println(uidRec);
   14564         }
   14565         return printed;
   14566     }
   14567 
   14568     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   14569             int opti, boolean dumpAll, String dumpPackage) {
   14570         boolean needSep = false;
   14571         boolean printedAnything = false;
   14572         int numPers = 0;
   14573 
   14574         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
   14575 
   14576         if (dumpAll) {
   14577             final int NP = mProcessNames.getMap().size();
   14578             for (int ip=0; ip<NP; ip++) {
   14579                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
   14580                 final int NA = procs.size();
   14581                 for (int ia=0; ia<NA; ia++) {
   14582                     ProcessRecord r = procs.valueAt(ia);
   14583                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   14584                         continue;
   14585                     }
   14586                     if (!needSep) {
   14587                         pw.println("  All known processes:");
   14588                         needSep = true;
   14589                         printedAnything = true;
   14590                     }
   14591                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
   14592                         pw.print(" UID "); pw.print(procs.keyAt(ia));
   14593                         pw.print(" "); pw.println(r);
   14594                     r.dump(pw, "    ");
   14595                     if (r.persistent) {
   14596                         numPers++;
   14597                     }
   14598                 }
   14599             }
   14600         }
   14601 
   14602         if (mIsolatedProcesses.size() > 0) {
   14603             boolean printed = false;
   14604             for (int i=0; i<mIsolatedProcesses.size(); i++) {
   14605                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
   14606                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   14607                     continue;
   14608                 }
   14609                 if (!printed) {
   14610                     if (needSep) {
   14611                         pw.println();
   14612                     }
   14613                     pw.println("  Isolated process list (sorted by uid):");
   14614                     printedAnything = true;
   14615                     printed = true;
   14616                     needSep = true;
   14617                 }
   14618                 pw.println(String.format("%sIsolated #%2d: %s",
   14619                         "    ", i, r.toString()));
   14620             }
   14621         }
   14622 
   14623         if (mActiveUids.size() > 0) {
   14624             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
   14625                 printedAnything = needSep = true;
   14626             }
   14627         }
   14628         if (mValidateUids.size() > 0) {
   14629             if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
   14630                 printedAnything = needSep = true;
   14631             }
   14632         }
   14633 
   14634         if (mLruProcesses.size() > 0) {
   14635             if (needSep) {
   14636                 pw.println();
   14637             }
   14638             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
   14639                     pw.print(" total, non-act at ");
   14640                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   14641                     pw.print(", non-svc at ");
   14642                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   14643                     pw.println("):");
   14644             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
   14645             needSep = true;
   14646             printedAnything = true;
   14647         }
   14648 
   14649         if (dumpAll || dumpPackage != null) {
   14650             synchronized (mPidsSelfLocked) {
   14651                 boolean printed = false;
   14652                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   14653                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
   14654                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   14655                         continue;
   14656                     }
   14657                     if (!printed) {
   14658                         if (needSep) pw.println();
   14659                         needSep = true;
   14660                         pw.println("  PID mappings:");
   14661                         printed = true;
   14662                         printedAnything = true;
   14663                     }
   14664                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
   14665                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
   14666                 }
   14667             }
   14668         }
   14669 
   14670         if (mForegroundProcesses.size() > 0) {
   14671             synchronized (mPidsSelfLocked) {
   14672                 boolean printed = false;
   14673                 for (int i=0; i<mForegroundProcesses.size(); i++) {
   14674                     ProcessRecord r = mPidsSelfLocked.get(
   14675                             mForegroundProcesses.valueAt(i).pid);
   14676                     if (dumpPackage != null && (r == null
   14677                             || !r.pkgList.containsKey(dumpPackage))) {
   14678                         continue;
   14679                     }
   14680                     if (!printed) {
   14681                         if (needSep) pw.println();
   14682                         needSep = true;
   14683                         pw.println("  Foreground Processes:");
   14684                         printed = true;
   14685                         printedAnything = true;
   14686                     }
   14687                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
   14688                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
   14689                 }
   14690             }
   14691         }
   14692 
   14693         if (mPersistentStartingProcesses.size() > 0) {
   14694             if (needSep) pw.println();
   14695             needSep = true;
   14696             printedAnything = true;
   14697             pw.println("  Persisent processes that are starting:");
   14698             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
   14699                     "Starting Norm", "Restarting PERS", dumpPackage);
   14700         }
   14701 
   14702         if (mRemovedProcesses.size() > 0) {
   14703             if (needSep) pw.println();
   14704             needSep = true;
   14705             printedAnything = true;
   14706             pw.println("  Processes that are being removed:");
   14707             dumpProcessList(pw, this, mRemovedProcesses, "    ",
   14708                     "Removed Norm", "Removed PERS", dumpPackage);
   14709         }
   14710 
   14711         if (mProcessesOnHold.size() > 0) {
   14712             if (needSep) pw.println();
   14713             needSep = true;
   14714             printedAnything = true;
   14715             pw.println("  Processes that are on old until the system is ready:");
   14716             dumpProcessList(pw, this, mProcessesOnHold, "    ",
   14717                     "OnHold Norm", "OnHold PERS", dumpPackage);
   14718         }
   14719 
   14720         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
   14721 
   14722         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
   14723         if (needSep) {
   14724             printedAnything = true;
   14725         }
   14726 
   14727         if (dumpPackage == null) {
   14728             pw.println();
   14729             needSep = false;
   14730             mUserController.dump(pw, dumpAll);
   14731         }
   14732         if (mHomeProcess != null && (dumpPackage == null
   14733                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
   14734             if (needSep) {
   14735                 pw.println();
   14736                 needSep = false;
   14737             }
   14738             pw.println("  mHomeProcess: " + mHomeProcess);
   14739         }
   14740         if (mPreviousProcess != null && (dumpPackage == null
   14741                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
   14742             if (needSep) {
   14743                 pw.println();
   14744                 needSep = false;
   14745             }
   14746             pw.println("  mPreviousProcess: " + mPreviousProcess);
   14747         }
   14748         if (dumpAll) {
   14749             StringBuilder sb = new StringBuilder(128);
   14750             sb.append("  mPreviousProcessVisibleTime: ");
   14751             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
   14752             pw.println(sb);
   14753         }
   14754         if (mHeavyWeightProcess != null && (dumpPackage == null
   14755                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
   14756             if (needSep) {
   14757                 pw.println();
   14758                 needSep = false;
   14759             }
   14760             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   14761         }
   14762         if (dumpPackage == null) {
   14763             pw.println("  mConfiguration: " + mConfiguration);
   14764         }
   14765         if (dumpAll) {
   14766             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
   14767             if (mCompatModePackages.getPackages().size() > 0) {
   14768                 boolean printed = false;
   14769                 for (Map.Entry<String, Integer> entry
   14770                         : mCompatModePackages.getPackages().entrySet()) {
   14771                     String pkg = entry.getKey();
   14772                     int mode = entry.getValue();
   14773                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
   14774                         continue;
   14775                     }
   14776                     if (!printed) {
   14777                         pw.println("  mScreenCompatPackages:");
   14778                         printed = true;
   14779                     }
   14780                     pw.print("    "); pw.print(pkg); pw.print(": ");
   14781                             pw.print(mode); pw.println();
   14782                 }
   14783             }
   14784         }
   14785         if (dumpPackage == null) {
   14786             pw.println("  mWakefulness="
   14787                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
   14788             pw.println("  mSleepTokens=" + mSleepTokens);
   14789             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
   14790                     + lockScreenShownToString());
   14791             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
   14792             if (mRunningVoice != null) {
   14793                 pw.println("  mRunningVoice=" + mRunningVoice);
   14794                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
   14795             }
   14796         }
   14797         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
   14798                 || mOrigWaitForDebugger) {
   14799             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
   14800                     || dumpPackage.equals(mOrigDebugApp)) {
   14801                 if (needSep) {
   14802                     pw.println();
   14803                     needSep = false;
   14804                 }
   14805                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
   14806                         + " mDebugTransient=" + mDebugTransient
   14807                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
   14808             }
   14809         }
   14810         if (mCurAppTimeTracker != null) {
   14811             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
   14812         }
   14813         if (mMemWatchProcesses.getMap().size() > 0) {
   14814             pw.println("  Mem watch processes:");
   14815             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
   14816                     = mMemWatchProcesses.getMap();
   14817             for (int i=0; i<procs.size(); i++) {
   14818                 final String proc = procs.keyAt(i);
   14819                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
   14820                 for (int j=0; j<uids.size(); j++) {
   14821                     if (needSep) {
   14822                         pw.println();
   14823                         needSep = false;
   14824                     }
   14825                     StringBuilder sb = new StringBuilder();
   14826                     sb.append("    ").append(proc).append('/');
   14827                     UserHandle.formatUid(sb, uids.keyAt(j));
   14828                     Pair<Long, String> val = uids.valueAt(j);
   14829                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
   14830                     if (val.second != null) {
   14831                         sb.append(", report to ").append(val.second);
   14832                     }
   14833                     pw.println(sb.toString());
   14834                 }
   14835             }
   14836             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
   14837             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
   14838             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
   14839                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
   14840         }
   14841         if (mTrackAllocationApp != null) {
   14842             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
   14843                 if (needSep) {
   14844                     pw.println();
   14845                     needSep = false;
   14846                 }
   14847                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
   14848             }
   14849         }
   14850         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
   14851                 || mProfileFd != null) {
   14852             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
   14853                 if (needSep) {
   14854                     pw.println();
   14855                     needSep = false;
   14856                 }
   14857                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
   14858                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
   14859                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
   14860                         + mAutoStopProfiler);
   14861                 pw.println("  mProfileType=" + mProfileType);
   14862             }
   14863         }
   14864         if (mNativeDebuggingApp != null) {
   14865             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
   14866                 if (needSep) {
   14867                     pw.println();
   14868                     needSep = false;
   14869                 }
   14870                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
   14871             }
   14872         }
   14873         if (dumpPackage == null) {
   14874             if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
   14875                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
   14876                         + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
   14877             }
   14878             if (mController != null) {
   14879                 pw.println("  mController=" + mController
   14880                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
   14881             }
   14882             if (dumpAll) {
   14883                 pw.println("  Total persistent processes: " + numPers);
   14884                 pw.println("  mProcessesReady=" + mProcessesReady
   14885                         + " mSystemReady=" + mSystemReady
   14886                         + " mBooted=" + mBooted
   14887                         + " mFactoryTest=" + mFactoryTest);
   14888                 pw.println("  mBooting=" + mBooting
   14889                         + " mCallFinishBooting=" + mCallFinishBooting
   14890                         + " mBootAnimationComplete=" + mBootAnimationComplete);
   14891                 pw.print("  mLastPowerCheckRealtime=");
   14892                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
   14893                         pw.println("");
   14894                 pw.print("  mLastPowerCheckUptime=");
   14895                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
   14896                         pw.println("");
   14897                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
   14898                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
   14899                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
   14900                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
   14901                         + " (" + mLruProcesses.size() + " total)"
   14902                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
   14903                         + " mNumServiceProcs=" + mNumServiceProcs
   14904                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
   14905                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
   14906                         + " mLastMemoryLevel=" + mLastMemoryLevel
   14907                         + " mLastNumProcesses=" + mLastNumProcesses);
   14908                 long now = SystemClock.uptimeMillis();
   14909                 pw.print("  mLastIdleTime=");
   14910                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
   14911                         pw.print(" mLowRamSinceLastIdle=");
   14912                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
   14913                         pw.println();
   14914             }
   14915         }
   14916 
   14917         if (!printedAnything) {
   14918             pw.println("  (nothing)");
   14919         }
   14920     }
   14921 
   14922     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
   14923             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
   14924         if (mProcessesToGc.size() > 0) {
   14925             boolean printed = false;
   14926             long now = SystemClock.uptimeMillis();
   14927             for (int i=0; i<mProcessesToGc.size(); i++) {
   14928                 ProcessRecord proc = mProcessesToGc.get(i);
   14929                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
   14930                     continue;
   14931                 }
   14932                 if (!printed) {
   14933                     if (needSep) pw.println();
   14934                     needSep = true;
   14935                     pw.println("  Processes that are waiting to GC:");
   14936                     printed = true;
   14937                 }
   14938                 pw.print("    Process "); pw.println(proc);
   14939                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
   14940                         pw.print(", last gced=");
   14941                         pw.print(now-proc.lastRequestedGc);
   14942                         pw.print(" ms ago, last lowMem=");
   14943                         pw.print(now-proc.lastLowMemory);
   14944                         pw.println(" ms ago");
   14945 
   14946             }
   14947         }
   14948         return needSep;
   14949     }
   14950 
   14951     void printOomLevel(PrintWriter pw, String name, int adj) {
   14952         pw.print("    ");
   14953         if (adj >= 0) {
   14954             pw.print(' ');
   14955             if (adj < 10) pw.print(' ');
   14956         } else {
   14957             if (adj > -10) pw.print(' ');
   14958         }
   14959         pw.print(adj);
   14960         pw.print(": ");
   14961         pw.print(name);
   14962         pw.print(" (");
   14963         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
   14964         pw.println(")");
   14965     }
   14966 
   14967     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   14968             int opti, boolean dumpAll) {
   14969         boolean needSep = false;
   14970 
   14971         if (mLruProcesses.size() > 0) {
   14972             if (needSep) pw.println();
   14973             needSep = true;
   14974             pw.println("  OOM levels:");
   14975             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
   14976             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
   14977             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
   14978             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
   14979             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
   14980             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
   14981             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
   14982             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
   14983             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
   14984             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
   14985             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
   14986             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
   14987             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
   14988             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
   14989 
   14990             if (needSep) pw.println();
   14991             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
   14992                     pw.print(" total, non-act at ");
   14993                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   14994                     pw.print(", non-svc at ");
   14995                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   14996                     pw.println("):");
   14997             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
   14998             needSep = true;
   14999         }
   15000 
   15001         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
   15002 
   15003         pw.println();
   15004         pw.println("  mHomeProcess: " + mHomeProcess);
   15005         pw.println("  mPreviousProcess: " + mPreviousProcess);
   15006         if (mHeavyWeightProcess != null) {
   15007             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   15008         }
   15009 
   15010         return true;
   15011     }
   15012 
   15013     /**
   15014      * There are three ways to call this:
   15015      *  - no provider specified: dump all the providers
   15016      *  - a flattened component name that matched an existing provider was specified as the
   15017      *    first arg: dump that one provider
   15018      *  - the first arg isn't the flattened component name of an existing provider:
   15019      *    dump all providers whose component contains the first arg as a substring
   15020      */
   15021     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   15022             int opti, boolean dumpAll) {
   15023         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
   15024     }
   15025 
   15026     static class ItemMatcher {
   15027         ArrayList<ComponentName> components;
   15028         ArrayList<String> strings;
   15029         ArrayList<Integer> objects;
   15030         boolean all;
   15031 
   15032         ItemMatcher() {
   15033             all = true;
   15034         }
   15035 
   15036         void build(String name) {
   15037             ComponentName componentName = ComponentName.unflattenFromString(name);
   15038             if (componentName != null) {
   15039                 if (components == null) {
   15040                     components = new ArrayList<ComponentName>();
   15041                 }
   15042                 components.add(componentName);
   15043                 all = false;
   15044             } else {
   15045                 int objectId = 0;
   15046                 // Not a '/' separated full component name; maybe an object ID?
   15047                 try {
   15048                     objectId = Integer.parseInt(name, 16);
   15049                     if (objects == null) {
   15050                         objects = new ArrayList<Integer>();
   15051                     }
   15052                     objects.add(objectId);
   15053                     all = false;
   15054                 } catch (RuntimeException e) {
   15055                     // Not an integer; just do string match.
   15056                     if (strings == null) {
   15057                         strings = new ArrayList<String>();
   15058                     }
   15059                     strings.add(name);
   15060                     all = false;
   15061                 }
   15062             }
   15063         }
   15064 
   15065         int build(String[] args, int opti) {
   15066             for (; opti<args.length; opti++) {
   15067                 String name = args[opti];
   15068                 if ("--".equals(name)) {
   15069                     return opti+1;
   15070                 }
   15071                 build(name);
   15072             }
   15073             return opti;
   15074         }
   15075 
   15076         boolean match(Object object, ComponentName comp) {
   15077             if (all) {
   15078                 return true;
   15079             }
   15080             if (components != null) {
   15081                 for (int i=0; i<components.size(); i++) {
   15082                     if (components.get(i).equals(comp)) {
   15083                         return true;
   15084                     }
   15085                 }
   15086             }
   15087             if (objects != null) {
   15088                 for (int i=0; i<objects.size(); i++) {
   15089                     if (System.identityHashCode(object) == objects.get(i)) {
   15090                         return true;
   15091                     }
   15092                 }
   15093             }
   15094             if (strings != null) {
   15095                 String flat = comp.flattenToString();
   15096                 for (int i=0; i<strings.size(); i++) {
   15097                     if (flat.contains(strings.get(i))) {
   15098                         return true;
   15099                     }
   15100                 }
   15101             }
   15102             return false;
   15103         }
   15104     }
   15105 
   15106     /**
   15107      * There are three things that cmd can be:
   15108      *  - a flattened component name that matches an existing activity
   15109      *  - the cmd arg isn't the flattened component name of an existing activity:
   15110      *    dump all activity whose component contains the cmd as a substring
   15111      *  - A hex number of the ActivityRecord object instance.
   15112      */
   15113     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   15114             int opti, boolean dumpAll) {
   15115         ArrayList<ActivityRecord> activities;
   15116 
   15117         synchronized (this) {
   15118             activities = mStackSupervisor.getDumpActivitiesLocked(name);
   15119         }
   15120 
   15121         if (activities.size() <= 0) {
   15122             return false;
   15123         }
   15124 
   15125         String[] newArgs = new String[args.length - opti];
   15126         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   15127 
   15128         TaskRecord lastTask = null;
   15129         boolean needSep = false;
   15130         for (int i=activities.size()-1; i>=0; i--) {
   15131             ActivityRecord r = activities.get(i);
   15132             if (needSep) {
   15133                 pw.println();
   15134             }
   15135             needSep = true;
   15136             synchronized (this) {
   15137                 if (lastTask != r.task) {
   15138                     lastTask = r.task;
   15139                     pw.print("TASK "); pw.print(lastTask.affinity);
   15140                             pw.print(" id="); pw.println(lastTask.taskId);
   15141                     if (dumpAll) {
   15142                         lastTask.dump(pw, "  ");
   15143                     }
   15144                 }
   15145             }
   15146             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
   15147         }
   15148         return true;
   15149     }
   15150 
   15151     /**
   15152      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
   15153      * there is a thread associated with the activity.
   15154      */
   15155     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
   15156             final ActivityRecord r, String[] args, boolean dumpAll) {
   15157         String innerPrefix = prefix + "  ";
   15158         synchronized (this) {
   15159             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
   15160                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
   15161                     pw.print(" pid=");
   15162                     if (r.app != null) pw.println(r.app.pid);
   15163                     else pw.println("(not running)");
   15164             if (dumpAll) {
   15165                 r.dump(pw, innerPrefix);
   15166             }
   15167         }
   15168         if (r.app != null && r.app.thread != null) {
   15169             // flush anything that is already in the PrintWriter since the thread is going
   15170             // to write to the file descriptor directly
   15171             pw.flush();
   15172             try {
   15173                 TransferPipe tp = new TransferPipe();
   15174                 try {
   15175                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   15176                             r.appToken, innerPrefix, args);
   15177                     tp.go(fd);
   15178                 } finally {
   15179                     tp.kill();
   15180                 }
   15181             } catch (IOException e) {
   15182                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   15183             } catch (RemoteException e) {
   15184                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   15185             }
   15186         }
   15187     }
   15188 
   15189     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15190             int opti, boolean dumpAll, String dumpPackage) {
   15191         boolean needSep = false;
   15192         boolean onlyHistory = false;
   15193         boolean printedAnything = false;
   15194 
   15195         if ("history".equals(dumpPackage)) {
   15196             if (opti < args.length && "-s".equals(args[opti])) {
   15197                 dumpAll = false;
   15198             }
   15199             onlyHistory = true;
   15200             dumpPackage = null;
   15201         }
   15202 
   15203         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
   15204         if (!onlyHistory && dumpAll) {
   15205             if (mRegisteredReceivers.size() > 0) {
   15206                 boolean printed = false;
   15207                 Iterator it = mRegisteredReceivers.values().iterator();
   15208                 while (it.hasNext()) {
   15209                     ReceiverList r = (ReceiverList)it.next();
   15210                     if (dumpPackage != null && (r.app == null ||
   15211                             !dumpPackage.equals(r.app.info.packageName))) {
   15212                         continue;
   15213                     }
   15214                     if (!printed) {
   15215                         pw.println("  Registered Receivers:");
   15216                         needSep = true;
   15217                         printed = true;
   15218                         printedAnything = true;
   15219                     }
   15220                     pw.print("  * "); pw.println(r);
   15221                     r.dump(pw, "    ");
   15222                 }
   15223             }
   15224 
   15225             if (mReceiverResolver.dump(pw, needSep ?
   15226                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
   15227                     "    ", dumpPackage, false, false)) {
   15228                 needSep = true;
   15229                 printedAnything = true;
   15230             }
   15231         }
   15232 
   15233         for (BroadcastQueue q : mBroadcastQueues) {
   15234             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
   15235             printedAnything |= needSep;
   15236         }
   15237 
   15238         needSep = true;
   15239 
   15240         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
   15241             for (int user=0; user<mStickyBroadcasts.size(); user++) {
   15242                 if (needSep) {
   15243                     pw.println();
   15244                 }
   15245                 needSep = true;
   15246                 printedAnything = true;
   15247                 pw.print("  Sticky broadcasts for user ");
   15248                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
   15249                 StringBuilder sb = new StringBuilder(128);
   15250                 for (Map.Entry<String, ArrayList<Intent>> ent
   15251                         : mStickyBroadcasts.valueAt(user).entrySet()) {
   15252                     pw.print("  * Sticky action "); pw.print(ent.getKey());
   15253                     if (dumpAll) {
   15254                         pw.println(":");
   15255                         ArrayList<Intent> intents = ent.getValue();
   15256                         final int N = intents.size();
   15257                         for (int i=0; i<N; i++) {
   15258                             sb.setLength(0);
   15259                             sb.append("    Intent: ");
   15260                             intents.get(i).toShortString(sb, false, true, false, false);
   15261                             pw.println(sb.toString());
   15262                             Bundle bundle = intents.get(i).getExtras();
   15263                             if (bundle != null) {
   15264                                 pw.print("      ");
   15265                                 pw.println(bundle.toString());
   15266                             }
   15267                         }
   15268                     } else {
   15269                         pw.println("");
   15270                     }
   15271                 }
   15272             }
   15273         }
   15274 
   15275         if (!onlyHistory && dumpAll) {
   15276             pw.println();
   15277             for (BroadcastQueue queue : mBroadcastQueues) {
   15278                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
   15279                         + queue.mBroadcastsScheduled);
   15280             }
   15281             pw.println("  mHandler:");
   15282             mHandler.dump(new PrintWriterPrinter(pw), "    ");
   15283             needSep = true;
   15284             printedAnything = true;
   15285         }
   15286 
   15287         if (!printedAnything) {
   15288             pw.println("  (nothing)");
   15289         }
   15290     }
   15291 
   15292     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15293             int opti, boolean dumpAll, String dumpPackage) {
   15294         if (mCurBroadcastStats == null) {
   15295             return;
   15296         }
   15297 
   15298         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
   15299         final long now = SystemClock.elapsedRealtime();
   15300         if (mLastBroadcastStats != null) {
   15301             pw.print("  Last stats (from ");
   15302             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
   15303             pw.print(" to ");
   15304             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
   15305             pw.print(", ");
   15306             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
   15307                     - mLastBroadcastStats.mStartUptime, pw);
   15308             pw.println(" uptime):");
   15309             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
   15310                 pw.println("    (nothing)");
   15311             }
   15312             pw.println();
   15313         }
   15314         pw.print("  Current stats (from ");
   15315         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
   15316         pw.print(" to now, ");
   15317         TimeUtils.formatDuration(SystemClock.uptimeMillis()
   15318                 - mCurBroadcastStats.mStartUptime, pw);
   15319         pw.println(" uptime):");
   15320         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
   15321             pw.println("    (nothing)");
   15322         }
   15323     }
   15324 
   15325     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15326             int opti, boolean fullCheckin, String dumpPackage) {
   15327         if (mCurBroadcastStats == null) {
   15328             return;
   15329         }
   15330 
   15331         if (mLastBroadcastStats != null) {
   15332             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
   15333             if (fullCheckin) {
   15334                 mLastBroadcastStats = null;
   15335                 return;
   15336             }
   15337         }
   15338         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
   15339         if (fullCheckin) {
   15340             mCurBroadcastStats = null;
   15341         }
   15342     }
   15343 
   15344     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15345             int opti, boolean dumpAll, String dumpPackage) {
   15346         boolean needSep;
   15347         boolean printedAnything = false;
   15348 
   15349         ItemMatcher matcher = new ItemMatcher();
   15350         matcher.build(args, opti);
   15351 
   15352         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
   15353 
   15354         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
   15355         printedAnything |= needSep;
   15356 
   15357         if (mLaunchingProviders.size() > 0) {
   15358             boolean printed = false;
   15359             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
   15360                 ContentProviderRecord r = mLaunchingProviders.get(i);
   15361                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
   15362                     continue;
   15363                 }
   15364                 if (!printed) {
   15365                     if (needSep) pw.println();
   15366                     needSep = true;
   15367                     pw.println("  Launching content providers:");
   15368                     printed = true;
   15369                     printedAnything = true;
   15370                 }
   15371                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
   15372                         pw.println(r);
   15373             }
   15374         }
   15375 
   15376         if (!printedAnything) {
   15377             pw.println("  (nothing)");
   15378         }
   15379     }
   15380 
   15381     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15382             int opti, boolean dumpAll, String dumpPackage) {
   15383         boolean needSep = false;
   15384         boolean printedAnything = false;
   15385 
   15386         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
   15387 
   15388         if (mGrantedUriPermissions.size() > 0) {
   15389             boolean printed = false;
   15390             int dumpUid = -2;
   15391             if (dumpPackage != null) {
   15392                 try {
   15393                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
   15394                             MATCH_UNINSTALLED_PACKAGES, 0);
   15395                 } catch (NameNotFoundException e) {
   15396                     dumpUid = -1;
   15397                 }
   15398             }
   15399             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
   15400                 int uid = mGrantedUriPermissions.keyAt(i);
   15401                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
   15402                     continue;
   15403                 }
   15404                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   15405                 if (!printed) {
   15406                     if (needSep) pw.println();
   15407                     needSep = true;
   15408                     pw.println("  Granted Uri Permissions:");
   15409                     printed = true;
   15410                     printedAnything = true;
   15411                 }
   15412                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
   15413                 for (UriPermission perm : perms.values()) {
   15414                     pw.print("    "); pw.println(perm);
   15415                     if (dumpAll) {
   15416                         perm.dump(pw, "      ");
   15417                     }
   15418                 }
   15419             }
   15420         }
   15421 
   15422         if (!printedAnything) {
   15423             pw.println("  (nothing)");
   15424         }
   15425     }
   15426 
   15427     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15428             int opti, boolean dumpAll, String dumpPackage) {
   15429         boolean printed = false;
   15430 
   15431         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
   15432 
   15433         if (mIntentSenderRecords.size() > 0) {
   15434             Iterator<WeakReference<PendingIntentRecord>> it
   15435                     = mIntentSenderRecords.values().iterator();
   15436             while (it.hasNext()) {
   15437                 WeakReference<PendingIntentRecord> ref = it.next();
   15438                 PendingIntentRecord rec = ref != null ? ref.get(): null;
   15439                 if (dumpPackage != null && (rec == null
   15440                         || !dumpPackage.equals(rec.key.packageName))) {
   15441                     continue;
   15442                 }
   15443                 printed = true;
   15444                 if (rec != null) {
   15445                     pw.print("  * "); pw.println(rec);
   15446                     if (dumpAll) {
   15447                         rec.dump(pw, "    ");
   15448                     }
   15449                 } else {
   15450                     pw.print("  * "); pw.println(ref);
   15451                 }
   15452             }
   15453         }
   15454 
   15455         if (!printed) {
   15456             pw.println("  (nothing)");
   15457         }
   15458     }
   15459 
   15460     private static final int dumpProcessList(PrintWriter pw,
   15461             ActivityManagerService service, List list,
   15462             String prefix, String normalLabel, String persistentLabel,
   15463             String dumpPackage) {
   15464         int numPers = 0;
   15465         final int N = list.size()-1;
   15466         for (int i=N; i>=0; i--) {
   15467             ProcessRecord r = (ProcessRecord)list.get(i);
   15468             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   15469                 continue;
   15470             }
   15471             pw.println(String.format("%s%s #%2d: %s",
   15472                     prefix, (r.persistent ? persistentLabel : normalLabel),
   15473                     i, r.toString()));
   15474             if (r.persistent) {
   15475                 numPers++;
   15476             }
   15477         }
   15478         return numPers;
   15479     }
   15480 
   15481     private static final boolean dumpProcessOomList(PrintWriter pw,
   15482             ActivityManagerService service, List<ProcessRecord> origList,
   15483             String prefix, String normalLabel, String persistentLabel,
   15484             boolean inclDetails, String dumpPackage) {
   15485 
   15486         ArrayList<Pair<ProcessRecord, Integer>> list
   15487                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
   15488         for (int i=0; i<origList.size(); i++) {
   15489             ProcessRecord r = origList.get(i);
   15490             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   15491                 continue;
   15492             }
   15493             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
   15494         }
   15495 
   15496         if (list.size() <= 0) {
   15497             return false;
   15498         }
   15499 
   15500         Comparator<Pair<ProcessRecord, Integer>> comparator
   15501                 = new Comparator<Pair<ProcessRecord, Integer>>() {
   15502             @Override
   15503             public int compare(Pair<ProcessRecord, Integer> object1,
   15504                     Pair<ProcessRecord, Integer> object2) {
   15505                 if (object1.first.setAdj != object2.first.setAdj) {
   15506                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
   15507                 }
   15508                 if (object1.first.setProcState != object2.first.setProcState) {
   15509                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
   15510                 }
   15511                 if (object1.second.intValue() != object2.second.intValue()) {
   15512                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
   15513                 }
   15514                 return 0;
   15515             }
   15516         };
   15517 
   15518         Collections.sort(list, comparator);
   15519 
   15520         final long curRealtime = SystemClock.elapsedRealtime();
   15521         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
   15522         final long curUptime = SystemClock.uptimeMillis();
   15523         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
   15524 
   15525         for (int i=list.size()-1; i>=0; i--) {
   15526             ProcessRecord r = list.get(i).first;
   15527             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
   15528             char schedGroup;
   15529             switch (r.setSchedGroup) {
   15530                 case ProcessList.SCHED_GROUP_BACKGROUND:
   15531                     schedGroup = 'B';
   15532                     break;
   15533                 case ProcessList.SCHED_GROUP_DEFAULT:
   15534                     schedGroup = 'F';
   15535                     break;
   15536                 case ProcessList.SCHED_GROUP_TOP_APP:
   15537                     schedGroup = 'T';
   15538                     break;
   15539                 default:
   15540                     schedGroup = '?';
   15541                     break;
   15542             }
   15543             char foreground;
   15544             if (r.foregroundActivities) {
   15545                 foreground = 'A';
   15546             } else if (r.foregroundServices) {
   15547                 foreground = 'S';
   15548             } else {
   15549                 foreground = ' ';
   15550             }
   15551             String procState = ProcessList.makeProcStateString(r.curProcState);
   15552             pw.print(prefix);
   15553             pw.print(r.persistent ? persistentLabel : normalLabel);
   15554             pw.print(" #");
   15555             int num = (origList.size()-1)-list.get(i).second;
   15556             if (num < 10) pw.print(' ');
   15557             pw.print(num);
   15558             pw.print(": ");
   15559             pw.print(oomAdj);
   15560             pw.print(' ');
   15561             pw.print(schedGroup);
   15562             pw.print('/');
   15563             pw.print(foreground);
   15564             pw.print('/');
   15565             pw.print(procState);
   15566             pw.print(" trm:");
   15567             if (r.trimMemoryLevel < 10) pw.print(' ');
   15568             pw.print(r.trimMemoryLevel);
   15569             pw.print(' ');
   15570             pw.print(r.toShortString());
   15571             pw.print(" (");
   15572             pw.print(r.adjType);
   15573             pw.println(')');
   15574             if (r.adjSource != null || r.adjTarget != null) {
   15575                 pw.print(prefix);
   15576                 pw.print("    ");
   15577                 if (r.adjTarget instanceof ComponentName) {
   15578                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
   15579                 } else if (r.adjTarget != null) {
   15580                     pw.print(r.adjTarget.toString());
   15581                 } else {
   15582                     pw.print("{null}");
   15583                 }
   15584                 pw.print("<=");
   15585                 if (r.adjSource instanceof ProcessRecord) {
   15586                     pw.print("Proc{");
   15587                     pw.print(((ProcessRecord)r.adjSource).toShortString());
   15588                     pw.println("}");
   15589                 } else if (r.adjSource != null) {
   15590                     pw.println(r.adjSource.toString());
   15591                 } else {
   15592                     pw.println("{null}");
   15593                 }
   15594             }
   15595             if (inclDetails) {
   15596                 pw.print(prefix);
   15597                 pw.print("    ");
   15598                 pw.print("oom: max="); pw.print(r.maxAdj);
   15599                 pw.print(" curRaw="); pw.print(r.curRawAdj);
   15600                 pw.print(" setRaw="); pw.print(r.setRawAdj);
   15601                 pw.print(" cur="); pw.print(r.curAdj);
   15602                 pw.print(" set="); pw.println(r.setAdj);
   15603                 pw.print(prefix);
   15604                 pw.print("    ");
   15605                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
   15606                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
   15607                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
   15608                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
   15609                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
   15610                 pw.println();
   15611                 pw.print(prefix);
   15612                 pw.print("    ");
   15613                 pw.print("cached="); pw.print(r.cached);
   15614                 pw.print(" empty="); pw.print(r.empty);
   15615                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
   15616 
   15617                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
   15618                     if (r.lastWakeTime != 0) {
   15619                         long wtime;
   15620                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
   15621                         synchronized (stats) {
   15622                             wtime = stats.getProcessWakeTime(r.info.uid,
   15623                                     r.pid, curRealtime);
   15624                         }
   15625                         long timeUsed = wtime - r.lastWakeTime;
   15626                         pw.print(prefix);
   15627                         pw.print("    ");
   15628                         pw.print("keep awake over ");
   15629                         TimeUtils.formatDuration(realtimeSince, pw);
   15630                         pw.print(" used ");
   15631                         TimeUtils.formatDuration(timeUsed, pw);
   15632                         pw.print(" (");
   15633                         pw.print((timeUsed*100)/realtimeSince);
   15634                         pw.println("%)");
   15635                     }
   15636                     if (r.lastCpuTime != 0) {
   15637                         long timeUsed = r.curCpuTime - r.lastCpuTime;
   15638                         pw.print(prefix);
   15639                         pw.print("    ");
   15640                         pw.print("run cpu over ");
   15641                         TimeUtils.formatDuration(uptimeSince, pw);
   15642                         pw.print(" used ");
   15643                         TimeUtils.formatDuration(timeUsed, pw);
   15644                         pw.print(" (");
   15645                         pw.print((timeUsed*100)/uptimeSince);
   15646                         pw.println("%)");
   15647                     }
   15648                 }
   15649             }
   15650         }
   15651         return true;
   15652     }
   15653 
   15654     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
   15655             String[] args) {
   15656         ArrayList<ProcessRecord> procs;
   15657         synchronized (this) {
   15658             if (args != null && args.length > start
   15659                     && args[start].charAt(0) != '-') {
   15660                 procs = new ArrayList<ProcessRecord>();
   15661                 int pid = -1;
   15662                 try {
   15663                     pid = Integer.parseInt(args[start]);
   15664                 } catch (NumberFormatException e) {
   15665                 }
   15666                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   15667                     ProcessRecord proc = mLruProcesses.get(i);
   15668                     if (proc.pid == pid) {
   15669                         procs.add(proc);
   15670                     } else if (allPkgs && proc.pkgList != null
   15671                             && proc.pkgList.containsKey(args[start])) {
   15672                         procs.add(proc);
   15673                     } else if (proc.processName.equals(args[start])) {
   15674                         procs.add(proc);
   15675                     }
   15676                 }
   15677                 if (procs.size() <= 0) {
   15678                     return null;
   15679                 }
   15680             } else {
   15681                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
   15682             }
   15683         }
   15684         return procs;
   15685     }
   15686 
   15687     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
   15688             PrintWriter pw, String[] args) {
   15689         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
   15690         if (procs == null) {
   15691             pw.println("No process found for: " + args[0]);
   15692             return;
   15693         }
   15694 
   15695         long uptime = SystemClock.uptimeMillis();
   15696         long realtime = SystemClock.elapsedRealtime();
   15697         pw.println("Applications Graphics Acceleration Info:");
   15698         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   15699 
   15700         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   15701             ProcessRecord r = procs.get(i);
   15702             if (r.thread != null) {
   15703                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
   15704                 pw.flush();
   15705                 try {
   15706                     TransferPipe tp = new TransferPipe();
   15707                     try {
   15708                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
   15709                         tp.go(fd);
   15710                     } finally {
   15711                         tp.kill();
   15712                     }
   15713                 } catch (IOException e) {
   15714                     pw.println("Failure while dumping the app: " + r);
   15715                     pw.flush();
   15716                 } catch (RemoteException e) {
   15717                     pw.println("Got a RemoteException while dumping the app " + r);
   15718                     pw.flush();
   15719                 }
   15720             }
   15721         }
   15722     }
   15723 
   15724     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
   15725         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
   15726         if (procs == null) {
   15727             pw.println("No process found for: " + args[0]);
   15728             return;
   15729         }
   15730 
   15731         pw.println("Applications Database Info:");
   15732 
   15733         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   15734             ProcessRecord r = procs.get(i);
   15735             if (r.thread != null) {
   15736                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
   15737                 pw.flush();
   15738                 try {
   15739                     TransferPipe tp = new TransferPipe();
   15740                     try {
   15741                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
   15742                         tp.go(fd);
   15743                     } finally {
   15744                         tp.kill();
   15745                     }
   15746                 } catch (IOException e) {
   15747                     pw.println("Failure while dumping the app: " + r);
   15748                     pw.flush();
   15749                 } catch (RemoteException e) {
   15750                     pw.println("Got a RemoteException while dumping the app " + r);
   15751                     pw.flush();
   15752                 }
   15753             }
   15754         }
   15755     }
   15756 
   15757     final static class MemItem {
   15758         final boolean isProc;
   15759         final String label;
   15760         final String shortLabel;
   15761         final long pss;
   15762         final long swapPss;
   15763         final int id;
   15764         final boolean hasActivities;
   15765         ArrayList<MemItem> subitems;
   15766 
   15767         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
   15768                 boolean _hasActivities) {
   15769             isProc = true;
   15770             label = _label;
   15771             shortLabel = _shortLabel;
   15772             pss = _pss;
   15773             swapPss = _swapPss;
   15774             id = _id;
   15775             hasActivities = _hasActivities;
   15776         }
   15777 
   15778         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
   15779             isProc = false;
   15780             label = _label;
   15781             shortLabel = _shortLabel;
   15782             pss = _pss;
   15783             swapPss = _swapPss;
   15784             id = _id;
   15785             hasActivities = false;
   15786         }
   15787     }
   15788 
   15789     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
   15790             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
   15791         if (sort && !isCompact) {
   15792             Collections.sort(items, new Comparator<MemItem>() {
   15793                 @Override
   15794                 public int compare(MemItem lhs, MemItem rhs) {
   15795                     if (lhs.pss < rhs.pss) {
   15796                         return 1;
   15797                     } else if (lhs.pss > rhs.pss) {
   15798                         return -1;
   15799                     }
   15800                     return 0;
   15801                 }
   15802             });
   15803         }
   15804 
   15805         for (int i=0; i<items.size(); i++) {
   15806             MemItem mi = items.get(i);
   15807             if (!isCompact) {
   15808                 if (dumpSwapPss) {
   15809                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
   15810                             mi.label, stringifyKBSize(mi.swapPss));
   15811                 } else {
   15812                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
   15813                 }
   15814             } else if (mi.isProc) {
   15815                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
   15816                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
   15817                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
   15818                 pw.println(mi.hasActivities ? ",a" : ",e");
   15819             } else {
   15820                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
   15821                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
   15822             }
   15823             if (mi.subitems != null) {
   15824                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
   15825                         true, isCompact, dumpSwapPss);
   15826             }
   15827         }
   15828     }
   15829 
   15830     // These are in KB.
   15831     static final long[] DUMP_MEM_BUCKETS = new long[] {
   15832         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
   15833         120*1024, 160*1024, 200*1024,
   15834         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
   15835         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
   15836     };
   15837 
   15838     static final void appendMemBucket(StringBuilder out, long memKB, String label,
   15839             boolean stackLike) {
   15840         int start = label.lastIndexOf('.');
   15841         if (start >= 0) start++;
   15842         else start = 0;
   15843         int end = label.length();
   15844         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
   15845             if (DUMP_MEM_BUCKETS[i] >= memKB) {
   15846                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
   15847                 out.append(bucket);
   15848                 out.append(stackLike ? "MB." : "MB ");
   15849                 out.append(label, start, end);
   15850                 return;
   15851             }
   15852         }
   15853         out.append(memKB/1024);
   15854         out.append(stackLike ? "MB." : "MB ");
   15855         out.append(label, start, end);
   15856     }
   15857 
   15858     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
   15859             ProcessList.NATIVE_ADJ,
   15860             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
   15861             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
   15862             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
   15863             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
   15864             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
   15865             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
   15866     };
   15867     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
   15868             "Native",
   15869             "System", "Persistent", "Persistent Service", "Foreground",
   15870             "Visible", "Perceptible",
   15871             "Heavy Weight", "Backup",
   15872             "A Services", "Home",
   15873             "Previous", "B Services", "Cached"
   15874     };
   15875     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
   15876             "native",
   15877             "sys", "pers", "persvc", "fore",
   15878             "vis", "percept",
   15879             "heavy", "backup",
   15880             "servicea", "home",
   15881             "prev", "serviceb", "cached"
   15882     };
   15883 
   15884     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
   15885             long realtime, boolean isCheckinRequest, boolean isCompact) {
   15886         if (isCompact) {
   15887             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
   15888         }
   15889         if (isCheckinRequest || isCompact) {
   15890             // short checkin version
   15891             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
   15892         } else {
   15893             pw.println("Applications Memory Usage (in Kilobytes):");
   15894             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   15895         }
   15896     }
   15897 
   15898     private static final int KSM_SHARED = 0;
   15899     private static final int KSM_SHARING = 1;
   15900     private static final int KSM_UNSHARED = 2;
   15901     private static final int KSM_VOLATILE = 3;
   15902 
   15903     private final long[] getKsmInfo() {
   15904         long[] longOut = new long[4];
   15905         final int[] SINGLE_LONG_FORMAT = new int[] {
   15906             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
   15907         };
   15908         long[] longTmp = new long[1];
   15909         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
   15910                 SINGLE_LONG_FORMAT, null, longTmp, null);
   15911         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   15912         longTmp[0] = 0;
   15913         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
   15914                 SINGLE_LONG_FORMAT, null, longTmp, null);
   15915         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   15916         longTmp[0] = 0;
   15917         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
   15918                 SINGLE_LONG_FORMAT, null, longTmp, null);
   15919         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   15920         longTmp[0] = 0;
   15921         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
   15922                 SINGLE_LONG_FORMAT, null, longTmp, null);
   15923         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   15924         return longOut;
   15925     }
   15926 
   15927     private static String stringifySize(long size, int order) {
   15928         Locale locale = Locale.US;
   15929         switch (order) {
   15930             case 1:
   15931                 return String.format(locale, "%,13d", size);
   15932             case 1024:
   15933                 return String.format(locale, "%,9dK", size / 1024);
   15934             case 1024 * 1024:
   15935                 return String.format(locale, "%,5dM", size / 1024 / 1024);
   15936             case 1024 * 1024 * 1024:
   15937                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
   15938             default:
   15939                 throw new IllegalArgumentException("Invalid size order");
   15940         }
   15941     }
   15942 
   15943     private static String stringifyKBSize(long size) {
   15944         return stringifySize(size * 1024, 1024);
   15945     }
   15946 
   15947     // Update this version number in case you change the 'compact' format
   15948     private static final int MEMINFO_COMPACT_VERSION = 1;
   15949 
   15950     final void dumpApplicationMemoryUsage(FileDescriptor fd,
   15951             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
   15952         boolean dumpDetails = false;
   15953         boolean dumpFullDetails = false;
   15954         boolean dumpDalvik = false;
   15955         boolean dumpSummaryOnly = false;
   15956         boolean dumpUnreachable = false;
   15957         boolean oomOnly = false;
   15958         boolean isCompact = false;
   15959         boolean localOnly = false;
   15960         boolean packages = false;
   15961         boolean isCheckinRequest = false;
   15962         boolean dumpSwapPss = false;
   15963 
   15964         int opti = 0;
   15965         while (opti < args.length) {
   15966             String opt = args[opti];
   15967             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   15968                 break;
   15969             }
   15970             opti++;
   15971             if ("-a".equals(opt)) {
   15972                 dumpDetails = true;
   15973                 dumpFullDetails = true;
   15974                 dumpDalvik = true;
   15975                 dumpSwapPss = true;
   15976             } else if ("-d".equals(opt)) {
   15977                 dumpDalvik = true;
   15978             } else if ("-c".equals(opt)) {
   15979                 isCompact = true;
   15980             } else if ("-s".equals(opt)) {
   15981                 dumpDetails = true;
   15982                 dumpSummaryOnly = true;
   15983             } else if ("-S".equals(opt)) {
   15984                 dumpSwapPss = true;
   15985             } else if ("--unreachable".equals(opt)) {
   15986                 dumpUnreachable = true;
   15987             } else if ("--oom".equals(opt)) {
   15988                 oomOnly = true;
   15989             } else if ("--local".equals(opt)) {
   15990                 localOnly = true;
   15991             } else if ("--package".equals(opt)) {
   15992                 packages = true;
   15993             } else if ("--checkin".equals(opt)) {
   15994                 isCheckinRequest = true;
   15995 
   15996             } else if ("-h".equals(opt)) {
   15997                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
   15998                 pw.println("  -a: include all available information for each process.");
   15999                 pw.println("  -d: include dalvik details.");
   16000                 pw.println("  -c: dump in a compact machine-parseable representation.");
   16001                 pw.println("  -s: dump only summary of application memory usage.");
   16002                 pw.println("  -S: dump also SwapPss.");
   16003                 pw.println("  --oom: only show processes organized by oom adj.");
   16004                 pw.println("  --local: only collect details locally, don't call process.");
   16005                 pw.println("  --package: interpret process arg as package, dumping all");
   16006                 pw.println("             processes that have loaded that package.");
   16007                 pw.println("  --checkin: dump data for a checkin");
   16008                 pw.println("If [process] is specified it can be the name or ");
   16009                 pw.println("pid of a specific process to dump.");
   16010                 return;
   16011             } else {
   16012                 pw.println("Unknown argument: " + opt + "; use -h for help");
   16013             }
   16014         }
   16015 
   16016         long uptime = SystemClock.uptimeMillis();
   16017         long realtime = SystemClock.elapsedRealtime();
   16018         final long[] tmpLong = new long[1];
   16019 
   16020         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
   16021         if (procs == null) {
   16022             // No Java processes.  Maybe they want to print a native process.
   16023             if (args != null && args.length > opti
   16024                     && args[opti].charAt(0) != '-') {
   16025                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
   16026                         = new ArrayList<ProcessCpuTracker.Stats>();
   16027                 updateCpuStatsNow();
   16028                 int findPid = -1;
   16029                 try {
   16030                     findPid = Integer.parseInt(args[opti]);
   16031                 } catch (NumberFormatException e) {
   16032                 }
   16033                 synchronized (mProcessCpuTracker) {
   16034                     final int N = mProcessCpuTracker.countStats();
   16035                     for (int i=0; i<N; i++) {
   16036                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   16037                         if (st.pid == findPid || (st.baseName != null
   16038                                 && st.baseName.equals(args[opti]))) {
   16039                             nativeProcs.add(st);
   16040                         }
   16041                     }
   16042                 }
   16043                 if (nativeProcs.size() > 0) {
   16044                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
   16045                             isCompact);
   16046                     Debug.MemoryInfo mi = null;
   16047                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
   16048                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
   16049                         final int pid = r.pid;
   16050                         if (!isCheckinRequest && dumpDetails) {
   16051                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
   16052                         }
   16053                         if (mi == null) {
   16054                             mi = new Debug.MemoryInfo();
   16055                         }
   16056                         if (dumpDetails || (!brief && !oomOnly)) {
   16057                             Debug.getMemoryInfo(pid, mi);
   16058                         } else {
   16059                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
   16060                             mi.dalvikPrivateDirty = (int)tmpLong[0];
   16061                         }
   16062                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
   16063                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
   16064                         if (isCheckinRequest) {
   16065                             pw.println();
   16066                         }
   16067                     }
   16068                     return;
   16069                 }
   16070             }
   16071             pw.println("No process found for: " + args[opti]);
   16072             return;
   16073         }
   16074 
   16075         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
   16076             dumpDetails = true;
   16077         }
   16078 
   16079         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
   16080 
   16081         String[] innerArgs = new String[args.length-opti];
   16082         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
   16083 
   16084         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
   16085         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
   16086         long nativePss = 0;
   16087         long nativeSwapPss = 0;
   16088         long dalvikPss = 0;
   16089         long dalvikSwapPss = 0;
   16090         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
   16091                 EmptyArray.LONG;
   16092         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
   16093                 EmptyArray.LONG;
   16094         long otherPss = 0;
   16095         long otherSwapPss = 0;
   16096         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   16097         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   16098 
   16099         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   16100         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   16101         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
   16102                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
   16103 
   16104         long totalPss = 0;
   16105         long totalSwapPss = 0;
   16106         long cachedPss = 0;
   16107         long cachedSwapPss = 0;
   16108         boolean hasSwapPss = false;
   16109 
   16110         Debug.MemoryInfo mi = null;
   16111         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   16112             final ProcessRecord r = procs.get(i);
   16113             final IApplicationThread thread;
   16114             final int pid;
   16115             final int oomAdj;
   16116             final boolean hasActivities;
   16117             synchronized (this) {
   16118                 thread = r.thread;
   16119                 pid = r.pid;
   16120                 oomAdj = r.getSetAdjWithServices();
   16121                 hasActivities = r.activities.size() > 0;
   16122             }
   16123             if (thread != null) {
   16124                 if (!isCheckinRequest && dumpDetails) {
   16125                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
   16126                 }
   16127                 if (mi == null) {
   16128                     mi = new Debug.MemoryInfo();
   16129                 }
   16130                 if (dumpDetails || (!brief && !oomOnly)) {
   16131                     Debug.getMemoryInfo(pid, mi);
   16132                     hasSwapPss = mi.hasSwappedOutPss;
   16133                 } else {
   16134                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
   16135                     mi.dalvikPrivateDirty = (int)tmpLong[0];
   16136                 }
   16137                 if (dumpDetails) {
   16138                     if (localOnly) {
   16139                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
   16140                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
   16141                         if (isCheckinRequest) {
   16142                             pw.println();
   16143                         }
   16144                     } else {
   16145                         try {
   16146                             pw.flush();
   16147                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
   16148                                     dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
   16149                         } catch (RemoteException e) {
   16150                             if (!isCheckinRequest) {
   16151                                 pw.println("Got RemoteException!");
   16152                                 pw.flush();
   16153                             }
   16154                         }
   16155                     }
   16156                 }
   16157 
   16158                 final long myTotalPss = mi.getTotalPss();
   16159                 final long myTotalUss = mi.getTotalUss();
   16160                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
   16161 
   16162                 synchronized (this) {
   16163                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
   16164                         // Record this for posterity if the process has been stable.
   16165                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
   16166                     }
   16167                 }
   16168 
   16169                 if (!isCheckinRequest && mi != null) {
   16170                     totalPss += myTotalPss;
   16171                     totalSwapPss += myTotalSwapPss;
   16172                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
   16173                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
   16174                             myTotalSwapPss, pid, hasActivities);
   16175                     procMems.add(pssItem);
   16176                     procMemsMap.put(pid, pssItem);
   16177 
   16178                     nativePss += mi.nativePss;
   16179                     nativeSwapPss += mi.nativeSwappedOutPss;
   16180                     dalvikPss += mi.dalvikPss;
   16181                     dalvikSwapPss += mi.dalvikSwappedOutPss;
   16182                     for (int j=0; j<dalvikSubitemPss.length; j++) {
   16183                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   16184                         dalvikSubitemSwapPss[j] +=
   16185                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   16186                     }
   16187                     otherPss += mi.otherPss;
   16188                     otherSwapPss += mi.otherSwappedOutPss;
   16189                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   16190                         long mem = mi.getOtherPss(j);
   16191                         miscPss[j] += mem;
   16192                         otherPss -= mem;
   16193                         mem = mi.getOtherSwappedOutPss(j);
   16194                         miscSwapPss[j] += mem;
   16195                         otherSwapPss -= mem;
   16196                     }
   16197 
   16198                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   16199                         cachedPss += myTotalPss;
   16200                         cachedSwapPss += myTotalSwapPss;
   16201                     }
   16202 
   16203                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
   16204                         if (oomIndex == (oomPss.length - 1)
   16205                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
   16206                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
   16207                             oomPss[oomIndex] += myTotalPss;
   16208                             oomSwapPss[oomIndex] += myTotalSwapPss;
   16209                             if (oomProcs[oomIndex] == null) {
   16210                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
   16211                             }
   16212                             oomProcs[oomIndex].add(pssItem);
   16213                             break;
   16214                         }
   16215                     }
   16216                 }
   16217             }
   16218         }
   16219 
   16220         long nativeProcTotalPss = 0;
   16221 
   16222         if (!isCheckinRequest && procs.size() > 1 && !packages) {
   16223             // If we are showing aggregations, also look for native processes to
   16224             // include so that our aggregations are more accurate.
   16225             updateCpuStatsNow();
   16226             mi = null;
   16227             synchronized (mProcessCpuTracker) {
   16228                 final int N = mProcessCpuTracker.countStats();
   16229                 for (int i=0; i<N; i++) {
   16230                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   16231                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
   16232                         if (mi == null) {
   16233                             mi = new Debug.MemoryInfo();
   16234                         }
   16235                         if (!brief && !oomOnly) {
   16236                             Debug.getMemoryInfo(st.pid, mi);
   16237                         } else {
   16238                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
   16239                             mi.nativePrivateDirty = (int)tmpLong[0];
   16240                         }
   16241 
   16242                         final long myTotalPss = mi.getTotalPss();
   16243                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
   16244                         totalPss += myTotalPss;
   16245                         nativeProcTotalPss += myTotalPss;
   16246 
   16247                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
   16248                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
   16249                         procMems.add(pssItem);
   16250 
   16251                         nativePss += mi.nativePss;
   16252                         nativeSwapPss += mi.nativeSwappedOutPss;
   16253                         dalvikPss += mi.dalvikPss;
   16254                         dalvikSwapPss += mi.dalvikSwappedOutPss;
   16255                         for (int j=0; j<dalvikSubitemPss.length; j++) {
   16256                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   16257                             dalvikSubitemSwapPss[j] +=
   16258                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   16259                         }
   16260                         otherPss += mi.otherPss;
   16261                         otherSwapPss += mi.otherSwappedOutPss;
   16262                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   16263                             long mem = mi.getOtherPss(j);
   16264                             miscPss[j] += mem;
   16265                             otherPss -= mem;
   16266                             mem = mi.getOtherSwappedOutPss(j);
   16267                             miscSwapPss[j] += mem;
   16268                             otherSwapPss -= mem;
   16269                         }
   16270                         oomPss[0] += myTotalPss;
   16271                         oomSwapPss[0] += myTotalSwapPss;
   16272                         if (oomProcs[0] == null) {
   16273                             oomProcs[0] = new ArrayList<MemItem>();
   16274                         }
   16275                         oomProcs[0].add(pssItem);
   16276                     }
   16277                 }
   16278             }
   16279 
   16280             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
   16281 
   16282             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
   16283             final MemItem dalvikItem =
   16284                     new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
   16285             if (dalvikSubitemPss.length > 0) {
   16286                 dalvikItem.subitems = new ArrayList<MemItem>();
   16287                 for (int j=0; j<dalvikSubitemPss.length; j++) {
   16288                     final String name = Debug.MemoryInfo.getOtherLabel(
   16289                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
   16290                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
   16291                                     dalvikSubitemSwapPss[j], j));
   16292                 }
   16293             }
   16294             catMems.add(dalvikItem);
   16295             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
   16296             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   16297                 String label = Debug.MemoryInfo.getOtherLabel(j);
   16298                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
   16299             }
   16300 
   16301             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
   16302             for (int j=0; j<oomPss.length; j++) {
   16303                 if (oomPss[j] != 0) {
   16304                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
   16305                             : DUMP_MEM_OOM_LABEL[j];
   16306                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
   16307                             DUMP_MEM_OOM_ADJ[j]);
   16308                     item.subitems = oomProcs[j];
   16309                     oomMems.add(item);
   16310                 }
   16311             }
   16312 
   16313             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
   16314             if (!brief && !oomOnly && !isCompact) {
   16315                 pw.println();
   16316                 pw.println("Total PSS by process:");
   16317                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
   16318                 pw.println();
   16319             }
   16320             if (!isCompact) {
   16321                 pw.println("Total PSS by OOM adjustment:");
   16322             }
   16323             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
   16324             if (!brief && !oomOnly) {
   16325                 PrintWriter out = categoryPw != null ? categoryPw : pw;
   16326                 if (!isCompact) {
   16327                     out.println();
   16328                     out.println("Total PSS by category:");
   16329                 }
   16330                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
   16331             }
   16332             if (!isCompact) {
   16333                 pw.println();
   16334             }
   16335             MemInfoReader memInfo = new MemInfoReader();
   16336             memInfo.readMemInfo();
   16337             if (nativeProcTotalPss > 0) {
   16338                 synchronized (this) {
   16339                     final long cachedKb = memInfo.getCachedSizeKb();
   16340                     final long freeKb = memInfo.getFreeSizeKb();
   16341                     final long zramKb = memInfo.getZramTotalSizeKb();
   16342                     final long kernelKb = memInfo.getKernelUsedSizeKb();
   16343                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
   16344                             kernelKb*1024, nativeProcTotalPss*1024);
   16345                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
   16346                             nativeProcTotalPss);
   16347                 }
   16348             }
   16349             if (!brief) {
   16350                 if (!isCompact) {
   16351                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
   16352                     pw.print(" (status ");
   16353                     switch (mLastMemoryLevel) {
   16354                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
   16355                             pw.println("normal)");
   16356                             break;
   16357                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
   16358                             pw.println("moderate)");
   16359                             break;
   16360                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
   16361                             pw.println("low)");
   16362                             break;
   16363                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
   16364                             pw.println("critical)");
   16365                             break;
   16366                         default:
   16367                             pw.print(mLastMemoryLevel);
   16368                             pw.println(")");
   16369                             break;
   16370                     }
   16371                     pw.print(" Free RAM: ");
   16372                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
   16373                             + memInfo.getFreeSizeKb()));
   16374                     pw.print(" (");
   16375                     pw.print(stringifyKBSize(cachedPss));
   16376                     pw.print(" cached pss + ");
   16377                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
   16378                     pw.print(" cached kernel + ");
   16379                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
   16380                     pw.println(" free)");
   16381                 } else {
   16382                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
   16383                     pw.print(cachedPss + memInfo.getCachedSizeKb()
   16384                             + memInfo.getFreeSizeKb()); pw.print(",");
   16385                     pw.println(totalPss - cachedPss);
   16386                 }
   16387             }
   16388             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
   16389                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
   16390                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
   16391             if (!isCompact) {
   16392                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
   16393                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
   16394                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
   16395                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
   16396                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
   16397             } else {
   16398                 pw.print("lostram,"); pw.println(lostRAM);
   16399             }
   16400             if (!brief) {
   16401                 if (memInfo.getZramTotalSizeKb() != 0) {
   16402                     if (!isCompact) {
   16403                         pw.print("     ZRAM: ");
   16404                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
   16405                                 pw.print(" physical used for ");
   16406                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
   16407                                         - memInfo.getSwapFreeSizeKb()));
   16408                                 pw.print(" in swap (");
   16409                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
   16410                                 pw.println(" total swap)");
   16411                     } else {
   16412                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
   16413                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
   16414                                 pw.println(memInfo.getSwapFreeSizeKb());
   16415                     }
   16416                 }
   16417                 final long[] ksm = getKsmInfo();
   16418                 if (!isCompact) {
   16419                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
   16420                             || ksm[KSM_VOLATILE] != 0) {
   16421                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
   16422                                 pw.print(" saved from shared ");
   16423                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
   16424                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
   16425                                 pw.print(" unshared; ");
   16426                                 pw.print(stringifyKBSize(
   16427                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
   16428                     }
   16429                     pw.print("   Tuning: ");
   16430                     pw.print(ActivityManager.staticGetMemoryClass());
   16431                     pw.print(" (large ");
   16432                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   16433                     pw.print("), oom ");
   16434                     pw.print(stringifySize(
   16435                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
   16436                     pw.print(", restore limit ");
   16437                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
   16438                     if (ActivityManager.isLowRamDeviceStatic()) {
   16439                         pw.print(" (low-ram)");
   16440                     }
   16441                     if (ActivityManager.isHighEndGfx()) {
   16442                         pw.print(" (high-end-gfx)");
   16443                     }
   16444                     pw.println();
   16445                 } else {
   16446                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
   16447                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
   16448                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
   16449                     pw.print("tuning,");
   16450                     pw.print(ActivityManager.staticGetMemoryClass());
   16451                     pw.print(',');
   16452                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   16453                     pw.print(',');
   16454                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
   16455                     if (ActivityManager.isLowRamDeviceStatic()) {
   16456                         pw.print(",low-ram");
   16457                     }
   16458                     if (ActivityManager.isHighEndGfx()) {
   16459                         pw.print(",high-end-gfx");
   16460                     }
   16461                     pw.println();
   16462                 }
   16463             }
   16464         }
   16465     }
   16466 
   16467     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
   16468             long memtrack, String name) {
   16469         sb.append("  ");
   16470         sb.append(ProcessList.makeOomAdjString(oomAdj));
   16471         sb.append(' ');
   16472         sb.append(ProcessList.makeProcStateString(procState));
   16473         sb.append(' ');
   16474         ProcessList.appendRamKb(sb, pss);
   16475         sb.append(": ");
   16476         sb.append(name);
   16477         if (memtrack > 0) {
   16478             sb.append(" (");
   16479             sb.append(stringifyKBSize(memtrack));
   16480             sb.append(" memtrack)");
   16481         }
   16482     }
   16483 
   16484     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
   16485         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
   16486         sb.append(" (pid ");
   16487         sb.append(mi.pid);
   16488         sb.append(") ");
   16489         sb.append(mi.adjType);
   16490         sb.append('\n');
   16491         if (mi.adjReason != null) {
   16492             sb.append("                      ");
   16493             sb.append(mi.adjReason);
   16494             sb.append('\n');
   16495         }
   16496     }
   16497 
   16498     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
   16499         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
   16500         for (int i=0, N=memInfos.size(); i<N; i++) {
   16501             ProcessMemInfo mi = memInfos.get(i);
   16502             infoMap.put(mi.pid, mi);
   16503         }
   16504         updateCpuStatsNow();
   16505         long[] memtrackTmp = new long[1];
   16506         synchronized (mProcessCpuTracker) {
   16507             final int N = mProcessCpuTracker.countStats();
   16508             for (int i=0; i<N; i++) {
   16509                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   16510                 if (st.vsize > 0) {
   16511                     long pss = Debug.getPss(st.pid, null, memtrackTmp);
   16512                     if (pss > 0) {
   16513                         if (infoMap.indexOfKey(st.pid) < 0) {
   16514                             ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
   16515                                     ProcessList.NATIVE_ADJ, -1, "native", null);
   16516                             mi.pss = pss;
   16517                             mi.memtrack = memtrackTmp[0];
   16518                             memInfos.add(mi);
   16519                         }
   16520                     }
   16521                 }
   16522             }
   16523         }
   16524 
   16525         long totalPss = 0;
   16526         long totalMemtrack = 0;
   16527         for (int i=0, N=memInfos.size(); i<N; i++) {
   16528             ProcessMemInfo mi = memInfos.get(i);
   16529             if (mi.pss == 0) {
   16530                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
   16531                 mi.memtrack = memtrackTmp[0];
   16532             }
   16533             totalPss += mi.pss;
   16534             totalMemtrack += mi.memtrack;
   16535         }
   16536         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
   16537             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
   16538                 if (lhs.oomAdj != rhs.oomAdj) {
   16539                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
   16540                 }
   16541                 if (lhs.pss != rhs.pss) {
   16542                     return lhs.pss < rhs.pss ? 1 : -1;
   16543                 }
   16544                 return 0;
   16545             }
   16546         });
   16547 
   16548         StringBuilder tag = new StringBuilder(128);
   16549         StringBuilder stack = new StringBuilder(128);
   16550         tag.append("Low on memory -- ");
   16551         appendMemBucket(tag, totalPss, "total", false);
   16552         appendMemBucket(stack, totalPss, "total", true);
   16553 
   16554         StringBuilder fullNativeBuilder = new StringBuilder(1024);
   16555         StringBuilder shortNativeBuilder = new StringBuilder(1024);
   16556         StringBuilder fullJavaBuilder = new StringBuilder(1024);
   16557 
   16558         boolean firstLine = true;
   16559         int lastOomAdj = Integer.MIN_VALUE;
   16560         long extraNativeRam = 0;
   16561         long extraNativeMemtrack = 0;
   16562         long cachedPss = 0;
   16563         for (int i=0, N=memInfos.size(); i<N; i++) {
   16564             ProcessMemInfo mi = memInfos.get(i);
   16565 
   16566             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   16567                 cachedPss += mi.pss;
   16568             }
   16569 
   16570             if (mi.oomAdj != ProcessList.NATIVE_ADJ
   16571                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
   16572                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
   16573                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
   16574                 if (lastOomAdj != mi.oomAdj) {
   16575                     lastOomAdj = mi.oomAdj;
   16576                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   16577                         tag.append(" / ");
   16578                     }
   16579                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
   16580                         if (firstLine) {
   16581                             stack.append(":");
   16582                             firstLine = false;
   16583                         }
   16584                         stack.append("\n\t at ");
   16585                     } else {
   16586                         stack.append("$");
   16587                     }
   16588                 } else {
   16589                     tag.append(" ");
   16590                     stack.append("$");
   16591                 }
   16592                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   16593                     appendMemBucket(tag, mi.pss, mi.name, false);
   16594                 }
   16595                 appendMemBucket(stack, mi.pss, mi.name, true);
   16596                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
   16597                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
   16598                     stack.append("(");
   16599                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
   16600                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
   16601                             stack.append(DUMP_MEM_OOM_LABEL[k]);
   16602                             stack.append(":");
   16603                             stack.append(DUMP_MEM_OOM_ADJ[k]);
   16604                         }
   16605                     }
   16606                     stack.append(")");
   16607                 }
   16608             }
   16609 
   16610             appendMemInfo(fullNativeBuilder, mi);
   16611             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
   16612                 // The short form only has native processes that are >= 512K.
   16613                 if (mi.pss >= 512) {
   16614                     appendMemInfo(shortNativeBuilder, mi);
   16615                 } else {
   16616                     extraNativeRam += mi.pss;
   16617                     extraNativeMemtrack += mi.memtrack;
   16618                 }
   16619             } else {
   16620                 // Short form has all other details, but if we have collected RAM
   16621                 // from smaller native processes let's dump a summary of that.
   16622                 if (extraNativeRam > 0) {
   16623                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
   16624                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
   16625                     shortNativeBuilder.append('\n');
   16626                     extraNativeRam = 0;
   16627                 }
   16628                 appendMemInfo(fullJavaBuilder, mi);
   16629             }
   16630         }
   16631 
   16632         fullJavaBuilder.append("           ");
   16633         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
   16634         fullJavaBuilder.append(": TOTAL");
   16635         if (totalMemtrack > 0) {
   16636             fullJavaBuilder.append(" (");
   16637             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
   16638             fullJavaBuilder.append(" memtrack)");
   16639         } else {
   16640         }
   16641         fullJavaBuilder.append("\n");
   16642 
   16643         MemInfoReader memInfo = new MemInfoReader();
   16644         memInfo.readMemInfo();
   16645         final long[] infos = memInfo.getRawInfo();
   16646 
   16647         StringBuilder memInfoBuilder = new StringBuilder(1024);
   16648         Debug.getMemInfo(infos);
   16649         memInfoBuilder.append("  MemInfo: ");
   16650         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
   16651         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
   16652         memInfoBuilder.append(stringifyKBSize(
   16653                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
   16654         memInfoBuilder.append(stringifyKBSize(
   16655                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
   16656         memInfoBuilder.append(stringifyKBSize(
   16657                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
   16658         memInfoBuilder.append("           ");
   16659         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
   16660         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
   16661         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
   16662         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
   16663         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
   16664             memInfoBuilder.append("  ZRAM: ");
   16665             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
   16666             memInfoBuilder.append(" RAM, ");
   16667             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
   16668             memInfoBuilder.append(" swap total, ");
   16669             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
   16670             memInfoBuilder.append(" swap free\n");
   16671         }
   16672         final long[] ksm = getKsmInfo();
   16673         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
   16674                 || ksm[KSM_VOLATILE] != 0) {
   16675             memInfoBuilder.append("  KSM: ");
   16676             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
   16677             memInfoBuilder.append(" saved from shared ");
   16678             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
   16679             memInfoBuilder.append("\n       ");
   16680             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
   16681             memInfoBuilder.append(" unshared; ");
   16682             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
   16683             memInfoBuilder.append(" volatile\n");
   16684         }
   16685         memInfoBuilder.append("  Free RAM: ");
   16686         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
   16687                 + memInfo.getFreeSizeKb()));
   16688         memInfoBuilder.append("\n");
   16689         memInfoBuilder.append("  Used RAM: ");
   16690         memInfoBuilder.append(stringifyKBSize(
   16691                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
   16692         memInfoBuilder.append("\n");
   16693         memInfoBuilder.append("  Lost RAM: ");
   16694         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
   16695                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
   16696                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
   16697         memInfoBuilder.append("\n");
   16698         Slog.i(TAG, "Low on memory:");
   16699         Slog.i(TAG, shortNativeBuilder.toString());
   16700         Slog.i(TAG, fullJavaBuilder.toString());
   16701         Slog.i(TAG, memInfoBuilder.toString());
   16702 
   16703         StringBuilder dropBuilder = new StringBuilder(1024);
   16704         /*
   16705         StringWriter oomSw = new StringWriter();
   16706         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
   16707         StringWriter catSw = new StringWriter();
   16708         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
   16709         String[] emptyArgs = new String[] { };
   16710         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
   16711         oomPw.flush();
   16712         String oomString = oomSw.toString();
   16713         */
   16714         dropBuilder.append("Low on memory:");
   16715         dropBuilder.append(stack);
   16716         dropBuilder.append('\n');
   16717         dropBuilder.append(fullNativeBuilder);
   16718         dropBuilder.append(fullJavaBuilder);
   16719         dropBuilder.append('\n');
   16720         dropBuilder.append(memInfoBuilder);
   16721         dropBuilder.append('\n');
   16722         /*
   16723         dropBuilder.append(oomString);
   16724         dropBuilder.append('\n');
   16725         */
   16726         StringWriter catSw = new StringWriter();
   16727         synchronized (ActivityManagerService.this) {
   16728             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
   16729             String[] emptyArgs = new String[] { };
   16730             catPw.println();
   16731             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
   16732             catPw.println();
   16733             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
   16734                     false, null).dumpLocked();
   16735             catPw.println();
   16736             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
   16737             catPw.flush();
   16738         }
   16739         dropBuilder.append(catSw.toString());
   16740         addErrorToDropBox("lowmem", null, "system_server", null,
   16741                 null, tag.toString(), dropBuilder.toString(), null, null);
   16742         //Slog.i(TAG, "Sent to dropbox:");
   16743         //Slog.i(TAG, dropBuilder.toString());
   16744         synchronized (ActivityManagerService.this) {
   16745             long now = SystemClock.uptimeMillis();
   16746             if (mLastMemUsageReportTime < now) {
   16747                 mLastMemUsageReportTime = now;
   16748             }
   16749         }
   16750     }
   16751 
   16752     /**
   16753      * Searches array of arguments for the specified string
   16754      * @param args array of argument strings
   16755      * @param value value to search for
   16756      * @return true if the value is contained in the array
   16757      */
   16758     private static boolean scanArgs(String[] args, String value) {
   16759         if (args != null) {
   16760             for (String arg : args) {
   16761                 if (value.equals(arg)) {
   16762                     return true;
   16763                 }
   16764             }
   16765         }
   16766         return false;
   16767     }
   16768 
   16769     private final boolean removeDyingProviderLocked(ProcessRecord proc,
   16770             ContentProviderRecord cpr, boolean always) {
   16771         final boolean inLaunching = mLaunchingProviders.contains(cpr);
   16772 
   16773         if (!inLaunching || always) {
   16774             synchronized (cpr) {
   16775                 cpr.launchingApp = null;
   16776                 cpr.notifyAll();
   16777             }
   16778             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
   16779             String names[] = cpr.info.authority.split(";");
   16780             for (int j = 0; j < names.length; j++) {
   16781                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
   16782             }
   16783         }
   16784 
   16785         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
   16786             ContentProviderConnection conn = cpr.connections.get(i);
   16787             if (conn.waiting) {
   16788                 // If this connection is waiting for the provider, then we don't
   16789                 // need to mess with its process unless we are always removing
   16790                 // or for some reason the provider is not currently launching.
   16791                 if (inLaunching && !always) {
   16792                     continue;
   16793                 }
   16794             }
   16795             ProcessRecord capp = conn.client;
   16796             conn.dead = true;
   16797             if (conn.stableCount > 0) {
   16798                 if (!capp.persistent && capp.thread != null
   16799                         && capp.pid != 0
   16800                         && capp.pid != MY_PID) {
   16801                     capp.kill("depends on provider "
   16802                             + cpr.name.flattenToShortString()
   16803                             + " in dying proc " + (proc != null ? proc.processName : "??")
   16804                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
   16805                 }
   16806             } else if (capp.thread != null && conn.provider.provider != null) {
   16807                 try {
   16808                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
   16809                 } catch (RemoteException e) {
   16810                 }
   16811                 // In the protocol here, we don't expect the client to correctly
   16812                 // clean up this connection, we'll just remove it.
   16813                 cpr.connections.remove(i);
   16814                 if (conn.client.conProviders.remove(conn)) {
   16815                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
   16816                 }
   16817             }
   16818         }
   16819 
   16820         if (inLaunching && always) {
   16821             mLaunchingProviders.remove(cpr);
   16822         }
   16823         return inLaunching;
   16824     }
   16825 
   16826     /**
   16827      * Main code for cleaning up a process when it has gone away.  This is
   16828      * called both as a result of the process dying, or directly when stopping
   16829      * a process when running in single process mode.
   16830      *
   16831      * @return Returns true if the given process has been restarted, so the
   16832      * app that was passed in must remain on the process lists.
   16833      */
   16834     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
   16835             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
   16836         Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
   16837         if (index >= 0) {
   16838             removeLruProcessLocked(app);
   16839             ProcessList.remove(app.pid);
   16840         }
   16841 
   16842         mProcessesToGc.remove(app);
   16843         mPendingPssProcesses.remove(app);
   16844 
   16845         // Dismiss any open dialogs.
   16846         if (app.crashDialog != null && !app.forceCrashReport) {
   16847             app.crashDialog.dismiss();
   16848             app.crashDialog = null;
   16849         }
   16850         if (app.anrDialog != null) {
   16851             app.anrDialog.dismiss();
   16852             app.anrDialog = null;
   16853         }
   16854         if (app.waitDialog != null) {
   16855             app.waitDialog.dismiss();
   16856             app.waitDialog = null;
   16857         }
   16858 
   16859         app.crashing = false;
   16860         app.notResponding = false;
   16861 
   16862         app.resetPackageList(mProcessStats);
   16863         app.unlinkDeathRecipient();
   16864         app.makeInactive(mProcessStats);
   16865         app.waitingToKill = null;
   16866         app.forcingToForeground = null;
   16867         updateProcessForegroundLocked(app, false, false);
   16868         app.foregroundActivities = false;
   16869         app.hasShownUi = false;
   16870         app.treatLikeActivity = false;
   16871         app.hasAboveClient = false;
   16872         app.hasClientActivities = false;
   16873 
   16874         mServices.killServicesLocked(app, allowRestart);
   16875 
   16876         boolean restart = false;
   16877 
   16878         // Remove published content providers.
   16879         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
   16880             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
   16881             final boolean always = app.bad || !allowRestart;
   16882             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
   16883             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
   16884                 // We left the provider in the launching list, need to
   16885                 // restart it.
   16886                 restart = true;
   16887             }
   16888 
   16889             cpr.provider = null;
   16890             cpr.proc = null;
   16891         }
   16892         app.pubProviders.clear();
   16893 
   16894         // Take care of any launching providers waiting for this process.
   16895         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
   16896             restart = true;
   16897         }
   16898 
   16899         // Unregister from connected content providers.
   16900         if (!app.conProviders.isEmpty()) {
   16901             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
   16902                 ContentProviderConnection conn = app.conProviders.get(i);
   16903                 conn.provider.connections.remove(conn);
   16904                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
   16905                         conn.provider.name);
   16906             }
   16907             app.conProviders.clear();
   16908         }
   16909 
   16910         // At this point there may be remaining entries in mLaunchingProviders
   16911         // where we were the only one waiting, so they are no longer of use.
   16912         // Look for these and clean up if found.
   16913         // XXX Commented out for now.  Trying to figure out a way to reproduce
   16914         // the actual situation to identify what is actually going on.
   16915         if (false) {
   16916             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
   16917                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
   16918                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
   16919                     synchronized (cpr) {
   16920                         cpr.launchingApp = null;
   16921                         cpr.notifyAll();
   16922                     }
   16923                 }
   16924             }
   16925         }
   16926 
   16927         skipCurrentReceiverLocked(app);
   16928 
   16929         // Unregister any receivers.
   16930         for (int i = app.receivers.size() - 1; i >= 0; i--) {
   16931             removeReceiverLocked(app.receivers.valueAt(i));
   16932         }
   16933         app.receivers.clear();
   16934 
   16935         // If the app is undergoing backup, tell the backup manager about it
   16936         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
   16937             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
   16938                     + mBackupTarget.appInfo + " died during backup");
   16939             try {
   16940                 IBackupManager bm = IBackupManager.Stub.asInterface(
   16941                         ServiceManager.getService(Context.BACKUP_SERVICE));
   16942                 bm.agentDisconnected(app.info.packageName);
   16943             } catch (RemoteException e) {
   16944                 // can't happen; backup manager is local
   16945             }
   16946         }
   16947 
   16948         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
   16949             ProcessChangeItem item = mPendingProcessChanges.get(i);
   16950             if (item.pid == app.pid) {
   16951                 mPendingProcessChanges.remove(i);
   16952                 mAvailProcessChanges.add(item);
   16953             }
   16954         }
   16955         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
   16956                 null).sendToTarget();
   16957 
   16958         // If the caller is restarting this app, then leave it in its
   16959         // current lists and let the caller take care of it.
   16960         if (restarting) {
   16961             return false;
   16962         }
   16963 
   16964         if (!app.persistent || app.isolated) {
   16965             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
   16966                     "Removing non-persistent process during cleanup: " + app);
   16967             if (!replacingPid) {
   16968                 removeProcessNameLocked(app.processName, app.uid);
   16969             }
   16970             if (mHeavyWeightProcess == app) {
   16971                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   16972                         mHeavyWeightProcess.userId, 0));
   16973                 mHeavyWeightProcess = null;
   16974             }
   16975         } else if (!app.removed) {
   16976             // This app is persistent, so we need to keep its record around.
   16977             // If it is not already on the pending app list, add it there
   16978             // and start a new process for it.
   16979             if (mPersistentStartingProcesses.indexOf(app) < 0) {
   16980                 mPersistentStartingProcesses.add(app);
   16981                 restart = true;
   16982             }
   16983         }
   16984         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
   16985                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
   16986         mProcessesOnHold.remove(app);
   16987 
   16988         if (app == mHomeProcess) {
   16989             mHomeProcess = null;
   16990         }
   16991         if (app == mPreviousProcess) {
   16992             mPreviousProcess = null;
   16993         }
   16994 
   16995         if (restart && !app.isolated) {
   16996             // We have components that still need to be running in the
   16997             // process, so re-launch it.
   16998             if (index < 0) {
   16999                 ProcessList.remove(app.pid);
   17000             }
   17001             addProcessNameLocked(app);
   17002             startProcessLocked(app, "restart", app.processName);
   17003             return true;
   17004         } else if (app.pid > 0 && app.pid != MY_PID) {
   17005             // Goodbye!
   17006             boolean removed;
   17007             synchronized (mPidsSelfLocked) {
   17008                 mPidsSelfLocked.remove(app.pid);
   17009                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   17010             }
   17011             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   17012             if (app.isolated) {
   17013                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   17014             }
   17015             app.setPid(0);
   17016         }
   17017         return false;
   17018     }
   17019 
   17020     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
   17021         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
   17022             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   17023             if (cpr.launchingApp == app) {
   17024                 return true;
   17025             }
   17026         }
   17027         return false;
   17028     }
   17029 
   17030     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
   17031         // Look through the content providers we are waiting to have launched,
   17032         // and if any run in this process then either schedule a restart of
   17033         // the process or kill the client waiting for it if this process has
   17034         // gone bad.
   17035         boolean restart = false;
   17036         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
   17037             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   17038             if (cpr.launchingApp == app) {
   17039                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
   17040                     restart = true;
   17041                 } else {
   17042                     removeDyingProviderLocked(app, cpr, true);
   17043                 }
   17044             }
   17045         }
   17046         return restart;
   17047     }
   17048 
   17049     // =========================================================
   17050     // SERVICES
   17051     // =========================================================
   17052 
   17053     @Override
   17054     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
   17055             int flags) {
   17056         enforceNotIsolatedCaller("getServices");
   17057         synchronized (this) {
   17058             return mServices.getRunningServiceInfoLocked(maxNum, flags);
   17059         }
   17060     }
   17061 
   17062     @Override
   17063     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
   17064         enforceNotIsolatedCaller("getRunningServiceControlPanel");
   17065         synchronized (this) {
   17066             return mServices.getRunningServiceControlPanelLocked(name);
   17067         }
   17068     }
   17069 
   17070     @Override
   17071     public ComponentName startService(IApplicationThread caller, Intent service,
   17072             String resolvedType, String callingPackage, int userId)
   17073             throws TransactionTooLargeException {
   17074         enforceNotIsolatedCaller("startService");
   17075         // Refuse possible leaked file descriptors
   17076         if (service != null && service.hasFileDescriptors() == true) {
   17077             throw new IllegalArgumentException("File descriptors passed in Intent");
   17078         }
   17079 
   17080         if (callingPackage == null) {
   17081             throw new IllegalArgumentException("callingPackage cannot be null");
   17082         }
   17083 
   17084         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
   17085                 "startService: " + service + " type=" + resolvedType);
   17086         synchronized(this) {
   17087             final int callingPid = Binder.getCallingPid();
   17088             final int callingUid = Binder.getCallingUid();
   17089             final long origId = Binder.clearCallingIdentity();
   17090             ComponentName res = mServices.startServiceLocked(caller, service,
   17091                     resolvedType, callingPid, callingUid, callingPackage, userId);
   17092             Binder.restoreCallingIdentity(origId);
   17093             return res;
   17094         }
   17095     }
   17096 
   17097     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
   17098             String callingPackage, int userId)
   17099             throws TransactionTooLargeException {
   17100         synchronized(this) {
   17101             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
   17102                     "startServiceInPackage: " + service + " type=" + resolvedType);
   17103             final long origId = Binder.clearCallingIdentity();
   17104             ComponentName res = mServices.startServiceLocked(null, service,
   17105                     resolvedType, -1, uid, callingPackage, userId);
   17106             Binder.restoreCallingIdentity(origId);
   17107             return res;
   17108         }
   17109     }
   17110 
   17111     @Override
   17112     public int stopService(IApplicationThread caller, Intent service,
   17113             String resolvedType, int userId) {
   17114         enforceNotIsolatedCaller("stopService");
   17115         // Refuse possible leaked file descriptors
   17116         if (service != null && service.hasFileDescriptors() == true) {
   17117             throw new IllegalArgumentException("File descriptors passed in Intent");
   17118         }
   17119 
   17120         synchronized(this) {
   17121             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
   17122         }
   17123     }
   17124 
   17125     @Override
   17126     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
   17127         enforceNotIsolatedCaller("peekService");
   17128         // Refuse possible leaked file descriptors
   17129         if (service != null && service.hasFileDescriptors() == true) {
   17130             throw new IllegalArgumentException("File descriptors passed in Intent");
   17131         }
   17132 
   17133         if (callingPackage == null) {
   17134             throw new IllegalArgumentException("callingPackage cannot be null");
   17135         }
   17136 
   17137         synchronized(this) {
   17138             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
   17139         }
   17140     }
   17141 
   17142     @Override
   17143     public boolean stopServiceToken(ComponentName className, IBinder token,
   17144             int startId) {
   17145         synchronized(this) {
   17146             return mServices.stopServiceTokenLocked(className, token, startId);
   17147         }
   17148     }
   17149 
   17150     @Override
   17151     public void setServiceForeground(ComponentName className, IBinder token,
   17152             int id, Notification notification, int flags) {
   17153         synchronized(this) {
   17154             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
   17155         }
   17156     }
   17157 
   17158     @Override
   17159     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
   17160             boolean requireFull, String name, String callerPackage) {
   17161         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
   17162                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
   17163     }
   17164 
   17165     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
   17166             String className, int flags) {
   17167         boolean result = false;
   17168         // For apps that don't have pre-defined UIDs, check for permission
   17169         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
   17170             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
   17171                 if (ActivityManager.checkUidPermission(
   17172                         INTERACT_ACROSS_USERS,
   17173                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
   17174                     ComponentName comp = new ComponentName(aInfo.packageName, className);
   17175                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
   17176                             + " requests FLAG_SINGLE_USER, but app does not hold "
   17177                             + INTERACT_ACROSS_USERS;
   17178                     Slog.w(TAG, msg);
   17179                     throw new SecurityException(msg);
   17180                 }
   17181                 // Permission passed
   17182                 result = true;
   17183             }
   17184         } else if ("system".equals(componentProcessName)) {
   17185             result = true;
   17186         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
   17187             // Phone app and persistent apps are allowed to export singleuser providers.
   17188             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
   17189                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
   17190         }
   17191         if (DEBUG_MU) Slog.v(TAG_MU,
   17192                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
   17193                 + Integer.toHexString(flags) + ") = " + result);
   17194         return result;
   17195     }
   17196 
   17197     /**
   17198      * Checks to see if the caller is in the same app as the singleton
   17199      * component, or the component is in a special app. It allows special apps
   17200      * to export singleton components but prevents exporting singleton
   17201      * components for regular apps.
   17202      */
   17203     boolean isValidSingletonCall(int callingUid, int componentUid) {
   17204         int componentAppId = UserHandle.getAppId(componentUid);
   17205         return UserHandle.isSameApp(callingUid, componentUid)
   17206                 || componentAppId == Process.SYSTEM_UID
   17207                 || componentAppId == Process.PHONE_UID
   17208                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
   17209                         == PackageManager.PERMISSION_GRANTED;
   17210     }
   17211 
   17212     public int bindService(IApplicationThread caller, IBinder token, Intent service,
   17213             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
   17214             int userId) throws TransactionTooLargeException {
   17215         enforceNotIsolatedCaller("bindService");
   17216 
   17217         // Refuse possible leaked file descriptors
   17218         if (service != null && service.hasFileDescriptors() == true) {
   17219             throw new IllegalArgumentException("File descriptors passed in Intent");
   17220         }
   17221 
   17222         if (callingPackage == null) {
   17223             throw new IllegalArgumentException("callingPackage cannot be null");
   17224         }
   17225 
   17226         synchronized(this) {
   17227             return mServices.bindServiceLocked(caller, token, service,
   17228                     resolvedType, connection, flags, callingPackage, userId);
   17229         }
   17230     }
   17231 
   17232     public boolean unbindService(IServiceConnection connection) {
   17233         synchronized (this) {
   17234             return mServices.unbindServiceLocked(connection);
   17235         }
   17236     }
   17237 
   17238     public void publishService(IBinder token, Intent intent, IBinder service) {
   17239         // Refuse possible leaked file descriptors
   17240         if (intent != null && intent.hasFileDescriptors() == true) {
   17241             throw new IllegalArgumentException("File descriptors passed in Intent");
   17242         }
   17243 
   17244         synchronized(this) {
   17245             if (!(token instanceof ServiceRecord)) {
   17246                 throw new IllegalArgumentException("Invalid service token");
   17247             }
   17248             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
   17249         }
   17250     }
   17251 
   17252     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
   17253         // Refuse possible leaked file descriptors
   17254         if (intent != null && intent.hasFileDescriptors() == true) {
   17255             throw new IllegalArgumentException("File descriptors passed in Intent");
   17256         }
   17257 
   17258         synchronized(this) {
   17259             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
   17260         }
   17261     }
   17262 
   17263     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
   17264         synchronized(this) {
   17265             if (!(token instanceof ServiceRecord)) {
   17266                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
   17267                 throw new IllegalArgumentException("Invalid service token");
   17268             }
   17269             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
   17270         }
   17271     }
   17272 
   17273     // =========================================================
   17274     // BACKUP AND RESTORE
   17275     // =========================================================
   17276 
   17277     // Cause the target app to be launched if necessary and its backup agent
   17278     // instantiated.  The backup agent will invoke backupAgentCreated() on the
   17279     // activity manager to announce its creation.
   17280     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
   17281         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
   17282         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
   17283 
   17284         IPackageManager pm = AppGlobals.getPackageManager();
   17285         ApplicationInfo app = null;
   17286         try {
   17287             app = pm.getApplicationInfo(packageName, 0, userId);
   17288         } catch (RemoteException e) {
   17289             // can't happen; package manager is process-local
   17290         }
   17291         if (app == null) {
   17292             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
   17293             return false;
   17294         }
   17295 
   17296         synchronized(this) {
   17297             // !!! TODO: currently no check here that we're already bound
   17298             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   17299             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   17300             synchronized (stats) {
   17301                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
   17302             }
   17303 
   17304             // Backup agent is now in use, its package can't be stopped.
   17305             try {
   17306                 AppGlobals.getPackageManager().setPackageStoppedState(
   17307                         app.packageName, false, UserHandle.getUserId(app.uid));
   17308             } catch (RemoteException e) {
   17309             } catch (IllegalArgumentException e) {
   17310                 Slog.w(TAG, "Failed trying to unstop package "
   17311                         + app.packageName + ": " + e);
   17312             }
   17313 
   17314             BackupRecord r = new BackupRecord(ss, app, backupMode);
   17315             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
   17316                     ? new ComponentName(app.packageName, app.backupAgentName)
   17317                     : new ComponentName("android", "FullBackupAgent");
   17318             // startProcessLocked() returns existing proc's record if it's already running
   17319             ProcessRecord proc = startProcessLocked(app.processName, app,
   17320                     false, 0, "backup", hostingName, false, false, false);
   17321             if (proc == null) {
   17322                 Slog.e(TAG, "Unable to start backup agent process " + r);
   17323                 return false;
   17324             }
   17325 
   17326             // If the app is a regular app (uid >= 10000) and not the system server or phone
   17327             // process, etc, then mark it as being in full backup so that certain calls to the
   17328             // process can be blocked. This is not reset to false anywhere because we kill the
   17329             // process after the full backup is done and the ProcessRecord will vaporize anyway.
   17330             if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
   17331                 proc.inFullBackup = true;
   17332             }
   17333             r.app = proc;
   17334             mBackupTarget = r;
   17335             mBackupAppName = app.packageName;
   17336 
   17337             // Try not to kill the process during backup
   17338             updateOomAdjLocked(proc);
   17339 
   17340             // If the process is already attached, schedule the creation of the backup agent now.
   17341             // If it is not yet live, this will be done when it attaches to the framework.
   17342             if (proc.thread != null) {
   17343                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
   17344                 try {
   17345                     proc.thread.scheduleCreateBackupAgent(app,
   17346                             compatibilityInfoForPackageLocked(app), backupMode);
   17347                 } catch (RemoteException e) {
   17348                     // Will time out on the backup manager side
   17349                 }
   17350             } else {
   17351                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
   17352             }
   17353             // Invariants: at this point, the target app process exists and the application
   17354             // is either already running or in the process of coming up.  mBackupTarget and
   17355             // mBackupAppName describe the app, so that when it binds back to the AM we
   17356             // know that it's scheduled for a backup-agent operation.
   17357         }
   17358 
   17359         return true;
   17360     }
   17361 
   17362     @Override
   17363     public void clearPendingBackup() {
   17364         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
   17365         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
   17366 
   17367         synchronized (this) {
   17368             mBackupTarget = null;
   17369             mBackupAppName = null;
   17370         }
   17371     }
   17372 
   17373     // A backup agent has just come up
   17374     public void backupAgentCreated(String agentPackageName, IBinder agent) {
   17375         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
   17376                 + " = " + agent);
   17377 
   17378         synchronized(this) {
   17379             if (!agentPackageName.equals(mBackupAppName)) {
   17380                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
   17381                 return;
   17382             }
   17383         }
   17384 
   17385         long oldIdent = Binder.clearCallingIdentity();
   17386         try {
   17387             IBackupManager bm = IBackupManager.Stub.asInterface(
   17388                     ServiceManager.getService(Context.BACKUP_SERVICE));
   17389             bm.agentConnected(agentPackageName, agent);
   17390         } catch (RemoteException e) {
   17391             // can't happen; the backup manager service is local
   17392         } catch (Exception e) {
   17393             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
   17394             e.printStackTrace();
   17395         } finally {
   17396             Binder.restoreCallingIdentity(oldIdent);
   17397         }
   17398     }
   17399 
   17400     // done with this agent
   17401     public void unbindBackupAgent(ApplicationInfo appInfo) {
   17402         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
   17403         if (appInfo == null) {
   17404             Slog.w(TAG, "unbind backup agent for null app");
   17405             return;
   17406         }
   17407 
   17408         synchronized(this) {
   17409             try {
   17410                 if (mBackupAppName == null) {
   17411                     Slog.w(TAG, "Unbinding backup agent with no active backup");
   17412                     return;
   17413                 }
   17414 
   17415                 if (!mBackupAppName.equals(appInfo.packageName)) {
   17416                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
   17417                     return;
   17418                 }
   17419 
   17420                 // Not backing this app up any more; reset its OOM adjustment
   17421                 final ProcessRecord proc = mBackupTarget.app;
   17422                 updateOomAdjLocked(proc);
   17423 
   17424                 // If the app crashed during backup, 'thread' will be null here
   17425                 if (proc.thread != null) {
   17426                     try {
   17427                         proc.thread.scheduleDestroyBackupAgent(appInfo,
   17428                                 compatibilityInfoForPackageLocked(appInfo));
   17429                     } catch (Exception e) {
   17430                         Slog.e(TAG, "Exception when unbinding backup agent:");
   17431                         e.printStackTrace();
   17432                     }
   17433                 }
   17434             } finally {
   17435                 mBackupTarget = null;
   17436                 mBackupAppName = null;
   17437             }
   17438         }
   17439     }
   17440     // =========================================================
   17441     // BROADCASTS
   17442     // =========================================================
   17443 
   17444     boolean isPendingBroadcastProcessLocked(int pid) {
   17445         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
   17446                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
   17447     }
   17448 
   17449     void skipPendingBroadcastLocked(int pid) {
   17450             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   17451             for (BroadcastQueue queue : mBroadcastQueues) {
   17452                 queue.skipPendingBroadcastLocked(pid);
   17453             }
   17454     }
   17455 
   17456     // The app just attached; send any pending broadcasts that it should receive
   17457     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
   17458         boolean didSomething = false;
   17459         for (BroadcastQueue queue : mBroadcastQueues) {
   17460             didSomething |= queue.sendPendingBroadcastsLocked(app);
   17461         }
   17462         return didSomething;
   17463     }
   17464 
   17465     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
   17466             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
   17467         enforceNotIsolatedCaller("registerReceiver");
   17468         ArrayList<Intent> stickyIntents = null;
   17469         ProcessRecord callerApp = null;
   17470         int callingUid;
   17471         int callingPid;
   17472         synchronized(this) {
   17473             if (caller != null) {
   17474                 callerApp = getRecordForAppLocked(caller);
   17475                 if (callerApp == null) {
   17476                     throw new SecurityException(
   17477                             "Unable to find app for caller " + caller
   17478                             + " (pid=" + Binder.getCallingPid()
   17479                             + ") when registering receiver " + receiver);
   17480                 }
   17481                 if (callerApp.info.uid != Process.SYSTEM_UID &&
   17482                         !callerApp.pkgList.containsKey(callerPackage) &&
   17483                         !"android".equals(callerPackage)) {
   17484                     throw new SecurityException("Given caller package " + callerPackage
   17485                             + " is not running in process " + callerApp);
   17486                 }
   17487                 callingUid = callerApp.info.uid;
   17488                 callingPid = callerApp.pid;
   17489             } else {
   17490                 callerPackage = null;
   17491                 callingUid = Binder.getCallingUid();
   17492                 callingPid = Binder.getCallingPid();
   17493             }
   17494 
   17495             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
   17496                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
   17497 
   17498             Iterator<String> actions = filter.actionsIterator();
   17499             if (actions == null) {
   17500                 ArrayList<String> noAction = new ArrayList<String>(1);
   17501                 noAction.add(null);
   17502                 actions = noAction.iterator();
   17503             }
   17504 
   17505             // Collect stickies of users
   17506             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
   17507             while (actions.hasNext()) {
   17508                 String action = actions.next();
   17509                 for (int id : userIds) {
   17510                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
   17511                     if (stickies != null) {
   17512                         ArrayList<Intent> intents = stickies.get(action);
   17513                         if (intents != null) {
   17514                             if (stickyIntents == null) {
   17515                                 stickyIntents = new ArrayList<Intent>();
   17516                             }
   17517                             stickyIntents.addAll(intents);
   17518                         }
   17519                     }
   17520                 }
   17521             }
   17522         }
   17523 
   17524         ArrayList<Intent> allSticky = null;
   17525         if (stickyIntents != null) {
   17526             final ContentResolver resolver = mContext.getContentResolver();
   17527             // Look for any matching sticky broadcasts...
   17528             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
   17529                 Intent intent = stickyIntents.get(i);
   17530                 // If intent has scheme "content", it will need to acccess
   17531                 // provider that needs to lock mProviderMap in ActivityThread
   17532                 // and also it may need to wait application response, so we
   17533                 // cannot lock ActivityManagerService here.
   17534                 if (filter.match(resolver, intent, true, TAG) >= 0) {
   17535                     if (allSticky == null) {
   17536                         allSticky = new ArrayList<Intent>();
   17537                     }
   17538                     allSticky.add(intent);
   17539                 }
   17540             }
   17541         }
   17542 
   17543         // The first sticky in the list is returned directly back to the client.
   17544         Intent sticky = allSticky != null ? allSticky.get(0) : null;
   17545         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
   17546         if (receiver == null) {
   17547             return sticky;
   17548         }
   17549 
   17550         synchronized (this) {
   17551             if (callerApp != null && (callerApp.thread == null
   17552                     || callerApp.thread.asBinder() != caller.asBinder())) {
   17553                 // Original caller already died
   17554                 return null;
   17555             }
   17556             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
   17557             if (rl == null) {
   17558                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
   17559                         userId, receiver);
   17560                 if (rl.app != null) {
   17561                     rl.app.receivers.add(rl);
   17562                 } else {
   17563                     try {
   17564                         receiver.asBinder().linkToDeath(rl, 0);
   17565                     } catch (RemoteException e) {
   17566                         return sticky;
   17567                     }
   17568                     rl.linkedToDeath = true;
   17569                 }
   17570                 mRegisteredReceivers.put(receiver.asBinder(), rl);
   17571             } else if (rl.uid != callingUid) {
   17572                 throw new IllegalArgumentException(
   17573                         "Receiver requested to register for uid " + callingUid
   17574                         + " was previously registered for uid " + rl.uid);
   17575             } else if (rl.pid != callingPid) {
   17576                 throw new IllegalArgumentException(
   17577                         "Receiver requested to register for pid " + callingPid
   17578                         + " was previously registered for pid " + rl.pid);
   17579             } else if (rl.userId != userId) {
   17580                 throw new IllegalArgumentException(
   17581                         "Receiver requested to register for user " + userId
   17582                         + " was previously registered for user " + rl.userId);
   17583             }
   17584             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
   17585                     permission, callingUid, userId);
   17586             rl.add(bf);
   17587             if (!bf.debugCheck()) {
   17588                 Slog.w(TAG, "==> For Dynamic broadcast");
   17589             }
   17590             mReceiverResolver.addFilter(bf);
   17591 
   17592             // Enqueue broadcasts for all existing stickies that match
   17593             // this filter.
   17594             if (allSticky != null) {
   17595                 ArrayList receivers = new ArrayList();
   17596                 receivers.add(bf);
   17597 
   17598                 final int stickyCount = allSticky.size();
   17599                 for (int i = 0; i < stickyCount; i++) {
   17600                     Intent intent = allSticky.get(i);
   17601                     BroadcastQueue queue = broadcastQueueForIntent(intent);
   17602                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
   17603                             null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
   17604                             null, 0, null, null, false, true, true, -1);
   17605                     queue.enqueueParallelBroadcastLocked(r);
   17606                     queue.scheduleBroadcastsLocked();
   17607                 }
   17608             }
   17609 
   17610             return sticky;
   17611         }
   17612     }
   17613 
   17614     public void unregisterReceiver(IIntentReceiver receiver) {
   17615         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
   17616 
   17617         final long origId = Binder.clearCallingIdentity();
   17618         try {
   17619             boolean doTrim = false;
   17620 
   17621             synchronized(this) {
   17622                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
   17623                 if (rl != null) {
   17624                     final BroadcastRecord r = rl.curBroadcast;
   17625                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
   17626                         final boolean doNext = r.queue.finishReceiverLocked(
   17627                                 r, r.resultCode, r.resultData, r.resultExtras,
   17628                                 r.resultAbort, false);
   17629                         if (doNext) {
   17630                             doTrim = true;
   17631                             r.queue.processNextBroadcast(false);
   17632                         }
   17633                     }
   17634 
   17635                     if (rl.app != null) {
   17636                         rl.app.receivers.remove(rl);
   17637                     }
   17638                     removeReceiverLocked(rl);
   17639                     if (rl.linkedToDeath) {
   17640                         rl.linkedToDeath = false;
   17641                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
   17642                     }
   17643                 }
   17644             }
   17645 
   17646             // If we actually concluded any broadcasts, we might now be able
   17647             // to trim the recipients' apps from our working set
   17648             if (doTrim) {
   17649                 trimApplications();
   17650                 return;
   17651             }
   17652 
   17653         } finally {
   17654             Binder.restoreCallingIdentity(origId);
   17655         }
   17656     }
   17657 
   17658     void removeReceiverLocked(ReceiverList rl) {
   17659         mRegisteredReceivers.remove(rl.receiver.asBinder());
   17660         for (int i = rl.size() - 1; i >= 0; i--) {
   17661             mReceiverResolver.removeFilter(rl.get(i));
   17662         }
   17663     }
   17664 
   17665     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
   17666         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   17667             ProcessRecord r = mLruProcesses.get(i);
   17668             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
   17669                 try {
   17670                     r.thread.dispatchPackageBroadcast(cmd, packages);
   17671                 } catch (RemoteException ex) {
   17672                 }
   17673             }
   17674         }
   17675     }
   17676 
   17677     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
   17678             int callingUid, int[] users) {
   17679         // TODO: come back and remove this assumption to triage all broadcasts
   17680         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
   17681 
   17682         List<ResolveInfo> receivers = null;
   17683         try {
   17684             HashSet<ComponentName> singleUserReceivers = null;
   17685             boolean scannedFirstReceivers = false;
   17686             for (int user : users) {
   17687                 // Skip users that have Shell restrictions, with exception of always permitted
   17688                 // Shell broadcasts
   17689                 if (callingUid == Process.SHELL_UID
   17690                         && mUserController.hasUserRestriction(
   17691                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
   17692                         && !isPermittedShellBroadcast(intent)) {
   17693                     continue;
   17694                 }
   17695                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
   17696                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
   17697                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
   17698                     // If this is not the system user, we need to check for
   17699                     // any receivers that should be filtered out.
   17700                     for (int i=0; i<newReceivers.size(); i++) {
   17701                         ResolveInfo ri = newReceivers.get(i);
   17702                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
   17703                             newReceivers.remove(i);
   17704                             i--;
   17705                         }
   17706                     }
   17707                 }
   17708                 if (newReceivers != null && newReceivers.size() == 0) {
   17709                     newReceivers = null;
   17710                 }
   17711                 if (receivers == null) {
   17712                     receivers = newReceivers;
   17713                 } else if (newReceivers != null) {
   17714                     // We need to concatenate the additional receivers
   17715                     // found with what we have do far.  This would be easy,
   17716                     // but we also need to de-dup any receivers that are
   17717                     // singleUser.
   17718                     if (!scannedFirstReceivers) {
   17719                         // Collect any single user receivers we had already retrieved.
   17720                         scannedFirstReceivers = true;
   17721                         for (int i=0; i<receivers.size(); i++) {
   17722                             ResolveInfo ri = receivers.get(i);
   17723                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   17724                                 ComponentName cn = new ComponentName(
   17725                                         ri.activityInfo.packageName, ri.activityInfo.name);
   17726                                 if (singleUserReceivers == null) {
   17727                                     singleUserReceivers = new HashSet<ComponentName>();
   17728                                 }
   17729                                 singleUserReceivers.add(cn);
   17730                             }
   17731                         }
   17732                     }
   17733                     // Add the new results to the existing results, tracking
   17734                     // and de-dupping single user receivers.
   17735                     for (int i=0; i<newReceivers.size(); i++) {
   17736                         ResolveInfo ri = newReceivers.get(i);
   17737                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   17738                             ComponentName cn = new ComponentName(
   17739                                     ri.activityInfo.packageName, ri.activityInfo.name);
   17740                             if (singleUserReceivers == null) {
   17741                                 singleUserReceivers = new HashSet<ComponentName>();
   17742                             }
   17743                             if (!singleUserReceivers.contains(cn)) {
   17744                                 singleUserReceivers.add(cn);
   17745                                 receivers.add(ri);
   17746                             }
   17747                         } else {
   17748                             receivers.add(ri);
   17749                         }
   17750                     }
   17751                 }
   17752             }
   17753         } catch (RemoteException ex) {
   17754             // pm is in same process, this will never happen.
   17755         }
   17756         return receivers;
   17757     }
   17758 
   17759     private boolean isPermittedShellBroadcast(Intent intent) {
   17760         // remote bugreport should always be allowed to be taken
   17761         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
   17762     }
   17763 
   17764     private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
   17765             String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
   17766         final String action = intent.getAction();
   17767         if (isProtectedBroadcast
   17768                 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
   17769                 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
   17770                 || Intent.ACTION_MEDIA_BUTTON.equals(action)
   17771                 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
   17772                 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
   17773                 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
   17774                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
   17775                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
   17776                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
   17777                 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
   17778             // Broadcast is either protected, or it's a public action that
   17779             // we've relaxed, so it's fine for system internals to send.
   17780             return;
   17781         }
   17782 
   17783         // This broadcast may be a problem...  but there are often system components that
   17784         // want to send an internal broadcast to themselves, which is annoying to have to
   17785         // explicitly list each action as a protected broadcast, so we will check for that
   17786         // one safe case and allow it: an explicit broadcast, only being received by something
   17787         // that has protected itself.
   17788         if (receivers != null && receivers.size() > 0
   17789                 && (intent.getPackage() != null || intent.getComponent() != null)) {
   17790             boolean allProtected = true;
   17791             for (int i = receivers.size()-1; i >= 0; i--) {
   17792                 Object target = receivers.get(i);
   17793                 if (target instanceof ResolveInfo) {
   17794                     ResolveInfo ri = (ResolveInfo)target;
   17795                     if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
   17796                         allProtected = false;
   17797                         break;
   17798                     }
   17799                 } else {
   17800                     BroadcastFilter bf = (BroadcastFilter)target;
   17801                     if (bf.requiredPermission == null) {
   17802                         allProtected = false;
   17803                         break;
   17804                     }
   17805                 }
   17806             }
   17807             if (allProtected) {
   17808                 // All safe!
   17809                 return;
   17810             }
   17811         }
   17812 
   17813         // The vast majority of broadcasts sent from system internals
   17814         // should be protected to avoid security holes, so yell loudly
   17815         // to ensure we examine these cases.
   17816         if (callerApp != null) {
   17817             Log.wtf(TAG, "Sending non-protected broadcast " + action
   17818                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
   17819                     new Throwable());
   17820         } else {
   17821             Log.wtf(TAG, "Sending non-protected broadcast " + action
   17822                             + " from system uid " + UserHandle.formatUid(callingUid)
   17823                             + " pkg " + callerPackage,
   17824                     new Throwable());
   17825         }
   17826     }
   17827 
   17828     final int broadcastIntentLocked(ProcessRecord callerApp,
   17829             String callerPackage, Intent intent, String resolvedType,
   17830             IIntentReceiver resultTo, int resultCode, String resultData,
   17831             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
   17832             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
   17833         intent = new Intent(intent);
   17834 
   17835         // By default broadcasts do not go to stopped apps.
   17836         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
   17837 
   17838         // If we have not finished booting, don't allow this to launch new processes.
   17839         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
   17840             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   17841         }
   17842 
   17843         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
   17844                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
   17845                 + " ordered=" + ordered + " userid=" + userId);
   17846         if ((resultTo != null) && !ordered) {
   17847             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
   17848         }
   17849 
   17850         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
   17851                 ALLOW_NON_FULL, "broadcast", callerPackage);
   17852 
   17853         // Make sure that the user who is receiving this broadcast is running.
   17854         // If not, we will just skip it. Make an exception for shutdown broadcasts
   17855         // and upgrade steps.
   17856 
   17857         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
   17858             if ((callingUid != Process.SYSTEM_UID
   17859                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
   17860                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
   17861                 Slog.w(TAG, "Skipping broadcast of " + intent
   17862                         + ": user " + userId + " is stopped");
   17863                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
   17864             }
   17865         }
   17866 
   17867         BroadcastOptions brOptions = null;
   17868         if (bOptions != null) {
   17869             brOptions = new BroadcastOptions(bOptions);
   17870             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
   17871                 // See if the caller is allowed to do this.  Note we are checking against
   17872                 // the actual real caller (not whoever provided the operation as say a
   17873                 // PendingIntent), because that who is actually supplied the arguments.
   17874                 if (checkComponentPermission(
   17875                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
   17876                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
   17877                         != PackageManager.PERMISSION_GRANTED) {
   17878                     String msg = "Permission Denial: " + intent.getAction()
   17879                             + " broadcast from " + callerPackage + " (pid=" + callingPid
   17880                             + ", uid=" + callingUid + ")"
   17881                             + " requires "
   17882                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
   17883                     Slog.w(TAG, msg);
   17884                     throw new SecurityException(msg);
   17885                 }
   17886             }
   17887         }
   17888 
   17889         // Verify that protected broadcasts are only being sent by system code,
   17890         // and that system code is only sending protected broadcasts.
   17891         final String action = intent.getAction();
   17892         final boolean isProtectedBroadcast;
   17893         try {
   17894             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
   17895         } catch (RemoteException e) {
   17896             Slog.w(TAG, "Remote exception", e);
   17897             return ActivityManager.BROADCAST_SUCCESS;
   17898         }
   17899 
   17900         final boolean isCallerSystem;
   17901         switch (UserHandle.getAppId(callingUid)) {
   17902             case Process.ROOT_UID:
   17903             case Process.SYSTEM_UID:
   17904             case Process.PHONE_UID:
   17905             case Process.BLUETOOTH_UID:
   17906             case Process.NFC_UID:
   17907                 isCallerSystem = true;
   17908                 break;
   17909             default:
   17910                 isCallerSystem = (callerApp != null) && callerApp.persistent;
   17911                 break;
   17912         }
   17913 
   17914         // First line security check before anything else: stop non-system apps from
   17915         // sending protected broadcasts.
   17916         if (!isCallerSystem) {
   17917             if (isProtectedBroadcast) {
   17918                 String msg = "Permission Denial: not allowed to send broadcast "
   17919                         + action + " from pid="
   17920                         + callingPid + ", uid=" + callingUid;
   17921                 Slog.w(TAG, msg);
   17922                 throw new SecurityException(msg);
   17923 
   17924             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
   17925                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
   17926                 // Special case for compatibility: we don't want apps to send this,
   17927                 // but historically it has not been protected and apps may be using it
   17928                 // to poke their own app widget.  So, instead of making it protected,
   17929                 // just limit it to the caller.
   17930                 if (callerPackage == null) {
   17931                     String msg = "Permission Denial: not allowed to send broadcast "
   17932                             + action + " from unknown caller.";
   17933                     Slog.w(TAG, msg);
   17934                     throw new SecurityException(msg);
   17935                 } else if (intent.getComponent() != null) {
   17936                     // They are good enough to send to an explicit component...  verify
   17937                     // it is being sent to the calling app.
   17938                     if (!intent.getComponent().getPackageName().equals(
   17939                             callerPackage)) {
   17940                         String msg = "Permission Denial: not allowed to send broadcast "
   17941                                 + action + " to "
   17942                                 + intent.getComponent().getPackageName() + " from "
   17943                                 + callerPackage;
   17944                         Slog.w(TAG, msg);
   17945                         throw new SecurityException(msg);
   17946                     }
   17947                 } else {
   17948                     // Limit broadcast to their own package.
   17949                     intent.setPackage(callerPackage);
   17950                 }
   17951             }
   17952         }
   17953 
   17954         if (action != null) {
   17955             switch (action) {
   17956                 case Intent.ACTION_UID_REMOVED:
   17957                 case Intent.ACTION_PACKAGE_REMOVED:
   17958                 case Intent.ACTION_PACKAGE_CHANGED:
   17959                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
   17960                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
   17961                 case Intent.ACTION_PACKAGES_SUSPENDED:
   17962                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
   17963                     // Handle special intents: if this broadcast is from the package
   17964                     // manager about a package being removed, we need to remove all of
   17965                     // its activities from the history stack.
   17966                     if (checkComponentPermission(
   17967                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
   17968                             callingPid, callingUid, -1, true)
   17969                             != PackageManager.PERMISSION_GRANTED) {
   17970                         String msg = "Permission Denial: " + intent.getAction()
   17971                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
   17972                                 + ", uid=" + callingUid + ")"
   17973                                 + " requires "
   17974                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
   17975                         Slog.w(TAG, msg);
   17976                         throw new SecurityException(msg);
   17977                     }
   17978                     switch (action) {
   17979                         case Intent.ACTION_UID_REMOVED:
   17980                             final Bundle intentExtras = intent.getExtras();
   17981                             final int uid = intentExtras != null
   17982                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
   17983                             if (uid >= 0) {
   17984                                 mBatteryStatsService.removeUid(uid);
   17985                                 mAppOpsService.uidRemoved(uid);
   17986                             }
   17987                             break;
   17988                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
   17989                             // If resources are unavailable just force stop all those packages
   17990                             // and flush the attribute cache as well.
   17991                             String list[] =
   17992                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   17993                             if (list != null && list.length > 0) {
   17994                                 for (int i = 0; i < list.length; i++) {
   17995                                     forceStopPackageLocked(list[i], -1, false, true, true,
   17996                                             false, false, userId, "storage unmount");
   17997                                 }
   17998                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
   17999                                 sendPackageBroadcastLocked(
   18000                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
   18001                                         userId);
   18002                             }
   18003                             break;
   18004                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
   18005                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
   18006                             break;
   18007                         case Intent.ACTION_PACKAGE_REMOVED:
   18008                         case Intent.ACTION_PACKAGE_CHANGED:
   18009                             Uri data = intent.getData();
   18010                             String ssp;
   18011                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   18012                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
   18013                                 final boolean replacing =
   18014                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
   18015                                 final boolean killProcess =
   18016                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
   18017                                 final boolean fullUninstall = removed && !replacing;
   18018                                 if (removed) {
   18019                                     if (killProcess) {
   18020                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
   18021                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
   18022                                                 false, true, true, false, fullUninstall, userId,
   18023                                                 removed ? "pkg removed" : "pkg changed");
   18024                                     }
   18025                                     final int cmd = killProcess
   18026                                             ? IApplicationThread.PACKAGE_REMOVED
   18027                                             : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
   18028                                     sendPackageBroadcastLocked(cmd,
   18029                                             new String[] {ssp}, userId);
   18030                                     if (fullUninstall) {
   18031                                         mAppOpsService.packageRemoved(
   18032                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
   18033 
   18034                                         // Remove all permissions granted from/to this package
   18035                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
   18036 
   18037                                         removeTasksByPackageNameLocked(ssp, userId);
   18038 
   18039                                         // Hide the "unsupported display" dialog if necessary.
   18040                                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
   18041                                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
   18042                                             mUnsupportedDisplaySizeDialog.dismiss();
   18043                                             mUnsupportedDisplaySizeDialog = null;
   18044                                         }
   18045                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
   18046                                         mBatteryStatsService.notePackageUninstalled(ssp);
   18047                                     }
   18048                                 } else {
   18049                                     if (killProcess) {
   18050                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
   18051                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
   18052                                                 userId, ProcessList.INVALID_ADJ,
   18053                                                 false, true, true, false, "change " + ssp);
   18054                                     }
   18055                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
   18056                                             intent.getStringArrayExtra(
   18057                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
   18058                                 }
   18059                             }
   18060                             break;
   18061                         case Intent.ACTION_PACKAGES_SUSPENDED:
   18062                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
   18063                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
   18064                                     intent.getAction());
   18065                             final String[] packageNames = intent.getStringArrayExtra(
   18066                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
   18067                             final int userHandle = intent.getIntExtra(
   18068                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
   18069 
   18070                             synchronized(ActivityManagerService.this) {
   18071                                 mRecentTasks.onPackagesSuspendedChanged(
   18072                                         packageNames, suspended, userHandle);
   18073                             }
   18074                             break;
   18075                     }
   18076                     break;
   18077                 case Intent.ACTION_PACKAGE_REPLACED:
   18078                 {
   18079                     final Uri data = intent.getData();
   18080                     final String ssp;
   18081                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
   18082                         final ApplicationInfo aInfo =
   18083                                 getPackageManagerInternalLocked().getApplicationInfo(
   18084                                         ssp,
   18085                                         userId);
   18086                         if (aInfo == null) {
   18087                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
   18088                                     + " ssp=" + ssp + " data=" + data);
   18089                             return ActivityManager.BROADCAST_SUCCESS;
   18090                         }
   18091                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
   18092                         sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
   18093                                 new String[] {ssp}, userId);
   18094                     }
   18095                     break;
   18096                 }
   18097                 case Intent.ACTION_PACKAGE_ADDED:
   18098                 {
   18099                     // Special case for adding a package: by default turn on compatibility mode.
   18100                     Uri data = intent.getData();
   18101                     String ssp;
   18102                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
   18103                         final boolean replacing =
   18104                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
   18105                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
   18106 
   18107                         try {
   18108                             ApplicationInfo ai = AppGlobals.getPackageManager().
   18109                                     getApplicationInfo(ssp, 0, 0);
   18110                             mBatteryStatsService.notePackageInstalled(ssp,
   18111                                     ai != null ? ai.versionCode : 0);
   18112                         } catch (RemoteException e) {
   18113                         }
   18114                     }
   18115                     break;
   18116                 }
   18117                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
   18118                 {
   18119                     Uri data = intent.getData();
   18120                     String ssp;
   18121                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
   18122                         // Hide the "unsupported display" dialog if necessary.
   18123                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
   18124                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
   18125                             mUnsupportedDisplaySizeDialog.dismiss();
   18126                             mUnsupportedDisplaySizeDialog = null;
   18127                         }
   18128                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
   18129                     }
   18130                     break;
   18131                 }
   18132                 case Intent.ACTION_TIMEZONE_CHANGED:
   18133                     // If this is the time zone changed action, queue up a message that will reset
   18134                     // the timezone of all currently running processes. This message will get
   18135                     // queued up before the broadcast happens.
   18136                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
   18137                     break;
   18138                 case Intent.ACTION_TIME_CHANGED:
   18139                     // If the user set the time, let all running processes know.
   18140                     final int is24Hour =
   18141                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
   18142                                     : 0;
   18143                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
   18144                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   18145                     synchronized (stats) {
   18146                         stats.noteCurrentTimeChangedLocked();
   18147                     }
   18148                     break;
   18149                 case Intent.ACTION_CLEAR_DNS_CACHE:
   18150                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
   18151                     break;
   18152                 case Proxy.PROXY_CHANGE_ACTION:
   18153                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
   18154                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
   18155                     break;
   18156                 case android.hardware.Camera.ACTION_NEW_PICTURE:
   18157                 case android.hardware.Camera.ACTION_NEW_VIDEO:
   18158                     // These broadcasts are no longer allowed by the system, since they can
   18159                     // cause significant thrashing at a crictical point (using the camera).
   18160                     // Apps should use JobScehduler to monitor for media provider changes.
   18161                     Slog.w(TAG, action + " no longer allowed; dropping from "
   18162                             + UserHandle.formatUid(callingUid));
   18163                     if (resultTo != null) {
   18164                         final BroadcastQueue queue = broadcastQueueForIntent(intent);
   18165                         try {
   18166                             queue.performReceiveLocked(callerApp, resultTo, intent,
   18167                                     Activity.RESULT_CANCELED, null, null,
   18168                                     false, false, userId);
   18169                         } catch (RemoteException e) {
   18170                             Slog.w(TAG, "Failure ["
   18171                                     + queue.mQueueName + "] sending broadcast result of "
   18172                                     + intent, e);
   18173 
   18174                         }
   18175                     }
   18176                     // Lie; we don't want to crash the app.
   18177                     return ActivityManager.BROADCAST_SUCCESS;
   18178             }
   18179         }
   18180 
   18181         // Add to the sticky list if requested.
   18182         if (sticky) {
   18183             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
   18184                     callingPid, callingUid)
   18185                     != PackageManager.PERMISSION_GRANTED) {
   18186                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
   18187                         + callingPid + ", uid=" + callingUid
   18188                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   18189                 Slog.w(TAG, msg);
   18190                 throw new SecurityException(msg);
   18191             }
   18192             if (requiredPermissions != null && requiredPermissions.length > 0) {
   18193                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
   18194                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
   18195                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
   18196             }
   18197             if (intent.getComponent() != null) {
   18198                 throw new SecurityException(
   18199                         "Sticky broadcasts can't target a specific component");
   18200             }
   18201             // We use userId directly here, since the "all" target is maintained
   18202             // as a separate set of sticky broadcasts.
   18203             if (userId != UserHandle.USER_ALL) {
   18204                 // But first, if this is not a broadcast to all users, then
   18205                 // make sure it doesn't conflict with an existing broadcast to
   18206                 // all users.
   18207                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
   18208                         UserHandle.USER_ALL);
   18209                 if (stickies != null) {
   18210                     ArrayList<Intent> list = stickies.get(intent.getAction());
   18211                     if (list != null) {
   18212                         int N = list.size();
   18213                         int i;
   18214                         for (i=0; i<N; i++) {
   18215                             if (intent.filterEquals(list.get(i))) {
   18216                                 throw new IllegalArgumentException(
   18217                                         "Sticky broadcast " + intent + " for user "
   18218                                         + userId + " conflicts with existing global broadcast");
   18219                             }
   18220                         }
   18221                     }
   18222                 }
   18223             }
   18224             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   18225             if (stickies == null) {
   18226                 stickies = new ArrayMap<>();
   18227                 mStickyBroadcasts.put(userId, stickies);
   18228             }
   18229             ArrayList<Intent> list = stickies.get(intent.getAction());
   18230             if (list == null) {
   18231                 list = new ArrayList<>();
   18232                 stickies.put(intent.getAction(), list);
   18233             }
   18234             final int stickiesCount = list.size();
   18235             int i;
   18236             for (i = 0; i < stickiesCount; i++) {
   18237                 if (intent.filterEquals(list.get(i))) {
   18238                     // This sticky already exists, replace it.
   18239                     list.set(i, new Intent(intent));
   18240                     break;
   18241                 }
   18242             }
   18243             if (i >= stickiesCount) {
   18244                 list.add(new Intent(intent));
   18245             }
   18246         }
   18247 
   18248         int[] users;
   18249         if (userId == UserHandle.USER_ALL) {
   18250             // Caller wants broadcast to go to all started users.
   18251             users = mUserController.getStartedUserArrayLocked();
   18252         } else {
   18253             // Caller wants broadcast to go to one specific user.
   18254             users = new int[] {userId};
   18255         }
   18256 
   18257         // Figure out who all will receive this broadcast.
   18258         List receivers = null;
   18259         List<BroadcastFilter> registeredReceivers = null;
   18260         // Need to resolve the intent to interested receivers...
   18261         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
   18262                  == 0) {
   18263             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
   18264         }
   18265         if (intent.getComponent() == null) {
   18266             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
   18267                 // Query one target user at a time, excluding shell-restricted users
   18268                 for (int i = 0; i < users.length; i++) {
   18269                     if (mUserController.hasUserRestriction(
   18270                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
   18271                         continue;
   18272                     }
   18273                     List<BroadcastFilter> registeredReceiversForUser =
   18274                             mReceiverResolver.queryIntent(intent,
   18275                                     resolvedType, false, users[i]);
   18276                     if (registeredReceivers == null) {
   18277                         registeredReceivers = registeredReceiversForUser;
   18278                     } else if (registeredReceiversForUser != null) {
   18279                         registeredReceivers.addAll(registeredReceiversForUser);
   18280                     }
   18281                 }
   18282             } else {
   18283                 registeredReceivers = mReceiverResolver.queryIntent(intent,
   18284                         resolvedType, false, userId);
   18285             }
   18286         }
   18287 
   18288         final boolean replacePending =
   18289                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
   18290 
   18291         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
   18292                 + " replacePending=" + replacePending);
   18293 
   18294         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
   18295         if (!ordered && NR > 0) {
   18296             // If we are not serializing this broadcast, then send the
   18297             // registered receivers separately so they don't wait for the
   18298             // components to be launched.
   18299             if (isCallerSystem) {
   18300                 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
   18301                         isProtectedBroadcast, registeredReceivers);
   18302             }
   18303             final BroadcastQueue queue = broadcastQueueForIntent(intent);
   18304             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   18305                     callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
   18306                     appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
   18307                     resultExtras, ordered, sticky, false, userId);
   18308             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
   18309             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
   18310             if (!replaced) {
   18311                 queue.enqueueParallelBroadcastLocked(r);
   18312                 queue.scheduleBroadcastsLocked();
   18313             }
   18314             registeredReceivers = null;
   18315             NR = 0;
   18316         }
   18317 
   18318         // Merge into one list.
   18319         int ir = 0;
   18320         if (receivers != null) {
   18321             // A special case for PACKAGE_ADDED: do not allow the package
   18322             // being added to see this broadcast.  This prevents them from
   18323             // using this as a back door to get run as soon as they are
   18324             // installed.  Maybe in the future we want to have a special install
   18325             // broadcast or such for apps, but we'd like to deliberately make
   18326             // this decision.
   18327             String skipPackages[] = null;
   18328             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
   18329                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
   18330                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
   18331                 Uri data = intent.getData();
   18332                 if (data != null) {
   18333                     String pkgName = data.getSchemeSpecificPart();
   18334                     if (pkgName != null) {
   18335                         skipPackages = new String[] { pkgName };
   18336                     }
   18337                 }
   18338             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
   18339                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   18340             }
   18341             if (skipPackages != null && (skipPackages.length > 0)) {
   18342                 for (String skipPackage : skipPackages) {
   18343                     if (skipPackage != null) {
   18344                         int NT = receivers.size();
   18345                         for (int it=0; it<NT; it++) {
   18346                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
   18347                             if (curt.activityInfo.packageName.equals(skipPackage)) {
   18348                                 receivers.remove(it);
   18349                                 it--;
   18350                                 NT--;
   18351                             }
   18352                         }
   18353                     }
   18354                 }
   18355             }
   18356 
   18357             int NT = receivers != null ? receivers.size() : 0;
   18358             int it = 0;
   18359             ResolveInfo curt = null;
   18360             BroadcastFilter curr = null;
   18361             while (it < NT && ir < NR) {
   18362                 if (curt == null) {
   18363                     curt = (ResolveInfo)receivers.get(it);
   18364                 }
   18365                 if (curr == null) {
   18366                     curr = registeredReceivers.get(ir);
   18367                 }
   18368                 if (curr.getPriority() >= curt.priority) {
   18369                     // Insert this broadcast record into the final list.
   18370                     receivers.add(it, curr);
   18371                     ir++;
   18372                     curr = null;
   18373                     it++;
   18374                     NT++;
   18375                 } else {
   18376                     // Skip to the next ResolveInfo in the final list.
   18377                     it++;
   18378                     curt = null;
   18379                 }
   18380             }
   18381         }
   18382         while (ir < NR) {
   18383             if (receivers == null) {
   18384                 receivers = new ArrayList();
   18385             }
   18386             receivers.add(registeredReceivers.get(ir));
   18387             ir++;
   18388         }
   18389 
   18390         if (isCallerSystem) {
   18391             checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
   18392                     isProtectedBroadcast, receivers);
   18393         }
   18394 
   18395         if ((receivers != null && receivers.size() > 0)
   18396                 || resultTo != null) {
   18397             BroadcastQueue queue = broadcastQueueForIntent(intent);
   18398             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   18399                     callerPackage, callingPid, callingUid, resolvedType,
   18400                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
   18401                     resultData, resultExtras, ordered, sticky, false, userId);
   18402 
   18403             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
   18404                     + ": prev had " + queue.mOrderedBroadcasts.size());
   18405             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
   18406                     "Enqueueing broadcast " + r.intent.getAction());
   18407 
   18408             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
   18409             if (!replaced) {
   18410                 queue.enqueueOrderedBroadcastLocked(r);
   18411                 queue.scheduleBroadcastsLocked();
   18412             }
   18413         } else {
   18414             // There was nobody interested in the broadcast, but we still want to record
   18415             // that it happened.
   18416             if (intent.getComponent() == null && intent.getPackage() == null
   18417                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   18418                 // This was an implicit broadcast... let's record it for posterity.
   18419                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
   18420             }
   18421         }
   18422 
   18423         return ActivityManager.BROADCAST_SUCCESS;
   18424     }
   18425 
   18426     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
   18427             int skipCount, long dispatchTime) {
   18428         final long now = SystemClock.elapsedRealtime();
   18429         if (mCurBroadcastStats == null ||
   18430                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
   18431             mLastBroadcastStats = mCurBroadcastStats;
   18432             if (mLastBroadcastStats != null) {
   18433                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
   18434                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
   18435             }
   18436             mCurBroadcastStats = new BroadcastStats();
   18437         }
   18438         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
   18439     }
   18440 
   18441     final Intent verifyBroadcastLocked(Intent intent) {
   18442         // Refuse possible leaked file descriptors
   18443         if (intent != null && intent.hasFileDescriptors() == true) {
   18444             throw new IllegalArgumentException("File descriptors passed in Intent");
   18445         }
   18446 
   18447         int flags = intent.getFlags();
   18448 
   18449         if (!mProcessesReady) {
   18450             // if the caller really truly claims to know what they're doing, go
   18451             // ahead and allow the broadcast without launching any receivers
   18452             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
   18453                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
   18454             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   18455                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
   18456                         + " before boot completion");
   18457                 throw new IllegalStateException("Cannot broadcast before boot completed");
   18458             }
   18459         }
   18460 
   18461         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   18462             throw new IllegalArgumentException(
   18463                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   18464         }
   18465 
   18466         return intent;
   18467     }
   18468 
   18469     public final int broadcastIntent(IApplicationThread caller,
   18470             Intent intent, String resolvedType, IIntentReceiver resultTo,
   18471             int resultCode, String resultData, Bundle resultExtras,
   18472             String[] requiredPermissions, int appOp, Bundle bOptions,
   18473             boolean serialized, boolean sticky, int userId) {
   18474         enforceNotIsolatedCaller("broadcastIntent");
   18475         synchronized(this) {
   18476             intent = verifyBroadcastLocked(intent);
   18477 
   18478             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   18479             final int callingPid = Binder.getCallingPid();
   18480             final int callingUid = Binder.getCallingUid();
   18481             final long origId = Binder.clearCallingIdentity();
   18482             int res = broadcastIntentLocked(callerApp,
   18483                     callerApp != null ? callerApp.info.packageName : null,
   18484                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
   18485                     requiredPermissions, appOp, bOptions, serialized, sticky,
   18486                     callingPid, callingUid, userId);
   18487             Binder.restoreCallingIdentity(origId);
   18488             return res;
   18489         }
   18490     }
   18491 
   18492 
   18493     int broadcastIntentInPackage(String packageName, int uid,
   18494             Intent intent, String resolvedType, IIntentReceiver resultTo,
   18495             int resultCode, String resultData, Bundle resultExtras,
   18496             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
   18497             int userId) {
   18498         synchronized(this) {
   18499             intent = verifyBroadcastLocked(intent);
   18500 
   18501             final long origId = Binder.clearCallingIdentity();
   18502             String[] requiredPermissions = requiredPermission == null ? null
   18503                     : new String[] {requiredPermission};
   18504             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
   18505                     resultTo, resultCode, resultData, resultExtras,
   18506                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
   18507                     sticky, -1, uid, userId);
   18508             Binder.restoreCallingIdentity(origId);
   18509             return res;
   18510         }
   18511     }
   18512 
   18513     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
   18514         // Refuse possible leaked file descriptors
   18515         if (intent != null && intent.hasFileDescriptors() == true) {
   18516             throw new IllegalArgumentException("File descriptors passed in Intent");
   18517         }
   18518 
   18519         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   18520                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
   18521 
   18522         synchronized(this) {
   18523             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
   18524                     != PackageManager.PERMISSION_GRANTED) {
   18525                 String msg = "Permission Denial: unbroadcastIntent() from pid="
   18526                         + Binder.getCallingPid()
   18527                         + ", uid=" + Binder.getCallingUid()
   18528                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   18529                 Slog.w(TAG, msg);
   18530                 throw new SecurityException(msg);
   18531             }
   18532             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   18533             if (stickies != null) {
   18534                 ArrayList<Intent> list = stickies.get(intent.getAction());
   18535                 if (list != null) {
   18536                     int N = list.size();
   18537                     int i;
   18538                     for (i=0; i<N; i++) {
   18539                         if (intent.filterEquals(list.get(i))) {
   18540                             list.remove(i);
   18541                             break;
   18542                         }
   18543                     }
   18544                     if (list.size() <= 0) {
   18545                         stickies.remove(intent.getAction());
   18546                     }
   18547                 }
   18548                 if (stickies.size() <= 0) {
   18549                     mStickyBroadcasts.remove(userId);
   18550                 }
   18551             }
   18552         }
   18553     }
   18554 
   18555     void backgroundServicesFinishedLocked(int userId) {
   18556         for (BroadcastQueue queue : mBroadcastQueues) {
   18557             queue.backgroundServicesFinishedLocked(userId);
   18558         }
   18559     }
   18560 
   18561     public void finishReceiver(IBinder who, int resultCode, String resultData,
   18562             Bundle resultExtras, boolean resultAbort, int flags) {
   18563         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
   18564 
   18565         // Refuse possible leaked file descriptors
   18566         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
   18567             throw new IllegalArgumentException("File descriptors passed in Bundle");
   18568         }
   18569 
   18570         final long origId = Binder.clearCallingIdentity();
   18571         try {
   18572             boolean doNext = false;
   18573             BroadcastRecord r;
   18574 
   18575             synchronized(this) {
   18576                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
   18577                         ? mFgBroadcastQueue : mBgBroadcastQueue;
   18578                 r = queue.getMatchingOrderedReceiver(who);
   18579                 if (r != null) {
   18580                     doNext = r.queue.finishReceiverLocked(r, resultCode,
   18581                         resultData, resultExtras, resultAbort, true);
   18582                 }
   18583             }
   18584 
   18585             if (doNext) {
   18586                 r.queue.processNextBroadcast(false);
   18587             }
   18588             trimApplications();
   18589         } finally {
   18590             Binder.restoreCallingIdentity(origId);
   18591         }
   18592     }
   18593 
   18594     // =========================================================
   18595     // INSTRUMENTATION
   18596     // =========================================================
   18597 
   18598     public boolean startInstrumentation(ComponentName className,
   18599             String profileFile, int flags, Bundle arguments,
   18600             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
   18601             int userId, String abiOverride) {
   18602         enforceNotIsolatedCaller("startInstrumentation");
   18603         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   18604                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
   18605         // Refuse possible leaked file descriptors
   18606         if (arguments != null && arguments.hasFileDescriptors()) {
   18607             throw new IllegalArgumentException("File descriptors passed in Bundle");
   18608         }
   18609 
   18610         synchronized(this) {
   18611             InstrumentationInfo ii = null;
   18612             ApplicationInfo ai = null;
   18613             try {
   18614                 ii = mContext.getPackageManager().getInstrumentationInfo(
   18615                     className, STOCK_PM_FLAGS);
   18616                 ai = AppGlobals.getPackageManager().getApplicationInfo(
   18617                         ii.targetPackage, STOCK_PM_FLAGS, userId);
   18618             } catch (PackageManager.NameNotFoundException e) {
   18619             } catch (RemoteException e) {
   18620             }
   18621             if (ii == null) {
   18622                 reportStartInstrumentationFailureLocked(watcher, className,
   18623                         "Unable to find instrumentation info for: " + className);
   18624                 return false;
   18625             }
   18626             if (ai == null) {
   18627                 reportStartInstrumentationFailureLocked(watcher, className,
   18628                         "Unable to find instrumentation target package: " + ii.targetPackage);
   18629                 return false;
   18630             }
   18631             if (!ai.hasCode()) {
   18632                 reportStartInstrumentationFailureLocked(watcher, className,
   18633                         "Instrumentation target has no code: " + ii.targetPackage);
   18634                 return false;
   18635             }
   18636 
   18637             int match = mContext.getPackageManager().checkSignatures(
   18638                     ii.targetPackage, ii.packageName);
   18639             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
   18640                 String msg = "Permission Denial: starting instrumentation "
   18641                         + className + " from pid="
   18642                         + Binder.getCallingPid()
   18643                         + ", uid=" + Binder.getCallingPid()
   18644                         + " not allowed because package " + ii.packageName
   18645                         + " does not have a signature matching the target "
   18646                         + ii.targetPackage;
   18647                 reportStartInstrumentationFailureLocked(watcher, className, msg);
   18648                 throw new SecurityException(msg);
   18649             }
   18650 
   18651             final long origId = Binder.clearCallingIdentity();
   18652             // Instrumentation can kill and relaunch even persistent processes
   18653             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
   18654                     "start instr");
   18655             ProcessRecord app = addAppLocked(ai, false, abiOverride);
   18656             app.instrumentationClass = className;
   18657             app.instrumentationInfo = ai;
   18658             app.instrumentationProfileFile = profileFile;
   18659             app.instrumentationArguments = arguments;
   18660             app.instrumentationWatcher = watcher;
   18661             app.instrumentationUiAutomationConnection = uiAutomationConnection;
   18662             app.instrumentationResultClass = className;
   18663             Binder.restoreCallingIdentity(origId);
   18664         }
   18665 
   18666         return true;
   18667     }
   18668 
   18669     /**
   18670      * Report errors that occur while attempting to start Instrumentation.  Always writes the
   18671      * error to the logs, but if somebody is watching, send the report there too.  This enables
   18672      * the "am" command to report errors with more information.
   18673      *
   18674      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
   18675      * @param cn The component name of the instrumentation.
   18676      * @param report The error report.
   18677      */
   18678     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
   18679             ComponentName cn, String report) {
   18680         Slog.w(TAG, report);
   18681         if (watcher != null) {
   18682             Bundle results = new Bundle();
   18683             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
   18684             results.putString("Error", report);
   18685             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
   18686         }
   18687     }
   18688 
   18689     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
   18690         if (app.instrumentationWatcher != null) {
   18691             mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
   18692                     app.instrumentationClass, resultCode, results);
   18693         }
   18694 
   18695         // Can't call out of the system process with a lock held, so post a message.
   18696         if (app.instrumentationUiAutomationConnection != null) {
   18697             mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
   18698                     app.instrumentationUiAutomationConnection).sendToTarget();
   18699         }
   18700 
   18701         app.instrumentationWatcher = null;
   18702         app.instrumentationUiAutomationConnection = null;
   18703         app.instrumentationClass = null;
   18704         app.instrumentationInfo = null;
   18705         app.instrumentationProfileFile = null;
   18706         app.instrumentationArguments = null;
   18707 
   18708         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
   18709                 "finished inst");
   18710     }
   18711 
   18712     public void finishInstrumentation(IApplicationThread target,
   18713             int resultCode, Bundle results) {
   18714         int userId = UserHandle.getCallingUserId();
   18715         // Refuse possible leaked file descriptors
   18716         if (results != null && results.hasFileDescriptors()) {
   18717             throw new IllegalArgumentException("File descriptors passed in Intent");
   18718         }
   18719 
   18720         synchronized(this) {
   18721             ProcessRecord app = getRecordForAppLocked(target);
   18722             if (app == null) {
   18723                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
   18724                 return;
   18725             }
   18726             final long origId = Binder.clearCallingIdentity();
   18727             finishInstrumentationLocked(app, resultCode, results);
   18728             Binder.restoreCallingIdentity(origId);
   18729         }
   18730     }
   18731 
   18732     // =========================================================
   18733     // CONFIGURATION
   18734     // =========================================================
   18735 
   18736     public ConfigurationInfo getDeviceConfigurationInfo() {
   18737         ConfigurationInfo config = new ConfigurationInfo();
   18738         synchronized (this) {
   18739             config.reqTouchScreen = mConfiguration.touchscreen;
   18740             config.reqKeyboardType = mConfiguration.keyboard;
   18741             config.reqNavigation = mConfiguration.navigation;
   18742             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
   18743                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
   18744                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
   18745             }
   18746             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
   18747                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
   18748                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
   18749             }
   18750             config.reqGlEsVersion = GL_ES_VERSION;
   18751         }
   18752         return config;
   18753     }
   18754 
   18755     ActivityStack getFocusedStack() {
   18756         return mStackSupervisor.getFocusedStack();
   18757     }
   18758 
   18759     @Override
   18760     public int getFocusedStackId() throws RemoteException {
   18761         ActivityStack focusedStack = getFocusedStack();
   18762         if (focusedStack != null) {
   18763             return focusedStack.getStackId();
   18764         }
   18765         return -1;
   18766     }
   18767 
   18768     public Configuration getConfiguration() {
   18769         Configuration ci;
   18770         synchronized(this) {
   18771             ci = new Configuration(mConfiguration);
   18772             ci.userSetLocale = false;
   18773         }
   18774         return ci;
   18775     }
   18776 
   18777     @Override
   18778     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
   18779         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
   18780         synchronized (this) {
   18781             mSuppressResizeConfigChanges = suppress;
   18782         }
   18783     }
   18784 
   18785     @Override
   18786     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
   18787         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
   18788         if (fromStackId == HOME_STACK_ID) {
   18789             throw new IllegalArgumentException("You can't move tasks from the home stack.");
   18790         }
   18791         synchronized (this) {
   18792             final long origId = Binder.clearCallingIdentity();
   18793             try {
   18794                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
   18795             } finally {
   18796                 Binder.restoreCallingIdentity(origId);
   18797             }
   18798         }
   18799     }
   18800 
   18801     @Override
   18802     public void updatePersistentConfiguration(Configuration values) {
   18803         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   18804                 "updateConfiguration()");
   18805         enforceWriteSettingsPermission("updateConfiguration()");
   18806         if (values == null) {
   18807             throw new NullPointerException("Configuration must not be null");
   18808         }
   18809 
   18810         int userId = UserHandle.getCallingUserId();
   18811 
   18812         synchronized(this) {
   18813             updatePersistentConfigurationLocked(values, userId);
   18814         }
   18815     }
   18816 
   18817     private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
   18818         final long origId = Binder.clearCallingIdentity();
   18819         try {
   18820             updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
   18821         } finally {
   18822             Binder.restoreCallingIdentity(origId);
   18823         }
   18824     }
   18825 
   18826     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
   18827         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
   18828                 FONT_SCALE, 1.0f, userId);
   18829         if (mConfiguration.fontScale != scaleFactor) {
   18830             final Configuration configuration = mWindowManager.computeNewConfiguration();
   18831             configuration.fontScale = scaleFactor;
   18832             synchronized (this) {
   18833                 updatePersistentConfigurationLocked(configuration, userId);
   18834             }
   18835         }
   18836     }
   18837 
   18838     private void enforceWriteSettingsPermission(String func) {
   18839         int uid = Binder.getCallingUid();
   18840         if (uid == Process.ROOT_UID) {
   18841             return;
   18842         }
   18843 
   18844         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
   18845                 Settings.getPackageNameForUid(mContext, uid), false)) {
   18846             return;
   18847         }
   18848 
   18849         String msg = "Permission Denial: " + func + " from pid="
   18850                 + Binder.getCallingPid()
   18851                 + ", uid=" + uid
   18852                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
   18853         Slog.w(TAG, msg);
   18854         throw new SecurityException(msg);
   18855     }
   18856 
   18857     public void updateConfiguration(Configuration values) {
   18858         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   18859                 "updateConfiguration()");
   18860 
   18861         synchronized(this) {
   18862             if (values == null && mWindowManager != null) {
   18863                 // sentinel: fetch the current configuration from the window manager
   18864                 values = mWindowManager.computeNewConfiguration();
   18865             }
   18866 
   18867             if (mWindowManager != null) {
   18868                 mProcessList.applyDisplaySize(mWindowManager);
   18869             }
   18870 
   18871             final long origId = Binder.clearCallingIdentity();
   18872             if (values != null) {
   18873                 Settings.System.clearConfiguration(values);
   18874             }
   18875             updateConfigurationLocked(values, null, false);
   18876             Binder.restoreCallingIdentity(origId);
   18877         }
   18878     }
   18879 
   18880     void updateUserConfigurationLocked() {
   18881         Configuration configuration = new Configuration(mConfiguration);
   18882         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
   18883                 mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
   18884         updateConfigurationLocked(configuration, null, false);
   18885     }
   18886 
   18887     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
   18888             boolean initLocale) {
   18889         return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
   18890     }
   18891 
   18892     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
   18893             boolean initLocale, boolean deferResume) {
   18894         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
   18895         return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
   18896                 UserHandle.USER_NULL, deferResume);
   18897     }
   18898 
   18899     // To cache the list of supported system locales
   18900     private String[] mSupportedSystemLocales = null;
   18901 
   18902     /**
   18903      * Do either or both things: (1) change the current configuration, and (2)
   18904      * make sure the given activity is running with the (now) current
   18905      * configuration.  Returns true if the activity has been left running, or
   18906      * false if <var>starting</var> is being destroyed to match the new
   18907      * configuration.
   18908      *
   18909      * @param userId is only used when persistent parameter is set to true to persist configuration
   18910      *               for that particular user
   18911      */
   18912     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
   18913             boolean initLocale, boolean persistent, int userId, boolean deferResume) {
   18914         int changes = 0;
   18915 
   18916         if (mWindowManager != null) {
   18917             mWindowManager.deferSurfaceLayout();
   18918         }
   18919         if (values != null) {
   18920             Configuration newConfig = new Configuration(mConfiguration);
   18921             changes = newConfig.updateFrom(values);
   18922             if (changes != 0) {
   18923                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
   18924                         "Updating configuration to: " + values);
   18925 
   18926                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
   18927 
   18928                 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
   18929                     final LocaleList locales = values.getLocales();
   18930                     int bestLocaleIndex = 0;
   18931                     if (locales.size() > 1) {
   18932                         if (mSupportedSystemLocales == null) {
   18933                             mSupportedSystemLocales =
   18934                                     Resources.getSystem().getAssets().getLocales();
   18935                         }
   18936                         bestLocaleIndex = Math.max(0,
   18937                                 locales.getFirstMatchIndex(mSupportedSystemLocales));
   18938                     }
   18939                     SystemProperties.set("persist.sys.locale",
   18940                             locales.get(bestLocaleIndex).toLanguageTag());
   18941                     LocaleList.setDefault(locales, bestLocaleIndex);
   18942                     mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
   18943                             locales.get(bestLocaleIndex)));
   18944                 }
   18945 
   18946                 mConfigurationSeq++;
   18947                 if (mConfigurationSeq <= 0) {
   18948                     mConfigurationSeq = 1;
   18949                 }
   18950                 newConfig.seq = mConfigurationSeq;
   18951                 mConfiguration = newConfig;
   18952                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
   18953                 mUsageStatsService.reportConfigurationChange(newConfig,
   18954                         mUserController.getCurrentUserIdLocked());
   18955                 //mUsageStatsService.noteStartConfig(newConfig);
   18956 
   18957                 final Configuration configCopy = new Configuration(mConfiguration);
   18958 
   18959                 // TODO: If our config changes, should we auto dismiss any currently
   18960                 // showing dialogs?
   18961                 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
   18962 
   18963                 AttributeCache ac = AttributeCache.instance();
   18964                 if (ac != null) {
   18965                     ac.updateConfiguration(configCopy);
   18966                 }
   18967 
   18968                 // Make sure all resources in our process are updated
   18969                 // right now, so that anyone who is going to retrieve
   18970                 // resource values after we return will be sure to get
   18971                 // the new ones.  This is especially important during
   18972                 // boot, where the first config change needs to guarantee
   18973                 // all resources have that config before following boot
   18974                 // code is executed.
   18975                 mSystemThread.applyConfigurationToResources(configCopy);
   18976 
   18977                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
   18978                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
   18979                     msg.obj = new Configuration(configCopy);
   18980                     msg.arg1 = userId;
   18981                     mHandler.sendMessage(msg);
   18982                 }
   18983 
   18984                 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
   18985                 if (isDensityChange) {
   18986                     // Reset the unsupported display size dialog.
   18987                     mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
   18988 
   18989                     killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
   18990                             ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
   18991                 }
   18992 
   18993                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   18994                     ProcessRecord app = mLruProcesses.get(i);
   18995                     try {
   18996                         if (app.thread != null) {
   18997                             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
   18998                                     + app.processName + " new config " + mConfiguration);
   18999                             app.thread.scheduleConfigurationChanged(configCopy);
   19000                         }
   19001                     } catch (Exception e) {
   19002                     }
   19003                 }
   19004                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
   19005                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   19006                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
   19007                         | Intent.FLAG_RECEIVER_FOREGROUND);
   19008                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
   19009                         null, AppOpsManager.OP_NONE, null, false, false,
   19010                         MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   19011                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
   19012                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
   19013                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   19014                     if (!mProcessesReady) {
   19015                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   19016                     }
   19017                     broadcastIntentLocked(null, null, intent,
   19018                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   19019                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   19020                 }
   19021             }
   19022             // Update the configuration with WM first and check if any of the stacks need to be
   19023             // resized due to the configuration change. If so, resize the stacks now and do any
   19024             // relaunches if necessary. This way we don't need to relaunch again below in
   19025             // ensureActivityConfigurationLocked().
   19026             if (mWindowManager != null) {
   19027                 final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
   19028                 if (resizedStacks != null) {
   19029                     for (int stackId : resizedStacks) {
   19030                         final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
   19031                         mStackSupervisor.resizeStackLocked(
   19032                                 stackId, newBounds, null, null, false, false, deferResume);
   19033                     }
   19034                 }
   19035             }
   19036         }
   19037 
   19038         boolean kept = true;
   19039         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
   19040         // mainStack is null during startup.
   19041         if (mainStack != null) {
   19042             if (changes != 0 && starting == null) {
   19043                 // If the configuration changed, and the caller is not already
   19044                 // in the process of starting an activity, then find the top
   19045                 // activity to check if its configuration needs to change.
   19046                 starting = mainStack.topRunningActivityLocked();
   19047             }
   19048 
   19049             if (starting != null) {
   19050                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
   19051                 // And we need to make sure at this point that all other activities
   19052                 // are made visible with the correct configuration.
   19053                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
   19054                         !PRESERVE_WINDOWS);
   19055             }
   19056         }
   19057         if (mWindowManager != null) {
   19058             mWindowManager.continueSurfaceLayout();
   19059         }
   19060         return kept;
   19061     }
   19062 
   19063     /**
   19064      * Decide based on the configuration whether we should shouw the ANR,
   19065      * crash, etc dialogs.  The idea is that if there is no affordence to
   19066      * press the on-screen buttons, or the user experience would be more
   19067      * greatly impacted than the crash itself, we shouldn't show the dialog.
   19068      *
   19069      * A thought: SystemUI might also want to get told about this, the Power
   19070      * dialog / global actions also might want different behaviors.
   19071      */
   19072     private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
   19073         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
   19074                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
   19075                                    && config.navigation == Configuration.NAVIGATION_NONAV);
   19076         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
   19077         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
   19078                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
   19079         return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
   19080     }
   19081 
   19082     @Override
   19083     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
   19084         synchronized (this) {
   19085             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
   19086             if (srec != null) {
   19087                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
   19088             }
   19089         }
   19090         return false;
   19091     }
   19092 
   19093     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
   19094             Intent resultData) {
   19095 
   19096         synchronized (this) {
   19097             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   19098             if (r != null) {
   19099                 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
   19100             }
   19101             return false;
   19102         }
   19103     }
   19104 
   19105     public int getLaunchedFromUid(IBinder activityToken) {
   19106         ActivityRecord srec;
   19107         synchronized (this) {
   19108             srec = ActivityRecord.forTokenLocked(activityToken);
   19109         }
   19110         if (srec == null) {
   19111             return -1;
   19112         }
   19113         return srec.launchedFromUid;
   19114     }
   19115 
   19116     public String getLaunchedFromPackage(IBinder activityToken) {
   19117         ActivityRecord srec;
   19118         synchronized (this) {
   19119             srec = ActivityRecord.forTokenLocked(activityToken);
   19120         }
   19121         if (srec == null) {
   19122             return null;
   19123         }
   19124         return srec.launchedFromPackage;
   19125     }
   19126 
   19127     // =========================================================
   19128     // LIFETIME MANAGEMENT
   19129     // =========================================================
   19130 
   19131     // Returns which broadcast queue the app is the current [or imminent] receiver
   19132     // on, or 'null' if the app is not an active broadcast recipient.
   19133     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
   19134         BroadcastRecord r = app.curReceiver;
   19135         if (r != null) {
   19136             return r.queue;
   19137         }
   19138 
   19139         // It's not the current receiver, but it might be starting up to become one
   19140         synchronized (this) {
   19141             for (BroadcastQueue queue : mBroadcastQueues) {
   19142                 r = queue.mPendingBroadcast;
   19143                 if (r != null && r.curApp == app) {
   19144                     // found it; report which queue it's in
   19145                     return queue;
   19146                 }
   19147             }
   19148         }
   19149 
   19150         return null;
   19151     }
   19152 
   19153     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
   19154             int targetUid, ComponentName targetComponent, String targetProcess) {
   19155         if (!mTrackingAssociations) {
   19156             return null;
   19157         }
   19158         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
   19159                 = mAssociations.get(targetUid);
   19160         if (components == null) {
   19161             components = new ArrayMap<>();
   19162             mAssociations.put(targetUid, components);
   19163         }
   19164         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
   19165         if (sourceUids == null) {
   19166             sourceUids = new SparseArray<>();
   19167             components.put(targetComponent, sourceUids);
   19168         }
   19169         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
   19170         if (sourceProcesses == null) {
   19171             sourceProcesses = new ArrayMap<>();
   19172             sourceUids.put(sourceUid, sourceProcesses);
   19173         }
   19174         Association ass = sourceProcesses.get(sourceProcess);
   19175         if (ass == null) {
   19176             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
   19177                     targetProcess);
   19178             sourceProcesses.put(sourceProcess, ass);
   19179         }
   19180         ass.mCount++;
   19181         ass.mNesting++;
   19182         if (ass.mNesting == 1) {
   19183             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
   19184             ass.mLastState = sourceState;
   19185         }
   19186         return ass;
   19187     }
   19188 
   19189     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
   19190             ComponentName targetComponent) {
   19191         if (!mTrackingAssociations) {
   19192             return;
   19193         }
   19194         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
   19195                 = mAssociations.get(targetUid);
   19196         if (components == null) {
   19197             return;
   19198         }
   19199         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
   19200         if (sourceUids == null) {
   19201             return;
   19202         }
   19203         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
   19204         if (sourceProcesses == null) {
   19205             return;
   19206         }
   19207         Association ass = sourceProcesses.get(sourceProcess);
   19208         if (ass == null || ass.mNesting <= 0) {
   19209             return;
   19210         }
   19211         ass.mNesting--;
   19212         if (ass.mNesting == 0) {
   19213             long uptime = SystemClock.uptimeMillis();
   19214             ass.mTime += uptime - ass.mStartTime;
   19215             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
   19216                     += uptime - ass.mLastStateUptime;
   19217             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
   19218         }
   19219     }
   19220 
   19221     private void noteUidProcessState(final int uid, final int state) {
   19222         mBatteryStatsService.noteUidProcessState(uid, state);
   19223         if (mTrackingAssociations) {
   19224             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
   19225                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
   19226                         = mAssociations.valueAt(i1);
   19227                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
   19228                     SparseArray<ArrayMap<String, Association>> sourceUids
   19229                             = targetComponents.valueAt(i2);
   19230                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
   19231                     if (sourceProcesses != null) {
   19232                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
   19233                             Association ass = sourceProcesses.valueAt(i4);
   19234                             if (ass.mNesting >= 1) {
   19235                                 // currently associated
   19236                                 long uptime = SystemClock.uptimeMillis();
   19237                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
   19238                                         += uptime - ass.mLastStateUptime;
   19239                                 ass.mLastState = state;
   19240                                 ass.mLastStateUptime = uptime;
   19241                             }
   19242                         }
   19243                     }
   19244                 }
   19245             }
   19246         }
   19247     }
   19248 
   19249     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
   19250             boolean doingAll, long now) {
   19251         if (mAdjSeq == app.adjSeq) {
   19252             // This adjustment has already been computed.
   19253             return app.curRawAdj;
   19254         }
   19255 
   19256         if (app.thread == null) {
   19257             app.adjSeq = mAdjSeq;
   19258             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   19259             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   19260             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
   19261         }
   19262 
   19263         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
   19264         app.adjSource = null;
   19265         app.adjTarget = null;
   19266         app.empty = false;
   19267         app.cached = false;
   19268 
   19269         final int activitiesSize = app.activities.size();
   19270 
   19271         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   19272             // The max adjustment doesn't allow this app to be anything
   19273             // below foreground, so it is not worth doing work for it.
   19274             app.adjType = "fixed";
   19275             app.adjSeq = mAdjSeq;
   19276             app.curRawAdj = app.maxAdj;
   19277             app.foregroundActivities = false;
   19278             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19279             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
   19280             // System processes can do UI, and when they do we want to have
   19281             // them trim their memory after the user leaves the UI.  To
   19282             // facilitate this, here we need to determine whether or not it
   19283             // is currently showing UI.
   19284             app.systemNoUi = true;
   19285             if (app == TOP_APP) {
   19286                 app.systemNoUi = false;
   19287                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
   19288                 app.adjType = "pers-top-activity";
   19289             } else if (app.hasTopUi) {
   19290                 app.systemNoUi = false;
   19291                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
   19292                 app.adjType = "pers-top-ui";
   19293             } else if (activitiesSize > 0) {
   19294                 for (int j = 0; j < activitiesSize; j++) {
   19295                     final ActivityRecord r = app.activities.get(j);
   19296                     if (r.visible) {
   19297                         app.systemNoUi = false;
   19298                     }
   19299                 }
   19300             }
   19301             if (!app.systemNoUi) {
   19302                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
   19303             }
   19304             return (app.curAdj=app.maxAdj);
   19305         }
   19306 
   19307         app.systemNoUi = false;
   19308 
   19309         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
   19310 
   19311         // Determine the importance of the process, starting with most
   19312         // important to least, and assign an appropriate OOM adjustment.
   19313         int adj;
   19314         int schedGroup;
   19315         int procState;
   19316         boolean foregroundActivities = false;
   19317         BroadcastQueue queue;
   19318         if (app == TOP_APP) {
   19319             // The last app on the list is the foreground app.
   19320             adj = ProcessList.FOREGROUND_APP_ADJ;
   19321             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
   19322             app.adjType = "top-activity";
   19323             foregroundActivities = true;
   19324             procState = PROCESS_STATE_CUR_TOP;
   19325         } else if (app.instrumentationClass != null) {
   19326             // Don't want to kill running instrumentation.
   19327             adj = ProcessList.FOREGROUND_APP_ADJ;
   19328             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19329             app.adjType = "instrumentation";
   19330             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
   19331         } else if ((queue = isReceivingBroadcast(app)) != null) {
   19332             // An app that is currently receiving a broadcast also
   19333             // counts as being in the foreground for OOM killer purposes.
   19334             // It's placed in a sched group based on the nature of the
   19335             // broadcast as reflected by which queue it's active in.
   19336             adj = ProcessList.FOREGROUND_APP_ADJ;
   19337             schedGroup = (queue == mFgBroadcastQueue)
   19338                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
   19339             app.adjType = "broadcast";
   19340             procState = ActivityManager.PROCESS_STATE_RECEIVER;
   19341         } else if (app.executingServices.size() > 0) {
   19342             // An app that is currently executing a service callback also
   19343             // counts as being in the foreground.
   19344             adj = ProcessList.FOREGROUND_APP_ADJ;
   19345             schedGroup = app.execServicesFg ?
   19346                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
   19347             app.adjType = "exec-service";
   19348             procState = ActivityManager.PROCESS_STATE_SERVICE;
   19349             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
   19350         } else {
   19351             // As far as we know the process is empty.  We may change our mind later.
   19352             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   19353             // At this point we don't actually know the adjustment.  Use the cached adj
   19354             // value that the caller wants us to.
   19355             adj = cachedAdj;
   19356             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   19357             app.cached = true;
   19358             app.empty = true;
   19359             app.adjType = "cch-empty";
   19360         }
   19361 
   19362         // Examine all activities if not already foreground.
   19363         if (!foregroundActivities && activitiesSize > 0) {
   19364             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
   19365             for (int j = 0; j < activitiesSize; j++) {
   19366                 final ActivityRecord r = app.activities.get(j);
   19367                 if (r.app != app) {
   19368                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
   19369                             + " instead of expected " + app);
   19370                     if (r.app == null || (r.app.uid == app.uid)) {
   19371                         // Only fix things up when they look sane
   19372                         r.app = app;
   19373                     } else {
   19374                         continue;
   19375                     }
   19376                 }
   19377                 if (r.visible) {
   19378                     // App has a visible activity; only upgrade adjustment.
   19379                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   19380                         adj = ProcessList.VISIBLE_APP_ADJ;
   19381                         app.adjType = "visible";
   19382                     }
   19383                     if (procState > PROCESS_STATE_CUR_TOP) {
   19384                         procState = PROCESS_STATE_CUR_TOP;
   19385                     }
   19386                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19387                     app.cached = false;
   19388                     app.empty = false;
   19389                     foregroundActivities = true;
   19390                     if (r.task != null && minLayer > 0) {
   19391                         final int layer = r.task.mLayerRank;
   19392                         if (layer >= 0 && minLayer > layer) {
   19393                             minLayer = layer;
   19394                         }
   19395                     }
   19396                     break;
   19397                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
   19398                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   19399                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   19400                         app.adjType = "pausing";
   19401                     }
   19402                     if (procState > PROCESS_STATE_CUR_TOP) {
   19403                         procState = PROCESS_STATE_CUR_TOP;
   19404                     }
   19405                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19406                     app.cached = false;
   19407                     app.empty = false;
   19408                     foregroundActivities = true;
   19409                 } else if (r.state == ActivityState.STOPPING) {
   19410                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   19411                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   19412                         app.adjType = "stopping";
   19413                     }
   19414                     // For the process state, we will at this point consider the
   19415                     // process to be cached.  It will be cached either as an activity
   19416                     // or empty depending on whether the activity is finishing.  We do
   19417                     // this so that we can treat the process as cached for purposes of
   19418                     // memory trimming (determing current memory level, trim command to
   19419                     // send to process) since there can be an arbitrary number of stopping
   19420                     // processes and they should soon all go into the cached state.
   19421                     if (!r.finishing) {
   19422                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   19423                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   19424                         }
   19425                     }
   19426                     app.cached = false;
   19427                     app.empty = false;
   19428                     foregroundActivities = true;
   19429                 } else {
   19430                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   19431                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   19432                         app.adjType = "cch-act";
   19433                     }
   19434                 }
   19435             }
   19436             if (adj == ProcessList.VISIBLE_APP_ADJ) {
   19437                 adj += minLayer;
   19438             }
   19439         }
   19440 
   19441         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
   19442                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
   19443             if (app.foregroundServices) {
   19444                 // The user is aware of this app, so make it visible.
   19445                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   19446                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
   19447                 app.cached = false;
   19448                 app.adjType = "fg-service";
   19449                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19450             } else if (app.forcingToForeground != null) {
   19451                 // The user is aware of this app, so make it visible.
   19452                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   19453                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   19454                 app.cached = false;
   19455                 app.adjType = "force-fg";
   19456                 app.adjSource = app.forcingToForeground;
   19457                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19458             }
   19459         }
   19460 
   19461         if (app == mHeavyWeightProcess) {
   19462             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   19463                 // We don't want to kill the current heavy-weight process.
   19464                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
   19465                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   19466                 app.cached = false;
   19467                 app.adjType = "heavy";
   19468             }
   19469             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
   19470                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
   19471             }
   19472         }
   19473 
   19474         if (app == mHomeProcess) {
   19475             if (adj > ProcessList.HOME_APP_ADJ) {
   19476                 // This process is hosting what we currently consider to be the
   19477                 // home app, so we don't want to let it go into the background.
   19478                 adj = ProcessList.HOME_APP_ADJ;
   19479                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   19480                 app.cached = false;
   19481                 app.adjType = "home";
   19482             }
   19483             if (procState > ActivityManager.PROCESS_STATE_HOME) {
   19484                 procState = ActivityManager.PROCESS_STATE_HOME;
   19485             }
   19486         }
   19487 
   19488         if (app == mPreviousProcess && app.activities.size() > 0) {
   19489             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
   19490                 // This was the previous process that showed UI to the user.
   19491                 // We want to try to keep it around more aggressively, to give
   19492                 // a good experience around switching between two apps.
   19493                 adj = ProcessList.PREVIOUS_APP_ADJ;
   19494                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   19495                 app.cached = false;
   19496                 app.adjType = "previous";
   19497             }
   19498             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   19499                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   19500             }
   19501         }
   19502 
   19503         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
   19504                 + " reason=" + app.adjType);
   19505 
   19506         // By default, we use the computed adjustment.  It may be changed if
   19507         // there are applications dependent on our services or providers, but
   19508         // this gives us a baseline and makes sure we don't get into an
   19509         // infinite recursion.
   19510         app.adjSeq = mAdjSeq;
   19511         app.curRawAdj = adj;
   19512         app.hasStartedServices = false;
   19513 
   19514         if (mBackupTarget != null && app == mBackupTarget.app) {
   19515             // If possible we want to avoid killing apps while they're being backed up
   19516             if (adj > ProcessList.BACKUP_APP_ADJ) {
   19517                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
   19518                 adj = ProcessList.BACKUP_APP_ADJ;
   19519                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   19520                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
   19521                 }
   19522                 app.adjType = "backup";
   19523                 app.cached = false;
   19524             }
   19525             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
   19526                 procState = ActivityManager.PROCESS_STATE_BACKUP;
   19527             }
   19528         }
   19529 
   19530         boolean mayBeTop = false;
   19531 
   19532         for (int is = app.services.size()-1;
   19533                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   19534                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   19535                         || procState > ActivityManager.PROCESS_STATE_TOP);
   19536                 is--) {
   19537             ServiceRecord s = app.services.valueAt(is);
   19538             if (s.startRequested) {
   19539                 app.hasStartedServices = true;
   19540                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
   19541                     procState = ActivityManager.PROCESS_STATE_SERVICE;
   19542                 }
   19543                 if (app.hasShownUi && app != mHomeProcess) {
   19544                     // If this process has shown some UI, let it immediately
   19545                     // go to the LRU list because it may be pretty heavy with
   19546                     // UI stuff.  We'll tag it with a label just to help
   19547                     // debug and understand what is going on.
   19548                     if (adj > ProcessList.SERVICE_ADJ) {
   19549                         app.adjType = "cch-started-ui-services";
   19550                     }
   19551                 } else {
   19552                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   19553                         // This service has seen some activity within
   19554                         // recent memory, so we will keep its process ahead
   19555                         // of the background processes.
   19556                         if (adj > ProcessList.SERVICE_ADJ) {
   19557                             adj = ProcessList.SERVICE_ADJ;
   19558                             app.adjType = "started-services";
   19559                             app.cached = false;
   19560                         }
   19561                     }
   19562                     // If we have let the service slide into the background
   19563                     // state, still have some text describing what it is doing
   19564                     // even though the service no longer has an impact.
   19565                     if (adj > ProcessList.SERVICE_ADJ) {
   19566                         app.adjType = "cch-started-services";
   19567                     }
   19568                 }
   19569             }
   19570 
   19571             for (int conni = s.connections.size()-1;
   19572                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   19573                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   19574                             || procState > ActivityManager.PROCESS_STATE_TOP);
   19575                     conni--) {
   19576                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
   19577                 for (int i = 0;
   19578                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
   19579                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   19580                                 || procState > ActivityManager.PROCESS_STATE_TOP);
   19581                         i++) {
   19582                     // XXX should compute this based on the max of
   19583                     // all connected clients.
   19584                     ConnectionRecord cr = clist.get(i);
   19585                     if (cr.binding.client == app) {
   19586                         // Binding to ourself is not interesting.
   19587                         continue;
   19588                     }
   19589 
   19590                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
   19591                         ProcessRecord client = cr.binding.client;
   19592                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
   19593                                 TOP_APP, doingAll, now);
   19594                         int clientProcState = client.curProcState;
   19595                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   19596                             // If the other app is cached for any reason, for purposes here
   19597                             // we are going to consider it empty.  The specific cached state
   19598                             // doesn't propagate except under certain conditions.
   19599                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   19600                         }
   19601                         String adjType = null;
   19602                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
   19603                             // Not doing bind OOM management, so treat
   19604                             // this guy more like a started service.
   19605                             if (app.hasShownUi && app != mHomeProcess) {
   19606                                 // If this process has shown some UI, let it immediately
   19607                                 // go to the LRU list because it may be pretty heavy with
   19608                                 // UI stuff.  We'll tag it with a label just to help
   19609                                 // debug and understand what is going on.
   19610                                 if (adj > clientAdj) {
   19611                                     adjType = "cch-bound-ui-services";
   19612                                 }
   19613                                 app.cached = false;
   19614                                 clientAdj = adj;
   19615                                 clientProcState = procState;
   19616                             } else {
   19617                                 if (now >= (s.lastActivity
   19618                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   19619                                     // This service has not seen activity within
   19620                                     // recent memory, so allow it to drop to the
   19621                                     // LRU list if there is no other reason to keep
   19622                                     // it around.  We'll also tag it with a label just
   19623                                     // to help debug and undertand what is going on.
   19624                                     if (adj > clientAdj) {
   19625                                         adjType = "cch-bound-services";
   19626                                     }
   19627                                     clientAdj = adj;
   19628                                 }
   19629                             }
   19630                         }
   19631                         if (adj > clientAdj) {
   19632                             // If this process has recently shown UI, and
   19633                             // the process that is binding to it is less
   19634                             // important than being visible, then we don't
   19635                             // care about the binding as much as we care
   19636                             // about letting this process get into the LRU
   19637                             // list to be killed and restarted if needed for
   19638                             // memory.
   19639                             if (app.hasShownUi && app != mHomeProcess
   19640                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   19641                                 adjType = "cch-bound-ui-services";
   19642                             } else {
   19643                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
   19644                                         |Context.BIND_IMPORTANT)) != 0) {
   19645                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
   19646                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
   19647                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
   19648                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
   19649                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   19650                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   19651                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   19652                                     adj = clientAdj;
   19653                                 } else {
   19654                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   19655                                         adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
   19656                                     }
   19657                                 }
   19658                                 if (!client.cached) {
   19659                                     app.cached = false;
   19660                                 }
   19661                                 adjType = "service";
   19662                             }
   19663                         }
   19664                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   19665                             // This will treat important bound services identically to
   19666                             // the top app, which may behave differently than generic
   19667                             // foreground work.
   19668                             if (client.curSchedGroup > schedGroup) {
   19669                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
   19670                                     schedGroup = client.curSchedGroup;
   19671                                 } else {
   19672                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19673                                 }
   19674                             }
   19675                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   19676                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   19677                                     // Special handling of clients who are in the top state.
   19678                                     // We *may* want to consider this process to be in the
   19679                                     // top state as well, but only if there is not another
   19680                                     // reason for it to be running.  Being on the top is a
   19681                                     // special state, meaning you are specifically running
   19682                                     // for the current top app.  If the process is already
   19683                                     // running in the background for some other reason, it
   19684                                     // is more important to continue considering it to be
   19685                                     // in the background state.
   19686                                     mayBeTop = true;
   19687                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   19688                                 } else {
   19689                                     // Special handling for above-top states (persistent
   19690                                     // processes).  These should not bring the current process
   19691                                     // into the top state, since they are not on top.  Instead
   19692                                     // give them the best state after that.
   19693                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
   19694                                         clientProcState =
   19695                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
   19696                                     } else if (mWakefulness
   19697                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
   19698                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
   19699                                                     != 0) {
   19700                                         clientProcState =
   19701                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
   19702                                     } else {
   19703                                         clientProcState =
   19704                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   19705                                     }
   19706                                 }
   19707                             }
   19708                         } else {
   19709                             if (clientProcState <
   19710                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   19711                                 clientProcState =
   19712                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
   19713                             }
   19714                         }
   19715                         if (procState > clientProcState) {
   19716                             procState = clientProcState;
   19717                         }
   19718                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   19719                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
   19720                             app.pendingUiClean = true;
   19721                         }
   19722                         if (adjType != null) {
   19723                             app.adjType = adjType;
   19724                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   19725                                     .REASON_SERVICE_IN_USE;
   19726                             app.adjSource = cr.binding.client;
   19727                             app.adjSourceProcState = clientProcState;
   19728                             app.adjTarget = s.name;
   19729                         }
   19730                     }
   19731                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
   19732                         app.treatLikeActivity = true;
   19733                     }
   19734                     final ActivityRecord a = cr.activity;
   19735                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
   19736                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
   19737                             (a.visible || a.state == ActivityState.RESUMED ||
   19738                              a.state == ActivityState.PAUSING)) {
   19739                             adj = ProcessList.FOREGROUND_APP_ADJ;
   19740                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   19741                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
   19742                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
   19743                                 } else {
   19744                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19745                                 }
   19746                             }
   19747                             app.cached = false;
   19748                             app.adjType = "service";
   19749                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   19750                                     .REASON_SERVICE_IN_USE;
   19751                             app.adjSource = a;
   19752                             app.adjSourceProcState = procState;
   19753                             app.adjTarget = s.name;
   19754                         }
   19755                     }
   19756                 }
   19757             }
   19758         }
   19759 
   19760         for (int provi = app.pubProviders.size()-1;
   19761                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   19762                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   19763                         || procState > ActivityManager.PROCESS_STATE_TOP);
   19764                 provi--) {
   19765             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
   19766             for (int i = cpr.connections.size()-1;
   19767                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   19768                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   19769                             || procState > ActivityManager.PROCESS_STATE_TOP);
   19770                     i--) {
   19771                 ContentProviderConnection conn = cpr.connections.get(i);
   19772                 ProcessRecord client = conn.client;
   19773                 if (client == app) {
   19774                     // Being our own client is not interesting.
   19775                     continue;
   19776                 }
   19777                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
   19778                 int clientProcState = client.curProcState;
   19779                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   19780                     // If the other app is cached for any reason, for purposes here
   19781                     // we are going to consider it empty.
   19782                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   19783                 }
   19784                 if (adj > clientAdj) {
   19785                     if (app.hasShownUi && app != mHomeProcess
   19786                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   19787                         app.adjType = "cch-ui-provider";
   19788                     } else {
   19789                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
   19790                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
   19791                         app.adjType = "provider";
   19792                     }
   19793                     app.cached &= client.cached;
   19794                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   19795                             .REASON_PROVIDER_IN_USE;
   19796                     app.adjSource = client;
   19797                     app.adjSourceProcState = clientProcState;
   19798                     app.adjTarget = cpr.name;
   19799                 }
   19800                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   19801                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   19802                         // Special handling of clients who are in the top state.
   19803                         // We *may* want to consider this process to be in the
   19804                         // top state as well, but only if there is not another
   19805                         // reason for it to be running.  Being on the top is a
   19806                         // special state, meaning you are specifically running
   19807                         // for the current top app.  If the process is already
   19808                         // running in the background for some other reason, it
   19809                         // is more important to continue considering it to be
   19810                         // in the background state.
   19811                         mayBeTop = true;
   19812                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   19813                     } else {
   19814                         // Special handling for above-top states (persistent
   19815                         // processes).  These should not bring the current process
   19816                         // into the top state, since they are not on top.  Instead
   19817                         // give them the best state after that.
   19818                         clientProcState =
   19819                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
   19820                     }
   19821                 }
   19822                 if (procState > clientProcState) {
   19823                     procState = clientProcState;
   19824                 }
   19825                 if (client.curSchedGroup > schedGroup) {
   19826                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19827                 }
   19828             }
   19829             // If the provider has external (non-framework) process
   19830             // dependencies, ensure that its adjustment is at least
   19831             // FOREGROUND_APP_ADJ.
   19832             if (cpr.hasExternalProcessHandles()) {
   19833                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
   19834                     adj = ProcessList.FOREGROUND_APP_ADJ;
   19835                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19836                     app.cached = false;
   19837                     app.adjType = "provider";
   19838                     app.adjTarget = cpr.name;
   19839                 }
   19840                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
   19841                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   19842                 }
   19843             }
   19844         }
   19845 
   19846         if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
   19847             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
   19848                 adj = ProcessList.PREVIOUS_APP_ADJ;
   19849                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   19850                 app.cached = false;
   19851                 app.adjType = "provider";
   19852             }
   19853             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   19854                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   19855             }
   19856         }
   19857 
   19858         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
   19859             // A client of one of our services or providers is in the top state.  We
   19860             // *may* want to be in the top state, but not if we are already running in
   19861             // the background for some other reason.  For the decision here, we are going
   19862             // to pick out a few specific states that we want to remain in when a client
   19863             // is top (states that tend to be longer-term) and otherwise allow it to go
   19864             // to the top state.
   19865             switch (procState) {
   19866                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
   19867                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
   19868                 case ActivityManager.PROCESS_STATE_SERVICE:
   19869                     // These all are longer-term states, so pull them up to the top
   19870                     // of the background states, but not all the way to the top state.
   19871                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
   19872                     break;
   19873                 default:
   19874                     // Otherwise, top is a better choice, so take it.
   19875                     procState = ActivityManager.PROCESS_STATE_TOP;
   19876                     break;
   19877             }
   19878         }
   19879 
   19880         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
   19881             if (app.hasClientActivities) {
   19882                 // This is a cached process, but with client activities.  Mark it so.
   19883                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
   19884                 app.adjType = "cch-client-act";
   19885             } else if (app.treatLikeActivity) {
   19886                 // This is a cached process, but somebody wants us to treat it like it has
   19887                 // an activity, okay!
   19888                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   19889                 app.adjType = "cch-as-act";
   19890             }
   19891         }
   19892 
   19893         if (adj == ProcessList.SERVICE_ADJ) {
   19894             if (doingAll) {
   19895                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
   19896                 mNewNumServiceProcs++;
   19897                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
   19898                 if (!app.serviceb) {
   19899                     // This service isn't far enough down on the LRU list to
   19900                     // normally be a B service, but if we are low on RAM and it
   19901                     // is large we want to force it down since we would prefer to
   19902                     // keep launcher over it.
   19903                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
   19904                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
   19905                         app.serviceHighRam = true;
   19906                         app.serviceb = true;
   19907                         //Slog.i(TAG, "ADJ " + app + " high ram!");
   19908                     } else {
   19909                         mNewNumAServiceProcs++;
   19910                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
   19911                     }
   19912                 } else {
   19913                     app.serviceHighRam = false;
   19914                 }
   19915             }
   19916             if (app.serviceb) {
   19917                 adj = ProcessList.SERVICE_B_ADJ;
   19918             }
   19919         }
   19920 
   19921         app.curRawAdj = adj;
   19922 
   19923         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
   19924         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
   19925         if (adj > app.maxAdj) {
   19926             adj = app.maxAdj;
   19927             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   19928                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19929             }
   19930         }
   19931 
   19932         // Do final modification to adj.  Everything we do between here and applying
   19933         // the final setAdj must be done in this function, because we will also use
   19934         // it when computing the final cached adj later.  Note that we don't need to
   19935         // worry about this for max adj above, since max adj will always be used to
   19936         // keep it out of the cached vaues.
   19937         app.curAdj = app.modifyRawOomAdj(adj);
   19938         app.curSchedGroup = schedGroup;
   19939         app.curProcState = procState;
   19940         app.foregroundActivities = foregroundActivities;
   19941 
   19942         return app.curRawAdj;
   19943     }
   19944 
   19945     /**
   19946      * Record new PSS sample for a process.
   19947      */
   19948     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
   19949             long now) {
   19950         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
   19951                 swapPss * 1024);
   19952         proc.lastPssTime = now;
   19953         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
   19954         if (DEBUG_PSS) Slog.d(TAG_PSS,
   19955                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
   19956                 + " state=" + ProcessList.makeProcStateString(procState));
   19957         if (proc.initialIdlePss == 0) {
   19958             proc.initialIdlePss = pss;
   19959         }
   19960         proc.lastPss = pss;
   19961         proc.lastSwapPss = swapPss;
   19962         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
   19963             proc.lastCachedPss = pss;
   19964             proc.lastCachedSwapPss = swapPss;
   19965         }
   19966 
   19967         final SparseArray<Pair<Long, String>> watchUids
   19968                 = mMemWatchProcesses.getMap().get(proc.processName);
   19969         Long check = null;
   19970         if (watchUids != null) {
   19971             Pair<Long, String> val = watchUids.get(proc.uid);
   19972             if (val == null) {
   19973                 val = watchUids.get(0);
   19974             }
   19975             if (val != null) {
   19976                 check = val.first;
   19977             }
   19978         }
   19979         if (check != null) {
   19980             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
   19981                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   19982                 if (!isDebuggable) {
   19983                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   19984                         isDebuggable = true;
   19985                     }
   19986                 }
   19987                 if (isDebuggable) {
   19988                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
   19989                     final ProcessRecord myProc = proc;
   19990                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
   19991                     mMemWatchDumpProcName = proc.processName;
   19992                     mMemWatchDumpFile = heapdumpFile.toString();
   19993                     mMemWatchDumpPid = proc.pid;
   19994                     mMemWatchDumpUid = proc.uid;
   19995                     BackgroundThread.getHandler().post(new Runnable() {
   19996                         @Override
   19997                         public void run() {
   19998                             revokeUriPermission(ActivityThread.currentActivityThread()
   19999                                             .getApplicationThread(),
   20000                                     DumpHeapActivity.JAVA_URI,
   20001                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
   20002                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
   20003                                     UserHandle.myUserId());
   20004                             ParcelFileDescriptor fd = null;
   20005                             try {
   20006                                 heapdumpFile.delete();
   20007                                 fd = ParcelFileDescriptor.open(heapdumpFile,
   20008                                         ParcelFileDescriptor.MODE_CREATE |
   20009                                                 ParcelFileDescriptor.MODE_TRUNCATE |
   20010                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
   20011                                                 ParcelFileDescriptor.MODE_APPEND);
   20012                                 IApplicationThread thread = myProc.thread;
   20013                                 if (thread != null) {
   20014                                     try {
   20015                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
   20016                                                 "Requesting dump heap from "
   20017                                                 + myProc + " to " + heapdumpFile);
   20018                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
   20019                                     } catch (RemoteException e) {
   20020                                     }
   20021                                 }
   20022                             } catch (FileNotFoundException e) {
   20023                                 e.printStackTrace();
   20024                             } finally {
   20025                                 if (fd != null) {
   20026                                     try {
   20027                                         fd.close();
   20028                                     } catch (IOException e) {
   20029                                     }
   20030                                 }
   20031                             }
   20032                         }
   20033                     });
   20034                 } else {
   20035                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
   20036                             + ", but debugging not enabled");
   20037                 }
   20038             }
   20039         }
   20040     }
   20041 
   20042     /**
   20043      * Schedule PSS collection of a process.
   20044      */
   20045     void requestPssLocked(ProcessRecord proc, int procState) {
   20046         if (mPendingPssProcesses.contains(proc)) {
   20047             return;
   20048         }
   20049         if (mPendingPssProcesses.size() == 0) {
   20050             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   20051         }
   20052         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
   20053         proc.pssProcState = procState;
   20054         mPendingPssProcesses.add(proc);
   20055     }
   20056 
   20057     /**
   20058      * Schedule PSS collection of all processes.
   20059      */
   20060     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
   20061         if (!always) {
   20062             if (now < (mLastFullPssTime +
   20063                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
   20064                 return;
   20065             }
   20066         }
   20067         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
   20068         mLastFullPssTime = now;
   20069         mFullPssPending = true;
   20070         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
   20071         mPendingPssProcesses.clear();
   20072         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   20073             ProcessRecord app = mLruProcesses.get(i);
   20074             if (app.thread == null
   20075                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
   20076                 continue;
   20077             }
   20078             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
   20079                 app.pssProcState = app.setProcState;
   20080                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
   20081                         mTestPssMode, isSleepingLocked(), now);
   20082                 mPendingPssProcesses.add(app);
   20083             }
   20084         }
   20085         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   20086     }
   20087 
   20088     public void setTestPssMode(boolean enabled) {
   20089         synchronized (this) {
   20090             mTestPssMode = enabled;
   20091             if (enabled) {
   20092                 // Whenever we enable the mode, we want to take a snapshot all of current
   20093                 // process mem use.
   20094                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
   20095             }
   20096         }
   20097     }
   20098 
   20099     /**
   20100      * Ask a given process to GC right now.
   20101      */
   20102     final void performAppGcLocked(ProcessRecord app) {
   20103         try {
   20104             app.lastRequestedGc = SystemClock.uptimeMillis();
   20105             if (app.thread != null) {
   20106                 if (app.reportLowMemory) {
   20107                     app.reportLowMemory = false;
   20108                     app.thread.scheduleLowMemory();
   20109                 } else {
   20110                     app.thread.processInBackground();
   20111                 }
   20112             }
   20113         } catch (Exception e) {
   20114             // whatever.
   20115         }
   20116     }
   20117 
   20118     /**
   20119      * Returns true if things are idle enough to perform GCs.
   20120      */
   20121     private final boolean canGcNowLocked() {
   20122         boolean processingBroadcasts = false;
   20123         for (BroadcastQueue q : mBroadcastQueues) {
   20124             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
   20125                 processingBroadcasts = true;
   20126             }
   20127         }
   20128         return !processingBroadcasts
   20129                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
   20130     }
   20131 
   20132     /**
   20133      * Perform GCs on all processes that are waiting for it, but only
   20134      * if things are idle.
   20135      */
   20136     final void performAppGcsLocked() {
   20137         final int N = mProcessesToGc.size();
   20138         if (N <= 0) {
   20139             return;
   20140         }
   20141         if (canGcNowLocked()) {
   20142             while (mProcessesToGc.size() > 0) {
   20143                 ProcessRecord proc = mProcessesToGc.remove(0);
   20144                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
   20145                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
   20146                             <= SystemClock.uptimeMillis()) {
   20147                         // To avoid spamming the system, we will GC processes one
   20148                         // at a time, waiting a few seconds between each.
   20149                         performAppGcLocked(proc);
   20150                         scheduleAppGcsLocked();
   20151                         return;
   20152                     } else {
   20153                         // It hasn't been long enough since we last GCed this
   20154                         // process...  put it in the list to wait for its time.
   20155                         addProcessToGcListLocked(proc);
   20156                         break;
   20157                     }
   20158                 }
   20159             }
   20160 
   20161             scheduleAppGcsLocked();
   20162         }
   20163     }
   20164 
   20165     /**
   20166      * If all looks good, perform GCs on all processes waiting for them.
   20167      */
   20168     final void performAppGcsIfAppropriateLocked() {
   20169         if (canGcNowLocked()) {
   20170             performAppGcsLocked();
   20171             return;
   20172         }
   20173         // Still not idle, wait some more.
   20174         scheduleAppGcsLocked();
   20175     }
   20176 
   20177     /**
   20178      * Schedule the execution of all pending app GCs.
   20179      */
   20180     final void scheduleAppGcsLocked() {
   20181         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
   20182 
   20183         if (mProcessesToGc.size() > 0) {
   20184             // Schedule a GC for the time to the next process.
   20185             ProcessRecord proc = mProcessesToGc.get(0);
   20186             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
   20187 
   20188             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
   20189             long now = SystemClock.uptimeMillis();
   20190             if (when < (now+GC_TIMEOUT)) {
   20191                 when = now + GC_TIMEOUT;
   20192             }
   20193             mHandler.sendMessageAtTime(msg, when);
   20194         }
   20195     }
   20196 
   20197     /**
   20198      * Add a process to the array of processes waiting to be GCed.  Keeps the
   20199      * list in sorted order by the last GC time.  The process can't already be
   20200      * on the list.
   20201      */
   20202     final void addProcessToGcListLocked(ProcessRecord proc) {
   20203         boolean added = false;
   20204         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
   20205             if (mProcessesToGc.get(i).lastRequestedGc <
   20206                     proc.lastRequestedGc) {
   20207                 added = true;
   20208                 mProcessesToGc.add(i+1, proc);
   20209                 break;
   20210             }
   20211         }
   20212         if (!added) {
   20213             mProcessesToGc.add(0, proc);
   20214         }
   20215     }
   20216 
   20217     /**
   20218      * Set up to ask a process to GC itself.  This will either do it
   20219      * immediately, or put it on the list of processes to gc the next
   20220      * time things are idle.
   20221      */
   20222     final void scheduleAppGcLocked(ProcessRecord app) {
   20223         long now = SystemClock.uptimeMillis();
   20224         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
   20225             return;
   20226         }
   20227         if (!mProcessesToGc.contains(app)) {
   20228             addProcessToGcListLocked(app);
   20229             scheduleAppGcsLocked();
   20230         }
   20231     }
   20232 
   20233     final void checkExcessivePowerUsageLocked(boolean doKills) {
   20234         updateCpuStatsNow();
   20235 
   20236         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   20237         boolean doWakeKills = doKills;
   20238         boolean doCpuKills = doKills;
   20239         if (mLastPowerCheckRealtime == 0) {
   20240             doWakeKills = false;
   20241         }
   20242         if (mLastPowerCheckUptime == 0) {
   20243             doCpuKills = false;
   20244         }
   20245         if (stats.isScreenOn()) {
   20246             doWakeKills = false;
   20247         }
   20248         final long curRealtime = SystemClock.elapsedRealtime();
   20249         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
   20250         final long curUptime = SystemClock.uptimeMillis();
   20251         final long uptimeSince = curUptime - mLastPowerCheckUptime;
   20252         mLastPowerCheckRealtime = curRealtime;
   20253         mLastPowerCheckUptime = curUptime;
   20254         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
   20255             doWakeKills = false;
   20256         }
   20257         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
   20258             doCpuKills = false;
   20259         }
   20260         int i = mLruProcesses.size();
   20261         while (i > 0) {
   20262             i--;
   20263             ProcessRecord app = mLruProcesses.get(i);
   20264             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
   20265                 long wtime;
   20266                 synchronized (stats) {
   20267                     wtime = stats.getProcessWakeTime(app.info.uid,
   20268                             app.pid, curRealtime);
   20269                 }
   20270                 long wtimeUsed = wtime - app.lastWakeTime;
   20271                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
   20272                 if (DEBUG_POWER) {
   20273                     StringBuilder sb = new StringBuilder(128);
   20274                     sb.append("Wake for ");
   20275                     app.toShortString(sb);
   20276                     sb.append(": over ");
   20277                     TimeUtils.formatDuration(realtimeSince, sb);
   20278                     sb.append(" used ");
   20279                     TimeUtils.formatDuration(wtimeUsed, sb);
   20280                     sb.append(" (");
   20281                     sb.append((wtimeUsed*100)/realtimeSince);
   20282                     sb.append("%)");
   20283                     Slog.i(TAG_POWER, sb.toString());
   20284                     sb.setLength(0);
   20285                     sb.append("CPU for ");
   20286                     app.toShortString(sb);
   20287                     sb.append(": over ");
   20288                     TimeUtils.formatDuration(uptimeSince, sb);
   20289                     sb.append(" used ");
   20290                     TimeUtils.formatDuration(cputimeUsed, sb);
   20291                     sb.append(" (");
   20292                     sb.append((cputimeUsed*100)/uptimeSince);
   20293                     sb.append("%)");
   20294                     Slog.i(TAG_POWER, sb.toString());
   20295                 }
   20296                 // If a process has held a wake lock for more
   20297                 // than 50% of the time during this period,
   20298                 // that sounds bad.  Kill!
   20299                 if (doWakeKills && realtimeSince > 0
   20300                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
   20301                     synchronized (stats) {
   20302                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
   20303                                 realtimeSince, wtimeUsed);
   20304                     }
   20305                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
   20306                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
   20307                 } else if (doCpuKills && uptimeSince > 0
   20308                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
   20309                     synchronized (stats) {
   20310                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
   20311                                 uptimeSince, cputimeUsed);
   20312                     }
   20313                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
   20314                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
   20315                 } else {
   20316                     app.lastWakeTime = wtime;
   20317                     app.lastCpuTime = app.curCpuTime;
   20318                 }
   20319             }
   20320         }
   20321     }
   20322 
   20323     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
   20324             long nowElapsed) {
   20325         boolean success = true;
   20326 
   20327         if (app.curRawAdj != app.setRawAdj) {
   20328             app.setRawAdj = app.curRawAdj;
   20329         }
   20330 
   20331         int changes = 0;
   20332 
   20333         if (app.curAdj != app.setAdj) {
   20334             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
   20335             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   20336                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
   20337                     + app.adjType);
   20338             app.setAdj = app.curAdj;
   20339             app.verifiedAdj = ProcessList.INVALID_ADJ;
   20340         }
   20341 
   20342         if (app.setSchedGroup != app.curSchedGroup) {
   20343             int oldSchedGroup = app.setSchedGroup;
   20344             app.setSchedGroup = app.curSchedGroup;
   20345             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   20346                     "Setting sched group of " + app.processName
   20347                     + " to " + app.curSchedGroup);
   20348             if (app.waitingToKill != null && app.curReceiver == null
   20349                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
   20350                 app.kill(app.waitingToKill, true);
   20351                 success = false;
   20352             } else {
   20353                 int processGroup;
   20354                 switch (app.curSchedGroup) {
   20355                     case ProcessList.SCHED_GROUP_BACKGROUND:
   20356                         processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   20357                         break;
   20358                     case ProcessList.SCHED_GROUP_TOP_APP:
   20359                     case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
   20360                         processGroup = Process.THREAD_GROUP_TOP_APP;
   20361                         break;
   20362                     default:
   20363                         processGroup = Process.THREAD_GROUP_DEFAULT;
   20364                         break;
   20365                 }
   20366                 long oldId = Binder.clearCallingIdentity();
   20367                 try {
   20368                     Process.setProcessGroup(app.pid, processGroup);
   20369                     if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
   20370                         // do nothing if we already switched to RT
   20371                         if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
   20372                             // Switch VR thread for app to SCHED_FIFO
   20373                             if (mInVrMode && app.vrThreadTid != 0) {
   20374                                 try {
   20375                                     Process.setThreadScheduler(app.vrThreadTid,
   20376                                         Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
   20377                                 } catch (IllegalArgumentException e) {
   20378                                     // thread died, ignore
   20379                                 }
   20380                             }
   20381                             if (mUseFifoUiScheduling) {
   20382                                 // Switch UI pipeline for app to SCHED_FIFO
   20383                                 app.savedPriority = Process.getThreadPriority(app.pid);
   20384                                 try {
   20385                                     Process.setThreadScheduler(app.pid,
   20386                                         Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
   20387                                 } catch (IllegalArgumentException e) {
   20388                                     // thread died, ignore
   20389                                 }
   20390                                 if (app.renderThreadTid != 0) {
   20391                                     try {
   20392                                         Process.setThreadScheduler(app.renderThreadTid,
   20393                                             Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
   20394                                     } catch (IllegalArgumentException e) {
   20395                                         // thread died, ignore
   20396                                     }
   20397                                     if (DEBUG_OOM_ADJ) {
   20398                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
   20399                                             app.renderThreadTid + ") to FIFO");
   20400                                     }
   20401                                 } else {
   20402                                     if (DEBUG_OOM_ADJ) {
   20403                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
   20404                                     }
   20405                                 }
   20406                             } else {
   20407                                 // Boost priority for top app UI and render threads
   20408                                 Process.setThreadPriority(app.pid, -10);
   20409                                 if (app.renderThreadTid != 0) {
   20410                                     try {
   20411                                         Process.setThreadPriority(app.renderThreadTid, -10);
   20412                                     } catch (IllegalArgumentException e) {
   20413                                         // thread died, ignore
   20414                                     }
   20415                                 }
   20416                             }
   20417                         }
   20418                     } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
   20419                                app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
   20420                         // Reset VR thread to SCHED_OTHER
   20421                         // Safe to do even if we're not in VR mode
   20422                         if (app.vrThreadTid != 0) {
   20423                             Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
   20424                         }
   20425                         if (mUseFifoUiScheduling) {
   20426                             // Reset UI pipeline to SCHED_OTHER
   20427                             Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
   20428                             Process.setThreadPriority(app.pid, app.savedPriority);
   20429                             if (app.renderThreadTid != 0) {
   20430                                 Process.setThreadScheduler(app.renderThreadTid,
   20431                                     Process.SCHED_OTHER, 0);
   20432                                 Process.setThreadPriority(app.renderThreadTid, -4);
   20433                             }
   20434                         } else {
   20435                             // Reset priority for top app UI and render threads
   20436                             Process.setThreadPriority(app.pid, 0);
   20437                             if (app.renderThreadTid != 0) {
   20438                                 Process.setThreadPriority(app.renderThreadTid, 0);
   20439                             }
   20440                         }
   20441                     }
   20442                 } catch (Exception e) {
   20443                     Slog.w(TAG, "Failed setting process group of " + app.pid
   20444                             + " to " + app.curSchedGroup);
   20445                     e.printStackTrace();
   20446                 } finally {
   20447                     Binder.restoreCallingIdentity(oldId);
   20448                 }
   20449             }
   20450         }
   20451         if (app.repForegroundActivities != app.foregroundActivities) {
   20452             app.repForegroundActivities = app.foregroundActivities;
   20453             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
   20454         }
   20455         if (app.repProcState != app.curProcState) {
   20456             app.repProcState = app.curProcState;
   20457             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
   20458             if (app.thread != null) {
   20459                 try {
   20460                     if (false) {
   20461                         //RuntimeException h = new RuntimeException("here");
   20462                         Slog.i(TAG, "Sending new process state " + app.repProcState
   20463                                 + " to " + app /*, h*/);
   20464                     }
   20465                     app.thread.setProcessState(app.repProcState);
   20466                 } catch (RemoteException e) {
   20467                 }
   20468             }
   20469         }
   20470         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
   20471                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
   20472             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
   20473                 // Experimental code to more aggressively collect pss while
   20474                 // running test...  the problem is that this tends to collect
   20475                 // the data right when a process is transitioning between process
   20476                 // states, which well tend to give noisy data.
   20477                 long start = SystemClock.uptimeMillis();
   20478                 long pss = Debug.getPss(app.pid, mTmpLong, null);
   20479                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
   20480                 mPendingPssProcesses.remove(app);
   20481                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
   20482                         + " to " + app.curProcState + ": "
   20483                         + (SystemClock.uptimeMillis()-start) + "ms");
   20484             }
   20485             app.lastStateTime = now;
   20486             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
   20487                     mTestPssMode, isSleepingLocked(), now);
   20488             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
   20489                     + ProcessList.makeProcStateString(app.setProcState) + " to "
   20490                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
   20491                     + (app.nextPssTime-now) + ": " + app);
   20492         } else {
   20493             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
   20494                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
   20495                     mTestPssMode)))) {
   20496                 requestPssLocked(app, app.setProcState);
   20497                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
   20498                         mTestPssMode, isSleepingLocked(), now);
   20499             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
   20500                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
   20501         }
   20502         if (app.setProcState != app.curProcState) {
   20503             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   20504                     "Proc state change of " + app.processName
   20505                             + " to " + app.curProcState);
   20506             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
   20507             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
   20508             if (setImportant && !curImportant) {
   20509                 // This app is no longer something we consider important enough to allow to
   20510                 // use arbitrary amounts of battery power.  Note
   20511                 // its current wake lock time to later know to kill it if
   20512                 // it is not behaving well.
   20513                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   20514                 synchronized (stats) {
   20515                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
   20516                             app.pid, nowElapsed);
   20517                 }
   20518                 app.lastCpuTime = app.curCpuTime;
   20519 
   20520             }
   20521             // Inform UsageStats of important process state change
   20522             // Must be called before updating setProcState
   20523             maybeUpdateUsageStatsLocked(app, nowElapsed);
   20524 
   20525             app.setProcState = app.curProcState;
   20526             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
   20527                 app.notCachedSinceIdle = false;
   20528             }
   20529             if (!doingAll) {
   20530                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
   20531             } else {
   20532                 app.procStateChanged = true;
   20533             }
   20534         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
   20535                 > USAGE_STATS_INTERACTION_INTERVAL) {
   20536             // For apps that sit around for a long time in the interactive state, we need
   20537             // to report this at least once a day so they don't go idle.
   20538             maybeUpdateUsageStatsLocked(app, nowElapsed);
   20539         }
   20540 
   20541         if (changes != 0) {
   20542             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   20543                     "Changes in " + app + ": " + changes);
   20544             int i = mPendingProcessChanges.size()-1;
   20545             ProcessChangeItem item = null;
   20546             while (i >= 0) {
   20547                 item = mPendingProcessChanges.get(i);
   20548                 if (item.pid == app.pid) {
   20549                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   20550                             "Re-using existing item: " + item);
   20551                     break;
   20552                 }
   20553                 i--;
   20554             }
   20555             if (i < 0) {
   20556                 // No existing item in pending changes; need a new one.
   20557                 final int NA = mAvailProcessChanges.size();
   20558                 if (NA > 0) {
   20559                     item = mAvailProcessChanges.remove(NA-1);
   20560                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   20561                             "Retrieving available item: " + item);
   20562                 } else {
   20563                     item = new ProcessChangeItem();
   20564                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   20565                             "Allocating new item: " + item);
   20566                 }
   20567                 item.changes = 0;
   20568                 item.pid = app.pid;
   20569                 item.uid = app.info.uid;
   20570                 if (mPendingProcessChanges.size() == 0) {
   20571                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   20572                             "*** Enqueueing dispatch processes changed!");
   20573                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
   20574                 }
   20575                 mPendingProcessChanges.add(item);
   20576             }
   20577             item.changes |= changes;
   20578             item.processState = app.repProcState;
   20579             item.foregroundActivities = app.repForegroundActivities;
   20580             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   20581                     "Item " + Integer.toHexString(System.identityHashCode(item))
   20582                     + " " + app.toShortString() + ": changes=" + item.changes
   20583                     + " procState=" + item.processState
   20584                     + " foreground=" + item.foregroundActivities
   20585                     + " type=" + app.adjType + " source=" + app.adjSource
   20586                     + " target=" + app.adjTarget);
   20587         }
   20588 
   20589         return success;
   20590     }
   20591 
   20592     private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
   20593         final UidRecord.ChangeItem pendingChange;
   20594         if (uidRec == null || uidRec.pendingChange == null) {
   20595             if (mPendingUidChanges.size() == 0) {
   20596                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   20597                         "*** Enqueueing dispatch uid changed!");
   20598                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
   20599             }
   20600             final int NA = mAvailUidChanges.size();
   20601             if (NA > 0) {
   20602                 pendingChange = mAvailUidChanges.remove(NA-1);
   20603                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   20604                         "Retrieving available item: " + pendingChange);
   20605             } else {
   20606                 pendingChange = new UidRecord.ChangeItem();
   20607                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   20608                         "Allocating new item: " + pendingChange);
   20609             }
   20610             if (uidRec != null) {
   20611                 uidRec.pendingChange = pendingChange;
   20612                 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
   20613                     // If this uid is going away, and we haven't yet reported it is gone,
   20614                     // then do so now.
   20615                     change = UidRecord.CHANGE_GONE_IDLE;
   20616                 }
   20617             } else if (uid < 0) {
   20618                 throw new IllegalArgumentException("No UidRecord or uid");
   20619             }
   20620             pendingChange.uidRecord = uidRec;
   20621             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
   20622             mPendingUidChanges.add(pendingChange);
   20623         } else {
   20624             pendingChange = uidRec.pendingChange;
   20625             if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
   20626                 change = UidRecord.CHANGE_GONE_IDLE;
   20627             }
   20628         }
   20629         pendingChange.change = change;
   20630         pendingChange.processState = uidRec != null
   20631                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
   20632     }
   20633 
   20634     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
   20635             String authority) {
   20636         if (app == null) return;
   20637         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
   20638             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
   20639             if (userState == null) return;
   20640             final long now = SystemClock.elapsedRealtime();
   20641             Long lastReported = userState.mProviderLastReportedFg.get(authority);
   20642             if (lastReported == null || lastReported < now - 60 * 1000L) {
   20643                 mUsageStatsService.reportContentProviderUsage(
   20644                         authority, providerPkgName, app.userId);
   20645                 userState.mProviderLastReportedFg.put(authority, now);
   20646             }
   20647         }
   20648     }
   20649 
   20650     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
   20651         if (DEBUG_USAGE_STATS) {
   20652             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
   20653                     + "] state changes: old = " + app.setProcState + ", new = "
   20654                     + app.curProcState);
   20655         }
   20656         if (mUsageStatsService == null) {
   20657             return;
   20658         }
   20659         boolean isInteraction;
   20660         // To avoid some abuse patterns, we are going to be careful about what we consider
   20661         // to be an app interaction.  Being the top activity doesn't count while the display
   20662         // is sleeping, nor do short foreground services.
   20663         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
   20664             isInteraction = true;
   20665             app.fgInteractionTime = 0;
   20666         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
   20667             if (app.fgInteractionTime == 0) {
   20668                 app.fgInteractionTime = nowElapsed;
   20669                 isInteraction = false;
   20670             } else {
   20671                 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
   20672             }
   20673         } else {
   20674             isInteraction = app.curProcState
   20675                     <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   20676             app.fgInteractionTime = 0;
   20677         }
   20678         if (isInteraction && (!app.reportedInteraction
   20679                 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
   20680             app.interactionEventTime = nowElapsed;
   20681             String[] packages = app.getPackageList();
   20682             if (packages != null) {
   20683                 for (int i = 0; i < packages.length; i++) {
   20684                     mUsageStatsService.reportEvent(packages[i], app.userId,
   20685                             UsageEvents.Event.SYSTEM_INTERACTION);
   20686                 }
   20687             }
   20688         }
   20689         app.reportedInteraction = isInteraction;
   20690         if (!isInteraction) {
   20691             app.interactionEventTime = 0;
   20692         }
   20693     }
   20694 
   20695     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
   20696         if (proc.thread != null) {
   20697             if (proc.baseProcessTracker != null) {
   20698                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
   20699             }
   20700         }
   20701     }
   20702 
   20703     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
   20704             ProcessRecord TOP_APP, boolean doingAll, long now) {
   20705         if (app.thread == null) {
   20706             return false;
   20707         }
   20708 
   20709         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
   20710 
   20711         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
   20712     }
   20713 
   20714     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
   20715             boolean oomAdj) {
   20716         if (isForeground != proc.foregroundServices) {
   20717             proc.foregroundServices = isForeground;
   20718             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
   20719                     proc.info.uid);
   20720             if (isForeground) {
   20721                 if (curProcs == null) {
   20722                     curProcs = new ArrayList<ProcessRecord>();
   20723                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
   20724                 }
   20725                 if (!curProcs.contains(proc)) {
   20726                     curProcs.add(proc);
   20727                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
   20728                             proc.info.packageName, proc.info.uid);
   20729                 }
   20730             } else {
   20731                 if (curProcs != null) {
   20732                     if (curProcs.remove(proc)) {
   20733                         mBatteryStatsService.noteEvent(
   20734                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
   20735                                 proc.info.packageName, proc.info.uid);
   20736                         if (curProcs.size() <= 0) {
   20737                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
   20738                         }
   20739                     }
   20740                 }
   20741             }
   20742             if (oomAdj) {
   20743                 updateOomAdjLocked();
   20744             }
   20745         }
   20746     }
   20747 
   20748     private final ActivityRecord resumedAppLocked() {
   20749         ActivityRecord act = mStackSupervisor.resumedAppLocked();
   20750         String pkg;
   20751         int uid;
   20752         if (act != null) {
   20753             pkg = act.packageName;
   20754             uid = act.info.applicationInfo.uid;
   20755         } else {
   20756             pkg = null;
   20757             uid = -1;
   20758         }
   20759         // Has the UID or resumed package name changed?
   20760         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
   20761                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
   20762             if (mCurResumedPackage != null) {
   20763                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
   20764                         mCurResumedPackage, mCurResumedUid);
   20765             }
   20766             mCurResumedPackage = pkg;
   20767             mCurResumedUid = uid;
   20768             if (mCurResumedPackage != null) {
   20769                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
   20770                         mCurResumedPackage, mCurResumedUid);
   20771             }
   20772         }
   20773         return act;
   20774     }
   20775 
   20776     final boolean updateOomAdjLocked(ProcessRecord app) {
   20777         final ActivityRecord TOP_ACT = resumedAppLocked();
   20778         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   20779         final boolean wasCached = app.cached;
   20780 
   20781         mAdjSeq++;
   20782 
   20783         // This is the desired cached adjusment we want to tell it to use.
   20784         // If our app is currently cached, we know it, and that is it.  Otherwise,
   20785         // we don't know it yet, and it needs to now be cached we will then
   20786         // need to do a complete oom adj.
   20787         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
   20788                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
   20789         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
   20790                 SystemClock.uptimeMillis());
   20791         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
   20792             // Changed to/from cached state, so apps after it in the LRU
   20793             // list may also be changed.
   20794             updateOomAdjLocked();
   20795         }
   20796         return success;
   20797     }
   20798 
   20799     final void updateOomAdjLocked() {
   20800         final ActivityRecord TOP_ACT = resumedAppLocked();
   20801         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   20802         final long now = SystemClock.uptimeMillis();
   20803         final long nowElapsed = SystemClock.elapsedRealtime();
   20804         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
   20805         final int N = mLruProcesses.size();
   20806 
   20807         if (false) {
   20808             RuntimeException e = new RuntimeException();
   20809             e.fillInStackTrace();
   20810             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
   20811         }
   20812 
   20813         // Reset state in all uid records.
   20814         for (int i=mActiveUids.size()-1; i>=0; i--) {
   20815             final UidRecord uidRec = mActiveUids.valueAt(i);
   20816             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   20817                     "Starting update of " + uidRec);
   20818             uidRec.reset();
   20819         }
   20820 
   20821         mStackSupervisor.rankTaskLayersIfNeeded();
   20822 
   20823         mAdjSeq++;
   20824         mNewNumServiceProcs = 0;
   20825         mNewNumAServiceProcs = 0;
   20826 
   20827         final int emptyProcessLimit;
   20828         final int cachedProcessLimit;
   20829         if (mProcessLimit <= 0) {
   20830             emptyProcessLimit = cachedProcessLimit = 0;
   20831         } else if (mProcessLimit == 1) {
   20832             emptyProcessLimit = 1;
   20833             cachedProcessLimit = 0;
   20834         } else {
   20835             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
   20836             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
   20837         }
   20838 
   20839         // Let's determine how many processes we have running vs.
   20840         // how many slots we have for background processes; we may want
   20841         // to put multiple processes in a slot of there are enough of
   20842         // them.
   20843         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
   20844                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
   20845         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
   20846         if (numEmptyProcs > cachedProcessLimit) {
   20847             // If there are more empty processes than our limit on cached
   20848             // processes, then use the cached process limit for the factor.
   20849             // This ensures that the really old empty processes get pushed
   20850             // down to the bottom, so if we are running low on memory we will
   20851             // have a better chance at keeping around more cached processes
   20852             // instead of a gazillion empty processes.
   20853             numEmptyProcs = cachedProcessLimit;
   20854         }
   20855         int emptyFactor = numEmptyProcs/numSlots;
   20856         if (emptyFactor < 1) emptyFactor = 1;
   20857         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
   20858         if (cachedFactor < 1) cachedFactor = 1;
   20859         int stepCached = 0;
   20860         int stepEmpty = 0;
   20861         int numCached = 0;
   20862         int numEmpty = 0;
   20863         int numTrimming = 0;
   20864 
   20865         mNumNonCachedProcs = 0;
   20866         mNumCachedHiddenProcs = 0;
   20867 
   20868         // First update the OOM adjustment for each of the
   20869         // application processes based on their current state.
   20870         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
   20871         int nextCachedAdj = curCachedAdj+1;
   20872         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
   20873         int nextEmptyAdj = curEmptyAdj+2;
   20874         for (int i=N-1; i>=0; i--) {
   20875             ProcessRecord app = mLruProcesses.get(i);
   20876             if (!app.killedByAm && app.thread != null) {
   20877                 app.procStateChanged = false;
   20878                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
   20879 
   20880                 // If we haven't yet assigned the final cached adj
   20881                 // to the process, do that now.
   20882                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
   20883                     switch (app.curProcState) {
   20884                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   20885                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   20886                             // This process is a cached process holding activities...
   20887                             // assign it the next cached value for that type, and then
   20888                             // step that cached level.
   20889                             app.curRawAdj = curCachedAdj;
   20890                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
   20891                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
   20892                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
   20893                                     + ")");
   20894                             if (curCachedAdj != nextCachedAdj) {
   20895                                 stepCached++;
   20896                                 if (stepCached >= cachedFactor) {
   20897                                     stepCached = 0;
   20898                                     curCachedAdj = nextCachedAdj;
   20899                                     nextCachedAdj += 2;
   20900                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   20901                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
   20902                                     }
   20903                                 }
   20904                             }
   20905                             break;
   20906                         default:
   20907                             // For everything else, assign next empty cached process
   20908                             // level and bump that up.  Note that this means that
   20909                             // long-running services that have dropped down to the
   20910                             // cached level will be treated as empty (since their process
   20911                             // state is still as a service), which is what we want.
   20912                             app.curRawAdj = curEmptyAdj;
   20913                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
   20914                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
   20915                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
   20916                                     + ")");
   20917                             if (curEmptyAdj != nextEmptyAdj) {
   20918                                 stepEmpty++;
   20919                                 if (stepEmpty >= emptyFactor) {
   20920                                     stepEmpty = 0;
   20921                                     curEmptyAdj = nextEmptyAdj;
   20922                                     nextEmptyAdj += 2;
   20923                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   20924                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
   20925                                     }
   20926                                 }
   20927                             }
   20928                             break;
   20929                     }
   20930                 }
   20931 
   20932                 applyOomAdjLocked(app, true, now, nowElapsed);
   20933 
   20934                 // Count the number of process types.
   20935                 switch (app.curProcState) {
   20936                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   20937                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   20938                         mNumCachedHiddenProcs++;
   20939                         numCached++;
   20940                         if (numCached > cachedProcessLimit) {
   20941                             app.kill("cached #" + numCached, true);
   20942                         }
   20943                         break;
   20944                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
   20945                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
   20946                                 && app.lastActivityTime < oldTime) {
   20947                             app.kill("empty for "
   20948                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
   20949                                     / 1000) + "s", true);
   20950                         } else {
   20951                             numEmpty++;
   20952                             if (numEmpty > emptyProcessLimit) {
   20953                                 app.kill("empty #" + numEmpty, true);
   20954                             }
   20955                         }
   20956                         break;
   20957                     default:
   20958                         mNumNonCachedProcs++;
   20959                         break;
   20960                 }
   20961 
   20962                 if (app.isolated && app.services.size() <= 0) {
   20963                     // If this is an isolated process, and there are no
   20964                     // services running in it, then the process is no longer
   20965                     // needed.  We agressively kill these because we can by
   20966                     // definition not re-use the same process again, and it is
   20967                     // good to avoid having whatever code was running in them
   20968                     // left sitting around after no longer needed.
   20969                     app.kill("isolated not needed", true);
   20970                 } else {
   20971                     // Keeping this process, update its uid.
   20972                     final UidRecord uidRec = app.uidRecord;
   20973                     if (uidRec != null && uidRec.curProcState > app.curProcState) {
   20974                         uidRec.curProcState = app.curProcState;
   20975                     }
   20976                 }
   20977 
   20978                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   20979                         && !app.killedByAm) {
   20980                     numTrimming++;
   20981                 }
   20982             }
   20983         }
   20984 
   20985         mNumServiceProcs = mNewNumServiceProcs;
   20986 
   20987         // Now determine the memory trimming level of background processes.
   20988         // Unfortunately we need to start at the back of the list to do this
   20989         // properly.  We only do this if the number of background apps we
   20990         // are managing to keep around is less than half the maximum we desire;
   20991         // if we are keeping a good number around, we'll let them use whatever
   20992         // memory they want.
   20993         final int numCachedAndEmpty = numCached + numEmpty;
   20994         int memFactor;
   20995         if (numCached <= ProcessList.TRIM_CACHED_APPS
   20996                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
   20997             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
   20998                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
   20999             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
   21000                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
   21001             } else {
   21002                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
   21003             }
   21004         } else {
   21005             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
   21006         }
   21007         // We always allow the memory level to go up (better).  We only allow it to go
   21008         // down if we are in a state where that is allowed, *and* the total number of processes
   21009         // has gone down since last time.
   21010         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
   21011                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
   21012                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
   21013         if (memFactor > mLastMemoryLevel) {
   21014             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
   21015                 memFactor = mLastMemoryLevel;
   21016                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
   21017             }
   21018         }
   21019         if (memFactor != mLastMemoryLevel) {
   21020             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
   21021         }
   21022         mLastMemoryLevel = memFactor;
   21023         mLastNumProcesses = mLruProcesses.size();
   21024         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
   21025         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
   21026         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
   21027             if (mLowRamStartTime == 0) {
   21028                 mLowRamStartTime = now;
   21029             }
   21030             int step = 0;
   21031             int fgTrimLevel;
   21032             switch (memFactor) {
   21033                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
   21034                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
   21035                     break;
   21036                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
   21037                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
   21038                     break;
   21039                 default:
   21040                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
   21041                     break;
   21042             }
   21043             int factor = numTrimming/3;
   21044             int minFactor = 2;
   21045             if (mHomeProcess != null) minFactor++;
   21046             if (mPreviousProcess != null) minFactor++;
   21047             if (factor < minFactor) factor = minFactor;
   21048             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
   21049             for (int i=N-1; i>=0; i--) {
   21050                 ProcessRecord app = mLruProcesses.get(i);
   21051                 if (allChanged || app.procStateChanged) {
   21052                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
   21053                     app.procStateChanged = false;
   21054                 }
   21055                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   21056                         && !app.killedByAm) {
   21057                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
   21058                         try {
   21059                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   21060                                     "Trimming memory of " + app.processName + " to " + curLevel);
   21061                             app.thread.scheduleTrimMemory(curLevel);
   21062                         } catch (RemoteException e) {
   21063                         }
   21064                         if (false) {
   21065                             // For now we won't do this; our memory trimming seems
   21066                             // to be good enough at this point that destroying
   21067                             // activities causes more harm than good.
   21068                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
   21069                                     && app != mHomeProcess && app != mPreviousProcess) {
   21070                                 // Need to do this on its own message because the stack may not
   21071                                 // be in a consistent state at this point.
   21072                                 // For these apps we will also finish their activities
   21073                                 // to help them free memory.
   21074                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
   21075                             }
   21076                         }
   21077                     }
   21078                     app.trimMemoryLevel = curLevel;
   21079                     step++;
   21080                     if (step >= factor) {
   21081                         step = 0;
   21082                         switch (curLevel) {
   21083                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
   21084                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
   21085                                 break;
   21086                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
   21087                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   21088                                 break;
   21089                         }
   21090                     }
   21091                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
   21092                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
   21093                             && app.thread != null) {
   21094                         try {
   21095                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   21096                                     "Trimming memory of heavy-weight " + app.processName
   21097                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   21098                             app.thread.scheduleTrimMemory(
   21099                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   21100                         } catch (RemoteException e) {
   21101                         }
   21102                     }
   21103                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   21104                 } else {
   21105                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   21106                             || app.systemNoUi) && app.pendingUiClean) {
   21107                         // If this application is now in the background and it
   21108                         // had done UI, then give it the special trim level to
   21109                         // have it free UI resources.
   21110                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
   21111                         if (app.trimMemoryLevel < level && app.thread != null) {
   21112                             try {
   21113                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   21114                                         "Trimming memory of bg-ui " + app.processName
   21115                                         + " to " + level);
   21116                                 app.thread.scheduleTrimMemory(level);
   21117                             } catch (RemoteException e) {
   21118                             }
   21119                         }
   21120                         app.pendingUiClean = false;
   21121                     }
   21122                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
   21123                         try {
   21124                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   21125                                     "Trimming memory of fg " + app.processName
   21126                                     + " to " + fgTrimLevel);
   21127                             app.thread.scheduleTrimMemory(fgTrimLevel);
   21128                         } catch (RemoteException e) {
   21129                         }
   21130                     }
   21131                     app.trimMemoryLevel = fgTrimLevel;
   21132                 }
   21133             }
   21134         } else {
   21135             if (mLowRamStartTime != 0) {
   21136                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
   21137                 mLowRamStartTime = 0;
   21138             }
   21139             for (int i=N-1; i>=0; i--) {
   21140                 ProcessRecord app = mLruProcesses.get(i);
   21141                 if (allChanged || app.procStateChanged) {
   21142                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
   21143                     app.procStateChanged = false;
   21144                 }
   21145                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   21146                         || app.systemNoUi) && app.pendingUiClean) {
   21147                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
   21148                             && app.thread != null) {
   21149                         try {
   21150                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   21151                                     "Trimming memory of ui hidden " + app.processName
   21152                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   21153                             app.thread.scheduleTrimMemory(
   21154                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   21155                         } catch (RemoteException e) {
   21156                         }
   21157                     }
   21158                     app.pendingUiClean = false;
   21159                 }
   21160                 app.trimMemoryLevel = 0;
   21161             }
   21162         }
   21163 
   21164         if (mAlwaysFinishActivities) {
   21165             // Need to do this on its own message because the stack may not
   21166             // be in a consistent state at this point.
   21167             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
   21168         }
   21169 
   21170         if (allChanged) {
   21171             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
   21172         }
   21173 
   21174         // Update from any uid changes.
   21175         for (int i=mActiveUids.size()-1; i>=0; i--) {
   21176             final UidRecord uidRec = mActiveUids.valueAt(i);
   21177             int uidChange = UidRecord.CHANGE_PROCSTATE;
   21178             if (uidRec.setProcState != uidRec.curProcState) {
   21179                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   21180                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
   21181                         + " to " + uidRec.curProcState);
   21182                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
   21183                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
   21184                         uidRec.lastBackgroundTime = nowElapsed;
   21185                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
   21186                             // Note: the background settle time is in elapsed realtime, while
   21187                             // the handler time base is uptime.  All this means is that we may
   21188                             // stop background uids later than we had intended, but that only
   21189                             // happens because the device was sleeping so we are okay anyway.
   21190                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
   21191                         }
   21192                     }
   21193                 } else {
   21194                     if (uidRec.idle) {
   21195                         uidChange = UidRecord.CHANGE_ACTIVE;
   21196                         uidRec.idle = false;
   21197                     }
   21198                     uidRec.lastBackgroundTime = 0;
   21199                 }
   21200                 uidRec.setProcState = uidRec.curProcState;
   21201                 enqueueUidChangeLocked(uidRec, -1, uidChange);
   21202                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
   21203             }
   21204         }
   21205 
   21206         if (mProcessStats.shouldWriteNowLocked(now)) {
   21207             mHandler.post(new Runnable() {
   21208                 @Override public void run() {
   21209                     synchronized (ActivityManagerService.this) {
   21210                         mProcessStats.writeStateAsyncLocked();
   21211                     }
   21212                 }
   21213             });
   21214         }
   21215 
   21216         if (DEBUG_OOM_ADJ) {
   21217             final long duration = SystemClock.uptimeMillis() - now;
   21218             if (false) {
   21219                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
   21220                         new RuntimeException("here").fillInStackTrace());
   21221             } else {
   21222                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
   21223             }
   21224         }
   21225     }
   21226 
   21227     final void idleUids() {
   21228         synchronized (this) {
   21229             final long nowElapsed = SystemClock.elapsedRealtime();
   21230             final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
   21231             long nextTime = 0;
   21232             for (int i=mActiveUids.size()-1; i>=0; i--) {
   21233                 final UidRecord uidRec = mActiveUids.valueAt(i);
   21234                 final long bgTime = uidRec.lastBackgroundTime;
   21235                 if (bgTime > 0 && !uidRec.idle) {
   21236                     if (bgTime <= maxBgTime) {
   21237                         uidRec.idle = true;
   21238                         doStopUidLocked(uidRec.uid, uidRec);
   21239                     } else {
   21240                         if (nextTime == 0 || nextTime > bgTime) {
   21241                             nextTime = bgTime;
   21242                         }
   21243                     }
   21244                 }
   21245             }
   21246             if (nextTime > 0) {
   21247                 mHandler.removeMessages(IDLE_UIDS_MSG);
   21248                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
   21249                         nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
   21250             }
   21251         }
   21252     }
   21253 
   21254     final void runInBackgroundDisabled(int uid) {
   21255         synchronized (this) {
   21256             UidRecord uidRec = mActiveUids.get(uid);
   21257             if (uidRec != null) {
   21258                 // This uid is actually running...  should it be considered background now?
   21259                 if (uidRec.idle) {
   21260                     doStopUidLocked(uidRec.uid, uidRec);
   21261                 }
   21262             } else {
   21263                 // This uid isn't actually running...  still send a report about it being "stopped".
   21264                 doStopUidLocked(uid, null);
   21265             }
   21266         }
   21267     }
   21268 
   21269     final void doStopUidLocked(int uid, final UidRecord uidRec) {
   21270         mServices.stopInBackgroundLocked(uid);
   21271         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
   21272     }
   21273 
   21274     final void trimApplications() {
   21275         synchronized (this) {
   21276             int i;
   21277 
   21278             // First remove any unused application processes whose package
   21279             // has been removed.
   21280             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
   21281                 final ProcessRecord app = mRemovedProcesses.get(i);
   21282                 if (app.activities.size() == 0
   21283                         && app.curReceiver == null && app.services.size() == 0) {
   21284                     Slog.i(
   21285                         TAG, "Exiting empty application process "
   21286                         + app.toShortString() + " ("
   21287                         + (app.thread != null ? app.thread.asBinder() : null)
   21288                         + ")\n");
   21289                     if (app.pid > 0 && app.pid != MY_PID) {
   21290                         app.kill("empty", false);
   21291                     } else {
   21292                         try {
   21293                             app.thread.scheduleExit();
   21294                         } catch (Exception e) {
   21295                             // Ignore exceptions.
   21296                         }
   21297                     }
   21298                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
   21299                     mRemovedProcesses.remove(i);
   21300 
   21301                     if (app.persistent) {
   21302                         addAppLocked(app.info, false, null /* ABI override */);
   21303                     }
   21304                 }
   21305             }
   21306 
   21307             // Now update the oom adj for all processes.
   21308             updateOomAdjLocked();
   21309         }
   21310     }
   21311 
   21312     /** This method sends the specified signal to each of the persistent apps */
   21313     public void signalPersistentProcesses(int sig) throws RemoteException {
   21314         if (sig != Process.SIGNAL_USR1) {
   21315             throw new SecurityException("Only SIGNAL_USR1 is allowed");
   21316         }
   21317 
   21318         synchronized (this) {
   21319             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
   21320                     != PackageManager.PERMISSION_GRANTED) {
   21321                 throw new SecurityException("Requires permission "
   21322                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
   21323             }
   21324 
   21325             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   21326                 ProcessRecord r = mLruProcesses.get(i);
   21327                 if (r.thread != null && r.persistent) {
   21328                     Process.sendSignal(r.pid, sig);
   21329                 }
   21330             }
   21331         }
   21332     }
   21333 
   21334     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
   21335         if (proc == null || proc == mProfileProc) {
   21336             proc = mProfileProc;
   21337             profileType = mProfileType;
   21338             clearProfilerLocked();
   21339         }
   21340         if (proc == null) {
   21341             return;
   21342         }
   21343         try {
   21344             proc.thread.profilerControl(false, null, profileType);
   21345         } catch (RemoteException e) {
   21346             throw new IllegalStateException("Process disappeared");
   21347         }
   21348     }
   21349 
   21350     private void clearProfilerLocked() {
   21351         if (mProfileFd != null) {
   21352             try {
   21353                 mProfileFd.close();
   21354             } catch (IOException e) {
   21355             }
   21356         }
   21357         mProfileApp = null;
   21358         mProfileProc = null;
   21359         mProfileFile = null;
   21360         mProfileType = 0;
   21361         mAutoStopProfiler = false;
   21362         mSamplingInterval = 0;
   21363     }
   21364 
   21365     public boolean profileControl(String process, int userId, boolean start,
   21366             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
   21367 
   21368         try {
   21369             synchronized (this) {
   21370                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   21371                 // its own permission.
   21372                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   21373                         != PackageManager.PERMISSION_GRANTED) {
   21374                     throw new SecurityException("Requires permission "
   21375                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   21376                 }
   21377 
   21378                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
   21379                     throw new IllegalArgumentException("null profile info or fd");
   21380                 }
   21381 
   21382                 ProcessRecord proc = null;
   21383                 if (process != null) {
   21384                     proc = findProcessLocked(process, userId, "profileControl");
   21385                 }
   21386 
   21387                 if (start && (proc == null || proc.thread == null)) {
   21388                     throw new IllegalArgumentException("Unknown process: " + process);
   21389                 }
   21390 
   21391                 if (start) {
   21392                     stopProfilerLocked(null, 0);
   21393                     setProfileApp(proc.info, proc.processName, profilerInfo);
   21394                     mProfileProc = proc;
   21395                     mProfileType = profileType;
   21396                     ParcelFileDescriptor fd = profilerInfo.profileFd;
   21397                     try {
   21398                         fd = fd.dup();
   21399                     } catch (IOException e) {
   21400                         fd = null;
   21401                     }
   21402                     profilerInfo.profileFd = fd;
   21403                     proc.thread.profilerControl(start, profilerInfo, profileType);
   21404                     fd = null;
   21405                     mProfileFd = null;
   21406                 } else {
   21407                     stopProfilerLocked(proc, profileType);
   21408                     if (profilerInfo != null && profilerInfo.profileFd != null) {
   21409                         try {
   21410                             profilerInfo.profileFd.close();
   21411                         } catch (IOException e) {
   21412                         }
   21413                     }
   21414                 }
   21415 
   21416                 return true;
   21417             }
   21418         } catch (RemoteException e) {
   21419             throw new IllegalStateException("Process disappeared");
   21420         } finally {
   21421             if (profilerInfo != null && profilerInfo.profileFd != null) {
   21422                 try {
   21423                     profilerInfo.profileFd.close();
   21424                 } catch (IOException e) {
   21425                 }
   21426             }
   21427         }
   21428     }
   21429 
   21430     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
   21431         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   21432                 userId, true, ALLOW_FULL_ONLY, callName, null);
   21433         ProcessRecord proc = null;
   21434         try {
   21435             int pid = Integer.parseInt(process);
   21436             synchronized (mPidsSelfLocked) {
   21437                 proc = mPidsSelfLocked.get(pid);
   21438             }
   21439         } catch (NumberFormatException e) {
   21440         }
   21441 
   21442         if (proc == null) {
   21443             ArrayMap<String, SparseArray<ProcessRecord>> all
   21444                     = mProcessNames.getMap();
   21445             SparseArray<ProcessRecord> procs = all.get(process);
   21446             if (procs != null && procs.size() > 0) {
   21447                 proc = procs.valueAt(0);
   21448                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
   21449                     for (int i=1; i<procs.size(); i++) {
   21450                         ProcessRecord thisProc = procs.valueAt(i);
   21451                         if (thisProc.userId == userId) {
   21452                             proc = thisProc;
   21453                             break;
   21454                         }
   21455                     }
   21456                 }
   21457             }
   21458         }
   21459 
   21460         return proc;
   21461     }
   21462 
   21463     public boolean dumpHeap(String process, int userId, boolean managed,
   21464             String path, ParcelFileDescriptor fd) throws RemoteException {
   21465 
   21466         try {
   21467             synchronized (this) {
   21468                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   21469                 // its own permission (same as profileControl).
   21470                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   21471                         != PackageManager.PERMISSION_GRANTED) {
   21472                     throw new SecurityException("Requires permission "
   21473                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   21474                 }
   21475 
   21476                 if (fd == null) {
   21477                     throw new IllegalArgumentException("null fd");
   21478                 }
   21479 
   21480                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
   21481                 if (proc == null || proc.thread == null) {
   21482                     throw new IllegalArgumentException("Unknown process: " + process);
   21483                 }
   21484 
   21485                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   21486                 if (!isDebuggable) {
   21487                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   21488                         throw new SecurityException("Process not debuggable: " + proc);
   21489                     }
   21490                 }
   21491 
   21492                 proc.thread.dumpHeap(managed, path, fd);
   21493                 fd = null;
   21494                 return true;
   21495             }
   21496         } catch (RemoteException e) {
   21497             throw new IllegalStateException("Process disappeared");
   21498         } finally {
   21499             if (fd != null) {
   21500                 try {
   21501                     fd.close();
   21502                 } catch (IOException e) {
   21503                 }
   21504             }
   21505         }
   21506     }
   21507 
   21508     @Override
   21509     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
   21510             String reportPackage) {
   21511         if (processName != null) {
   21512             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   21513                     "setDumpHeapDebugLimit()");
   21514         } else {
   21515             synchronized (mPidsSelfLocked) {
   21516                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
   21517                 if (proc == null) {
   21518                     throw new SecurityException("No process found for calling pid "
   21519                             + Binder.getCallingPid());
   21520                 }
   21521                 if (!Build.IS_DEBUGGABLE
   21522                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   21523                     throw new SecurityException("Not running a debuggable build");
   21524                 }
   21525                 processName = proc.processName;
   21526                 uid = proc.uid;
   21527                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
   21528                     throw new SecurityException("Package " + reportPackage + " is not running in "
   21529                             + proc);
   21530                 }
   21531             }
   21532         }
   21533         synchronized (this) {
   21534             if (maxMemSize > 0) {
   21535                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
   21536             } else {
   21537                 if (uid != 0) {
   21538                     mMemWatchProcesses.remove(processName, uid);
   21539                 } else {
   21540                     mMemWatchProcesses.getMap().remove(processName);
   21541                 }
   21542             }
   21543         }
   21544     }
   21545 
   21546     @Override
   21547     public void dumpHeapFinished(String path) {
   21548         synchronized (this) {
   21549             if (Binder.getCallingPid() != mMemWatchDumpPid) {
   21550                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
   21551                         + " does not match last pid " + mMemWatchDumpPid);
   21552                 return;
   21553             }
   21554             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
   21555                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
   21556                         + " does not match last path " + mMemWatchDumpFile);
   21557                 return;
   21558             }
   21559             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
   21560             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
   21561         }
   21562     }
   21563 
   21564     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
   21565     public void monitor() {
   21566         synchronized (this) { }
   21567     }
   21568 
   21569     void onCoreSettingsChange(Bundle settings) {
   21570         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   21571             ProcessRecord processRecord = mLruProcesses.get(i);
   21572             try {
   21573                 if (processRecord.thread != null) {
   21574                     processRecord.thread.setCoreSettings(settings);
   21575                 }
   21576             } catch (RemoteException re) {
   21577                 /* ignore */
   21578             }
   21579         }
   21580     }
   21581 
   21582     // Multi-user methods
   21583 
   21584     /**
   21585      * Start user, if its not already running, but don't bring it to foreground.
   21586      */
   21587     @Override
   21588     public boolean startUserInBackground(final int userId) {
   21589         return mUserController.startUser(userId, /* foreground */ false);
   21590     }
   21591 
   21592     @Override
   21593     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
   21594         return mUserController.unlockUser(userId, token, secret, listener);
   21595     }
   21596 
   21597     @Override
   21598     public boolean switchUser(final int targetUserId) {
   21599         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
   21600         UserInfo currentUserInfo;
   21601         UserInfo targetUserInfo;
   21602         synchronized (this) {
   21603             int currentUserId = mUserController.getCurrentUserIdLocked();
   21604             currentUserInfo = mUserController.getUserInfo(currentUserId);
   21605             targetUserInfo = mUserController.getUserInfo(targetUserId);
   21606             if (targetUserInfo == null) {
   21607                 Slog.w(TAG, "No user info for user #" + targetUserId);
   21608                 return false;
   21609             }
   21610             if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
   21611                 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
   21612                         + " when device is in demo mode");
   21613                 return false;
   21614             }
   21615             if (!targetUserInfo.supportsSwitchTo()) {
   21616                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
   21617                 return false;
   21618             }
   21619             if (targetUserInfo.isManagedProfile()) {
   21620                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
   21621                 return false;
   21622             }
   21623             mUserController.setTargetUserIdLocked(targetUserId);
   21624         }
   21625         Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
   21626         mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
   21627         mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
   21628         return true;
   21629     }
   21630 
   21631     void scheduleStartProfilesLocked() {
   21632         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
   21633             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
   21634                     DateUtils.SECOND_IN_MILLIS);
   21635         }
   21636     }
   21637 
   21638     @Override
   21639     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
   21640         return mUserController.stopUser(userId, force, callback);
   21641     }
   21642 
   21643     @Override
   21644     public UserInfo getCurrentUser() {
   21645         return mUserController.getCurrentUser();
   21646     }
   21647 
   21648     @Override
   21649     public boolean isUserRunning(int userId, int flags) {
   21650         if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
   21651                 && checkCallingPermission(INTERACT_ACROSS_USERS)
   21652                     != PackageManager.PERMISSION_GRANTED) {
   21653             String msg = "Permission Denial: isUserRunning() from pid="
   21654                     + Binder.getCallingPid()
   21655                     + ", uid=" + Binder.getCallingUid()
   21656                     + " requires " + INTERACT_ACROSS_USERS;
   21657             Slog.w(TAG, msg);
   21658             throw new SecurityException(msg);
   21659         }
   21660         synchronized (this) {
   21661             return mUserController.isUserRunningLocked(userId, flags);
   21662         }
   21663     }
   21664 
   21665     @Override
   21666     public int[] getRunningUserIds() {
   21667         if (checkCallingPermission(INTERACT_ACROSS_USERS)
   21668                 != PackageManager.PERMISSION_GRANTED) {
   21669             String msg = "Permission Denial: isUserRunning() from pid="
   21670                     + Binder.getCallingPid()
   21671                     + ", uid=" + Binder.getCallingUid()
   21672                     + " requires " + INTERACT_ACROSS_USERS;
   21673             Slog.w(TAG, msg);
   21674             throw new SecurityException(msg);
   21675         }
   21676         synchronized (this) {
   21677             return mUserController.getStartedUserArrayLocked();
   21678         }
   21679     }
   21680 
   21681     @Override
   21682     public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
   21683         mUserController.registerUserSwitchObserver(observer, name);
   21684     }
   21685 
   21686     @Override
   21687     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
   21688         mUserController.unregisterUserSwitchObserver(observer);
   21689     }
   21690 
   21691     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
   21692         if (info == null) return null;
   21693         ApplicationInfo newInfo = new ApplicationInfo(info);
   21694         newInfo.initForUser(userId);
   21695         return newInfo;
   21696     }
   21697 
   21698     public boolean isUserStopped(int userId) {
   21699         synchronized (this) {
   21700             return mUserController.getStartedUserStateLocked(userId) == null;
   21701         }
   21702     }
   21703 
   21704     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
   21705         if (aInfo == null
   21706                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
   21707             return aInfo;
   21708         }
   21709 
   21710         ActivityInfo info = new ActivityInfo(aInfo);
   21711         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
   21712         return info;
   21713     }
   21714 
   21715     private boolean processSanityChecksLocked(ProcessRecord process) {
   21716         if (process == null || process.thread == null) {
   21717             return false;
   21718         }
   21719 
   21720         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   21721         if (!isDebuggable) {
   21722             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   21723                 return false;
   21724             }
   21725         }
   21726 
   21727         return true;
   21728     }
   21729 
   21730     public boolean startBinderTracking() throws RemoteException {
   21731         synchronized (this) {
   21732             mBinderTransactionTrackingEnabled = true;
   21733             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
   21734             // permission (same as profileControl).
   21735             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   21736                     != PackageManager.PERMISSION_GRANTED) {
   21737                 throw new SecurityException("Requires permission "
   21738                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   21739             }
   21740 
   21741             for (int i = 0; i < mLruProcesses.size(); i++) {
   21742                 ProcessRecord process = mLruProcesses.get(i);
   21743                 if (!processSanityChecksLocked(process)) {
   21744                     continue;
   21745                 }
   21746                 try {
   21747                     process.thread.startBinderTracking();
   21748                 } catch (RemoteException e) {
   21749                     Log.v(TAG, "Process disappared");
   21750                 }
   21751             }
   21752             return true;
   21753         }
   21754     }
   21755 
   21756     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
   21757         try {
   21758             synchronized (this) {
   21759                 mBinderTransactionTrackingEnabled = false;
   21760                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
   21761                 // permission (same as profileControl).
   21762                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   21763                         != PackageManager.PERMISSION_GRANTED) {
   21764                     throw new SecurityException("Requires permission "
   21765                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   21766                 }
   21767 
   21768                 if (fd == null) {
   21769                     throw new IllegalArgumentException("null fd");
   21770                 }
   21771 
   21772                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
   21773                 pw.println("Binder transaction traces for all processes.\n");
   21774                 for (ProcessRecord process : mLruProcesses) {
   21775                     if (!processSanityChecksLocked(process)) {
   21776                         continue;
   21777                     }
   21778 
   21779                     pw.println("Traces for process: " + process.processName);
   21780                     pw.flush();
   21781                     try {
   21782                         TransferPipe tp = new TransferPipe();
   21783                         try {
   21784                             process.thread.stopBinderTrackingAndDump(
   21785                                     tp.getWriteFd().getFileDescriptor());
   21786                             tp.go(fd.getFileDescriptor());
   21787                         } finally {
   21788                             tp.kill();
   21789                         }
   21790                     } catch (IOException e) {
   21791                         pw.println("Failure while dumping IPC traces from " + process +
   21792                                 ".  Exception: " + e);
   21793                         pw.flush();
   21794                     } catch (RemoteException e) {
   21795                         pw.println("Got a RemoteException while dumping IPC traces from " +
   21796                                 process + ".  Exception: " + e);
   21797                         pw.flush();
   21798                     }
   21799                 }
   21800                 fd = null;
   21801                 return true;
   21802             }
   21803         } finally {
   21804             if (fd != null) {
   21805                 try {
   21806                     fd.close();
   21807                 } catch (IOException e) {
   21808                 }
   21809             }
   21810         }
   21811     }
   21812 
   21813     private final class LocalService extends ActivityManagerInternal {
   21814         @Override
   21815         public void onWakefulnessChanged(int wakefulness) {
   21816             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
   21817         }
   21818 
   21819         @Override
   21820         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
   21821                 String processName, String abiOverride, int uid, Runnable crashHandler) {
   21822             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
   21823                     processName, abiOverride, uid, crashHandler);
   21824         }
   21825 
   21826         @Override
   21827         public SleepToken acquireSleepToken(String tag) {
   21828             Preconditions.checkNotNull(tag);
   21829 
   21830             ComponentName requestedVrService = null;
   21831             ComponentName callingVrActivity = null;
   21832             int userId = -1;
   21833             synchronized (ActivityManagerService.this) {
   21834                 if (mFocusedActivity != null) {
   21835                     requestedVrService = mFocusedActivity.requestedVrComponent;
   21836                     callingVrActivity = mFocusedActivity.info.getComponentName();
   21837                     userId = mFocusedActivity.userId;
   21838                 }
   21839             }
   21840 
   21841             if (requestedVrService != null) {
   21842                 applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
   21843             }
   21844 
   21845             synchronized (ActivityManagerService.this) {
   21846                 SleepTokenImpl token = new SleepTokenImpl(tag);
   21847                 mSleepTokens.add(token);
   21848                 updateSleepIfNeededLocked();
   21849                 return token;
   21850             }
   21851         }
   21852 
   21853         @Override
   21854         public ComponentName getHomeActivityForUser(int userId) {
   21855             synchronized (ActivityManagerService.this) {
   21856                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
   21857                 return homeActivity == null ? null : homeActivity.realActivity;
   21858             }
   21859         }
   21860 
   21861         @Override
   21862         public void onUserRemoved(int userId) {
   21863             synchronized (ActivityManagerService.this) {
   21864                 ActivityManagerService.this.onUserStoppedLocked(userId);
   21865             }
   21866         }
   21867 
   21868         @Override
   21869         public void onLocalVoiceInteractionStarted(IBinder activity,
   21870                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
   21871             synchronized (ActivityManagerService.this) {
   21872                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
   21873                         voiceSession, voiceInteractor);
   21874             }
   21875         }
   21876 
   21877         @Override
   21878         public void notifyStartingWindowDrawn() {
   21879             synchronized (ActivityManagerService.this) {
   21880                 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
   21881             }
   21882         }
   21883 
   21884         @Override
   21885         public void notifyAppTransitionStarting(int reason) {
   21886             synchronized (ActivityManagerService.this) {
   21887                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
   21888             }
   21889         }
   21890 
   21891         @Override
   21892         public void notifyAppTransitionFinished() {
   21893             synchronized (ActivityManagerService.this) {
   21894                 mStackSupervisor.notifyAppTransitionDone();
   21895             }
   21896         }
   21897 
   21898         @Override
   21899         public void notifyAppTransitionCancelled() {
   21900             synchronized (ActivityManagerService.this) {
   21901                 mStackSupervisor.notifyAppTransitionDone();
   21902             }
   21903         }
   21904 
   21905         @Override
   21906         public List<IBinder> getTopVisibleActivities() {
   21907             synchronized (ActivityManagerService.this) {
   21908                 return mStackSupervisor.getTopVisibleActivities();
   21909             }
   21910         }
   21911 
   21912         @Override
   21913         public void notifyDockedStackMinimizedChanged(boolean minimized) {
   21914             synchronized (ActivityManagerService.this) {
   21915                 mStackSupervisor.setDockedStackMinimized(minimized);
   21916             }
   21917         }
   21918 
   21919         @Override
   21920         public void killForegroundAppsForUser(int userHandle) {
   21921             synchronized (ActivityManagerService.this) {
   21922                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
   21923                 final int NP = mProcessNames.getMap().size();
   21924                 for (int ip = 0; ip < NP; ip++) {
   21925                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   21926                     final int NA = apps.size();
   21927                     for (int ia = 0; ia < NA; ia++) {
   21928                         final ProcessRecord app = apps.valueAt(ia);
   21929                         if (app.persistent) {
   21930                             // We don't kill persistent processes.
   21931                             continue;
   21932                         }
   21933                         if (app.removed) {
   21934                             procs.add(app);
   21935                         } else if (app.userId == userHandle && app.foregroundActivities) {
   21936                             app.removed = true;
   21937                             procs.add(app);
   21938                         }
   21939                     }
   21940                 }
   21941 
   21942                 final int N = procs.size();
   21943                 for (int i = 0; i < N; i++) {
   21944                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
   21945                 }
   21946             }
   21947         }
   21948 
   21949         @Override
   21950         public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
   21951             if (!(target instanceof PendingIntentRecord)) {
   21952                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
   21953                 return;
   21954             }
   21955             ((PendingIntentRecord) target).setWhitelistDuration(duration);
   21956         }
   21957 
   21958         @Override
   21959         public void updatePersistentConfigurationForUser(@NonNull Configuration values,
   21960                 int userId) {
   21961             Preconditions.checkNotNull(values, "Configuration must not be null");
   21962             Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
   21963             synchronized (ActivityManagerService.this) {
   21964                 updateConfigurationLocked(values, null, false, true, userId,
   21965                         false /* deferResume */);
   21966             }
   21967         }
   21968 
   21969         @Override
   21970         public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
   21971                 Bundle bOptions) {
   21972             Preconditions.checkNotNull(intents, "intents");
   21973             final String[] resolvedTypes = new String[intents.length];
   21974             for (int i = 0; i < intents.length; i++) {
   21975                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
   21976             }
   21977 
   21978             // UID of the package on user userId.
   21979             // "= 0" is needed because otherwise catch(RemoteException) would make it look like
   21980             // packageUid may not be initialized.
   21981             int packageUid = 0;
   21982             try {
   21983                 packageUid = AppGlobals.getPackageManager().getPackageUid(
   21984                         packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
   21985             } catch (RemoteException e) {
   21986                 // Shouldn't happen.
   21987             }
   21988 
   21989             synchronized (ActivityManagerService.this) {
   21990                 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
   21991                         /*resultTo*/ null, bOptions, userId);
   21992             }
   21993         }
   21994 
   21995         @Override
   21996         public int getUidProcessState(int uid) {
   21997             return getUidState(uid);
   21998         }
   21999     }
   22000 
   22001     private final class SleepTokenImpl extends SleepToken {
   22002         private final String mTag;
   22003         private final long mAcquireTime;
   22004 
   22005         public SleepTokenImpl(String tag) {
   22006             mTag = tag;
   22007             mAcquireTime = SystemClock.uptimeMillis();
   22008         }
   22009 
   22010         @Override
   22011         public void release() {
   22012             synchronized (ActivityManagerService.this) {
   22013                 if (mSleepTokens.remove(this)) {
   22014                     updateSleepIfNeededLocked();
   22015                 }
   22016             }
   22017         }
   22018 
   22019         @Override
   22020         public String toString() {
   22021             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
   22022         }
   22023     }
   22024 
   22025     /**
   22026      * An implementation of IAppTask, that allows an app to manage its own tasks via
   22027      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
   22028      * only the process that calls getAppTasks() can call the AppTask methods.
   22029      */
   22030     class AppTaskImpl extends IAppTask.Stub {
   22031         private int mTaskId;
   22032         private int mCallingUid;
   22033 
   22034         public AppTaskImpl(int taskId, int callingUid) {
   22035             mTaskId = taskId;
   22036             mCallingUid = callingUid;
   22037         }
   22038 
   22039         private void checkCaller() {
   22040             if (mCallingUid != Binder.getCallingUid()) {
   22041                 throw new SecurityException("Caller " + mCallingUid
   22042                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
   22043             }
   22044         }
   22045 
   22046         @Override
   22047         public void finishAndRemoveTask() {
   22048             checkCaller();
   22049 
   22050             synchronized (ActivityManagerService.this) {
   22051                 long origId = Binder.clearCallingIdentity();
   22052                 try {
   22053                     // We remove the task from recents to preserve backwards
   22054                     if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
   22055                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   22056                     }
   22057                 } finally {
   22058                     Binder.restoreCallingIdentity(origId);
   22059                 }
   22060             }
   22061         }
   22062 
   22063         @Override
   22064         public ActivityManager.RecentTaskInfo getTaskInfo() {
   22065             checkCaller();
   22066 
   22067             synchronized (ActivityManagerService.this) {
   22068                 long origId = Binder.clearCallingIdentity();
   22069                 try {
   22070                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
   22071                     if (tr == null) {
   22072                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   22073                     }
   22074                     return createRecentTaskInfoFromTaskRecord(tr);
   22075                 } finally {
   22076                     Binder.restoreCallingIdentity(origId);
   22077                 }
   22078             }
   22079         }
   22080 
   22081         @Override
   22082         public void moveToFront() {
   22083             checkCaller();
   22084             // Will bring task to front if it already has a root activity.
   22085             final long origId = Binder.clearCallingIdentity();
   22086             try {
   22087                 synchronized (this) {
   22088                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
   22089                 }
   22090             } finally {
   22091                 Binder.restoreCallingIdentity(origId);
   22092             }
   22093         }
   22094 
   22095         @Override
   22096         public int startActivity(IBinder whoThread, String callingPackage,
   22097                 Intent intent, String resolvedType, Bundle bOptions) {
   22098             checkCaller();
   22099 
   22100             int callingUser = UserHandle.getCallingUserId();
   22101             TaskRecord tr;
   22102             IApplicationThread appThread;
   22103             synchronized (ActivityManagerService.this) {
   22104                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
   22105                 if (tr == null) {
   22106                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   22107                 }
   22108                 appThread = ApplicationThreadNative.asInterface(whoThread);
   22109                 if (appThread == null) {
   22110                     throw new IllegalArgumentException("Bad app thread " + appThread);
   22111                 }
   22112             }
   22113             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
   22114                     resolvedType, null, null, null, null, 0, 0, null, null,
   22115                     null, bOptions, false, callingUser, null, tr);
   22116         }
   22117 
   22118         @Override
   22119         public void setExcludeFromRecents(boolean exclude) {
   22120             checkCaller();
   22121 
   22122             synchronized (ActivityManagerService.this) {
   22123                 long origId = Binder.clearCallingIdentity();
   22124                 try {
   22125                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
   22126                     if (tr == null) {
   22127                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   22128                     }
   22129                     Intent intent = tr.getBaseIntent();
   22130                     if (exclude) {
   22131                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
   22132                     } else {
   22133                         intent.setFlags(intent.getFlags()
   22134                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
   22135                     }
   22136                 } finally {
   22137                     Binder.restoreCallingIdentity(origId);
   22138                 }
   22139             }
   22140         }
   22141     }
   22142 
   22143     /**
   22144      * Kill processes for the user with id userId and that depend on the package named packageName
   22145      */
   22146     @Override
   22147     public void killPackageDependents(String packageName, int userId) {
   22148         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
   22149         if (packageName == null) {
   22150             throw new NullPointerException(
   22151                     "Cannot kill the dependents of a package without its name.");
   22152         }
   22153 
   22154         long callingId = Binder.clearCallingIdentity();
   22155         IPackageManager pm = AppGlobals.getPackageManager();
   22156         int pkgUid = -1;
   22157         try {
   22158             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
   22159         } catch (RemoteException e) {
   22160         }
   22161         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
   22162             throw new IllegalArgumentException(
   22163                     "Cannot kill dependents of non-existing package " + packageName);
   22164         }
   22165         try {
   22166             synchronized(this) {
   22167                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
   22168                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
   22169                         "dep: " + packageName);
   22170             }
   22171         } finally {
   22172             Binder.restoreCallingIdentity(callingId);
   22173         }
   22174     }
   22175 }
   22176