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                 && mLockScreenShown != LOCK_SCREEN_SHOWN;
    646     }
    647 
    648     private static final class PriorityState {
    649         // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
    650         // the current thread is currently in. When it drops down to zero, we will no longer boost
    651         // the thread's priority.
    652         private int regionCounter = 0;
    653 
    654         // The thread's previous priority before boosting.
    655         private int prevPriority = Integer.MIN_VALUE;
    656     }
    657 
    658     static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
    659         @Override protected PriorityState initialValue() {
    660             return new PriorityState();
    661         }
    662     };
    663 
    664     static void boostPriorityForLockedSection() {
    665         int tid = Process.myTid();
    666         int prevPriority = Process.getThreadPriority(tid);
    667         PriorityState state = sThreadPriorityState.get();
    668         if (state.regionCounter == 0 && prevPriority > -2) {
    669             state.prevPriority = prevPriority;
    670             Process.setThreadPriority(tid, -2);
    671         }
    672         state.regionCounter++;
    673     }
    674 
    675     static void resetPriorityAfterLockedSection() {
    676         PriorityState state = sThreadPriorityState.get();
    677         state.regionCounter--;
    678         if (state.regionCounter == 0 && state.prevPriority > -2) {
    679             Process.setThreadPriority(Process.myTid(), state.prevPriority);
    680         }
    681     }
    682 
    683     public class PendingAssistExtras extends Binder implements Runnable {
    684         public final ActivityRecord activity;
    685         public final Bundle extras;
    686         public final Intent intent;
    687         public final String hint;
    688         public final IResultReceiver receiver;
    689         public final int userHandle;
    690         public boolean haveResult = false;
    691         public Bundle result = null;
    692         public AssistStructure structure = null;
    693         public AssistContent content = null;
    694         public Bundle receiverExtras;
    695 
    696         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
    697                 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
    698             activity = _activity;
    699             extras = _extras;
    700             intent = _intent;
    701             hint = _hint;
    702             receiver = _receiver;
    703             receiverExtras = _receiverExtras;
    704             userHandle = _userHandle;
    705         }
    706         @Override
    707         public void run() {
    708             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
    709             synchronized (this) {
    710                 haveResult = true;
    711                 notifyAll();
    712             }
    713             pendingAssistExtrasTimedOut(this);
    714         }
    715     }
    716 
    717     final ArrayList<PendingAssistExtras> mPendingAssistExtras
    718             = new ArrayList<PendingAssistExtras>();
    719 
    720     /**
    721      * Process management.
    722      */
    723     final ProcessList mProcessList = new ProcessList();
    724 
    725     /**
    726      * All of the applications we currently have running organized by name.
    727      * The keys are strings of the application package name (as
    728      * returned by the package manager), and the keys are ApplicationRecord
    729      * objects.
    730      */
    731     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
    732 
    733     /**
    734      * Tracking long-term execution of processes to look for abuse and other
    735      * bad app behavior.
    736      */
    737     final ProcessStatsService mProcessStats;
    738 
    739     /**
    740      * The currently running isolated processes.
    741      */
    742     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
    743 
    744     /**
    745      * Counter for assigning isolated process uids, to avoid frequently reusing the
    746      * same ones.
    747      */
    748     int mNextIsolatedProcessUid = 0;
    749 
    750     /**
    751      * The currently running heavy-weight process, if any.
    752      */
    753     ProcessRecord mHeavyWeightProcess = null;
    754 
    755     /**
    756      * All of the processes we currently have running organized by pid.
    757      * The keys are the pid running the application.
    758      *
    759      * <p>NOTE: This object is protected by its own lock, NOT the global
    760      * activity manager lock!
    761      */
    762     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
    763 
    764     /**
    765      * All of the processes that have been forced to be foreground.  The key
    766      * is the pid of the caller who requested it (we hold a death
    767      * link on it).
    768      */
    769     abstract class ForegroundToken implements IBinder.DeathRecipient {
    770         int pid;
    771         IBinder token;
    772     }
    773     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
    774 
    775     /**
    776      * List of records for processes that someone had tried to start before the
    777      * system was ready.  We don't start them at that point, but ensure they
    778      * are started by the time booting is complete.
    779      */
    780     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
    781 
    782     /**
    783      * List of persistent applications that are in the process
    784      * of being started.
    785      */
    786     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
    787 
    788     /**
    789      * Processes that are being forcibly torn down.
    790      */
    791     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
    792 
    793     /**
    794      * List of running applications, sorted by recent usage.
    795      * The first entry in the list is the least recently used.
    796      */
    797     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
    798 
    799     /**
    800      * Where in mLruProcesses that the processes hosting activities start.
    801      */
    802     int mLruProcessActivityStart = 0;
    803 
    804     /**
    805      * Where in mLruProcesses that the processes hosting services start.
    806      * This is after (lower index) than mLruProcessesActivityStart.
    807      */
    808     int mLruProcessServiceStart = 0;
    809 
    810     /**
    811      * List of processes that should gc as soon as things are idle.
    812      */
    813     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
    814 
    815     /**
    816      * Processes we want to collect PSS data from.
    817      */
    818     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
    819 
    820     private boolean mBinderTransactionTrackingEnabled = false;
    821 
    822     /**
    823      * Last time we requested PSS data of all processes.
    824      */
    825     long mLastFullPssTime = SystemClock.uptimeMillis();
    826 
    827     /**
    828      * If set, the next time we collect PSS data we should do a full collection
    829      * with data from native processes and the kernel.
    830      */
    831     boolean mFullPssPending = false;
    832 
    833     /**
    834      * This is the process holding what we currently consider to be
    835      * the "home" activity.
    836      */
    837     ProcessRecord mHomeProcess;
    838 
    839     /**
    840      * This is the process holding the activity the user last visited that
    841      * is in a different process from the one they are currently in.
    842      */
    843     ProcessRecord mPreviousProcess;
    844 
    845     /**
    846      * The time at which the previous process was last visible.
    847      */
    848     long mPreviousProcessVisibleTime;
    849 
    850     /**
    851      * Track all uids that have actively running processes.
    852      */
    853     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
    854 
    855     /**
    856      * This is for verifying the UID report flow.
    857      */
    858     static final boolean VALIDATE_UID_STATES = true;
    859     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
    860 
    861     /**
    862      * Packages that the user has asked to have run in screen size
    863      * compatibility mode instead of filling the screen.
    864      */
    865     final CompatModePackages mCompatModePackages;
    866 
    867     /**
    868      * Set of IntentSenderRecord objects that are currently active.
    869      */
    870     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
    871             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
    872 
    873     /**
    874      * Fingerprints (hashCode()) of stack traces that we've
    875      * already logged DropBox entries for.  Guarded by itself.  If
    876      * something (rogue user app) forces this over
    877      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
    878      */
    879     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
    880     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
    881 
    882     /**
    883      * Strict Mode background batched logging state.
    884      *
    885      * The string buffer is guarded by itself, and its lock is also
    886      * used to determine if another batched write is already
    887      * in-flight.
    888      */
    889     private final StringBuilder mStrictModeBuffer = new StringBuilder();
    890 
    891     /**
    892      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
    893      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
    894      */
    895     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
    896 
    897     /**
    898      * Resolver for broadcast intents to registered receivers.
    899      * Holds BroadcastFilter (subclass of IntentFilter).
    900      */
    901     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
    902             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
    903         @Override
    904         protected boolean allowFilterResult(
    905                 BroadcastFilter filter, List<BroadcastFilter> dest) {
    906             IBinder target = filter.receiverList.receiver.asBinder();
    907             for (int i = dest.size() - 1; i >= 0; i--) {
    908                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
    909                     return false;
    910                 }
    911             }
    912             return true;
    913         }
    914 
    915         @Override
    916         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
    917             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
    918                     || userId == filter.owningUserId) {
    919                 return super.newResult(filter, match, userId);
    920             }
    921             return null;
    922         }
    923 
    924         @Override
    925         protected BroadcastFilter[] newArray(int size) {
    926             return new BroadcastFilter[size];
    927         }
    928 
    929         @Override
    930         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
    931             return packageName.equals(filter.packageName);
    932         }
    933     };
    934 
    935     /**
    936      * State of all active sticky broadcasts per user.  Keys are the action of the
    937      * sticky Intent, values are an ArrayList of all broadcasted intents with
    938      * that action (which should usually be one).  The SparseArray is keyed
    939      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
    940      * for stickies that are sent to all users.
    941      */
    942     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
    943             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
    944 
    945     final ActiveServices mServices;
    946 
    947     final static class Association {
    948         final int mSourceUid;
    949         final String mSourceProcess;
    950         final int mTargetUid;
    951         final ComponentName mTargetComponent;
    952         final String mTargetProcess;
    953 
    954         int mCount;
    955         long mTime;
    956 
    957         int mNesting;
    958         long mStartTime;
    959 
    960         // states of the source process when the bind occurred.
    961         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
    962         long mLastStateUptime;
    963         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
    964                 - ActivityManager.MIN_PROCESS_STATE+1];
    965 
    966         Association(int sourceUid, String sourceProcess, int targetUid,
    967                 ComponentName targetComponent, String targetProcess) {
    968             mSourceUid = sourceUid;
    969             mSourceProcess = sourceProcess;
    970             mTargetUid = targetUid;
    971             mTargetComponent = targetComponent;
    972             mTargetProcess = targetProcess;
    973         }
    974     }
    975 
    976     /**
    977      * When service association tracking is enabled, this is all of the associations we
    978      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
    979      * -> association data.
    980      */
    981     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
    982             mAssociations = new SparseArray<>();
    983     boolean mTrackingAssociations;
    984 
    985     /**
    986      * Backup/restore process management
    987      */
    988     String mBackupAppName = null;
    989     BackupRecord mBackupTarget = null;
    990 
    991     final ProviderMap mProviderMap;
    992 
    993     /**
    994      * List of content providers who have clients waiting for them.  The
    995      * application is currently being launched and the provider will be
    996      * removed from this list once it is published.
    997      */
    998     final ArrayList<ContentProviderRecord> mLaunchingProviders
    999             = new ArrayList<ContentProviderRecord>();
   1000 
   1001     /**
   1002      * File storing persisted {@link #mGrantedUriPermissions}.
   1003      */
   1004     private final AtomicFile mGrantFile;
   1005 
   1006     /** XML constants used in {@link #mGrantFile} */
   1007     private static final String TAG_URI_GRANTS = "uri-grants";
   1008     private static final String TAG_URI_GRANT = "uri-grant";
   1009     private static final String ATTR_USER_HANDLE = "userHandle";
   1010     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
   1011     private static final String ATTR_TARGET_USER_ID = "targetUserId";
   1012     private static final String ATTR_SOURCE_PKG = "sourcePkg";
   1013     private static final String ATTR_TARGET_PKG = "targetPkg";
   1014     private static final String ATTR_URI = "uri";
   1015     private static final String ATTR_MODE_FLAGS = "modeFlags";
   1016     private static final String ATTR_CREATED_TIME = "createdTime";
   1017     private static final String ATTR_PREFIX = "prefix";
   1018 
   1019     /**
   1020      * Global set of specific {@link Uri} permissions that have been granted.
   1021      * This optimized lookup structure maps from {@link UriPermission#targetUid}
   1022      * to {@link UriPermission#uri} to {@link UriPermission}.
   1023      */
   1024     @GuardedBy("this")
   1025     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
   1026             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
   1027 
   1028     public static class GrantUri {
   1029         public final int sourceUserId;
   1030         public final Uri uri;
   1031         public boolean prefix;
   1032 
   1033         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
   1034             this.sourceUserId = sourceUserId;
   1035             this.uri = uri;
   1036             this.prefix = prefix;
   1037         }
   1038 
   1039         @Override
   1040         public int hashCode() {
   1041             int hashCode = 1;
   1042             hashCode = 31 * hashCode + sourceUserId;
   1043             hashCode = 31 * hashCode + uri.hashCode();
   1044             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
   1045             return hashCode;
   1046         }
   1047 
   1048         @Override
   1049         public boolean equals(Object o) {
   1050             if (o instanceof GrantUri) {
   1051                 GrantUri other = (GrantUri) o;
   1052                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
   1053                         && prefix == other.prefix;
   1054             }
   1055             return false;
   1056         }
   1057 
   1058         @Override
   1059         public String toString() {
   1060             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
   1061             if (prefix) result += " [prefix]";
   1062             return result;
   1063         }
   1064 
   1065         public String toSafeString() {
   1066             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
   1067             if (prefix) result += " [prefix]";
   1068             return result;
   1069         }
   1070 
   1071         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
   1072             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
   1073                     ContentProvider.getUriWithoutUserId(uri), false);
   1074         }
   1075     }
   1076 
   1077     CoreSettingsObserver mCoreSettingsObserver;
   1078 
   1079     FontScaleSettingObserver mFontScaleSettingObserver;
   1080 
   1081     private final class FontScaleSettingObserver extends ContentObserver {
   1082         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
   1083 
   1084         public FontScaleSettingObserver() {
   1085             super(mHandler);
   1086             ContentResolver resolver = mContext.getContentResolver();
   1087             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
   1088         }
   1089 
   1090         @Override
   1091         public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
   1092             if (mFontScaleUri.equals(uri)) {
   1093                 updateFontScaleIfNeeded(userId);
   1094             }
   1095         }
   1096     }
   1097 
   1098     /**
   1099      * Thread-local storage used to carry caller permissions over through
   1100      * indirect content-provider access.
   1101      */
   1102     private class Identity {
   1103         public final IBinder token;
   1104         public final int pid;
   1105         public final int uid;
   1106 
   1107         Identity(IBinder _token, int _pid, int _uid) {
   1108             token = _token;
   1109             pid = _pid;
   1110             uid = _uid;
   1111         }
   1112     }
   1113 
   1114     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
   1115 
   1116     /**
   1117      * All information we have collected about the runtime performance of
   1118      * any user id that can impact battery performance.
   1119      */
   1120     final BatteryStatsService mBatteryStatsService;
   1121 
   1122     /**
   1123      * Information about component usage
   1124      */
   1125     UsageStatsManagerInternal mUsageStatsService;
   1126 
   1127     /**
   1128      * Access to DeviceIdleController service.
   1129      */
   1130     DeviceIdleController.LocalService mLocalDeviceIdleController;
   1131 
   1132     /**
   1133      * Information about and control over application operations
   1134      */
   1135     final AppOpsService mAppOpsService;
   1136 
   1137     /**
   1138      * Current configuration information.  HistoryRecord objects are given
   1139      * a reference to this object to indicate which configuration they are
   1140      * currently running in, so this object must be kept immutable.
   1141      */
   1142     Configuration mConfiguration = new Configuration();
   1143 
   1144     /**
   1145      * Current sequencing integer of the configuration, for skipping old
   1146      * configurations.
   1147      */
   1148     int mConfigurationSeq = 0;
   1149 
   1150     boolean mSuppressResizeConfigChanges = false;
   1151 
   1152     /**
   1153      * Hardware-reported OpenGLES version.
   1154      */
   1155     final int GL_ES_VERSION;
   1156 
   1157     /**
   1158      * List of initialization arguments to pass to all processes when binding applications to them.
   1159      * For example, references to the commonly used services.
   1160      */
   1161     HashMap<String, IBinder> mAppBindArgs;
   1162     HashMap<String, IBinder> mIsolatedAppBindArgs;
   1163 
   1164     /**
   1165      * Temporary to avoid allocations.  Protected by main lock.
   1166      */
   1167     final StringBuilder mStringBuilder = new StringBuilder(256);
   1168 
   1169     /**
   1170      * Used to control how we initialize the service.
   1171      */
   1172     ComponentName mTopComponent;
   1173     String mTopAction = Intent.ACTION_MAIN;
   1174     String mTopData;
   1175 
   1176     volatile boolean mProcessesReady = false;
   1177     volatile boolean mSystemReady = false;
   1178     volatile boolean mOnBattery = false;
   1179     volatile int mFactoryTest;
   1180 
   1181     @GuardedBy("this") boolean mBooting = false;
   1182     @GuardedBy("this") boolean mCallFinishBooting = false;
   1183     @GuardedBy("this") boolean mBootAnimationComplete = false;
   1184     @GuardedBy("this") boolean mLaunchWarningShown = false;
   1185     @GuardedBy("this") boolean mCheckedForSetup = false;
   1186 
   1187     Context mContext;
   1188 
   1189     /**
   1190      * The time at which we will allow normal application switches again,
   1191      * after a call to {@link #stopAppSwitches()}.
   1192      */
   1193     long mAppSwitchesAllowedTime;
   1194 
   1195     /**
   1196      * This is set to true after the first switch after mAppSwitchesAllowedTime
   1197      * is set; any switches after that will clear the time.
   1198      */
   1199     boolean mDidAppSwitch;
   1200 
   1201     /**
   1202      * Last time (in realtime) at which we checked for power usage.
   1203      */
   1204     long mLastPowerCheckRealtime;
   1205 
   1206     /**
   1207      * Last time (in uptime) at which we checked for power usage.
   1208      */
   1209     long mLastPowerCheckUptime;
   1210 
   1211     /**
   1212      * Set while we are wanting to sleep, to prevent any
   1213      * activities from being started/resumed.
   1214      */
   1215     private boolean mSleeping = false;
   1216 
   1217     /**
   1218      * The process state used for processes that are running the top activities.
   1219      * This changes between TOP and TOP_SLEEPING to following mSleeping.
   1220      */
   1221     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
   1222 
   1223     /**
   1224      * Set while we are running a voice interaction.  This overrides
   1225      * sleeping while it is active.
   1226      */
   1227     private IVoiceInteractionSession mRunningVoice;
   1228 
   1229     /**
   1230      * For some direct access we need to power manager.
   1231      */
   1232     PowerManagerInternal mLocalPowerManager;
   1233 
   1234     /**
   1235      * We want to hold a wake lock while running a voice interaction session, since
   1236      * this may happen with the screen off and we need to keep the CPU running to
   1237      * be able to continue to interact with the user.
   1238      */
   1239     PowerManager.WakeLock mVoiceWakeLock;
   1240 
   1241     /**
   1242      * State of external calls telling us if the device is awake or asleep.
   1243      */
   1244     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
   1245 
   1246     /**
   1247      * A list of tokens that cause the top activity to be put to sleep.
   1248      * They are used by components that may hide and block interaction with underlying
   1249      * activities.
   1250      */
   1251     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
   1252 
   1253     static final int LOCK_SCREEN_HIDDEN = 0;
   1254     static final int LOCK_SCREEN_LEAVING = 1;
   1255     static final int LOCK_SCREEN_SHOWN = 2;
   1256     /**
   1257      * State of external call telling us if the lock screen is shown.
   1258      */
   1259     int mLockScreenShown = LOCK_SCREEN_HIDDEN;
   1260 
   1261     /**
   1262      * Set if we are shutting down the system, similar to sleeping.
   1263      */
   1264     boolean mShuttingDown = false;
   1265 
   1266     /**
   1267      * Current sequence id for oom_adj computation traversal.
   1268      */
   1269     int mAdjSeq = 0;
   1270 
   1271     /**
   1272      * Current sequence id for process LRU updating.
   1273      */
   1274     int mLruSeq = 0;
   1275 
   1276     /**
   1277      * Keep track of the non-cached/empty process we last found, to help
   1278      * determine how to distribute cached/empty processes next time.
   1279      */
   1280     int mNumNonCachedProcs = 0;
   1281 
   1282     /**
   1283      * Keep track of the number of cached hidden procs, to balance oom adj
   1284      * distribution between those and empty procs.
   1285      */
   1286     int mNumCachedHiddenProcs = 0;
   1287 
   1288     /**
   1289      * Keep track of the number of service processes we last found, to
   1290      * determine on the next iteration which should be B services.
   1291      */
   1292     int mNumServiceProcs = 0;
   1293     int mNewNumAServiceProcs = 0;
   1294     int mNewNumServiceProcs = 0;
   1295 
   1296     /**
   1297      * Allow the current computed overall memory level of the system to go down?
   1298      * This is set to false when we are killing processes for reasons other than
   1299      * memory management, so that the now smaller process list will not be taken as
   1300      * an indication that memory is tighter.
   1301      */
   1302     boolean mAllowLowerMemLevel = false;
   1303 
   1304     /**
   1305      * The last computed memory level, for holding when we are in a state that
   1306      * processes are going away for other reasons.
   1307      */
   1308     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
   1309 
   1310     /**
   1311      * The last total number of process we have, to determine if changes actually look
   1312      * like a shrinking number of process due to lower RAM.
   1313      */
   1314     int mLastNumProcesses;
   1315 
   1316     /**
   1317      * The uptime of the last time we performed idle maintenance.
   1318      */
   1319     long mLastIdleTime = SystemClock.uptimeMillis();
   1320 
   1321     /**
   1322      * Total time spent with RAM that has been added in the past since the last idle time.
   1323      */
   1324     long mLowRamTimeSinceLastIdle = 0;
   1325 
   1326     /**
   1327      * If RAM is currently low, when that horrible situation started.
   1328      */
   1329     long mLowRamStartTime = 0;
   1330 
   1331     /**
   1332      * For reporting to battery stats the current top application.
   1333      */
   1334     private String mCurResumedPackage = null;
   1335     private int mCurResumedUid = -1;
   1336 
   1337     /**
   1338      * For reporting to battery stats the apps currently running foreground
   1339      * service.  The ProcessMap is package/uid tuples; each of these contain
   1340      * an array of the currently foreground processes.
   1341      */
   1342     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
   1343             = new ProcessMap<ArrayList<ProcessRecord>>();
   1344 
   1345     /**
   1346      * This is set if we had to do a delayed dexopt of an app before launching
   1347      * it, to increase the ANR timeouts in that case.
   1348      */
   1349     boolean mDidDexOpt;
   1350 
   1351     /**
   1352      * Set if the systemServer made a call to enterSafeMode.
   1353      */
   1354     boolean mSafeMode;
   1355 
   1356     /**
   1357      * If true, we are running under a test environment so will sample PSS from processes
   1358      * much more rapidly to try to collect better data when the tests are rapidly
   1359      * running through apps.
   1360      */
   1361     boolean mTestPssMode = false;
   1362 
   1363     String mDebugApp = null;
   1364     boolean mWaitForDebugger = false;
   1365     boolean mDebugTransient = false;
   1366     String mOrigDebugApp = null;
   1367     boolean mOrigWaitForDebugger = false;
   1368     boolean mAlwaysFinishActivities = false;
   1369     boolean mLenientBackgroundCheck = false;
   1370     boolean mForceResizableActivities;
   1371     boolean mSupportsMultiWindow;
   1372     boolean mSupportsFreeformWindowManagement;
   1373     boolean mSupportsPictureInPicture;
   1374     boolean mSupportsLeanbackOnly;
   1375     Rect mDefaultPinnedStackBounds;
   1376     IActivityController mController = null;
   1377     boolean mControllerIsAMonkey = false;
   1378     String mProfileApp = null;
   1379     ProcessRecord mProfileProc = null;
   1380     String mProfileFile;
   1381     ParcelFileDescriptor mProfileFd;
   1382     int mSamplingInterval = 0;
   1383     boolean mAutoStopProfiler = false;
   1384     int mProfileType = 0;
   1385     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
   1386     String mMemWatchDumpProcName;
   1387     String mMemWatchDumpFile;
   1388     int mMemWatchDumpPid;
   1389     int mMemWatchDumpUid;
   1390     String mTrackAllocationApp = null;
   1391     String mNativeDebuggingApp = null;
   1392 
   1393     final long[] mTmpLong = new long[2];
   1394 
   1395     static final class ProcessChangeItem {
   1396         static final int CHANGE_ACTIVITIES = 1<<0;
   1397         static final int CHANGE_PROCESS_STATE = 1<<1;
   1398         int changes;
   1399         int uid;
   1400         int pid;
   1401         int processState;
   1402         boolean foregroundActivities;
   1403     }
   1404 
   1405     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
   1406     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
   1407 
   1408     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
   1409     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
   1410 
   1411     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
   1412     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
   1413 
   1414     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
   1415     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
   1416 
   1417     /**
   1418      * Runtime CPU use collection thread.  This object's lock is used to
   1419      * perform synchronization with the thread (notifying it to run).
   1420      */
   1421     final Thread mProcessCpuThread;
   1422 
   1423     /**
   1424      * Used to collect per-process CPU use for ANRs, battery stats, etc.
   1425      * Must acquire this object's lock when accessing it.
   1426      * NOTE: this lock will be held while doing long operations (trawling
   1427      * through all processes in /proc), so it should never be acquired by
   1428      * any critical paths such as when holding the main activity manager lock.
   1429      */
   1430     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
   1431             MONITOR_THREAD_CPU_USAGE);
   1432     final AtomicLong mLastCpuTime = new AtomicLong(0);
   1433     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
   1434 
   1435     long mLastWriteTime = 0;
   1436 
   1437     /**
   1438      * Used to retain an update lock when the foreground activity is in
   1439      * immersive mode.
   1440      */
   1441     final UpdateLock mUpdateLock = new UpdateLock("immersive");
   1442 
   1443     /**
   1444      * Set to true after the system has finished booting.
   1445      */
   1446     boolean mBooted = false;
   1447 
   1448     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
   1449     int mProcessLimitOverride = -1;
   1450 
   1451     WindowManagerService mWindowManager;
   1452     final ActivityThread mSystemThread;
   1453 
   1454     private final class AppDeathRecipient implements IBinder.DeathRecipient {
   1455         final ProcessRecord mApp;
   1456         final int mPid;
   1457         final IApplicationThread mAppThread;
   1458 
   1459         AppDeathRecipient(ProcessRecord app, int pid,
   1460                 IApplicationThread thread) {
   1461             if (DEBUG_ALL) Slog.v(
   1462                 TAG, "New death recipient " + this
   1463                 + " for thread " + thread.asBinder());
   1464             mApp = app;
   1465             mPid = pid;
   1466             mAppThread = thread;
   1467         }
   1468 
   1469         @Override
   1470         public void binderDied() {
   1471             if (DEBUG_ALL) Slog.v(
   1472                 TAG, "Death received in " + this
   1473                 + " for thread " + mAppThread.asBinder());
   1474             synchronized(ActivityManagerService.this) {
   1475                 appDiedLocked(mApp, mPid, mAppThread, true);
   1476             }
   1477         }
   1478     }
   1479 
   1480     static final int SHOW_ERROR_UI_MSG = 1;
   1481     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
   1482     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
   1483     static final int UPDATE_CONFIGURATION_MSG = 4;
   1484     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
   1485     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
   1486     static final int SERVICE_TIMEOUT_MSG = 12;
   1487     static final int UPDATE_TIME_ZONE = 13;
   1488     static final int SHOW_UID_ERROR_UI_MSG = 14;
   1489     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
   1490     static final int PROC_START_TIMEOUT_MSG = 20;
   1491     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
   1492     static final int KILL_APPLICATION_MSG = 22;
   1493     static final int FINALIZE_PENDING_INTENT_MSG = 23;
   1494     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
   1495     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
   1496     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
   1497     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
   1498     static final int CLEAR_DNS_CACHE_MSG = 28;
   1499     static final int UPDATE_HTTP_PROXY_MSG = 29;
   1500     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
   1501     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
   1502     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
   1503     static final int REPORT_MEM_USAGE_MSG = 33;
   1504     static final int REPORT_USER_SWITCH_MSG = 34;
   1505     static final int CONTINUE_USER_SWITCH_MSG = 35;
   1506     static final int USER_SWITCH_TIMEOUT_MSG = 36;
   1507     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
   1508     static final int PERSIST_URI_GRANTS_MSG = 38;
   1509     static final int REQUEST_ALL_PSS_MSG = 39;
   1510     static final int START_PROFILES_MSG = 40;
   1511     static final int UPDATE_TIME = 41;
   1512     static final int SYSTEM_USER_START_MSG = 42;
   1513     static final int SYSTEM_USER_CURRENT_MSG = 43;
   1514     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
   1515     static final int FINISH_BOOTING_MSG = 45;
   1516     static final int START_USER_SWITCH_UI_MSG = 46;
   1517     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
   1518     static final int DISMISS_DIALOG_UI_MSG = 48;
   1519     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
   1520     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
   1521     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
   1522     static final int DELETE_DUMPHEAP_MSG = 52;
   1523     static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
   1524     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
   1525     static final int REPORT_TIME_TRACKER_MSG = 55;
   1526     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
   1527     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
   1528     static final int APP_BOOST_DEACTIVATE_MSG = 58;
   1529     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
   1530     static final int IDLE_UIDS_MSG = 60;
   1531     static final int SYSTEM_USER_UNLOCK_MSG = 61;
   1532     static final int LOG_STACK_STATE = 62;
   1533     static final int VR_MODE_CHANGE_MSG = 63;
   1534     static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
   1535     static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
   1536     static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
   1537     static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
   1538     static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
   1539     static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
   1540     static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
   1541 
   1542     static final int FIRST_ACTIVITY_STACK_MSG = 100;
   1543     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
   1544     static final int FIRST_COMPAT_MODE_MSG = 300;
   1545     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
   1546 
   1547     static ServiceThread sKillThread = null;
   1548     static KillHandler sKillHandler = null;
   1549 
   1550     CompatModeDialog mCompatModeDialog;
   1551     UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
   1552     long mLastMemUsageReportTime = 0;
   1553 
   1554     /**
   1555      * Flag whether the current user is a "monkey", i.e. whether
   1556      * the UI is driven by a UI automation tool.
   1557      */
   1558     private boolean mUserIsMonkey;
   1559 
   1560     /** Flag whether the device has a Recents UI */
   1561     boolean mHasRecents;
   1562 
   1563     /** The dimensions of the thumbnails in the Recents UI. */
   1564     int mThumbnailWidth;
   1565     int mThumbnailHeight;
   1566     float mFullscreenThumbnailScale;
   1567 
   1568     final ServiceThread mHandlerThread;
   1569     final MainHandler mHandler;
   1570     final UiHandler mUiHandler;
   1571 
   1572     PackageManagerInternal mPackageManagerInt;
   1573 
   1574     // VoiceInteraction session ID that changes for each new request except when
   1575     // being called for multiwindow assist in a single session.
   1576     private int mViSessionId = 1000;
   1577 
   1578     final class KillHandler extends Handler {
   1579         static final int KILL_PROCESS_GROUP_MSG = 4000;
   1580 
   1581         public KillHandler(Looper looper) {
   1582             super(looper, null, true);
   1583         }
   1584 
   1585         @Override
   1586         public void handleMessage(Message msg) {
   1587             switch (msg.what) {
   1588                 case KILL_PROCESS_GROUP_MSG:
   1589                 {
   1590                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
   1591                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
   1592                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   1593                 }
   1594                 break;
   1595 
   1596                 default:
   1597                     super.handleMessage(msg);
   1598             }
   1599         }
   1600     }
   1601 
   1602     final class UiHandler extends Handler {
   1603         public UiHandler() {
   1604             super(com.android.server.UiThread.get().getLooper(), null, true);
   1605         }
   1606 
   1607         @Override
   1608         public void handleMessage(Message msg) {
   1609             switch (msg.what) {
   1610             case SHOW_ERROR_UI_MSG: {
   1611                 mAppErrors.handleShowAppErrorUi(msg);
   1612                 ensureBootCompleted();
   1613             } break;
   1614             case SHOW_NOT_RESPONDING_UI_MSG: {
   1615                 mAppErrors.handleShowAnrUi(msg);
   1616                 ensureBootCompleted();
   1617             } break;
   1618             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
   1619                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
   1620                 synchronized (ActivityManagerService.this) {
   1621                     ProcessRecord proc = (ProcessRecord) data.get("app");
   1622                     if (proc == null) {
   1623                         Slog.e(TAG, "App not found when showing strict mode dialog.");
   1624                         break;
   1625                     }
   1626                     if (proc.crashDialog != null) {
   1627                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
   1628                         return;
   1629                     }
   1630                     AppErrorResult res = (AppErrorResult) data.get("result");
   1631                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
   1632                         Dialog d = new StrictModeViolationDialog(mContext,
   1633                                 ActivityManagerService.this, res, proc);
   1634                         d.show();
   1635                         proc.crashDialog = d;
   1636                     } else {
   1637                         // The device is asleep, so just pretend that the user
   1638                         // saw a crash dialog and hit "force quit".
   1639                         res.set(0);
   1640                     }
   1641                 }
   1642                 ensureBootCompleted();
   1643             } break;
   1644             case SHOW_FACTORY_ERROR_UI_MSG: {
   1645                 Dialog d = new FactoryErrorDialog(
   1646                     mContext, msg.getData().getCharSequence("msg"));
   1647                 d.show();
   1648                 ensureBootCompleted();
   1649             } break;
   1650             case WAIT_FOR_DEBUGGER_UI_MSG: {
   1651                 synchronized (ActivityManagerService.this) {
   1652                     ProcessRecord app = (ProcessRecord)msg.obj;
   1653                     if (msg.arg1 != 0) {
   1654                         if (!app.waitedForDebugger) {
   1655                             Dialog d = new AppWaitingForDebuggerDialog(
   1656                                     ActivityManagerService.this,
   1657                                     mContext, app);
   1658                             app.waitDialog = d;
   1659                             app.waitedForDebugger = true;
   1660                             d.show();
   1661                         }
   1662                     } else {
   1663                         if (app.waitDialog != null) {
   1664                             app.waitDialog.dismiss();
   1665                             app.waitDialog = null;
   1666                         }
   1667                     }
   1668                 }
   1669             } break;
   1670             case SHOW_UID_ERROR_UI_MSG: {
   1671                 if (mShowDialogs) {
   1672                     AlertDialog d = new BaseErrorDialog(mContext);
   1673                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   1674                     d.setCancelable(false);
   1675                     d.setTitle(mContext.getText(R.string.android_system_label));
   1676                     d.setMessage(mContext.getText(R.string.system_error_wipe_data));
   1677                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
   1678                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
   1679                     d.show();
   1680                 }
   1681             } break;
   1682             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
   1683                 if (mShowDialogs) {
   1684                     AlertDialog d = new BaseErrorDialog(mContext);
   1685                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   1686                     d.setCancelable(false);
   1687                     d.setTitle(mContext.getText(R.string.android_system_label));
   1688                     d.setMessage(mContext.getText(R.string.system_error_manufacturer));
   1689                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
   1690                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
   1691                     d.show();
   1692                 }
   1693             } break;
   1694             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
   1695                 synchronized (ActivityManagerService.this) {
   1696                     ActivityRecord ar = (ActivityRecord) msg.obj;
   1697                     if (mCompatModeDialog != null) {
   1698                         if (mCompatModeDialog.mAppInfo.packageName.equals(
   1699                                 ar.info.applicationInfo.packageName)) {
   1700                             return;
   1701                         }
   1702                         mCompatModeDialog.dismiss();
   1703                         mCompatModeDialog = null;
   1704                     }
   1705                     if (ar != null && false) {
   1706                         if (mCompatModePackages.getPackageAskCompatModeLocked(
   1707                                 ar.packageName)) {
   1708                             int mode = mCompatModePackages.computeCompatModeLocked(
   1709                                     ar.info.applicationInfo);
   1710                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
   1711                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
   1712                                 mCompatModeDialog = new CompatModeDialog(
   1713                                         ActivityManagerService.this, mContext,
   1714                                         ar.info.applicationInfo);
   1715                                 mCompatModeDialog.show();
   1716                             }
   1717                         }
   1718                     }
   1719                 }
   1720                 break;
   1721             }
   1722             case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
   1723                 synchronized (ActivityManagerService.this) {
   1724                     final ActivityRecord ar = (ActivityRecord) msg.obj;
   1725                     if (mUnsupportedDisplaySizeDialog != null) {
   1726                         mUnsupportedDisplaySizeDialog.dismiss();
   1727                         mUnsupportedDisplaySizeDialog = null;
   1728                     }
   1729                     if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
   1730                             ar.packageName)) {
   1731                         mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
   1732                                 ActivityManagerService.this, mContext, ar.info.applicationInfo);
   1733                         mUnsupportedDisplaySizeDialog.show();
   1734                     }
   1735                 }
   1736                 break;
   1737             }
   1738             case START_USER_SWITCH_UI_MSG: {
   1739                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
   1740                 break;
   1741             }
   1742             case DISMISS_DIALOG_UI_MSG: {
   1743                 final Dialog d = (Dialog) msg.obj;
   1744                 d.dismiss();
   1745                 break;
   1746             }
   1747             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
   1748                 dispatchProcessesChanged();
   1749                 break;
   1750             }
   1751             case DISPATCH_PROCESS_DIED_UI_MSG: {
   1752                 final int pid = msg.arg1;
   1753                 final int uid = msg.arg2;
   1754                 dispatchProcessDied(pid, uid);
   1755                 break;
   1756             }
   1757             case DISPATCH_UIDS_CHANGED_UI_MSG: {
   1758                 dispatchUidsChanged();
   1759             } break;
   1760             }
   1761         }
   1762     }
   1763 
   1764     final class MainHandler extends Handler {
   1765         public MainHandler(Looper looper) {
   1766             super(looper, null, true);
   1767         }
   1768 
   1769         @Override
   1770         public void handleMessage(Message msg) {
   1771             switch (msg.what) {
   1772             case UPDATE_CONFIGURATION_MSG: {
   1773                 final ContentResolver resolver = mContext.getContentResolver();
   1774                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
   1775                         msg.arg1);
   1776             } break;
   1777             case GC_BACKGROUND_PROCESSES_MSG: {
   1778                 synchronized (ActivityManagerService.this) {
   1779                     performAppGcsIfAppropriateLocked();
   1780                 }
   1781             } break;
   1782             case SERVICE_TIMEOUT_MSG: {
   1783                 if (mDidDexOpt) {
   1784                     mDidDexOpt = false;
   1785                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   1786                     nmsg.obj = msg.obj;
   1787                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
   1788                     return;
   1789                 }
   1790                 mServices.serviceTimeout((ProcessRecord)msg.obj);
   1791             } break;
   1792             case UPDATE_TIME_ZONE: {
   1793                 synchronized (ActivityManagerService.this) {
   1794                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1795                         ProcessRecord r = mLruProcesses.get(i);
   1796                         if (r.thread != null) {
   1797                             try {
   1798                                 r.thread.updateTimeZone();
   1799                             } catch (RemoteException ex) {
   1800                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
   1801                             }
   1802                         }
   1803                     }
   1804                 }
   1805             } break;
   1806             case CLEAR_DNS_CACHE_MSG: {
   1807                 synchronized (ActivityManagerService.this) {
   1808                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1809                         ProcessRecord r = mLruProcesses.get(i);
   1810                         if (r.thread != null) {
   1811                             try {
   1812                                 r.thread.clearDnsCache();
   1813                             } catch (RemoteException ex) {
   1814                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
   1815                             }
   1816                         }
   1817                     }
   1818                 }
   1819             } break;
   1820             case UPDATE_HTTP_PROXY_MSG: {
   1821                 ProxyInfo proxy = (ProxyInfo)msg.obj;
   1822                 String host = "";
   1823                 String port = "";
   1824                 String exclList = "";
   1825                 Uri pacFileUrl = Uri.EMPTY;
   1826                 if (proxy != null) {
   1827                     host = proxy.getHost();
   1828                     port = Integer.toString(proxy.getPort());
   1829                     exclList = proxy.getExclusionListAsString();
   1830                     pacFileUrl = proxy.getPacFileUrl();
   1831                 }
   1832                 synchronized (ActivityManagerService.this) {
   1833                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1834                         ProcessRecord r = mLruProcesses.get(i);
   1835                         if (r.thread != null) {
   1836                             try {
   1837                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
   1838                             } catch (RemoteException ex) {
   1839                                 Slog.w(TAG, "Failed to update http proxy for: " +
   1840                                         r.info.processName);
   1841                             }
   1842                         }
   1843                     }
   1844                 }
   1845             } break;
   1846             case PROC_START_TIMEOUT_MSG: {
   1847                 if (mDidDexOpt) {
   1848                     mDidDexOpt = false;
   1849                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   1850                     nmsg.obj = msg.obj;
   1851                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
   1852                     return;
   1853                 }
   1854                 ProcessRecord app = (ProcessRecord)msg.obj;
   1855                 synchronized (ActivityManagerService.this) {
   1856                     processStartTimedOutLocked(app);
   1857                 }
   1858             } break;
   1859             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
   1860                 ProcessRecord app = (ProcessRecord)msg.obj;
   1861                 synchronized (ActivityManagerService.this) {
   1862                     processContentProviderPublishTimedOutLocked(app);
   1863                 }
   1864             } break;
   1865             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
   1866                 synchronized (ActivityManagerService.this) {
   1867                     mActivityStarter.doPendingActivityLaunchesLocked(true);
   1868                 }
   1869             } break;
   1870             case KILL_APPLICATION_MSG: {
   1871                 synchronized (ActivityManagerService.this) {
   1872                     final int appId = msg.arg1;
   1873                     final int userId = msg.arg2;
   1874                     Bundle bundle = (Bundle)msg.obj;
   1875                     String pkg = bundle.getString("pkg");
   1876                     String reason = bundle.getString("reason");
   1877                     forceStopPackageLocked(pkg, appId, false, false, true, false,
   1878                             false, userId, reason);
   1879                 }
   1880             } break;
   1881             case FINALIZE_PENDING_INTENT_MSG: {
   1882                 ((PendingIntentRecord)msg.obj).completeFinalize();
   1883             } break;
   1884             case POST_HEAVY_NOTIFICATION_MSG: {
   1885                 INotificationManager inm = NotificationManager.getService();
   1886                 if (inm == null) {
   1887                     return;
   1888                 }
   1889 
   1890                 ActivityRecord root = (ActivityRecord)msg.obj;
   1891                 ProcessRecord process = root.app;
   1892                 if (process == null) {
   1893                     return;
   1894                 }
   1895 
   1896                 try {
   1897                     Context context = mContext.createPackageContext(process.info.packageName, 0);
   1898                     String text = mContext.getString(R.string.heavy_weight_notification,
   1899                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
   1900                     Notification notification = new Notification.Builder(context)
   1901                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
   1902                             .setWhen(0)
   1903                             .setOngoing(true)
   1904                             .setTicker(text)
   1905                             .setColor(mContext.getColor(
   1906                                     com.android.internal.R.color.system_notification_accent_color))
   1907                             .setContentTitle(text)
   1908                             .setContentText(
   1909                                     mContext.getText(R.string.heavy_weight_notification_detail))
   1910                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
   1911                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
   1912                                     new UserHandle(root.userId)))
   1913                             .build();
   1914                     try {
   1915                         int[] outId = new int[1];
   1916                         inm.enqueueNotificationWithTag("android", "android", null,
   1917                                 R.string.heavy_weight_notification,
   1918                                 notification, outId, root.userId);
   1919                     } catch (RuntimeException e) {
   1920                         Slog.w(ActivityManagerService.TAG,
   1921                                 "Error showing notification for heavy-weight app", e);
   1922                     } catch (RemoteException e) {
   1923                     }
   1924                 } catch (NameNotFoundException e) {
   1925                     Slog.w(TAG, "Unable to create context for heavy notification", e);
   1926                 }
   1927             } break;
   1928             case CANCEL_HEAVY_NOTIFICATION_MSG: {
   1929                 INotificationManager inm = NotificationManager.getService();
   1930                 if (inm == null) {
   1931                     return;
   1932                 }
   1933                 try {
   1934                     inm.cancelNotificationWithTag("android", null,
   1935                             R.string.heavy_weight_notification,  msg.arg1);
   1936                 } catch (RuntimeException e) {
   1937                     Slog.w(ActivityManagerService.TAG,
   1938                             "Error canceling notification for service", e);
   1939                 } catch (RemoteException e) {
   1940                 }
   1941             } break;
   1942             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
   1943                 synchronized (ActivityManagerService.this) {
   1944                     checkExcessivePowerUsageLocked(true);
   1945                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1946                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1947                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   1948                 }
   1949             } break;
   1950             case REPORT_MEM_USAGE_MSG: {
   1951                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
   1952                 Thread thread = new Thread() {
   1953                     @Override public void run() {
   1954                         reportMemUsage(memInfos);
   1955                     }
   1956                 };
   1957                 thread.start();
   1958                 break;
   1959             }
   1960             case REPORT_USER_SWITCH_MSG: {
   1961                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
   1962                 break;
   1963             }
   1964             case CONTINUE_USER_SWITCH_MSG: {
   1965                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
   1966                 break;
   1967             }
   1968             case USER_SWITCH_TIMEOUT_MSG: {
   1969                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
   1970                 break;
   1971             }
   1972             case IMMERSIVE_MODE_LOCK_MSG: {
   1973                 final boolean nextState = (msg.arg1 != 0);
   1974                 if (mUpdateLock.isHeld() != nextState) {
   1975                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
   1976                             "Applying new update lock state '" + nextState
   1977                             + "' for " + (ActivityRecord)msg.obj);
   1978                     if (nextState) {
   1979                         mUpdateLock.acquire();
   1980                     } else {
   1981                         mUpdateLock.release();
   1982                     }
   1983                 }
   1984                 break;
   1985             }
   1986             case PERSIST_URI_GRANTS_MSG: {
   1987                 writeGrantedUriPermissions();
   1988                 break;
   1989             }
   1990             case REQUEST_ALL_PSS_MSG: {
   1991                 synchronized (ActivityManagerService.this) {
   1992                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
   1993                 }
   1994                 break;
   1995             }
   1996             case START_PROFILES_MSG: {
   1997                 synchronized (ActivityManagerService.this) {
   1998                     mUserController.startProfilesLocked();
   1999                 }
   2000                 break;
   2001             }
   2002             case UPDATE_TIME: {
   2003                 synchronized (ActivityManagerService.this) {
   2004                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   2005                         ProcessRecord r = mLruProcesses.get(i);
   2006                         if (r.thread != null) {
   2007                             try {
   2008                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
   2009                             } catch (RemoteException ex) {
   2010                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
   2011                             }
   2012                         }
   2013                     }
   2014                 }
   2015                 break;
   2016             }
   2017             case SYSTEM_USER_START_MSG: {
   2018                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
   2019                         Integer.toString(msg.arg1), msg.arg1);
   2020                 mSystemServiceManager.startUser(msg.arg1);
   2021                 break;
   2022             }
   2023             case SYSTEM_USER_UNLOCK_MSG: {
   2024                 final int userId = msg.arg1;
   2025                 mSystemServiceManager.unlockUser(userId);
   2026                 synchronized (ActivityManagerService.this) {
   2027                     mRecentTasks.loadUserRecentsLocked(userId);
   2028                 }
   2029                 if (userId == UserHandle.USER_SYSTEM) {
   2030                     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
   2031                 }
   2032                 installEncryptionUnawareProviders(userId);
   2033                 mUserController.finishUserUnlocked((UserState) msg.obj);
   2034                 break;
   2035             }
   2036             case SYSTEM_USER_CURRENT_MSG: {
   2037                 mBatteryStatsService.noteEvent(
   2038                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
   2039                         Integer.toString(msg.arg2), msg.arg2);
   2040                 mBatteryStatsService.noteEvent(
   2041                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
   2042                         Integer.toString(msg.arg1), msg.arg1);
   2043                 mSystemServiceManager.switchUser(msg.arg1);
   2044                 break;
   2045             }
   2046             case ENTER_ANIMATION_COMPLETE_MSG: {
   2047                 synchronized (ActivityManagerService.this) {
   2048                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
   2049                     if (r != null && r.app != null && r.app.thread != null) {
   2050                         try {
   2051                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
   2052                         } catch (RemoteException e) {
   2053                         }
   2054                     }
   2055                 }
   2056                 break;
   2057             }
   2058             case FINISH_BOOTING_MSG: {
   2059                 if (msg.arg1 != 0) {
   2060                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
   2061                     finishBooting();
   2062                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   2063                 }
   2064                 if (msg.arg2 != 0) {
   2065                     enableScreenAfterBoot();
   2066                 }
   2067                 break;
   2068             }
   2069             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
   2070                 try {
   2071                     Locale l = (Locale) msg.obj;
   2072                     IBinder service = ServiceManager.getService("mount");
   2073                     IMountService mountService = IMountService.Stub.asInterface(service);
   2074                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
   2075                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
   2076                 } catch (RemoteException e) {
   2077                     Log.e(TAG, "Error storing locale for decryption UI", e);
   2078                 }
   2079                 break;
   2080             }
   2081             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
   2082                 synchronized (ActivityManagerService.this) {
   2083                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
   2084                         try {
   2085                             // Make a one-way callback to the listener
   2086                             mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
   2087                         } catch (RemoteException e){
   2088                             // Handled by the RemoteCallbackList
   2089                         }
   2090                     }
   2091                     mTaskStackListeners.finishBroadcast();
   2092                 }
   2093                 break;
   2094             }
   2095             case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
   2096                 synchronized (ActivityManagerService.this) {
   2097                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
   2098                         try {
   2099                             // Make a one-way callback to the listener
   2100                             mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
   2101                         } catch (RemoteException e){
   2102                             // Handled by the RemoteCallbackList
   2103                         }
   2104                     }
   2105                     mTaskStackListeners.finishBroadcast();
   2106                 }
   2107                 break;
   2108             }
   2109             case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
   2110                 synchronized (ActivityManagerService.this) {
   2111                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
   2112                         try {
   2113                             // Make a one-way callback to the listener
   2114                             mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
   2115                         } catch (RemoteException e){
   2116                             // Handled by the RemoteCallbackList
   2117                         }
   2118                     }
   2119                     mTaskStackListeners.finishBroadcast();
   2120                 }
   2121                 break;
   2122             }
   2123             case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
   2124                 synchronized (ActivityManagerService.this) {
   2125                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
   2126                         try {
   2127                             // Make a one-way callback to the listener
   2128                             mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
   2129                         } catch (RemoteException e){
   2130                             // Handled by the RemoteCallbackList
   2131                         }
   2132                     }
   2133                     mTaskStackListeners.finishBroadcast();
   2134                 }
   2135                 break;
   2136             }
   2137             case NOTIFY_FORCED_RESIZABLE_MSG: {
   2138                 synchronized (ActivityManagerService.this) {
   2139                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
   2140                         try {
   2141                             // Make a one-way callback to the listener
   2142                             mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
   2143                                     (String) msg.obj, msg.arg1);
   2144                         } catch (RemoteException e){
   2145                             // Handled by the RemoteCallbackList
   2146                         }
   2147                     }
   2148                     mTaskStackListeners.finishBroadcast();
   2149                 }
   2150                 break;
   2151             }
   2152                 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
   2153                     synchronized (ActivityManagerService.this) {
   2154                         for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
   2155                             try {
   2156                                 // Make a one-way callback to the listener
   2157                                 mTaskStackListeners.getBroadcastItem(i)
   2158                                         .onActivityDismissingDockedStack();
   2159                             } catch (RemoteException e){
   2160                                 // Handled by the RemoteCallbackList
   2161                             }
   2162                         }
   2163                         mTaskStackListeners.finishBroadcast();
   2164                     }
   2165                     break;
   2166                 }
   2167             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
   2168                 final int uid = msg.arg1;
   2169                 final byte[] firstPacket = (byte[]) msg.obj;
   2170 
   2171                 synchronized (mPidsSelfLocked) {
   2172                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
   2173                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
   2174                         if (p.uid == uid) {
   2175                             try {
   2176                                 p.thread.notifyCleartextNetwork(firstPacket);
   2177                             } catch (RemoteException ignored) {
   2178                             }
   2179                         }
   2180                     }
   2181                 }
   2182                 break;
   2183             }
   2184             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
   2185                 final String procName;
   2186                 final int uid;
   2187                 final long memLimit;
   2188                 final String reportPackage;
   2189                 synchronized (ActivityManagerService.this) {
   2190                     procName = mMemWatchDumpProcName;
   2191                     uid = mMemWatchDumpUid;
   2192                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
   2193                     if (val == null) {
   2194                         val = mMemWatchProcesses.get(procName, 0);
   2195                     }
   2196                     if (val != null) {
   2197                         memLimit = val.first;
   2198                         reportPackage = val.second;
   2199                     } else {
   2200                         memLimit = 0;
   2201                         reportPackage = null;
   2202                     }
   2203                 }
   2204                 if (procName == null) {
   2205                     return;
   2206                 }
   2207 
   2208                 if (DEBUG_PSS) Slog.d(TAG_PSS,
   2209                         "Showing dump heap notification from " + procName + "/" + uid);
   2210 
   2211                 INotificationManager inm = NotificationManager.getService();
   2212                 if (inm == null) {
   2213                     return;
   2214                 }
   2215 
   2216                 String text = mContext.getString(R.string.dump_heap_notification, procName);
   2217 
   2218 
   2219                 Intent deleteIntent = new Intent();
   2220                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
   2221                 Intent intent = new Intent();
   2222                 intent.setClassName("android", DumpHeapActivity.class.getName());
   2223                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
   2224                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
   2225                 if (reportPackage != null) {
   2226                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
   2227                 }
   2228                 int userId = UserHandle.getUserId(uid);
   2229                 Notification notification = new Notification.Builder(mContext)
   2230                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
   2231                         .setWhen(0)
   2232                         .setOngoing(true)
   2233                         .setAutoCancel(true)
   2234                         .setTicker(text)
   2235                         .setColor(mContext.getColor(
   2236                                 com.android.internal.R.color.system_notification_accent_color))
   2237                         .setContentTitle(text)
   2238                         .setContentText(
   2239                                 mContext.getText(R.string.dump_heap_notification_detail))
   2240                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
   2241                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
   2242                                 new UserHandle(userId)))
   2243                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
   2244                                 deleteIntent, 0, UserHandle.SYSTEM))
   2245                         .build();
   2246 
   2247                 try {
   2248                     int[] outId = new int[1];
   2249                     inm.enqueueNotificationWithTag("android", "android", null,
   2250                             R.string.dump_heap_notification,
   2251                             notification, outId, userId);
   2252                 } catch (RuntimeException e) {
   2253                     Slog.w(ActivityManagerService.TAG,
   2254                             "Error showing notification for dump heap", e);
   2255                 } catch (RemoteException e) {
   2256                 }
   2257             } break;
   2258             case DELETE_DUMPHEAP_MSG: {
   2259                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
   2260                         DumpHeapActivity.JAVA_URI,
   2261                         Intent.FLAG_GRANT_READ_URI_PERMISSION
   2262                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
   2263                         UserHandle.myUserId());
   2264                 synchronized (ActivityManagerService.this) {
   2265                     mMemWatchDumpFile = null;
   2266                     mMemWatchDumpProcName = null;
   2267                     mMemWatchDumpPid = -1;
   2268                     mMemWatchDumpUid = -1;
   2269                 }
   2270             } break;
   2271             case FOREGROUND_PROFILE_CHANGED_MSG: {
   2272                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
   2273             } break;
   2274             case REPORT_TIME_TRACKER_MSG: {
   2275                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
   2276                 tracker.deliverResult(mContext);
   2277             } break;
   2278             case REPORT_USER_SWITCH_COMPLETE_MSG: {
   2279                 mUserController.dispatchUserSwitchComplete(msg.arg1);
   2280             } break;
   2281             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
   2282                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
   2283                 try {
   2284                     connection.shutdown();
   2285                 } catch (RemoteException e) {
   2286                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
   2287                 }
   2288                 // Only a UiAutomation can set this flag and now that
   2289                 // it is finished we make sure it is reset to its default.
   2290                 mUserIsMonkey = false;
   2291             } break;
   2292             case APP_BOOST_DEACTIVATE_MSG: {
   2293                 synchronized(ActivityManagerService.this) {
   2294                     if (mIsBoosted) {
   2295                         if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
   2296                             nativeMigrateFromBoost();
   2297                             mIsBoosted = false;
   2298                             mBoostStartTime = 0;
   2299                         } else {
   2300                             Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
   2301                             mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
   2302                         }
   2303                     }
   2304                 }
   2305             } break;
   2306             case IDLE_UIDS_MSG: {
   2307                 idleUids();
   2308             } break;
   2309             case LOG_STACK_STATE: {
   2310                 synchronized (ActivityManagerService.this) {
   2311                     mStackSupervisor.logStackState();
   2312                 }
   2313             } break;
   2314             case VR_MODE_CHANGE_MSG: {
   2315                 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
   2316                 final ActivityRecord r = (ActivityRecord) msg.obj;
   2317                 boolean vrMode;
   2318                 ComponentName requestedPackage;
   2319                 ComponentName callingPackage;
   2320                 int userId;
   2321                 synchronized (ActivityManagerService.this) {
   2322                     vrMode = r.requestedVrComponent != null;
   2323                     requestedPackage = r.requestedVrComponent;
   2324                     userId = r.userId;
   2325                     callingPackage = r.info.getComponentName();
   2326                     if (mInVrMode != vrMode) {
   2327                         mInVrMode = vrMode;
   2328                         mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
   2329                         if (r.app != null) {
   2330                             ProcessRecord proc = r.app;
   2331                             if (proc.vrThreadTid > 0) {
   2332                                 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
   2333                                     try {
   2334                                         if (mInVrMode == true) {
   2335                                             Process.setThreadScheduler(proc.vrThreadTid,
   2336                                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
   2337                                         } else {
   2338                                             Process.setThreadScheduler(proc.vrThreadTid,
   2339                                                 Process.SCHED_OTHER, 0);
   2340                                         }
   2341                                     } catch (IllegalArgumentException e) {
   2342                                         Slog.w(TAG, "Failed to set scheduling policy, thread does"
   2343                                                 + " not exist:\n" + e);
   2344                                     }
   2345                                 }
   2346                             }
   2347                         }
   2348                     }
   2349                 }
   2350                 vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
   2351             } break;
   2352             case VR_MODE_APPLY_IF_NEEDED_MSG: {
   2353                 final ActivityRecord r = (ActivityRecord) msg.obj;
   2354                 final boolean needsVrMode = r != null && r.requestedVrComponent != null;
   2355                 if (needsVrMode) {
   2356                     applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
   2357                             r.info.getComponentName(), false);
   2358                 }
   2359             } break;
   2360             }
   2361         }
   2362     };
   2363 
   2364     static final int COLLECT_PSS_BG_MSG = 1;
   2365 
   2366     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
   2367         @Override
   2368         public void handleMessage(Message msg) {
   2369             switch (msg.what) {
   2370             case COLLECT_PSS_BG_MSG: {
   2371                 long start = SystemClock.uptimeMillis();
   2372                 MemInfoReader memInfo = null;
   2373                 synchronized (ActivityManagerService.this) {
   2374                     if (mFullPssPending) {
   2375                         mFullPssPending = false;
   2376                         memInfo = new MemInfoReader();
   2377                     }
   2378                 }
   2379                 if (memInfo != null) {
   2380                     updateCpuStatsNow();
   2381                     long nativeTotalPss = 0;
   2382                     final List<ProcessCpuTracker.Stats> stats;
   2383                     synchronized (mProcessCpuTracker) {
   2384                         stats = mProcessCpuTracker.getStats( (st)-> {
   2385                             return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
   2386                         });
   2387                     }
   2388                     final int N = stats.size();
   2389                     for (int j = 0; j < N; j++) {
   2390                         synchronized (mPidsSelfLocked) {
   2391                             if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
   2392                                 // This is one of our own processes; skip it.
   2393                                 continue;
   2394                             }
   2395                         }
   2396                         nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
   2397                     }
   2398                     memInfo.readMemInfo();
   2399                     synchronized (ActivityManagerService.this) {
   2400                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
   2401                                 + (SystemClock.uptimeMillis()-start) + "ms");
   2402                         final long cachedKb = memInfo.getCachedSizeKb();
   2403                         final long freeKb = memInfo.getFreeSizeKb();
   2404                         final long zramKb = memInfo.getZramTotalSizeKb();
   2405                         final long kernelKb = memInfo.getKernelUsedSizeKb();
   2406                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
   2407                                 kernelKb*1024, nativeTotalPss*1024);
   2408                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
   2409                                 nativeTotalPss);
   2410                     }
   2411                 }
   2412 
   2413                 int num = 0;
   2414                 long[] tmp = new long[2];
   2415                 do {
   2416                     ProcessRecord proc;
   2417                     int procState;
   2418                     int pid;
   2419                     long lastPssTime;
   2420                     synchronized (ActivityManagerService.this) {
   2421                         if (mPendingPssProcesses.size() <= 0) {
   2422                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
   2423                                     "Collected PSS of " + num + " processes in "
   2424                                     + (SystemClock.uptimeMillis() - start) + "ms");
   2425                             mPendingPssProcesses.clear();
   2426                             return;
   2427                         }
   2428                         proc = mPendingPssProcesses.remove(0);
   2429                         procState = proc.pssProcState;
   2430                         lastPssTime = proc.lastPssTime;
   2431                         if (proc.thread != null && procState == proc.setProcState
   2432                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
   2433                                         < SystemClock.uptimeMillis()) {
   2434                             pid = proc.pid;
   2435                         } else {
   2436                             proc = null;
   2437                             pid = 0;
   2438                         }
   2439                     }
   2440                     if (proc != null) {
   2441                         long pss = Debug.getPss(pid, tmp, null);
   2442                         synchronized (ActivityManagerService.this) {
   2443                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
   2444                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
   2445                                 num++;
   2446                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
   2447                                         SystemClock.uptimeMillis());
   2448                             }
   2449                         }
   2450                     }
   2451                 } while (true);
   2452             }
   2453             }
   2454         }
   2455     };
   2456 
   2457     public void setSystemProcess() {
   2458         try {
   2459             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
   2460             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
   2461             ServiceManager.addService("meminfo", new MemBinder(this));
   2462             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
   2463             ServiceManager.addService("dbinfo", new DbBinder(this));
   2464             if (MONITOR_CPU_USAGE) {
   2465                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
   2466             }
   2467             ServiceManager.addService("permission", new PermissionController(this));
   2468             ServiceManager.addService("processinfo", new ProcessInfoService(this));
   2469 
   2470             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
   2471                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
   2472             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
   2473 
   2474             synchronized (this) {
   2475                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
   2476                 app.persistent = true;
   2477                 app.pid = MY_PID;
   2478                 app.maxAdj = ProcessList.SYSTEM_ADJ;
   2479                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
   2480                 synchronized (mPidsSelfLocked) {
   2481                     mPidsSelfLocked.put(app.pid, app);
   2482                 }
   2483                 updateLruProcessLocked(app, false, null);
   2484                 updateOomAdjLocked();
   2485             }
   2486         } catch (PackageManager.NameNotFoundException e) {
   2487             throw new RuntimeException(
   2488                     "Unable to find android system package", e);
   2489         }
   2490     }
   2491 
   2492     public void setWindowManager(WindowManagerService wm) {
   2493         mWindowManager = wm;
   2494         mStackSupervisor.setWindowManager(wm);
   2495         mActivityStarter.setWindowManager(wm);
   2496     }
   2497 
   2498     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
   2499         mUsageStatsService = usageStatsManager;
   2500     }
   2501 
   2502     public void startObservingNativeCrashes() {
   2503         final NativeCrashListener ncl = new NativeCrashListener(this);
   2504         ncl.start();
   2505     }
   2506 
   2507     public IAppOpsService getAppOpsService() {
   2508         return mAppOpsService;
   2509     }
   2510 
   2511     static class MemBinder extends Binder {
   2512         ActivityManagerService mActivityManagerService;
   2513         MemBinder(ActivityManagerService activityManagerService) {
   2514             mActivityManagerService = activityManagerService;
   2515         }
   2516 
   2517         @Override
   2518         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2519             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   2520                     != PackageManager.PERMISSION_GRANTED) {
   2521                 pw.println("Permission Denial: can't dump meminfo from from pid="
   2522                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   2523                         + " without permission " + android.Manifest.permission.DUMP);
   2524                 return;
   2525             }
   2526 
   2527             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
   2528         }
   2529     }
   2530 
   2531     static class GraphicsBinder extends Binder {
   2532         ActivityManagerService mActivityManagerService;
   2533         GraphicsBinder(ActivityManagerService activityManagerService) {
   2534             mActivityManagerService = activityManagerService;
   2535         }
   2536 
   2537         @Override
   2538         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2539             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   2540                     != PackageManager.PERMISSION_GRANTED) {
   2541                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
   2542                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   2543                         + " without permission " + android.Manifest.permission.DUMP);
   2544                 return;
   2545             }
   2546 
   2547             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
   2548         }
   2549     }
   2550 
   2551     static class DbBinder extends Binder {
   2552         ActivityManagerService mActivityManagerService;
   2553         DbBinder(ActivityManagerService activityManagerService) {
   2554             mActivityManagerService = activityManagerService;
   2555         }
   2556 
   2557         @Override
   2558         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2559             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   2560                     != PackageManager.PERMISSION_GRANTED) {
   2561                 pw.println("Permission Denial: can't dump dbinfo from from pid="
   2562                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   2563                         + " without permission " + android.Manifest.permission.DUMP);
   2564                 return;
   2565             }
   2566 
   2567             mActivityManagerService.dumpDbInfo(fd, pw, args);
   2568         }
   2569     }
   2570 
   2571     static class CpuBinder extends Binder {
   2572         ActivityManagerService mActivityManagerService;
   2573         CpuBinder(ActivityManagerService activityManagerService) {
   2574             mActivityManagerService = activityManagerService;
   2575         }
   2576 
   2577         @Override
   2578         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2579             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   2580                     != PackageManager.PERMISSION_GRANTED) {
   2581                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
   2582                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   2583                         + " without permission " + android.Manifest.permission.DUMP);
   2584                 return;
   2585             }
   2586 
   2587             synchronized (mActivityManagerService.mProcessCpuTracker) {
   2588                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
   2589                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
   2590                         SystemClock.uptimeMillis()));
   2591             }
   2592         }
   2593     }
   2594 
   2595     public static final class Lifecycle extends SystemService {
   2596         private final ActivityManagerService mService;
   2597 
   2598         public Lifecycle(Context context) {
   2599             super(context);
   2600             mService = new ActivityManagerService(context);
   2601         }
   2602 
   2603         @Override
   2604         public void onStart() {
   2605             mService.start();
   2606         }
   2607 
   2608         public ActivityManagerService getService() {
   2609             return mService;
   2610         }
   2611     }
   2612 
   2613     // Note: This method is invoked on the main thread but may need to attach various
   2614     // handlers to other threads.  So take care to be explicit about the looper.
   2615     public ActivityManagerService(Context systemContext) {
   2616         mContext = systemContext;
   2617         mFactoryTest = FactoryTest.getMode();
   2618         mSystemThread = ActivityThread.currentActivityThread();
   2619 
   2620         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
   2621 
   2622         mHandlerThread = new ServiceThread(TAG,
   2623                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
   2624         mHandlerThread.start();
   2625         mHandler = new MainHandler(mHandlerThread.getLooper());
   2626         mUiHandler = new UiHandler();
   2627 
   2628         /* static; one-time init here */
   2629         if (sKillHandler == null) {
   2630             sKillThread = new ServiceThread(TAG + ":kill",
   2631                     android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
   2632             sKillThread.start();
   2633             sKillHandler = new KillHandler(sKillThread.getLooper());
   2634         }
   2635 
   2636         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
   2637                 "foreground", BROADCAST_FG_TIMEOUT, false);
   2638         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
   2639                 "background", BROADCAST_BG_TIMEOUT, true);
   2640         mBroadcastQueues[0] = mFgBroadcastQueue;
   2641         mBroadcastQueues[1] = mBgBroadcastQueue;
   2642 
   2643         mServices = new ActiveServices(this);
   2644         mProviderMap = new ProviderMap(this);
   2645         mAppErrors = new AppErrors(mContext, this);
   2646 
   2647         // TODO: Move creation of battery stats service outside of activity manager service.
   2648         File dataDir = Environment.getDataDirectory();
   2649         File systemDir = new File(dataDir, "system");
   2650         systemDir.mkdirs();
   2651         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
   2652         mBatteryStatsService.getActiveStatistics().readLocked();
   2653         mBatteryStatsService.scheduleWriteToDisk();
   2654         mOnBattery = DEBUG_POWER ? true
   2655                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
   2656         mBatteryStatsService.getActiveStatistics().setCallback(this);
   2657 
   2658         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
   2659 
   2660         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
   2661         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
   2662                 new IAppOpsCallback.Stub() {
   2663                     @Override public void opChanged(int op, int uid, String packageName) {
   2664                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
   2665                             if (mAppOpsService.checkOperation(op, uid, packageName)
   2666                                     != AppOpsManager.MODE_ALLOWED) {
   2667                                 runInBackgroundDisabled(uid);
   2668                             }
   2669                         }
   2670                     }
   2671                 });
   2672 
   2673         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
   2674 
   2675         mUserController = new UserController(this);
   2676 
   2677         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
   2678             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
   2679 
   2680         if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
   2681             mUseFifoUiScheduling = true;
   2682         }
   2683 
   2684         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
   2685 
   2686         mConfiguration.setToDefaults();
   2687         mConfiguration.setLocales(LocaleList.getDefault());
   2688 
   2689         mConfigurationSeq = mConfiguration.seq = 1;
   2690         mProcessCpuTracker.init();
   2691 
   2692         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
   2693         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
   2694         mStackSupervisor = new ActivityStackSupervisor(this);
   2695         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
   2696         mRecentTasks = new RecentTasks(this, mStackSupervisor);
   2697 
   2698         mProcessCpuThread = new Thread("CpuTracker") {
   2699             @Override
   2700             public void run() {
   2701                 while (true) {
   2702                     try {
   2703                         try {
   2704                             synchronized(this) {
   2705                                 final long now = SystemClock.uptimeMillis();
   2706                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
   2707                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
   2708                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
   2709                                 //        + ", write delay=" + nextWriteDelay);
   2710                                 if (nextWriteDelay < nextCpuDelay) {
   2711                                     nextCpuDelay = nextWriteDelay;
   2712                                 }
   2713                                 if (nextCpuDelay > 0) {
   2714                                     mProcessCpuMutexFree.set(true);
   2715                                     this.wait(nextCpuDelay);
   2716                                 }
   2717                             }
   2718                         } catch (InterruptedException e) {
   2719                         }
   2720                         updateCpuStatsNow();
   2721                     } catch (Exception e) {
   2722                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
   2723                     }
   2724                 }
   2725             }
   2726         };
   2727 
   2728         Watchdog.getInstance().addMonitor(this);
   2729         Watchdog.getInstance().addThread(mHandler);
   2730     }
   2731 
   2732     public void setSystemServiceManager(SystemServiceManager mgr) {
   2733         mSystemServiceManager = mgr;
   2734     }
   2735 
   2736     public void setInstaller(Installer installer) {
   2737         mInstaller = installer;
   2738     }
   2739 
   2740     private void start() {
   2741         Process.removeAllProcessGroups();
   2742         mProcessCpuThread.start();
   2743 
   2744         mBatteryStatsService.publish(mContext);
   2745         mAppOpsService.publish(mContext);
   2746         Slog.d("AppOps", "AppOpsService published");
   2747         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
   2748     }
   2749 
   2750     void onUserStoppedLocked(int userId) {
   2751         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
   2752     }
   2753 
   2754     public void initPowerManagement() {
   2755         mStackSupervisor.initPowerManagement();
   2756         mBatteryStatsService.initPowerManagement();
   2757         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
   2758         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
   2759         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
   2760         mVoiceWakeLock.setReferenceCounted(false);
   2761     }
   2762 
   2763     @Override
   2764     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   2765             throws RemoteException {
   2766         if (code == SYSPROPS_TRANSACTION) {
   2767             // We need to tell all apps about the system property change.
   2768             ArrayList<IBinder> procs = new ArrayList<IBinder>();
   2769             synchronized(this) {
   2770                 final int NP = mProcessNames.getMap().size();
   2771                 for (int ip=0; ip<NP; ip++) {
   2772                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   2773                     final int NA = apps.size();
   2774                     for (int ia=0; ia<NA; ia++) {
   2775                         ProcessRecord app = apps.valueAt(ia);
   2776                         if (app.thread != null) {
   2777                             procs.add(app.thread.asBinder());
   2778                         }
   2779                     }
   2780                 }
   2781             }
   2782 
   2783             int N = procs.size();
   2784             for (int i=0; i<N; i++) {
   2785                 Parcel data2 = Parcel.obtain();
   2786                 try {
   2787                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
   2788                 } catch (RemoteException e) {
   2789                 }
   2790                 data2.recycle();
   2791             }
   2792         }
   2793         try {
   2794             return super.onTransact(code, data, reply, flags);
   2795         } catch (RuntimeException e) {
   2796             // The activity manager only throws security exceptions, so let's
   2797             // log all others.
   2798             if (!(e instanceof SecurityException)) {
   2799                 Slog.wtf(TAG, "Activity Manager Crash", e);
   2800             }
   2801             throw e;
   2802         }
   2803     }
   2804 
   2805     void updateCpuStats() {
   2806         final long now = SystemClock.uptimeMillis();
   2807         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
   2808             return;
   2809         }
   2810         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
   2811             synchronized (mProcessCpuThread) {
   2812                 mProcessCpuThread.notify();
   2813             }
   2814         }
   2815     }
   2816 
   2817     void updateCpuStatsNow() {
   2818         synchronized (mProcessCpuTracker) {
   2819             mProcessCpuMutexFree.set(false);
   2820             final long now = SystemClock.uptimeMillis();
   2821             boolean haveNewCpuStats = false;
   2822 
   2823             if (MONITOR_CPU_USAGE &&
   2824                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
   2825                 mLastCpuTime.set(now);
   2826                 mProcessCpuTracker.update();
   2827                 if (mProcessCpuTracker.hasGoodLastStats()) {
   2828                     haveNewCpuStats = true;
   2829                     //Slog.i(TAG, mProcessCpu.printCurrentState());
   2830                     //Slog.i(TAG, "Total CPU usage: "
   2831                     //        + mProcessCpu.getTotalCpuPercent() + "%");
   2832 
   2833                     // Slog the cpu usage if the property is set.
   2834                     if ("true".equals(SystemProperties.get("events.cpu"))) {
   2835                         int user = mProcessCpuTracker.getLastUserTime();
   2836                         int system = mProcessCpuTracker.getLastSystemTime();
   2837                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
   2838                         int irq = mProcessCpuTracker.getLastIrqTime();
   2839                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
   2840                         int idle = mProcessCpuTracker.getLastIdleTime();
   2841 
   2842                         int total = user + system + iowait + irq + softIrq + idle;
   2843                         if (total == 0) total = 1;
   2844 
   2845                         EventLog.writeEvent(EventLogTags.CPU,
   2846                                 ((user+system+iowait+irq+softIrq) * 100) / total,
   2847                                 (user * 100) / total,
   2848                                 (system * 100) / total,
   2849                                 (iowait * 100) / total,
   2850                                 (irq * 100) / total,
   2851                                 (softIrq * 100) / total);
   2852                     }
   2853                 }
   2854             }
   2855 
   2856             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
   2857             synchronized(bstats) {
   2858                 synchronized(mPidsSelfLocked) {
   2859                     if (haveNewCpuStats) {
   2860                         if (bstats.startAddingCpuLocked()) {
   2861                             int totalUTime = 0;
   2862                             int totalSTime = 0;
   2863                             final int N = mProcessCpuTracker.countStats();
   2864                             for (int i=0; i<N; i++) {
   2865                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   2866                                 if (!st.working) {
   2867                                     continue;
   2868                                 }
   2869                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
   2870                                 totalUTime += st.rel_utime;
   2871                                 totalSTime += st.rel_stime;
   2872                                 if (pr != null) {
   2873                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
   2874                                     if (ps == null || !ps.isActive()) {
   2875                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
   2876                                                 pr.info.uid, pr.processName);
   2877                                     }
   2878                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
   2879                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
   2880                                 } else {
   2881                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
   2882                                     if (ps == null || !ps.isActive()) {
   2883                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
   2884                                                 bstats.mapUid(st.uid), st.name);
   2885                                     }
   2886                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
   2887                                 }
   2888                             }
   2889                             final int userTime = mProcessCpuTracker.getLastUserTime();
   2890                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
   2891                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
   2892                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
   2893                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
   2894                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
   2895                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
   2896                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
   2897                         }
   2898                     }
   2899                 }
   2900 
   2901                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
   2902                     mLastWriteTime = now;
   2903                     mBatteryStatsService.scheduleWriteToDisk();
   2904                 }
   2905             }
   2906         }
   2907     }
   2908 
   2909     @Override
   2910     public void batteryNeedsCpuUpdate() {
   2911         updateCpuStatsNow();
   2912     }
   2913 
   2914     @Override
   2915     public void batteryPowerChanged(boolean onBattery) {
   2916         // When plugging in, update the CPU stats first before changing
   2917         // the plug state.
   2918         updateCpuStatsNow();
   2919         synchronized (this) {
   2920             synchronized(mPidsSelfLocked) {
   2921                 mOnBattery = DEBUG_POWER ? true : onBattery;
   2922             }
   2923         }
   2924     }
   2925 
   2926     @Override
   2927     public void batterySendBroadcast(Intent intent) {
   2928         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
   2929                 AppOpsManager.OP_NONE, null, false, false,
   2930                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
   2931     }
   2932 
   2933     /**
   2934      * Initialize the application bind args. These are passed to each
   2935      * process when the bindApplication() IPC is sent to the process. They're
   2936      * lazily setup to make sure the services are running when they're asked for.
   2937      */
   2938     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
   2939         // Isolated processes won't get this optimization, so that we don't
   2940         // violate the rules about which services they have access to.
   2941         if (isolated) {
   2942             if (mIsolatedAppBindArgs == null) {
   2943                 mIsolatedAppBindArgs = new HashMap<>();
   2944                 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
   2945             }
   2946             return mIsolatedAppBindArgs;
   2947         }
   2948 
   2949         if (mAppBindArgs == null) {
   2950             mAppBindArgs = new HashMap<>();
   2951 
   2952             // Setup the application init args
   2953             mAppBindArgs.put("package", ServiceManager.getService("package"));
   2954             mAppBindArgs.put("window", ServiceManager.getService("window"));
   2955             mAppBindArgs.put(Context.ALARM_SERVICE,
   2956                     ServiceManager.getService(Context.ALARM_SERVICE));
   2957         }
   2958         return mAppBindArgs;
   2959     }
   2960 
   2961     boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
   2962         if (r == null || mFocusedActivity == r) {
   2963             return false;
   2964         }
   2965 
   2966         if (!r.isFocusable()) {
   2967             if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
   2968             return false;
   2969         }
   2970 
   2971         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
   2972 
   2973         final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
   2974         if (wasDoingSetFocusedActivity) Slog.w(TAG,
   2975                 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
   2976         mDoingSetFocusedActivity = true;
   2977 
   2978         final ActivityRecord last = mFocusedActivity;
   2979         mFocusedActivity = r;
   2980         if (r.task.isApplicationTask()) {
   2981             if (mCurAppTimeTracker != r.appTimeTracker) {
   2982                 // We are switching app tracking.  Complete the current one.
   2983                 if (mCurAppTimeTracker != null) {
   2984                     mCurAppTimeTracker.stop();
   2985                     mHandler.obtainMessage(
   2986                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
   2987                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
   2988                     mCurAppTimeTracker = null;
   2989                 }
   2990                 if (r.appTimeTracker != null) {
   2991                     mCurAppTimeTracker = r.appTimeTracker;
   2992                     startTimeTrackingFocusedActivityLocked();
   2993                 }
   2994             } else {
   2995                 startTimeTrackingFocusedActivityLocked();
   2996             }
   2997         } else {
   2998             r.appTimeTracker = null;
   2999         }
   3000         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
   3001         // TODO: Probably not, because we don't want to resume voice on switching
   3002         // back to this activity
   3003         if (r.task.voiceInteractor != null) {
   3004             startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
   3005         } else {
   3006             finishRunningVoiceLocked();
   3007             IVoiceInteractionSession session;
   3008             if (last != null && ((session = last.task.voiceSession) != null
   3009                     || (session = last.voiceSession) != null)) {
   3010                 // We had been in a voice interaction session, but now focused has
   3011                 // move to something different.  Just finish the session, we can't
   3012                 // return to it and retain the proper state and synchronization with
   3013                 // the voice interaction service.
   3014                 finishVoiceTask(session);
   3015             }
   3016         }
   3017         if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
   3018             mWindowManager.setFocusedApp(r.appToken, true);
   3019         }
   3020         applyUpdateLockStateLocked(r);
   3021         applyUpdateVrModeLocked(r);
   3022         if (mFocusedActivity.userId != mLastFocusedUserId) {
   3023             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
   3024             mHandler.obtainMessage(
   3025                     FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
   3026             mLastFocusedUserId = mFocusedActivity.userId;
   3027         }
   3028 
   3029         // Log a warning if the focused app is changed during the process. This could
   3030         // indicate a problem of the focus setting logic!
   3031         if (mFocusedActivity != r) Slog.w(TAG,
   3032                 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
   3033         mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
   3034 
   3035         EventLogTags.writeAmFocusedActivity(
   3036                 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
   3037                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
   3038                 reason);
   3039         return true;
   3040     }
   3041 
   3042     final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
   3043         if (mFocusedActivity != goingAway) {
   3044             return;
   3045         }
   3046 
   3047         final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
   3048         if (focusedStack != null) {
   3049             final ActivityRecord top = focusedStack.topActivity();
   3050             if (top != null && top.userId != mLastFocusedUserId) {
   3051                 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
   3052                 mHandler.sendMessage(
   3053                         mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
   3054                 mLastFocusedUserId = top.userId;
   3055             }
   3056         }
   3057 
   3058         // Try to move focus to another activity if possible.
   3059         if (setFocusedActivityLocked(
   3060                 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
   3061             return;
   3062         }
   3063 
   3064         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
   3065                 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
   3066         mFocusedActivity = null;
   3067         EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
   3068     }
   3069 
   3070     @Override
   3071     public void setFocusedStack(int stackId) {
   3072         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
   3073         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
   3074         final long callingId = Binder.clearCallingIdentity();
   3075         try {
   3076             synchronized (this) {
   3077                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
   3078                 if (stack == null) {
   3079                     return;
   3080                 }
   3081                 final ActivityRecord r = stack.topRunningActivityLocked();
   3082                 if (setFocusedActivityLocked(r, "setFocusedStack")) {
   3083                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
   3084                 }
   3085             }
   3086         } finally {
   3087             Binder.restoreCallingIdentity(callingId);
   3088         }
   3089     }
   3090 
   3091     @Override
   3092     public void setFocusedTask(int taskId) {
   3093         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
   3094         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
   3095         final long callingId = Binder.clearCallingIdentity();
   3096         try {
   3097             synchronized (this) {
   3098                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   3099                 if (task == null) {
   3100                     return;
   3101                 }
   3102                 if (mUserController.shouldConfirmCredentials(task.userId)) {
   3103                     mActivityStarter.showConfirmDeviceCredential(task.userId);
   3104                     if (task.stack != null && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
   3105                         mStackSupervisor.moveTaskToStackLocked(task.taskId,
   3106                                 FULLSCREEN_WORKSPACE_STACK_ID, !ON_TOP, !FORCE_FOCUS,
   3107                                 "setFocusedTask", ANIMATE);
   3108                     }
   3109                     return;
   3110                 }
   3111                 final ActivityRecord r = task.topRunningActivityLocked();
   3112                 if (setFocusedActivityLocked(r, "setFocusedTask")) {
   3113                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
   3114                 }
   3115             }
   3116         } finally {
   3117             Binder.restoreCallingIdentity(callingId);
   3118         }
   3119     }
   3120 
   3121     /** Sets the task stack listener that gets callbacks when a task stack changes. */
   3122     @Override
   3123     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
   3124         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
   3125         synchronized (this) {
   3126             if (listener != null) {
   3127                 mTaskStackListeners.register(listener);
   3128             }
   3129         }
   3130     }
   3131 
   3132     @Override
   3133     public void notifyActivityDrawn(IBinder token) {
   3134         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
   3135         synchronized (this) {
   3136             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
   3137             if (r != null) {
   3138                 r.task.stack.notifyActivityDrawnLocked(r);
   3139             }
   3140         }
   3141     }
   3142 
   3143     final void applyUpdateLockStateLocked(ActivityRecord r) {
   3144         // Modifications to the UpdateLock state are done on our handler, outside
   3145         // the activity manager's locks.  The new state is determined based on the
   3146         // state *now* of the relevant activity record.  The object is passed to
   3147         // the handler solely for logging detail, not to be consulted/modified.
   3148         final boolean nextState = r != null && r.immersive;
   3149         mHandler.sendMessage(
   3150                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
   3151     }
   3152 
   3153     final void applyUpdateVrModeLocked(ActivityRecord r) {
   3154         mHandler.sendMessage(
   3155                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
   3156     }
   3157 
   3158     private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
   3159         mHandler.sendMessage(
   3160                 mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
   3161     }
   3162 
   3163     private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
   3164             ComponentName callingPackage, boolean immediate) {
   3165         VrManagerInternal vrService =
   3166                 LocalServices.getService(VrManagerInternal.class);
   3167         if (immediate) {
   3168             vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
   3169         } else {
   3170             vrService.setVrMode(enabled, packageName, userId, callingPackage);
   3171         }
   3172     }
   3173 
   3174     final void showAskCompatModeDialogLocked(ActivityRecord r) {
   3175         Message msg = Message.obtain();
   3176         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
   3177         msg.obj = r.task.askedCompatMode ? null : r;
   3178         mUiHandler.sendMessage(msg);
   3179     }
   3180 
   3181     final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
   3182         if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
   3183                 && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
   3184             final Message msg = Message.obtain();
   3185             msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
   3186             msg.obj = r;
   3187             mUiHandler.sendMessage(msg);
   3188         }
   3189     }
   3190 
   3191     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
   3192             String what, Object obj, ProcessRecord srcApp) {
   3193         app.lastActivityTime = now;
   3194 
   3195         if (app.activities.size() > 0) {
   3196             // Don't want to touch dependent processes that are hosting activities.
   3197             return index;
   3198         }
   3199 
   3200         int lrui = mLruProcesses.lastIndexOf(app);
   3201         if (lrui < 0) {
   3202             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
   3203                     + what + " " + obj + " from " + srcApp);
   3204             return index;
   3205         }
   3206 
   3207         if (lrui >= index) {
   3208             // Don't want to cause this to move dependent processes *back* in the
   3209             // list as if they were less frequently used.
   3210             return index;
   3211         }
   3212 
   3213         if (lrui >= mLruProcessActivityStart) {
   3214             // Don't want to touch dependent processes that are hosting activities.
   3215             return index;
   3216         }
   3217 
   3218         mLruProcesses.remove(lrui);
   3219         if (index > 0) {
   3220             index--;
   3221         }
   3222         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
   3223                 + " in LRU list: " + app);
   3224         mLruProcesses.add(index, app);
   3225         return index;
   3226     }
   3227 
   3228     static void killProcessGroup(int uid, int pid) {
   3229         if (sKillHandler != null) {
   3230             sKillHandler.sendMessage(
   3231                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
   3232         } else {
   3233             Slog.w(TAG, "Asked to kill process group before system bringup!");
   3234             Process.killProcessGroup(uid, pid);
   3235         }
   3236     }
   3237 
   3238     final void removeLruProcessLocked(ProcessRecord app) {
   3239         int lrui = mLruProcesses.lastIndexOf(app);
   3240         if (lrui >= 0) {
   3241             if (!app.killed) {
   3242                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
   3243                 Process.killProcessQuiet(app.pid);
   3244                 killProcessGroup(app.uid, app.pid);
   3245             }
   3246             if (lrui <= mLruProcessActivityStart) {
   3247                 mLruProcessActivityStart--;
   3248             }
   3249             if (lrui <= mLruProcessServiceStart) {
   3250                 mLruProcessServiceStart--;
   3251             }
   3252             mLruProcesses.remove(lrui);
   3253         }
   3254     }
   3255 
   3256     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
   3257             ProcessRecord client) {
   3258         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
   3259                 || app.treatLikeActivity;
   3260         final boolean hasService = false; // not impl yet. app.services.size() > 0;
   3261         if (!activityChange && hasActivity) {
   3262             // The process has activities, so we are only allowing activity-based adjustments
   3263             // to move it.  It should be kept in the front of the list with other
   3264             // processes that have activities, and we don't want those to change their
   3265             // order except due to activity operations.
   3266             return;
   3267         }
   3268 
   3269         mLruSeq++;
   3270         final long now = SystemClock.uptimeMillis();
   3271         app.lastActivityTime = now;
   3272 
   3273         // First a quick reject: if the app is already at the position we will
   3274         // put it, then there is nothing to do.
   3275         if (hasActivity) {
   3276             final int N = mLruProcesses.size();
   3277             if (N > 0 && mLruProcesses.get(N-1) == app) {
   3278                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
   3279                 return;
   3280             }
   3281         } else {
   3282             if (mLruProcessServiceStart > 0
   3283                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
   3284                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
   3285                 return;
   3286             }
   3287         }
   3288 
   3289         int lrui = mLruProcesses.lastIndexOf(app);
   3290 
   3291         if (app.persistent && lrui >= 0) {
   3292             // We don't care about the position of persistent processes, as long as
   3293             // they are in the list.
   3294             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
   3295             return;
   3296         }
   3297 
   3298         /* In progress: compute new position first, so we can avoid doing work
   3299            if the process is not actually going to move.  Not yet working.
   3300         int addIndex;
   3301         int nextIndex;
   3302         boolean inActivity = false, inService = false;
   3303         if (hasActivity) {
   3304             // Process has activities, put it at the very tipsy-top.
   3305             addIndex = mLruProcesses.size();
   3306             nextIndex = mLruProcessServiceStart;
   3307             inActivity = true;
   3308         } else if (hasService) {
   3309             // Process has services, put it at the top of the service list.
   3310             addIndex = mLruProcessActivityStart;
   3311             nextIndex = mLruProcessServiceStart;
   3312             inActivity = true;
   3313             inService = true;
   3314         } else  {
   3315             // Process not otherwise of interest, it goes to the top of the non-service area.
   3316             addIndex = mLruProcessServiceStart;
   3317             if (client != null) {
   3318                 int clientIndex = mLruProcesses.lastIndexOf(client);
   3319                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
   3320                         + app);
   3321                 if (clientIndex >= 0 && addIndex > clientIndex) {
   3322                     addIndex = clientIndex;
   3323                 }
   3324             }
   3325             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
   3326         }
   3327 
   3328         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
   3329                 + mLruProcessActivityStart + "): " + app);
   3330         */
   3331 
   3332         if (lrui >= 0) {
   3333             if (lrui < mLruProcessActivityStart) {
   3334                 mLruProcessActivityStart--;
   3335             }
   3336             if (lrui < mLruProcessServiceStart) {
   3337                 mLruProcessServiceStart--;
   3338             }
   3339             /*
   3340             if (addIndex > lrui) {
   3341                 addIndex--;
   3342             }
   3343             if (nextIndex > lrui) {
   3344                 nextIndex--;
   3345             }
   3346             */
   3347             mLruProcesses.remove(lrui);
   3348         }
   3349 
   3350         /*
   3351         mLruProcesses.add(addIndex, app);
   3352         if (inActivity) {
   3353             mLruProcessActivityStart++;
   3354         }
   3355         if (inService) {
   3356             mLruProcessActivityStart++;
   3357         }
   3358         */
   3359 
   3360         int nextIndex;
   3361         if (hasActivity) {
   3362             final int N = mLruProcesses.size();
   3363             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
   3364                 // Process doesn't have activities, but has clients with
   3365                 // activities...  move it up, but one below the top (the top
   3366                 // should always have a real activity).
   3367                 if (DEBUG_LRU) Slog.d(TAG_LRU,
   3368                         "Adding to second-top of LRU activity list: " + app);
   3369                 mLruProcesses.add(N - 1, app);
   3370                 // To keep it from spamming the LRU list (by making a bunch of clients),
   3371                 // we will push down any other entries owned by the app.
   3372                 final int uid = app.info.uid;
   3373                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
   3374                     ProcessRecord subProc = mLruProcesses.get(i);
   3375                     if (subProc.info.uid == uid) {
   3376                         // We want to push this one down the list.  If the process after
   3377                         // it is for the same uid, however, don't do so, because we don't
   3378                         // want them internally to be re-ordered.
   3379                         if (mLruProcesses.get(i - 1).info.uid != uid) {
   3380                             if (DEBUG_LRU) Slog.d(TAG_LRU,
   3381                                     "Pushing uid " + uid + " swapping at " + i + ": "
   3382                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
   3383                             ProcessRecord tmp = mLruProcesses.get(i);
   3384                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
   3385                             mLruProcesses.set(i - 1, tmp);
   3386                             i--;
   3387                         }
   3388                     } else {
   3389                         // A gap, we can stop here.
   3390                         break;
   3391                     }
   3392                 }
   3393             } else {
   3394                 // Process has activities, put it at the very tipsy-top.
   3395                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
   3396                 mLruProcesses.add(app);
   3397             }
   3398             nextIndex = mLruProcessServiceStart;
   3399         } else if (hasService) {
   3400             // Process has services, put it at the top of the service list.
   3401             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
   3402             mLruProcesses.add(mLruProcessActivityStart, app);
   3403             nextIndex = mLruProcessServiceStart;
   3404             mLruProcessActivityStart++;
   3405         } else  {
   3406             // Process not otherwise of interest, it goes to the top of the non-service area.
   3407             int index = mLruProcessServiceStart;
   3408             if (client != null) {
   3409                 // If there is a client, don't allow the process to be moved up higher
   3410                 // in the list than that client.
   3411                 int clientIndex = mLruProcesses.lastIndexOf(client);
   3412                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
   3413                         + " when updating " + app);
   3414                 if (clientIndex <= lrui) {
   3415                     // Don't allow the client index restriction to push it down farther in the
   3416                     // list than it already is.
   3417                     clientIndex = lrui;
   3418                 }
   3419                 if (clientIndex >= 0 && index > clientIndex) {
   3420                     index = clientIndex;
   3421                 }
   3422             }
   3423             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
   3424             mLruProcesses.add(index, app);
   3425             nextIndex = index-1;
   3426             mLruProcessActivityStart++;
   3427             mLruProcessServiceStart++;
   3428         }
   3429 
   3430         // If the app is currently using a content provider or service,
   3431         // bump those processes as well.
   3432         for (int j=app.connections.size()-1; j>=0; j--) {
   3433             ConnectionRecord cr = app.connections.valueAt(j);
   3434             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
   3435                     && cr.binding.service.app != null
   3436                     && cr.binding.service.app.lruSeq != mLruSeq
   3437                     && !cr.binding.service.app.persistent) {
   3438                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
   3439                         "service connection", cr, app);
   3440             }
   3441         }
   3442         for (int j=app.conProviders.size()-1; j>=0; j--) {
   3443             ContentProviderRecord cpr = app.conProviders.get(j).provider;
   3444             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
   3445                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
   3446                         "provider reference", cpr, app);
   3447             }
   3448         }
   3449     }
   3450 
   3451     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
   3452         if (uid == Process.SYSTEM_UID) {
   3453             // The system gets to run in any process.  If there are multiple
   3454             // processes with the same uid, just pick the first (this
   3455             // should never happen).
   3456             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
   3457             if (procs == null) return null;
   3458             final int procCount = procs.size();
   3459             for (int i = 0; i < procCount; i++) {
   3460                 final int procUid = procs.keyAt(i);
   3461                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
   3462                     // Don't use an app process or different user process for system component.
   3463                     continue;
   3464                 }
   3465                 return procs.valueAt(i);
   3466             }
   3467         }
   3468         ProcessRecord proc = mProcessNames.get(processName, uid);
   3469         if (false && proc != null && !keepIfLarge
   3470                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
   3471                 && proc.lastCachedPss >= 4000) {
   3472             // Turn this condition on to cause killing to happen regularly, for testing.
   3473             if (proc.baseProcessTracker != null) {
   3474                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
   3475             }
   3476             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
   3477         } else if (proc != null && !keepIfLarge
   3478                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
   3479                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
   3480             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
   3481             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
   3482                 if (proc.baseProcessTracker != null) {
   3483                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
   3484                 }
   3485                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
   3486             }
   3487         }
   3488         return proc;
   3489     }
   3490 
   3491     void notifyPackageUse(String packageName, int reason) {
   3492         IPackageManager pm = AppGlobals.getPackageManager();
   3493         try {
   3494             pm.notifyPackageUse(packageName, reason);
   3495         } catch (RemoteException e) {
   3496         }
   3497     }
   3498 
   3499     boolean isNextTransitionForward() {
   3500         int transit = mWindowManager.getPendingAppTransition();
   3501         return transit == TRANSIT_ACTIVITY_OPEN
   3502                 || transit == TRANSIT_TASK_OPEN
   3503                 || transit == TRANSIT_TASK_TO_FRONT;
   3504     }
   3505 
   3506     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
   3507             String processName, String abiOverride, int uid, Runnable crashHandler) {
   3508         synchronized(this) {
   3509             ApplicationInfo info = new ApplicationInfo();
   3510             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
   3511             // For isolated processes, the former contains the parent's uid and the latter the
   3512             // actual uid of the isolated process.
   3513             // In the special case introduced by this method (which is, starting an isolated
   3514             // process directly from the SystemServer without an actual parent app process) the
   3515             // closest thing to a parent's uid is SYSTEM_UID.
   3516             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
   3517             // the |isolated| logic in the ProcessRecord constructor.
   3518             info.uid = Process.SYSTEM_UID;
   3519             info.processName = processName;
   3520             info.className = entryPoint;
   3521             info.packageName = "android";
   3522             ProcessRecord proc = startProcessLocked(processName, info /* info */,
   3523                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
   3524                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
   3525                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
   3526                     crashHandler);
   3527             return proc != null ? proc.pid : 0;
   3528         }
   3529     }
   3530 
   3531     final ProcessRecord startProcessLocked(String processName,
   3532             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
   3533             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
   3534             boolean isolated, boolean keepIfLarge) {
   3535         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
   3536                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
   3537                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
   3538                 null /* crashHandler */);
   3539     }
   3540 
   3541     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
   3542             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
   3543             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
   3544             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
   3545         long startTime = SystemClock.elapsedRealtime();
   3546         ProcessRecord app;
   3547         if (!isolated) {
   3548             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
   3549             checkTime(startTime, "startProcess: after getProcessRecord");
   3550 
   3551             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
   3552                 // If we are in the background, then check to see if this process
   3553                 // is bad.  If so, we will just silently fail.
   3554                 if (mAppErrors.isBadProcessLocked(info)) {
   3555                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
   3556                             + "/" + info.processName);
   3557                     return null;
   3558                 }
   3559             } else {
   3560                 // When the user is explicitly starting a process, then clear its
   3561                 // crash count so that we won't make it bad until they see at
   3562                 // least one crash dialog again, and make the process good again
   3563                 // if it had been bad.
   3564                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
   3565                         + "/" + info.processName);
   3566                 mAppErrors.resetProcessCrashTimeLocked(info);
   3567                 if (mAppErrors.isBadProcessLocked(info)) {
   3568                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
   3569                             UserHandle.getUserId(info.uid), info.uid,
   3570                             info.processName);
   3571                     mAppErrors.clearBadProcessLocked(info);
   3572                     if (app != null) {
   3573                         app.bad = false;
   3574                     }
   3575                 }
   3576             }
   3577         } else {
   3578             // If this is an isolated process, it can't re-use an existing process.
   3579             app = null;
   3580         }
   3581 
   3582         // app launch boost for big.little configurations
   3583         // use cpusets to migrate freshly launched tasks to big cores
   3584         nativeMigrateToBoost();
   3585         mIsBoosted = true;
   3586         mBoostStartTime = SystemClock.uptimeMillis();
   3587         Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
   3588         mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
   3589 
   3590         // We don't have to do anything more if:
   3591         // (1) There is an existing application record; and
   3592         // (2) The caller doesn't think it is dead, OR there is no thread
   3593         //     object attached to it so we know it couldn't have crashed; and
   3594         // (3) There is a pid assigned to it, so it is either starting or
   3595         //     already running.
   3596         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
   3597                 + " app=" + app + " knownToBeDead=" + knownToBeDead
   3598                 + " thread=" + (app != null ? app.thread : null)
   3599                 + " pid=" + (app != null ? app.pid : -1));
   3600         if (app != null && app.pid > 0) {
   3601             if ((!knownToBeDead && !app.killed) || app.thread == null) {
   3602                 // We already have the app running, or are waiting for it to
   3603                 // come up (we have a pid but not yet its thread), so keep it.
   3604                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
   3605                 // If this is a new package in the process, add the package to the list
   3606                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
   3607                 checkTime(startTime, "startProcess: done, added package to proc");
   3608                 return app;
   3609             }
   3610 
   3611             // An application record is attached to a previous process,
   3612             // clean it up now.
   3613             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
   3614             checkTime(startTime, "startProcess: bad proc running, killing");
   3615             killProcessGroup(app.uid, app.pid);
   3616             handleAppDiedLocked(app, true, true);
   3617             checkTime(startTime, "startProcess: done killing old proc");
   3618         }
   3619 
   3620         String hostingNameStr = hostingName != null
   3621                 ? hostingName.flattenToShortString() : null;
   3622 
   3623         if (app == null) {
   3624             checkTime(startTime, "startProcess: creating new process record");
   3625             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
   3626             if (app == null) {
   3627                 Slog.w(TAG, "Failed making new process record for "
   3628                         + processName + "/" + info.uid + " isolated=" + isolated);
   3629                 return null;
   3630             }
   3631             app.crashHandler = crashHandler;
   3632             checkTime(startTime, "startProcess: done creating new process record");
   3633         } else {
   3634             // If this is a new package in the process, add the package to the list
   3635             app.addPackage(info.packageName, info.versionCode, mProcessStats);
   3636             checkTime(startTime, "startProcess: added package to existing proc");
   3637         }
   3638 
   3639         // If the system is not ready yet, then hold off on starting this
   3640         // process until it is.
   3641         if (!mProcessesReady
   3642                 && !isAllowedWhileBooting(info)
   3643                 && !allowWhileBooting) {
   3644             if (!mProcessesOnHold.contains(app)) {
   3645                 mProcessesOnHold.add(app);
   3646             }
   3647             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
   3648                     "System not ready, putting on hold: " + app);
   3649             checkTime(startTime, "startProcess: returning with proc on hold");
   3650             return app;
   3651         }
   3652 
   3653         checkTime(startTime, "startProcess: stepping in to startProcess");
   3654         startProcessLocked(
   3655                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
   3656         checkTime(startTime, "startProcess: done starting proc!");
   3657         return (app.pid != 0) ? app : null;
   3658     }
   3659 
   3660     boolean isAllowedWhileBooting(ApplicationInfo ai) {
   3661         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
   3662     }
   3663 
   3664     private final void startProcessLocked(ProcessRecord app,
   3665             String hostingType, String hostingNameStr) {
   3666         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
   3667                 null /* entryPoint */, null /* entryPointArgs */);
   3668     }
   3669 
   3670     private final void startProcessLocked(ProcessRecord app, String hostingType,
   3671             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
   3672         long startTime = SystemClock.elapsedRealtime();
   3673         if (app.pid > 0 && app.pid != MY_PID) {
   3674             checkTime(startTime, "startProcess: removing from pids map");
   3675             synchronized (mPidsSelfLocked) {
   3676                 mPidsSelfLocked.remove(app.pid);
   3677                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   3678             }
   3679             checkTime(startTime, "startProcess: done removing from pids map");
   3680             app.setPid(0);
   3681         }
   3682 
   3683         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
   3684                 "startProcessLocked removing on hold: " + app);
   3685         mProcessesOnHold.remove(app);
   3686 
   3687         checkTime(startTime, "startProcess: starting to update cpu stats");
   3688         updateCpuStats();
   3689         checkTime(startTime, "startProcess: done updating cpu stats");
   3690 
   3691         try {
   3692             try {
   3693                 final int userId = UserHandle.getUserId(app.uid);
   3694                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
   3695             } catch (RemoteException e) {
   3696                 throw e.rethrowAsRuntimeException();
   3697             }
   3698 
   3699             int uid = app.uid;
   3700             int[] gids = null;
   3701             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
   3702             if (!app.isolated) {
   3703                 int[] permGids = null;
   3704                 try {
   3705                     checkTime(startTime, "startProcess: getting gids from package manager");
   3706                     final IPackageManager pm = AppGlobals.getPackageManager();
   3707                     permGids = pm.getPackageGids(app.info.packageName,
   3708                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
   3709                     MountServiceInternal mountServiceInternal = LocalServices.getService(
   3710                             MountServiceInternal.class);
   3711                     mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
   3712                             app.info.packageName);
   3713                 } catch (RemoteException e) {
   3714                     throw e.rethrowAsRuntimeException();
   3715                 }
   3716 
   3717                 /*
   3718                  * Add shared application and profile GIDs so applications can share some
   3719                  * resources like shared libraries and access user-wide resources
   3720                  */
   3721                 if (ArrayUtils.isEmpty(permGids)) {
   3722                     gids = new int[2];
   3723                 } else {
   3724                     gids = new int[permGids.length + 2];
   3725                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
   3726                 }
   3727                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
   3728                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
   3729             }
   3730             checkTime(startTime, "startProcess: building args");
   3731             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
   3732                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
   3733                         && mTopComponent != null
   3734                         && app.processName.equals(mTopComponent.getPackageName())) {
   3735                     uid = 0;
   3736                 }
   3737                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
   3738                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
   3739                     uid = 0;
   3740                 }
   3741             }
   3742             int debugFlags = 0;
   3743             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   3744                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
   3745                 // Also turn on CheckJNI for debuggable apps. It's quite
   3746                 // awkward to turn on otherwise.
   3747                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   3748             }
   3749             // Run the app in safe mode if its manifest requests so or the
   3750             // system is booted in safe mode.
   3751             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
   3752                 mSafeMode == true) {
   3753                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
   3754             }
   3755             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
   3756                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   3757             }
   3758             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
   3759             if ("true".equals(genDebugInfoProperty)) {
   3760                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
   3761             }
   3762             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
   3763                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
   3764             }
   3765             if ("1".equals(SystemProperties.get("debug.assert"))) {
   3766                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
   3767             }
   3768             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
   3769                 // Enable all debug flags required by the native debugger.
   3770                 debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
   3771                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
   3772                 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
   3773                 mNativeDebuggingApp = null;
   3774             }
   3775 
   3776             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
   3777             if (requiredAbi == null) {
   3778                 requiredAbi = Build.SUPPORTED_ABIS[0];
   3779             }
   3780 
   3781             String instructionSet = null;
   3782             if (app.info.primaryCpuAbi != null) {
   3783                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
   3784             }
   3785 
   3786             app.gids = gids;
   3787             app.requiredAbi = requiredAbi;
   3788             app.instructionSet = instructionSet;
   3789 
   3790             // Start the process.  It will either succeed and return a result containing
   3791             // the PID of the new process, or else throw a RuntimeException.
   3792             boolean isActivityProcess = (entryPoint == null);
   3793             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
   3794             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
   3795                     app.processName);
   3796             checkTime(startTime, "startProcess: asking zygote to start proc");
   3797             Process.ProcessStartResult startResult = Process.start(entryPoint,
   3798                     app.processName, uid, uid, gids, debugFlags, mountExternal,
   3799                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
   3800                     app.info.dataDir, entryPointArgs);
   3801             checkTime(startTime, "startProcess: returned from zygote!");
   3802             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   3803 
   3804             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
   3805             checkTime(startTime, "startProcess: done updating battery stats");
   3806 
   3807             EventLog.writeEvent(EventLogTags.AM_PROC_START,
   3808                     UserHandle.getUserId(uid), startResult.pid, uid,
   3809                     app.processName, hostingType,
   3810                     hostingNameStr != null ? hostingNameStr : "");
   3811 
   3812             try {
   3813                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
   3814                         app.info.seinfo, app.info.sourceDir, startResult.pid);
   3815             } catch (RemoteException ex) {
   3816                 // Ignore
   3817             }
   3818 
   3819             if (app.persistent) {
   3820                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
   3821             }
   3822 
   3823             checkTime(startTime, "startProcess: building log message");
   3824             StringBuilder buf = mStringBuilder;
   3825             buf.setLength(0);
   3826             buf.append("Start proc ");
   3827             buf.append(startResult.pid);
   3828             buf.append(':');
   3829             buf.append(app.processName);
   3830             buf.append('/');
   3831             UserHandle.formatUid(buf, uid);
   3832             if (!isActivityProcess) {
   3833                 buf.append(" [");
   3834                 buf.append(entryPoint);
   3835                 buf.append("]");
   3836             }
   3837             buf.append(" for ");
   3838             buf.append(hostingType);
   3839             if (hostingNameStr != null) {
   3840                 buf.append(" ");
   3841                 buf.append(hostingNameStr);
   3842             }
   3843             Slog.i(TAG, buf.toString());
   3844             app.setPid(startResult.pid);
   3845             app.usingWrapper = startResult.usingWrapper;
   3846             app.removed = false;
   3847             app.killed = false;
   3848             app.killedByAm = false;
   3849             checkTime(startTime, "startProcess: starting to update pids map");
   3850             ProcessRecord oldApp;
   3851             synchronized (mPidsSelfLocked) {
   3852                 oldApp = mPidsSelfLocked.get(startResult.pid);
   3853             }
   3854             // If there is already an app occupying that pid that hasn't been cleaned up
   3855             if (oldApp != null && !app.isolated) {
   3856                 // Clean up anything relating to this pid first
   3857                 Slog.w(TAG, "Reusing pid " + startResult.pid
   3858                         + " while app is still mapped to it");
   3859                 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
   3860                         true /*replacingPid*/);
   3861             }
   3862             synchronized (mPidsSelfLocked) {
   3863                 this.mPidsSelfLocked.put(startResult.pid, app);
   3864                 if (isActivityProcess) {
   3865                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   3866                     msg.obj = app;
   3867                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
   3868                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
   3869                 }
   3870             }
   3871             checkTime(startTime, "startProcess: done updating pids map");
   3872         } catch (RuntimeException e) {
   3873             Slog.e(TAG, "Failure starting process " + app.processName, e);
   3874 
   3875             // Something went very wrong while trying to start this process; one
   3876             // common case is when the package is frozen due to an active
   3877             // upgrade. To recover, clean up any active bookkeeping related to
   3878             // starting this process. (We already invoked this method once when
   3879             // the package was initially frozen through KILL_APPLICATION_MSG, so
   3880             // it doesn't hurt to use it again.)
   3881             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
   3882                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
   3883         }
   3884     }
   3885 
   3886     void updateUsageStats(ActivityRecord component, boolean resumed) {
   3887         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
   3888                 "updateUsageStats: comp=" + component + "res=" + resumed);
   3889         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   3890         if (resumed) {
   3891             if (mUsageStatsService != null) {
   3892                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
   3893                         UsageEvents.Event.MOVE_TO_FOREGROUND);
   3894             }
   3895             synchronized (stats) {
   3896                 stats.noteActivityResumedLocked(component.app.uid);
   3897             }
   3898         } else {
   3899             if (mUsageStatsService != null) {
   3900                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
   3901                         UsageEvents.Event.MOVE_TO_BACKGROUND);
   3902             }
   3903             synchronized (stats) {
   3904                 stats.noteActivityPausedLocked(component.app.uid);
   3905             }
   3906         }
   3907     }
   3908 
   3909     Intent getHomeIntent() {
   3910         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
   3911         intent.setComponent(mTopComponent);
   3912         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
   3913         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   3914             intent.addCategory(Intent.CATEGORY_HOME);
   3915         }
   3916         return intent;
   3917     }
   3918 
   3919     boolean startHomeActivityLocked(int userId, String reason) {
   3920         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
   3921                 && mTopAction == null) {
   3922             // We are running in factory test mode, but unable to find
   3923             // the factory test app, so just sit around displaying the
   3924             // error message and don't try to start anything.
   3925             return false;
   3926         }
   3927         Intent intent = getHomeIntent();
   3928         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
   3929         if (aInfo != null) {
   3930             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
   3931             // Don't do this if the home app is currently being
   3932             // instrumented.
   3933             aInfo = new ActivityInfo(aInfo);
   3934             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
   3935             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
   3936                     aInfo.applicationInfo.uid, true);
   3937             if (app == null || app.instrumentationClass == null) {
   3938                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
   3939                 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
   3940             }
   3941         } else {
   3942             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
   3943         }
   3944 
   3945         return true;
   3946     }
   3947 
   3948     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
   3949         ActivityInfo ai = null;
   3950         ComponentName comp = intent.getComponent();
   3951         try {
   3952             if (comp != null) {
   3953                 // Factory test.
   3954                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
   3955             } else {
   3956                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
   3957                         intent,
   3958                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
   3959                         flags, userId);
   3960 
   3961                 if (info != null) {
   3962                     ai = info.activityInfo;
   3963                 }
   3964             }
   3965         } catch (RemoteException e) {
   3966             // ignore
   3967         }
   3968 
   3969         return ai;
   3970     }
   3971 
   3972     /**
   3973      * Starts the "new version setup screen" if appropriate.
   3974      */
   3975     void startSetupActivityLocked() {
   3976         // Only do this once per boot.
   3977         if (mCheckedForSetup) {
   3978             return;
   3979         }
   3980 
   3981         // We will show this screen if the current one is a different
   3982         // version than the last one shown, and we are not running in
   3983         // low-level factory test mode.
   3984         final ContentResolver resolver = mContext.getContentResolver();
   3985         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
   3986                 Settings.Global.getInt(resolver,
   3987                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
   3988             mCheckedForSetup = true;
   3989 
   3990             // See if we should be showing the platform update setup UI.
   3991             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
   3992             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
   3993                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
   3994             if (!ris.isEmpty()) {
   3995                 final ResolveInfo ri = ris.get(0);
   3996                 String vers = ri.activityInfo.metaData != null
   3997                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
   3998                         : null;
   3999                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
   4000                     vers = ri.activityInfo.applicationInfo.metaData.getString(
   4001                             Intent.METADATA_SETUP_VERSION);
   4002                 }
   4003                 String lastVers = Settings.Secure.getString(
   4004                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
   4005                 if (vers != null && !vers.equals(lastVers)) {
   4006                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   4007                     intent.setComponent(new ComponentName(
   4008                             ri.activityInfo.packageName, ri.activityInfo.name));
   4009                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
   4010                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
   4011                             null, 0, 0, 0, null, false, false, null, null, null);
   4012                 }
   4013             }
   4014         }
   4015     }
   4016 
   4017     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
   4018         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
   4019     }
   4020 
   4021     void enforceNotIsolatedCaller(String caller) {
   4022         if (UserHandle.isIsolated(Binder.getCallingUid())) {
   4023             throw new SecurityException("Isolated process not allowed to call " + caller);
   4024         }
   4025     }
   4026 
   4027     void enforceShellRestriction(String restriction, int userHandle) {
   4028         if (Binder.getCallingUid() == Process.SHELL_UID) {
   4029             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
   4030                 throw new SecurityException("Shell does not have permission to access user "
   4031                         + userHandle);
   4032             }
   4033         }
   4034     }
   4035 
   4036     @Override
   4037     public int getFrontActivityScreenCompatMode() {
   4038         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
   4039         synchronized (this) {
   4040             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
   4041         }
   4042     }
   4043 
   4044     @Override
   4045     public void setFrontActivityScreenCompatMode(int mode) {
   4046         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   4047                 "setFrontActivityScreenCompatMode");
   4048         synchronized (this) {
   4049             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
   4050         }
   4051     }
   4052 
   4053     @Override
   4054     public int getPackageScreenCompatMode(String packageName) {
   4055         enforceNotIsolatedCaller("getPackageScreenCompatMode");
   4056         synchronized (this) {
   4057             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
   4058         }
   4059     }
   4060 
   4061     @Override
   4062     public void setPackageScreenCompatMode(String packageName, int mode) {
   4063         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   4064                 "setPackageScreenCompatMode");
   4065         synchronized (this) {
   4066             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
   4067         }
   4068     }
   4069 
   4070     @Override
   4071     public boolean getPackageAskScreenCompat(String packageName) {
   4072         enforceNotIsolatedCaller("getPackageAskScreenCompat");
   4073         synchronized (this) {
   4074             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
   4075         }
   4076     }
   4077 
   4078     @Override
   4079     public void setPackageAskScreenCompat(String packageName, boolean ask) {
   4080         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   4081                 "setPackageAskScreenCompat");
   4082         synchronized (this) {
   4083             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
   4084         }
   4085     }
   4086 
   4087     private boolean hasUsageStatsPermission(String callingPackage) {
   4088         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
   4089                 Binder.getCallingUid(), callingPackage);
   4090         if (mode == AppOpsManager.MODE_DEFAULT) {
   4091             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
   4092                     == PackageManager.PERMISSION_GRANTED;
   4093         }
   4094         return mode == AppOpsManager.MODE_ALLOWED;
   4095     }
   4096 
   4097     @Override
   4098     public int getPackageProcessState(String packageName, String callingPackage) {
   4099         if (!hasUsageStatsPermission(callingPackage)) {
   4100             enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
   4101                     "getPackageProcessState");
   4102         }
   4103 
   4104         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
   4105         synchronized (this) {
   4106             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   4107                 final ProcessRecord proc = mLruProcesses.get(i);
   4108                 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
   4109                         || procState > proc.setProcState) {
   4110                     boolean found = false;
   4111                     for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
   4112                         if (proc.pkgList.keyAt(j).equals(packageName)) {
   4113                             procState = proc.setProcState;
   4114                             found = true;
   4115                         }
   4116                     }
   4117                     if (proc.pkgDeps != null && !found) {
   4118                         for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
   4119                             if (proc.pkgDeps.valueAt(j).equals(packageName)) {
   4120                                 procState = proc.setProcState;
   4121                                 break;
   4122                             }
   4123                         }
   4124                     }
   4125                 }
   4126             }
   4127         }
   4128         return procState;
   4129     }
   4130 
   4131     @Override
   4132     public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
   4133         synchronized (this) {
   4134             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
   4135             if (app == null) {
   4136                 return false;
   4137             }
   4138             if (app.trimMemoryLevel < level && app.thread != null &&
   4139                     (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
   4140                             app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
   4141                 try {
   4142                     app.thread.scheduleTrimMemory(level);
   4143                     app.trimMemoryLevel = level;
   4144                     return true;
   4145                 } catch (RemoteException e) {
   4146                     // Fallthrough to failure case.
   4147                 }
   4148             }
   4149         }
   4150         return false;
   4151     }
   4152 
   4153     private void dispatchProcessesChanged() {
   4154         int N;
   4155         synchronized (this) {
   4156             N = mPendingProcessChanges.size();
   4157             if (mActiveProcessChanges.length < N) {
   4158                 mActiveProcessChanges = new ProcessChangeItem[N];
   4159             }
   4160             mPendingProcessChanges.toArray(mActiveProcessChanges);
   4161             mPendingProcessChanges.clear();
   4162             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   4163                     "*** Delivering " + N + " process changes");
   4164         }
   4165 
   4166         int i = mProcessObservers.beginBroadcast();
   4167         while (i > 0) {
   4168             i--;
   4169             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   4170             if (observer != null) {
   4171                 try {
   4172                     for (int j=0; j<N; j++) {
   4173                         ProcessChangeItem item = mActiveProcessChanges[j];
   4174                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
   4175                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   4176                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
   4177                                     + item.uid + ": " + item.foregroundActivities);
   4178                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
   4179                                     item.foregroundActivities);
   4180                         }
   4181                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
   4182                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   4183                                     "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
   4184                                     + ": " + item.processState);
   4185                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
   4186                         }
   4187                     }
   4188                 } catch (RemoteException e) {
   4189                 }
   4190             }
   4191         }
   4192         mProcessObservers.finishBroadcast();
   4193 
   4194         synchronized (this) {
   4195             for (int j=0; j<N; j++) {
   4196                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
   4197             }
   4198         }
   4199     }
   4200 
   4201     private void dispatchProcessDied(int pid, int uid) {
   4202         int i = mProcessObservers.beginBroadcast();
   4203         while (i > 0) {
   4204             i--;
   4205             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   4206             if (observer != null) {
   4207                 try {
   4208                     observer.onProcessDied(pid, uid);
   4209                 } catch (RemoteException e) {
   4210                 }
   4211             }
   4212         }
   4213         mProcessObservers.finishBroadcast();
   4214     }
   4215 
   4216     private void dispatchUidsChanged() {
   4217         int N;
   4218         synchronized (this) {
   4219             N = mPendingUidChanges.size();
   4220             if (mActiveUidChanges.length < N) {
   4221                 mActiveUidChanges = new UidRecord.ChangeItem[N];
   4222             }
   4223             for (int i=0; i<N; i++) {
   4224                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
   4225                 mActiveUidChanges[i] = change;
   4226                 if (change.uidRecord != null) {
   4227                     change.uidRecord.pendingChange = null;
   4228                     change.uidRecord = null;
   4229                 }
   4230             }
   4231             mPendingUidChanges.clear();
   4232             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4233                     "*** Delivering " + N + " uid changes");
   4234         }
   4235 
   4236         if (mLocalPowerManager != null) {
   4237             for (int j=0; j<N; j++) {
   4238                 UidRecord.ChangeItem item = mActiveUidChanges[j];
   4239                 if (item.change == UidRecord.CHANGE_GONE
   4240                         || item.change == UidRecord.CHANGE_GONE_IDLE) {
   4241                     mLocalPowerManager.uidGone(item.uid);
   4242                 } else {
   4243                     mLocalPowerManager.updateUidProcState(item.uid, item.processState);
   4244                 }
   4245             }
   4246         }
   4247 
   4248         int i = mUidObservers.beginBroadcast();
   4249         while (i > 0) {
   4250             i--;
   4251             final IUidObserver observer = mUidObservers.getBroadcastItem(i);
   4252             final int which = (Integer)mUidObservers.getBroadcastCookie(i);
   4253             if (observer != null) {
   4254                 try {
   4255                     for (int j=0; j<N; j++) {
   4256                         UidRecord.ChangeItem item = mActiveUidChanges[j];
   4257                         final int change = item.change;
   4258                         UidRecord validateUid = null;
   4259                         if (VALIDATE_UID_STATES && i == 0) {
   4260                             validateUid = mValidateUids.get(item.uid);
   4261                             if (validateUid == null && change != UidRecord.CHANGE_GONE
   4262                                     && change != UidRecord.CHANGE_GONE_IDLE) {
   4263                                 validateUid = new UidRecord(item.uid);
   4264                                 mValidateUids.put(item.uid, validateUid);
   4265                             }
   4266                         }
   4267                         if (change == UidRecord.CHANGE_IDLE
   4268                                 || change == UidRecord.CHANGE_GONE_IDLE) {
   4269                             if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
   4270                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4271                                         "UID idle uid=" + item.uid);
   4272                                 observer.onUidIdle(item.uid);
   4273                             }
   4274                             if (VALIDATE_UID_STATES && i == 0) {
   4275                                 if (validateUid != null) {
   4276                                     validateUid.idle = true;
   4277                                 }
   4278                             }
   4279                         } else if (change == UidRecord.CHANGE_ACTIVE) {
   4280                             if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
   4281                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4282                                         "UID active uid=" + item.uid);
   4283                                 observer.onUidActive(item.uid);
   4284                             }
   4285                             if (VALIDATE_UID_STATES && i == 0) {
   4286                                 validateUid.idle = false;
   4287                             }
   4288                         }
   4289                         if (change == UidRecord.CHANGE_GONE
   4290                                 || change == UidRecord.CHANGE_GONE_IDLE) {
   4291                             if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
   4292                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4293                                         "UID gone uid=" + item.uid);
   4294                                 observer.onUidGone(item.uid);
   4295                             }
   4296                             if (VALIDATE_UID_STATES && i == 0) {
   4297                                 if (validateUid != null) {
   4298                                     mValidateUids.remove(item.uid);
   4299                                 }
   4300                             }
   4301                         } else {
   4302                             if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
   4303                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4304                                         "UID CHANGED uid=" + item.uid
   4305                                                 + ": " + item.processState);
   4306                                 observer.onUidStateChanged(item.uid, item.processState);
   4307                             }
   4308                             if (VALIDATE_UID_STATES && i == 0) {
   4309                                 validateUid.curProcState = validateUid.setProcState
   4310                                         = item.processState;
   4311                             }
   4312                         }
   4313                     }
   4314                 } catch (RemoteException e) {
   4315                 }
   4316             }
   4317         }
   4318         mUidObservers.finishBroadcast();
   4319 
   4320         synchronized (this) {
   4321             for (int j=0; j<N; j++) {
   4322                 mAvailUidChanges.add(mActiveUidChanges[j]);
   4323             }
   4324         }
   4325     }
   4326 
   4327     @Override
   4328     public final int startActivity(IApplicationThread caller, String callingPackage,
   4329             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   4330             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
   4331         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
   4332                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
   4333                 UserHandle.getCallingUserId());
   4334     }
   4335 
   4336     final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
   4337         enforceNotIsolatedCaller("ActivityContainer.startActivity");
   4338         final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
   4339                 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
   4340                 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
   4341 
   4342         // TODO: Switch to user app stacks here.
   4343         String mimeType = intent.getType();
   4344         final Uri data = intent.getData();
   4345         if (mimeType == null && data != null && "content".equals(data.getScheme())) {
   4346             mimeType = getProviderMimeType(data, userId);
   4347         }
   4348         container.checkEmbeddedAllowedInner(userId, intent, mimeType);
   4349 
   4350         intent.addFlags(FORCE_NEW_TASK_FLAGS);
   4351         return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
   4352                 null, 0, 0, null, null, null, null, false, userId, container, null);
   4353     }
   4354 
   4355     @Override
   4356     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
   4357             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   4358             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
   4359         enforceNotIsolatedCaller("startActivity");
   4360         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4361                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
   4362         // TODO: Switch to user app stacks here.
   4363         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
   4364                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
   4365                 profilerInfo, null, null, bOptions, false, userId, null, null);
   4366     }
   4367 
   4368     @Override
   4369     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
   4370             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   4371             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
   4372             int userId) {
   4373 
   4374         // This is very dangerous -- it allows you to perform a start activity (including
   4375         // permission grants) as any app that may launch one of your own activities.  So
   4376         // we will only allow this to be done from activities that are part of the core framework,
   4377         // and then only when they are running as the system.
   4378         final ActivityRecord sourceRecord;
   4379         final int targetUid;
   4380         final String targetPackage;
   4381         synchronized (this) {
   4382             if (resultTo == null) {
   4383                 throw new SecurityException("Must be called from an activity");
   4384             }
   4385             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
   4386             if (sourceRecord == null) {
   4387                 throw new SecurityException("Called with bad activity token: " + resultTo);
   4388             }
   4389             if (!sourceRecord.info.packageName.equals("android")) {
   4390                 throw new SecurityException(
   4391                         "Must be called from an activity that is declared in the android package");
   4392             }
   4393             if (sourceRecord.app == null) {
   4394                 throw new SecurityException("Called without a process attached to activity");
   4395             }
   4396             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
   4397                 // This is still okay, as long as this activity is running under the
   4398                 // uid of the original calling activity.
   4399                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
   4400                     throw new SecurityException(
   4401                             "Calling activity in uid " + sourceRecord.app.uid
   4402                                     + " must be system uid or original calling uid "
   4403                                     + sourceRecord.launchedFromUid);
   4404                 }
   4405             }
   4406             if (ignoreTargetSecurity) {
   4407                 if (intent.getComponent() == null) {
   4408                     throw new SecurityException(
   4409                             "Component must be specified with ignoreTargetSecurity");
   4410                 }
   4411                 if (intent.getSelector() != null) {
   4412                     throw new SecurityException(
   4413                             "Selector not allowed with ignoreTargetSecurity");
   4414                 }
   4415             }
   4416             targetUid = sourceRecord.launchedFromUid;
   4417             targetPackage = sourceRecord.launchedFromPackage;
   4418         }
   4419 
   4420         if (userId == UserHandle.USER_NULL) {
   4421             userId = UserHandle.getUserId(sourceRecord.app.uid);
   4422         }
   4423 
   4424         // TODO: Switch to user app stacks here.
   4425         try {
   4426             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
   4427                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
   4428                     null, null, bOptions, ignoreTargetSecurity, userId, null, null);
   4429             return ret;
   4430         } catch (SecurityException e) {
   4431             // XXX need to figure out how to propagate to original app.
   4432             // A SecurityException here is generally actually a fault of the original
   4433             // calling activity (such as a fairly granting permissions), so propagate it
   4434             // back to them.
   4435             /*
   4436             StringBuilder msg = new StringBuilder();
   4437             msg.append("While launching");
   4438             msg.append(intent.toString());
   4439             msg.append(": ");
   4440             msg.append(e.getMessage());
   4441             */
   4442             throw e;
   4443         }
   4444     }
   4445 
   4446     @Override
   4447     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
   4448             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   4449             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
   4450         enforceNotIsolatedCaller("startActivityAndWait");
   4451         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4452                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
   4453         WaitResult res = new WaitResult();
   4454         // TODO: Switch to user app stacks here.
   4455         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
   4456                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
   4457                 bOptions, false, userId, null, null);
   4458         return res;
   4459     }
   4460 
   4461     @Override
   4462     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
   4463             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   4464             int startFlags, Configuration config, Bundle bOptions, int userId) {
   4465         enforceNotIsolatedCaller("startActivityWithConfig");
   4466         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4467                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
   4468         // TODO: Switch to user app stacks here.
   4469         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
   4470                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
   4471                 null, null, config, bOptions, false, userId, null, null);
   4472         return ret;
   4473     }
   4474 
   4475     @Override
   4476     public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
   4477             Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
   4478             int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
   4479             throws TransactionTooLargeException {
   4480         enforceNotIsolatedCaller("startActivityIntentSender");
   4481         // Refuse possible leaked file descriptors
   4482         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
   4483             throw new IllegalArgumentException("File descriptors passed in Intent");
   4484         }
   4485 
   4486         IIntentSender sender = intent.getTarget();
   4487         if (!(sender instanceof PendingIntentRecord)) {
   4488             throw new IllegalArgumentException("Bad PendingIntent object");
   4489         }
   4490 
   4491         PendingIntentRecord pir = (PendingIntentRecord)sender;
   4492 
   4493         synchronized (this) {
   4494             // If this is coming from the currently resumed activity, it is
   4495             // effectively saying that app switches are allowed at this point.
   4496             final ActivityStack stack = getFocusedStack();
   4497             if (stack.mResumedActivity != null &&
   4498                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
   4499                 mAppSwitchesAllowedTime = 0;
   4500             }
   4501         }
   4502         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
   4503                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
   4504         return ret;
   4505     }
   4506 
   4507     @Override
   4508     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
   4509             Intent intent, String resolvedType, IVoiceInteractionSession session,
   4510             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
   4511             Bundle bOptions, int userId) {
   4512         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
   4513                 != PackageManager.PERMISSION_GRANTED) {
   4514             String msg = "Permission Denial: startVoiceActivity() from pid="
   4515                     + Binder.getCallingPid()
   4516                     + ", uid=" + Binder.getCallingUid()
   4517                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
   4518             Slog.w(TAG, msg);
   4519             throw new SecurityException(msg);
   4520         }
   4521         if (session == null || interactor == null) {
   4522             throw new NullPointerException("null session or interactor");
   4523         }
   4524         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
   4525                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
   4526         // TODO: Switch to user app stacks here.
   4527         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
   4528                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
   4529                 null, bOptions, false, userId, null, null);
   4530     }
   4531 
   4532     @Override
   4533     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
   4534             throws RemoteException {
   4535         Slog.i(TAG, "Activity tried to startVoiceInteraction");
   4536         synchronized (this) {
   4537             ActivityRecord activity = getFocusedStack().topActivity();
   4538             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
   4539                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
   4540             }
   4541             if (mRunningVoice != null || activity.task.voiceSession != null
   4542                     || activity.voiceSession != null) {
   4543                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
   4544                 return;
   4545             }
   4546             if (activity.pendingVoiceInteractionStart) {
   4547                 Slog.w(TAG, "Pending start of voice interaction already.");
   4548                 return;
   4549             }
   4550             activity.pendingVoiceInteractionStart = true;
   4551         }
   4552         LocalServices.getService(VoiceInteractionManagerInternal.class)
   4553                 .startLocalVoiceInteraction(callingActivity, options);
   4554     }
   4555 
   4556     @Override
   4557     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
   4558         LocalServices.getService(VoiceInteractionManagerInternal.class)
   4559                 .stopLocalVoiceInteraction(callingActivity);
   4560     }
   4561 
   4562     @Override
   4563     public boolean supportsLocalVoiceInteraction() throws RemoteException {
   4564         return LocalServices.getService(VoiceInteractionManagerInternal.class)
   4565                 .supportsLocalVoiceInteraction();
   4566     }
   4567 
   4568     void onLocalVoiceInteractionStartedLocked(IBinder activity,
   4569             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
   4570         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
   4571         if (activityToCallback == null) return;
   4572         activityToCallback.setVoiceSessionLocked(voiceSession);
   4573 
   4574         // Inform the activity
   4575         try {
   4576             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
   4577                     voiceInteractor);
   4578             long token = Binder.clearCallingIdentity();
   4579             try {
   4580                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
   4581             } finally {
   4582                 Binder.restoreCallingIdentity(token);
   4583             }
   4584             // TODO: VI Should we cache the activity so that it's easier to find later
   4585             // rather than scan through all the stacks and activities?
   4586         } catch (RemoteException re) {
   4587             activityToCallback.clearVoiceSessionLocked();
   4588             // TODO: VI Should this terminate the voice session?
   4589         }
   4590     }
   4591 
   4592     @Override
   4593     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
   4594         synchronized (this) {
   4595             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
   4596                 if (keepAwake) {
   4597                     mVoiceWakeLock.acquire();
   4598                 } else {
   4599                     mVoiceWakeLock.release();
   4600                 }
   4601             }
   4602         }
   4603     }
   4604 
   4605     @Override
   4606     public boolean startNextMatchingActivity(IBinder callingActivity,
   4607             Intent intent, Bundle bOptions) {
   4608         // Refuse possible leaked file descriptors
   4609         if (intent != null && intent.hasFileDescriptors() == true) {
   4610             throw new IllegalArgumentException("File descriptors passed in Intent");
   4611         }
   4612         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
   4613 
   4614         synchronized (this) {
   4615             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
   4616             if (r == null) {
   4617                 ActivityOptions.abort(options);
   4618                 return false;
   4619             }
   4620             if (r.app == null || r.app.thread == null) {
   4621                 // The caller is not running...  d'oh!
   4622                 ActivityOptions.abort(options);
   4623                 return false;
   4624             }
   4625             intent = new Intent(intent);
   4626             // The caller is not allowed to change the data.
   4627             intent.setDataAndType(r.intent.getData(), r.intent.getType());
   4628             // And we are resetting to find the next component...
   4629             intent.setComponent(null);
   4630 
   4631             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
   4632 
   4633             ActivityInfo aInfo = null;
   4634             try {
   4635                 List<ResolveInfo> resolves =
   4636                     AppGlobals.getPackageManager().queryIntentActivities(
   4637                             intent, r.resolvedType,
   4638                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
   4639                             UserHandle.getCallingUserId()).getList();
   4640 
   4641                 // Look for the original activity in the list...
   4642                 final int N = resolves != null ? resolves.size() : 0;
   4643                 for (int i=0; i<N; i++) {
   4644                     ResolveInfo rInfo = resolves.get(i);
   4645                     if (rInfo.activityInfo.packageName.equals(r.packageName)
   4646                             && rInfo.activityInfo.name.equals(r.info.name)) {
   4647                         // We found the current one...  the next matching is
   4648                         // after it.
   4649                         i++;
   4650                         if (i<N) {
   4651                             aInfo = resolves.get(i).activityInfo;
   4652                         }
   4653                         if (debug) {
   4654                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
   4655                                     + "/" + r.info.name);
   4656                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
   4657                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
   4658                         }
   4659                         break;
   4660                     }
   4661                 }
   4662             } catch (RemoteException e) {
   4663             }
   4664 
   4665             if (aInfo == null) {
   4666                 // Nobody who is next!
   4667                 ActivityOptions.abort(options);
   4668                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
   4669                 return false;
   4670             }
   4671 
   4672             intent.setComponent(new ComponentName(
   4673                     aInfo.applicationInfo.packageName, aInfo.name));
   4674             intent.setFlags(intent.getFlags()&~(
   4675                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
   4676                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
   4677                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
   4678                     Intent.FLAG_ACTIVITY_NEW_TASK));
   4679 
   4680             // Okay now we need to start the new activity, replacing the
   4681             // currently running activity.  This is a little tricky because
   4682             // we want to start the new one as if the current one is finished,
   4683             // but not finish the current one first so that there is no flicker.
   4684             // And thus...
   4685             final boolean wasFinishing = r.finishing;
   4686             r.finishing = true;
   4687 
   4688             // Propagate reply information over to the new activity.
   4689             final ActivityRecord resultTo = r.resultTo;
   4690             final String resultWho = r.resultWho;
   4691             final int requestCode = r.requestCode;
   4692             r.resultTo = null;
   4693             if (resultTo != null) {
   4694                 resultTo.removeResultsLocked(r, resultWho, requestCode);
   4695             }
   4696 
   4697             final long origId = Binder.clearCallingIdentity();
   4698             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
   4699                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
   4700                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
   4701                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
   4702                     false, false, null, null, null);
   4703             Binder.restoreCallingIdentity(origId);
   4704 
   4705             r.finishing = wasFinishing;
   4706             if (res != ActivityManager.START_SUCCESS) {
   4707                 return false;
   4708             }
   4709             return true;
   4710         }
   4711     }
   4712 
   4713     @Override
   4714     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
   4715         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
   4716             String msg = "Permission Denial: startActivityFromRecents called without " +
   4717                     START_TASKS_FROM_RECENTS;
   4718             Slog.w(TAG, msg);
   4719             throw new SecurityException(msg);
   4720         }
   4721         final long origId = Binder.clearCallingIdentity();
   4722         try {
   4723             synchronized (this) {
   4724                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
   4725             }
   4726         } finally {
   4727             Binder.restoreCallingIdentity(origId);
   4728         }
   4729     }
   4730 
   4731     final int startActivityInPackage(int uid, String callingPackage,
   4732             Intent intent, String resolvedType, IBinder resultTo,
   4733             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
   4734             IActivityContainer container, TaskRecord inTask) {
   4735 
   4736         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4737                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
   4738 
   4739         // TODO: Switch to user app stacks here.
   4740         int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
   4741                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
   4742                 null, null, null, bOptions, false, userId, container, inTask);
   4743         return ret;
   4744     }
   4745 
   4746     @Override
   4747     public final int startActivities(IApplicationThread caller, String callingPackage,
   4748             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
   4749             int userId) {
   4750         enforceNotIsolatedCaller("startActivities");
   4751         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4752                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
   4753         // TODO: Switch to user app stacks here.
   4754         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
   4755                 resolvedTypes, resultTo, bOptions, userId);
   4756         return ret;
   4757     }
   4758 
   4759     final int startActivitiesInPackage(int uid, String callingPackage,
   4760             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
   4761             Bundle bOptions, int userId) {
   4762 
   4763         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4764                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
   4765         // TODO: Switch to user app stacks here.
   4766         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
   4767                 resultTo, bOptions, userId);
   4768         return ret;
   4769     }
   4770 
   4771     @Override
   4772     public void reportActivityFullyDrawn(IBinder token) {
   4773         synchronized (this) {
   4774             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4775             if (r == null) {
   4776                 return;
   4777             }
   4778             r.reportFullyDrawnLocked();
   4779         }
   4780     }
   4781 
   4782     @Override
   4783     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
   4784         synchronized (this) {
   4785             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4786             if (r == null) {
   4787                 return;
   4788             }
   4789             TaskRecord task = r.task;
   4790             if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
   4791                 // Fixed screen orientation isn't supported when activities aren't in full screen
   4792                 // mode.
   4793                 return;
   4794             }
   4795             final long origId = Binder.clearCallingIdentity();
   4796             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
   4797             Configuration config = mWindowManager.updateOrientationFromAppTokens(
   4798                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
   4799             if (config != null) {
   4800                 r.frozenBeforeDestroy = true;
   4801                 if (!updateConfigurationLocked(config, r, false)) {
   4802                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
   4803                 }
   4804             }
   4805             Binder.restoreCallingIdentity(origId);
   4806         }
   4807     }
   4808 
   4809     @Override
   4810     public int getRequestedOrientation(IBinder token) {
   4811         synchronized (this) {
   4812             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4813             if (r == null) {
   4814                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
   4815             }
   4816             return mWindowManager.getAppOrientation(r.appToken);
   4817         }
   4818     }
   4819 
   4820     /**
   4821      * This is the internal entry point for handling Activity.finish().
   4822      *
   4823      * @param token The Binder token referencing the Activity we want to finish.
   4824      * @param resultCode Result code, if any, from this Activity.
   4825      * @param resultData Result data (Intent), if any, from this Activity.
   4826      * @param finishTask Whether to finish the task associated with this Activity.
   4827      *
   4828      * @return Returns true if the activity successfully finished, or false if it is still running.
   4829      */
   4830     @Override
   4831     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
   4832             int finishTask) {
   4833         // Refuse possible leaked file descriptors
   4834         if (resultData != null && resultData.hasFileDescriptors() == true) {
   4835             throw new IllegalArgumentException("File descriptors passed in Intent");
   4836         }
   4837 
   4838         synchronized(this) {
   4839             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4840             if (r == null) {
   4841                 return true;
   4842             }
   4843             // Keep track of the root activity of the task before we finish it
   4844             TaskRecord tr = r.task;
   4845             ActivityRecord rootR = tr.getRootActivity();
   4846             if (rootR == null) {
   4847                 Slog.w(TAG, "Finishing task with all activities already finished");
   4848             }
   4849             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
   4850             // finish.
   4851             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
   4852                     mStackSupervisor.isLastLockedTask(tr)) {
   4853                 Slog.i(TAG, "Not finishing task in lock task mode");
   4854                 mStackSupervisor.showLockTaskToast();
   4855                 return false;
   4856             }
   4857             if (mController != null) {
   4858                 // Find the first activity that is not finishing.
   4859                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
   4860                 if (next != null) {
   4861                     // ask watcher if this is allowed
   4862                     boolean resumeOK = true;
   4863                     try {
   4864                         resumeOK = mController.activityResuming(next.packageName);
   4865                     } catch (RemoteException e) {
   4866                         mController = null;
   4867                         Watchdog.getInstance().setActivityController(null);
   4868                     }
   4869 
   4870                     if (!resumeOK) {
   4871                         Slog.i(TAG, "Not finishing activity because controller resumed");
   4872                         return false;
   4873                     }
   4874                 }
   4875             }
   4876             final long origId = Binder.clearCallingIdentity();
   4877             try {
   4878                 boolean res;
   4879                 final boolean finishWithRootActivity =
   4880                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
   4881                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
   4882                         || (finishWithRootActivity && r == rootR)) {
   4883                     // If requested, remove the task that is associated to this activity only if it
   4884                     // was the root activity in the task. The result code and data is ignored
   4885                     // because we don't support returning them across task boundaries. Also, to
   4886                     // keep backwards compatibility we remove the task from recents when finishing
   4887                     // task with root activity.
   4888                     res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
   4889                     if (!res) {
   4890                         Slog.i(TAG, "Removing task failed to finish activity");
   4891                     }
   4892                 } else {
   4893                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
   4894                             resultData, "app-request", true);
   4895                     if (!res) {
   4896                         Slog.i(TAG, "Failed to finish by app-request");
   4897                     }
   4898                 }
   4899                 return res;
   4900             } finally {
   4901                 Binder.restoreCallingIdentity(origId);
   4902             }
   4903         }
   4904     }
   4905 
   4906     @Override
   4907     public final void finishHeavyWeightApp() {
   4908         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   4909                 != PackageManager.PERMISSION_GRANTED) {
   4910             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
   4911                     + Binder.getCallingPid()
   4912                     + ", uid=" + Binder.getCallingUid()
   4913                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   4914             Slog.w(TAG, msg);
   4915             throw new SecurityException(msg);
   4916         }
   4917 
   4918         synchronized(this) {
   4919             if (mHeavyWeightProcess == null) {
   4920                 return;
   4921             }
   4922 
   4923             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
   4924             for (int i = 0; i < activities.size(); i++) {
   4925                 ActivityRecord r = activities.get(i);
   4926                 if (!r.finishing && r.isInStackLocked()) {
   4927                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
   4928                             null, "finish-heavy", true);
   4929                 }
   4930             }
   4931 
   4932             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   4933                     mHeavyWeightProcess.userId, 0));
   4934             mHeavyWeightProcess = null;
   4935         }
   4936     }
   4937 
   4938     @Override
   4939     public void crashApplication(int uid, int initialPid, String packageName,
   4940             String message) {
   4941         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   4942                 != PackageManager.PERMISSION_GRANTED) {
   4943             String msg = "Permission Denial: crashApplication() from pid="
   4944                     + Binder.getCallingPid()
   4945                     + ", uid=" + Binder.getCallingUid()
   4946                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   4947             Slog.w(TAG, msg);
   4948             throw new SecurityException(msg);
   4949         }
   4950 
   4951         synchronized(this) {
   4952             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
   4953         }
   4954     }
   4955 
   4956     @Override
   4957     public final void finishSubActivity(IBinder token, String resultWho,
   4958             int requestCode) {
   4959         synchronized(this) {
   4960             final long origId = Binder.clearCallingIdentity();
   4961             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4962             if (r != null) {
   4963                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
   4964             }
   4965             Binder.restoreCallingIdentity(origId);
   4966         }
   4967     }
   4968 
   4969     @Override
   4970     public boolean finishActivityAffinity(IBinder token) {
   4971         synchronized(this) {
   4972             final long origId = Binder.clearCallingIdentity();
   4973             try {
   4974                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4975                 if (r == null) {
   4976                     return false;
   4977                 }
   4978 
   4979                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
   4980                 // can finish.
   4981                 final TaskRecord task = r.task;
   4982                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
   4983                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
   4984                     mStackSupervisor.showLockTaskToast();
   4985                     return false;
   4986                 }
   4987                 return task.stack.finishActivityAffinityLocked(r);
   4988             } finally {
   4989                 Binder.restoreCallingIdentity(origId);
   4990             }
   4991         }
   4992     }
   4993 
   4994     @Override
   4995     public void finishVoiceTask(IVoiceInteractionSession session) {
   4996         synchronized (this) {
   4997             final long origId = Binder.clearCallingIdentity();
   4998             try {
   4999                 // TODO: VI Consider treating local voice interactions and voice tasks
   5000                 // differently here
   5001                 mStackSupervisor.finishVoiceTask(session);
   5002             } finally {
   5003                 Binder.restoreCallingIdentity(origId);
   5004             }
   5005         }
   5006 
   5007     }
   5008 
   5009     @Override
   5010     public boolean releaseActivityInstance(IBinder token) {
   5011         synchronized(this) {
   5012             final long origId = Binder.clearCallingIdentity();
   5013             try {
   5014                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
   5015                 if (r == null) {
   5016                     return false;
   5017                 }
   5018                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
   5019             } finally {
   5020                 Binder.restoreCallingIdentity(origId);
   5021             }
   5022         }
   5023     }
   5024 
   5025     @Override
   5026     public void releaseSomeActivities(IApplicationThread appInt) {
   5027         synchronized(this) {
   5028             final long origId = Binder.clearCallingIdentity();
   5029             try {
   5030                 ProcessRecord app = getRecordForAppLocked(appInt);
   5031                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
   5032             } finally {
   5033                 Binder.restoreCallingIdentity(origId);
   5034             }
   5035         }
   5036     }
   5037 
   5038     @Override
   5039     public boolean willActivityBeVisible(IBinder token) {
   5040         synchronized(this) {
   5041             ActivityStack stack = ActivityRecord.getStackLocked(token);
   5042             if (stack != null) {
   5043                 return stack.willActivityBeVisibleLocked(token);
   5044             }
   5045             return false;
   5046         }
   5047     }
   5048 
   5049     @Override
   5050     public void overridePendingTransition(IBinder token, String packageName,
   5051             int enterAnim, int exitAnim) {
   5052         synchronized(this) {
   5053             ActivityRecord self = ActivityRecord.isInStackLocked(token);
   5054             if (self == null) {
   5055                 return;
   5056             }
   5057 
   5058             final long origId = Binder.clearCallingIdentity();
   5059 
   5060             if (self.state == ActivityState.RESUMED
   5061                     || self.state == ActivityState.PAUSING) {
   5062                 mWindowManager.overridePendingAppTransition(packageName,
   5063                         enterAnim, exitAnim, null);
   5064             }
   5065 
   5066             Binder.restoreCallingIdentity(origId);
   5067         }
   5068     }
   5069 
   5070     /**
   5071      * Main function for removing an existing process from the activity manager
   5072      * as a result of that process going away.  Clears out all connections
   5073      * to the process.
   5074      */
   5075     private final void handleAppDiedLocked(ProcessRecord app,
   5076             boolean restarting, boolean allowRestart) {
   5077         int pid = app.pid;
   5078         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
   5079                 false /*replacingPid*/);
   5080         if (!kept && !restarting) {
   5081             removeLruProcessLocked(app);
   5082             if (pid > 0) {
   5083                 ProcessList.remove(pid);
   5084             }
   5085         }
   5086 
   5087         if (mProfileProc == app) {
   5088             clearProfilerLocked();
   5089         }
   5090 
   5091         // Remove this application's activities from active lists.
   5092         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
   5093 
   5094         app.activities.clear();
   5095 
   5096         if (app.instrumentationClass != null) {
   5097             Slog.w(TAG, "Crash of app " + app.processName
   5098                   + " running instrumentation " + app.instrumentationClass);
   5099             Bundle info = new Bundle();
   5100             info.putString("shortMsg", "Process crashed.");
   5101             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
   5102         }
   5103 
   5104         if (!restarting && hasVisibleActivities
   5105                 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
   5106             // If there was nothing to resume, and we are not already restarting this process, but
   5107             // there is a visible activity that is hosted by the process...  then make sure all
   5108             // visible activities are running, taking care of restarting this process.
   5109             mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   5110         }
   5111     }
   5112 
   5113     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
   5114         IBinder threadBinder = thread.asBinder();
   5115         // Find the application record.
   5116         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   5117             ProcessRecord rec = mLruProcesses.get(i);
   5118             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
   5119                 return i;
   5120             }
   5121         }
   5122         return -1;
   5123     }
   5124 
   5125     final ProcessRecord getRecordForAppLocked(
   5126             IApplicationThread thread) {
   5127         if (thread == null) {
   5128             return null;
   5129         }
   5130 
   5131         int appIndex = getLRURecordIndexForAppLocked(thread);
   5132         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
   5133     }
   5134 
   5135     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
   5136         // If there are no longer any background processes running,
   5137         // and the app that died was not running instrumentation,
   5138         // then tell everyone we are now low on memory.
   5139         boolean haveBg = false;
   5140         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   5141             ProcessRecord rec = mLruProcesses.get(i);
   5142             if (rec.thread != null
   5143                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   5144                 haveBg = true;
   5145                 break;
   5146             }
   5147         }
   5148 
   5149         if (!haveBg) {
   5150             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   5151             if (doReport) {
   5152                 long now = SystemClock.uptimeMillis();
   5153                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
   5154                     doReport = false;
   5155                 } else {
   5156                     mLastMemUsageReportTime = now;
   5157                 }
   5158             }
   5159             final ArrayList<ProcessMemInfo> memInfos
   5160                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
   5161             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
   5162             long now = SystemClock.uptimeMillis();
   5163             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   5164                 ProcessRecord rec = mLruProcesses.get(i);
   5165                 if (rec == dyingProc || rec.thread == null) {
   5166                     continue;
   5167                 }
   5168                 if (doReport) {
   5169                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
   5170                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
   5171                 }
   5172                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
   5173                     // The low memory report is overriding any current
   5174                     // state for a GC request.  Make sure to do
   5175                     // heavy/important/visible/foreground processes first.
   5176                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   5177                         rec.lastRequestedGc = 0;
   5178                     } else {
   5179                         rec.lastRequestedGc = rec.lastLowMemory;
   5180                     }
   5181                     rec.reportLowMemory = true;
   5182                     rec.lastLowMemory = now;
   5183                     mProcessesToGc.remove(rec);
   5184                     addProcessToGcListLocked(rec);
   5185                 }
   5186             }
   5187             if (doReport) {
   5188                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
   5189                 mHandler.sendMessage(msg);
   5190             }
   5191             scheduleAppGcsLocked();
   5192         }
   5193     }
   5194 
   5195     final void appDiedLocked(ProcessRecord app) {
   5196        appDiedLocked(app, app.pid, app.thread, false);
   5197     }
   5198 
   5199     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
   5200             boolean fromBinderDied) {
   5201         // First check if this ProcessRecord is actually active for the pid.
   5202         synchronized (mPidsSelfLocked) {
   5203             ProcessRecord curProc = mPidsSelfLocked.get(pid);
   5204             if (curProc != app) {
   5205                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
   5206                 return;
   5207             }
   5208         }
   5209 
   5210         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   5211         synchronized (stats) {
   5212             stats.noteProcessDiedLocked(app.info.uid, pid);
   5213         }
   5214 
   5215         if (!app.killed) {
   5216             if (!fromBinderDied) {
   5217                 Process.killProcessQuiet(pid);
   5218             }
   5219             killProcessGroup(app.uid, pid);
   5220             app.killed = true;
   5221         }
   5222 
   5223         // Clean up already done if the process has been re-started.
   5224         if (app.pid == pid && app.thread != null &&
   5225                 app.thread.asBinder() == thread.asBinder()) {
   5226             boolean doLowMem = app.instrumentationClass == null;
   5227             boolean doOomAdj = doLowMem;
   5228             if (!app.killedByAm) {
   5229                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   5230                         + ") has died");
   5231                 mAllowLowerMemLevel = true;
   5232             } else {
   5233                 // Note that we always want to do oom adj to update our state with the
   5234                 // new number of procs.
   5235                 mAllowLowerMemLevel = false;
   5236                 doLowMem = false;
   5237             }
   5238             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   5239             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
   5240                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
   5241             handleAppDiedLocked(app, false, true);
   5242 
   5243             if (doOomAdj) {
   5244                 updateOomAdjLocked();
   5245             }
   5246             if (doLowMem) {
   5247                 doLowMemReportIfNeededLocked(app);
   5248             }
   5249         } else if (app.pid != pid) {
   5250             // A new process has already been started.
   5251             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   5252                     + ") has died and restarted (pid " + app.pid + ").");
   5253             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   5254         } else if (DEBUG_PROCESSES) {
   5255             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
   5256                     + thread.asBinder());
   5257         }
   5258     }
   5259 
   5260     /**
   5261      * If a stack trace dump file is configured, dump process stack traces.
   5262      * @param clearTraces causes the dump file to be erased prior to the new
   5263      *    traces being written, if true; when false, the new traces will be
   5264      *    appended to any existing file content.
   5265      * @param firstPids of dalvik VM processes to dump stack traces for first
   5266      * @param lastPids of dalvik VM processes to dump stack traces for last
   5267      * @param nativeProcs optional list of native process names to dump stack crawls
   5268      * @return file containing stack traces, or null if no dump file is configured
   5269      */
   5270     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
   5271             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   5272         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   5273         if (tracesPath == null || tracesPath.length() == 0) {
   5274             return null;
   5275         }
   5276 
   5277         File tracesFile = new File(tracesPath);
   5278         try {
   5279             if (clearTraces && tracesFile.exists()) tracesFile.delete();
   5280             tracesFile.createNewFile();
   5281             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   5282         } catch (IOException e) {
   5283             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
   5284             return null;
   5285         }
   5286 
   5287         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
   5288         return tracesFile;
   5289     }
   5290 
   5291     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
   5292             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   5293         // Use a FileObserver to detect when traces finish writing.
   5294         // The order of traces is considered important to maintain for legibility.
   5295         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
   5296             @Override
   5297             public synchronized void onEvent(int event, String path) { notify(); }
   5298         };
   5299 
   5300         try {
   5301             observer.startWatching();
   5302 
   5303             // First collect all of the stacks of the most important pids.
   5304             if (firstPids != null) {
   5305                 try {
   5306                     int num = firstPids.size();
   5307                     for (int i = 0; i < num; i++) {
   5308                         synchronized (observer) {
   5309                             if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
   5310                                     + firstPids.get(i));
   5311                             final long sime = SystemClock.elapsedRealtime();
   5312                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
   5313                             observer.wait(1000);  // Wait for write-close, give up after 1 sec
   5314                             if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
   5315                                     + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
   5316                         }
   5317                     }
   5318                 } catch (InterruptedException e) {
   5319                     Slog.wtf(TAG, e);
   5320                 }
   5321             }
   5322 
   5323             // Next collect the stacks of the native pids
   5324             if (nativeProcs != null) {
   5325                 int[] pids = Process.getPidsForCommands(nativeProcs);
   5326                 if (pids != null) {
   5327                     for (int pid : pids) {
   5328                         if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
   5329                         final long sime = SystemClock.elapsedRealtime();
   5330                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
   5331                         if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
   5332                                 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
   5333                     }
   5334                 }
   5335             }
   5336 
   5337             // Lastly, measure CPU usage.
   5338             if (processCpuTracker != null) {
   5339                 processCpuTracker.init();
   5340                 System.gc();
   5341                 processCpuTracker.update();
   5342                 try {
   5343                     synchronized (processCpuTracker) {
   5344                         processCpuTracker.wait(500); // measure over 1/2 second.
   5345                     }
   5346                 } catch (InterruptedException e) {
   5347                 }
   5348                 processCpuTracker.update();
   5349 
   5350                 // We'll take the stack crawls of just the top apps using CPU.
   5351                 final int N = processCpuTracker.countWorkingStats();
   5352                 int numProcs = 0;
   5353                 for (int i=0; i<N && numProcs<5; i++) {
   5354                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
   5355                     if (lastPids.indexOfKey(stats.pid) >= 0) {
   5356                         numProcs++;
   5357                         try {
   5358                             synchronized (observer) {
   5359                                 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
   5360                                         + stats.pid);
   5361                                 final long stime = SystemClock.elapsedRealtime();
   5362                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
   5363                                 observer.wait(1000);  // Wait for write-close, give up after 1 sec
   5364                                 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
   5365                                         + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
   5366                             }
   5367                         } catch (InterruptedException e) {
   5368                             Slog.wtf(TAG, e);
   5369                         }
   5370                     } else if (DEBUG_ANR) {
   5371                         Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
   5372                                 + stats.pid);
   5373                     }
   5374                 }
   5375             }
   5376         } finally {
   5377             observer.stopWatching();
   5378         }
   5379     }
   5380 
   5381     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
   5382         if (true || IS_USER_BUILD) {
   5383             return;
   5384         }
   5385         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   5386         if (tracesPath == null || tracesPath.length() == 0) {
   5387             return;
   5388         }
   5389 
   5390         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
   5391         StrictMode.allowThreadDiskWrites();
   5392         try {
   5393             final File tracesFile = new File(tracesPath);
   5394             final File tracesDir = tracesFile.getParentFile();
   5395             final File tracesTmp = new File(tracesDir, "__tmp__");
   5396             try {
   5397                 if (tracesFile.exists()) {
   5398                     tracesTmp.delete();
   5399                     tracesFile.renameTo(tracesTmp);
   5400                 }
   5401                 StringBuilder sb = new StringBuilder();
   5402                 Time tobj = new Time();
   5403                 tobj.set(System.currentTimeMillis());
   5404                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
   5405                 sb.append(": ");
   5406                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
   5407                 sb.append(" since ");
   5408                 sb.append(msg);
   5409                 FileOutputStream fos = new FileOutputStream(tracesFile);
   5410                 fos.write(sb.toString().getBytes());
   5411                 if (app == null) {
   5412                     fos.write("\n*** No application process!".getBytes());
   5413                 }
   5414                 fos.close();
   5415                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   5416             } catch (IOException e) {
   5417                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
   5418                 return;
   5419             }
   5420 
   5421             if (app != null) {
   5422                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
   5423                 firstPids.add(app.pid);
   5424                 dumpStackTraces(tracesPath, firstPids, null, null, null);
   5425             }
   5426 
   5427             File lastTracesFile = null;
   5428             File curTracesFile = null;
   5429             for (int i=9; i>=0; i--) {
   5430                 String name = String.format(Locale.US, "slow%02d.txt", i);
   5431                 curTracesFile = new File(tracesDir, name);
   5432                 if (curTracesFile.exists()) {
   5433                     if (lastTracesFile != null) {
   5434                         curTracesFile.renameTo(lastTracesFile);
   5435                     } else {
   5436                         curTracesFile.delete();
   5437                     }
   5438                 }
   5439                 lastTracesFile = curTracesFile;
   5440             }
   5441             tracesFile.renameTo(curTracesFile);
   5442             if (tracesTmp.exists()) {
   5443                 tracesTmp.renameTo(tracesFile);
   5444             }
   5445         } finally {
   5446             StrictMode.setThreadPolicy(oldPolicy);
   5447         }
   5448     }
   5449 
   5450     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
   5451         if (!mLaunchWarningShown) {
   5452             mLaunchWarningShown = true;
   5453             mUiHandler.post(new Runnable() {
   5454                 @Override
   5455                 public void run() {
   5456                     synchronized (ActivityManagerService.this) {
   5457                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
   5458                         d.show();
   5459                         mUiHandler.postDelayed(new Runnable() {
   5460                             @Override
   5461                             public void run() {
   5462                                 synchronized (ActivityManagerService.this) {
   5463                                     d.dismiss();
   5464                                     mLaunchWarningShown = false;
   5465                                 }
   5466                             }
   5467                         }, 4000);
   5468                     }
   5469                 }
   5470             });
   5471         }
   5472     }
   5473 
   5474     @Override
   5475     public boolean clearApplicationUserData(final String packageName,
   5476             final IPackageDataObserver observer, int userId) {
   5477         enforceNotIsolatedCaller("clearApplicationUserData");
   5478         int uid = Binder.getCallingUid();
   5479         int pid = Binder.getCallingPid();
   5480         userId = mUserController.handleIncomingUser(pid, uid, userId, false,
   5481                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
   5482 
   5483 
   5484         long callingId = Binder.clearCallingIdentity();
   5485         try {
   5486             IPackageManager pm = AppGlobals.getPackageManager();
   5487             int pkgUid = -1;
   5488             synchronized(this) {
   5489                 if (getPackageManagerInternalLocked().isPackageDataProtected(
   5490                         userId, packageName)) {
   5491                     throw new SecurityException(
   5492                             "Cannot clear data for a protected package: " + packageName);
   5493                 }
   5494 
   5495                 try {
   5496                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
   5497                 } catch (RemoteException e) {
   5498                 }
   5499                 if (pkgUid == -1) {
   5500                     Slog.w(TAG, "Invalid packageName: " + packageName);
   5501                     if (observer != null) {
   5502                         try {
   5503                             observer.onRemoveCompleted(packageName, false);
   5504                         } catch (RemoteException e) {
   5505                             Slog.i(TAG, "Observer no longer exists.");
   5506                         }
   5507                     }
   5508                     return false;
   5509                 }
   5510                 if (uid == pkgUid || checkComponentPermission(
   5511                         android.Manifest.permission.CLEAR_APP_USER_DATA,
   5512                         pid, uid, -1, true)
   5513                         == PackageManager.PERMISSION_GRANTED) {
   5514                     forceStopPackageLocked(packageName, pkgUid, "clear data");
   5515                 } else {
   5516                     throw new SecurityException("PID " + pid + " does not have permission "
   5517                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
   5518                                     + " of package " + packageName);
   5519                 }
   5520 
   5521                 // Remove all tasks match the cleared application package and user
   5522                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
   5523                     final TaskRecord tr = mRecentTasks.get(i);
   5524                     final String taskPackageName =
   5525                             tr.getBaseIntent().getComponent().getPackageName();
   5526                     if (tr.userId != userId) continue;
   5527                     if (!taskPackageName.equals(packageName)) continue;
   5528                     removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
   5529                 }
   5530             }
   5531 
   5532             final int pkgUidF = pkgUid;
   5533             final int userIdF = userId;
   5534             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
   5535                 @Override
   5536                 public void onRemoveCompleted(String packageName, boolean succeeded)
   5537                         throws RemoteException {
   5538                     synchronized (ActivityManagerService.this) {
   5539                         finishForceStopPackageLocked(packageName, pkgUidF);
   5540                     }
   5541 
   5542                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
   5543                             Uri.fromParts("package", packageName, null));
   5544                     intent.putExtra(Intent.EXTRA_UID, pkgUidF);
   5545                     intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
   5546                     broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
   5547                             null, null, 0, null, null, null, null, false, false, userIdF);
   5548 
   5549                     if (observer != null) {
   5550                         observer.onRemoveCompleted(packageName, succeeded);
   5551                     }
   5552                 }
   5553             };
   5554 
   5555             try {
   5556                 // Clear application user data
   5557                 pm.clearApplicationUserData(packageName, localObserver, userId);
   5558 
   5559                 synchronized(this) {
   5560                     // Remove all permissions granted from/to this package
   5561                     removeUriPermissionsForPackageLocked(packageName, userId, true);
   5562                 }
   5563 
   5564                 // Remove all zen rules created by this package; revoke it's zen access.
   5565                 INotificationManager inm = NotificationManager.getService();
   5566                 inm.removeAutomaticZenRules(packageName);
   5567                 inm.setNotificationPolicyAccessGranted(packageName, false);
   5568 
   5569             } catch (RemoteException e) {
   5570             }
   5571         } finally {
   5572             Binder.restoreCallingIdentity(callingId);
   5573         }
   5574         return true;
   5575     }
   5576 
   5577     @Override
   5578     public void killBackgroundProcesses(final String packageName, int userId) {
   5579         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   5580                 != PackageManager.PERMISSION_GRANTED &&
   5581                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
   5582                         != PackageManager.PERMISSION_GRANTED) {
   5583             String msg = "Permission Denial: killBackgroundProcesses() from pid="
   5584                     + Binder.getCallingPid()
   5585                     + ", uid=" + Binder.getCallingUid()
   5586                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   5587             Slog.w(TAG, msg);
   5588             throw new SecurityException(msg);
   5589         }
   5590 
   5591         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   5592                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
   5593         long callingId = Binder.clearCallingIdentity();
   5594         try {
   5595             IPackageManager pm = AppGlobals.getPackageManager();
   5596             synchronized(this) {
   5597                 int appId = -1;
   5598                 try {
   5599                     appId = UserHandle.getAppId(
   5600                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
   5601                 } catch (RemoteException e) {
   5602                 }
   5603                 if (appId == -1) {
   5604                     Slog.w(TAG, "Invalid packageName: " + packageName);
   5605                     return;
   5606                 }
   5607                 killPackageProcessesLocked(packageName, appId, userId,
   5608                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
   5609             }
   5610         } finally {
   5611             Binder.restoreCallingIdentity(callingId);
   5612         }
   5613     }
   5614 
   5615     @Override
   5616     public void killAllBackgroundProcesses() {
   5617         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   5618                 != PackageManager.PERMISSION_GRANTED) {
   5619             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
   5620                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   5621                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   5622             Slog.w(TAG, msg);
   5623             throw new SecurityException(msg);
   5624         }
   5625 
   5626         final long callingId = Binder.clearCallingIdentity();
   5627         try {
   5628             synchronized (this) {
   5629                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
   5630                 final int NP = mProcessNames.getMap().size();
   5631                 for (int ip = 0; ip < NP; ip++) {
   5632                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   5633                     final int NA = apps.size();
   5634                     for (int ia = 0; ia < NA; ia++) {
   5635                         final ProcessRecord app = apps.valueAt(ia);
   5636                         if (app.persistent) {
   5637                             // We don't kill persistent processes.
   5638                             continue;
   5639                         }
   5640                         if (app.removed) {
   5641                             procs.add(app);
   5642                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   5643                             app.removed = true;
   5644                             procs.add(app);
   5645                         }
   5646                     }
   5647                 }
   5648 
   5649                 final int N = procs.size();
   5650                 for (int i = 0; i < N; i++) {
   5651                     removeProcessLocked(procs.get(i), false, true, "kill all background");
   5652                 }
   5653 
   5654                 mAllowLowerMemLevel = true;
   5655 
   5656                 updateOomAdjLocked();
   5657                 doLowMemReportIfNeededLocked(null);
   5658             }
   5659         } finally {
   5660             Binder.restoreCallingIdentity(callingId);
   5661         }
   5662     }
   5663 
   5664     /**
   5665      * Kills all background processes, except those matching any of the
   5666      * specified properties.
   5667      *
   5668      * @param minTargetSdk the target SDK version at or above which to preserve
   5669      *                     processes, or {@code -1} to ignore the target SDK
   5670      * @param maxProcState the process state at or below which to preserve
   5671      *                     processes, or {@code -1} to ignore the process state
   5672      */
   5673     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
   5674         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   5675                 != PackageManager.PERMISSION_GRANTED) {
   5676             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
   5677                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   5678                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   5679             Slog.w(TAG, msg);
   5680             throw new SecurityException(msg);
   5681         }
   5682 
   5683         final long callingId = Binder.clearCallingIdentity();
   5684         try {
   5685             synchronized (this) {
   5686                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
   5687                 final int NP = mProcessNames.getMap().size();
   5688                 for (int ip = 0; ip < NP; ip++) {
   5689                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   5690                     final int NA = apps.size();
   5691                     for (int ia = 0; ia < NA; ia++) {
   5692                         final ProcessRecord app = apps.valueAt(ia);
   5693                         if (app.removed) {
   5694                             procs.add(app);
   5695                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
   5696                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
   5697                             app.removed = true;
   5698                             procs.add(app);
   5699                         }
   5700                     }
   5701                 }
   5702 
   5703                 final int N = procs.size();
   5704                 for (int i = 0; i < N; i++) {
   5705                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
   5706                 }
   5707             }
   5708         } finally {
   5709             Binder.restoreCallingIdentity(callingId);
   5710         }
   5711     }
   5712 
   5713     @Override
   5714     public void forceStopPackage(final String packageName, int userId) {
   5715         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   5716                 != PackageManager.PERMISSION_GRANTED) {
   5717             String msg = "Permission Denial: forceStopPackage() from pid="
   5718                     + Binder.getCallingPid()
   5719                     + ", uid=" + Binder.getCallingUid()
   5720                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   5721             Slog.w(TAG, msg);
   5722             throw new SecurityException(msg);
   5723         }
   5724         final int callingPid = Binder.getCallingPid();
   5725         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
   5726                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
   5727         long callingId = Binder.clearCallingIdentity();
   5728         try {
   5729             IPackageManager pm = AppGlobals.getPackageManager();
   5730             synchronized(this) {
   5731                 int[] users = userId == UserHandle.USER_ALL
   5732                         ? mUserController.getUsers() : new int[] { userId };
   5733                 for (int user : users) {
   5734                     int pkgUid = -1;
   5735                     try {
   5736                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
   5737                                 user);
   5738                     } catch (RemoteException e) {
   5739                     }
   5740                     if (pkgUid == -1) {
   5741                         Slog.w(TAG, "Invalid packageName: " + packageName);
   5742                         continue;
   5743                     }
   5744                     try {
   5745                         pm.setPackageStoppedState(packageName, true, user);
   5746                     } catch (RemoteException e) {
   5747                     } catch (IllegalArgumentException e) {
   5748                         Slog.w(TAG, "Failed trying to unstop package "
   5749                                 + packageName + ": " + e);
   5750                     }
   5751                     if (mUserController.isUserRunningLocked(user, 0)) {
   5752                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
   5753                         finishForceStopPackageLocked(packageName, pkgUid);
   5754                     }
   5755                 }
   5756             }
   5757         } finally {
   5758             Binder.restoreCallingIdentity(callingId);
   5759         }
   5760     }
   5761 
   5762     @Override
   5763     public void addPackageDependency(String packageName) {
   5764         synchronized (this) {
   5765             int callingPid = Binder.getCallingPid();
   5766             if (callingPid == Process.myPid()) {
   5767                 //  Yeah, um, no.
   5768                 return;
   5769             }
   5770             ProcessRecord proc;
   5771             synchronized (mPidsSelfLocked) {
   5772                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   5773             }
   5774             if (proc != null) {
   5775                 if (proc.pkgDeps == null) {
   5776                     proc.pkgDeps = new ArraySet<String>(1);
   5777                 }
   5778                 proc.pkgDeps.add(packageName);
   5779             }
   5780         }
   5781     }
   5782 
   5783     /*
   5784      * The pkg name and app id have to be specified.
   5785      */
   5786     @Override
   5787     public void killApplication(String pkg, int appId, int userId, String reason) {
   5788         if (pkg == null) {
   5789             return;
   5790         }
   5791         // Make sure the uid is valid.
   5792         if (appId < 0) {
   5793             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
   5794             return;
   5795         }
   5796         int callerUid = Binder.getCallingUid();
   5797         // Only the system server can kill an application
   5798         if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
   5799             // Post an aysnc message to kill the application
   5800             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
   5801             msg.arg1 = appId;
   5802             msg.arg2 = userId;
   5803             Bundle bundle = new Bundle();
   5804             bundle.putString("pkg", pkg);
   5805             bundle.putString("reason", reason);
   5806             msg.obj = bundle;
   5807             mHandler.sendMessage(msg);
   5808         } else {
   5809             throw new SecurityException(callerUid + " cannot kill pkg: " +
   5810                     pkg);
   5811         }
   5812     }
   5813 
   5814     @Override
   5815     public void closeSystemDialogs(String reason) {
   5816         enforceNotIsolatedCaller("closeSystemDialogs");
   5817 
   5818         final int pid = Binder.getCallingPid();
   5819         final int uid = Binder.getCallingUid();
   5820         final long origId = Binder.clearCallingIdentity();
   5821         try {
   5822             synchronized (this) {
   5823                 // Only allow this from foreground processes, so that background
   5824                 // applications can't abuse it to prevent system UI from being shown.
   5825                 if (uid >= Process.FIRST_APPLICATION_UID) {
   5826                     ProcessRecord proc;
   5827                     synchronized (mPidsSelfLocked) {
   5828                         proc = mPidsSelfLocked.get(pid);
   5829                     }
   5830                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   5831                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
   5832                                 + " from background process " + proc);
   5833                         return;
   5834                     }
   5835                 }
   5836                 closeSystemDialogsLocked(reason);
   5837             }
   5838         } finally {
   5839             Binder.restoreCallingIdentity(origId);
   5840         }
   5841     }
   5842 
   5843     void closeSystemDialogsLocked(String reason) {
   5844         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
   5845         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   5846                 | Intent.FLAG_RECEIVER_FOREGROUND);
   5847         if (reason != null) {
   5848             intent.putExtra("reason", reason);
   5849         }
   5850         mWindowManager.closeSystemDialogs(reason);
   5851 
   5852         mStackSupervisor.closeSystemDialogsLocked();
   5853 
   5854         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
   5855                 AppOpsManager.OP_NONE, null, false, false,
   5856                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
   5857     }
   5858 
   5859     @Override
   5860     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
   5861         enforceNotIsolatedCaller("getProcessMemoryInfo");
   5862         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
   5863         for (int i=pids.length-1; i>=0; i--) {
   5864             ProcessRecord proc;
   5865             int oomAdj;
   5866             synchronized (this) {
   5867                 synchronized (mPidsSelfLocked) {
   5868                     proc = mPidsSelfLocked.get(pids[i]);
   5869                     oomAdj = proc != null ? proc.setAdj : 0;
   5870                 }
   5871             }
   5872             infos[i] = new Debug.MemoryInfo();
   5873             Debug.getMemoryInfo(pids[i], infos[i]);
   5874             if (proc != null) {
   5875                 synchronized (this) {
   5876                     if (proc.thread != null && proc.setAdj == oomAdj) {
   5877                         // Record this for posterity if the process has been stable.
   5878                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
   5879                                 infos[i].getTotalUss(), false, proc.pkgList);
   5880                     }
   5881                 }
   5882             }
   5883         }
   5884         return infos;
   5885     }
   5886 
   5887     @Override
   5888     public long[] getProcessPss(int[] pids) {
   5889         enforceNotIsolatedCaller("getProcessPss");
   5890         long[] pss = new long[pids.length];
   5891         for (int i=pids.length-1; i>=0; i--) {
   5892             ProcessRecord proc;
   5893             int oomAdj;
   5894             synchronized (this) {
   5895                 synchronized (mPidsSelfLocked) {
   5896                     proc = mPidsSelfLocked.get(pids[i]);
   5897                     oomAdj = proc != null ? proc.setAdj : 0;
   5898                 }
   5899             }
   5900             long[] tmpUss = new long[1];
   5901             pss[i] = Debug.getPss(pids[i], tmpUss, null);
   5902             if (proc != null) {
   5903                 synchronized (this) {
   5904                     if (proc.thread != null && proc.setAdj == oomAdj) {
   5905                         // Record this for posterity if the process has been stable.
   5906                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
   5907                     }
   5908                 }
   5909             }
   5910         }
   5911         return pss;
   5912     }
   5913 
   5914     @Override
   5915     public void killApplicationProcess(String processName, int uid) {
   5916         if (processName == null) {
   5917             return;
   5918         }
   5919 
   5920         int callerUid = Binder.getCallingUid();
   5921         // Only the system server can kill an application
   5922         if (callerUid == Process.SYSTEM_UID) {
   5923             synchronized (this) {
   5924                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
   5925                 if (app != null && app.thread != null) {
   5926                     try {
   5927                         app.thread.scheduleSuicide();
   5928                     } catch (RemoteException e) {
   5929                         // If the other end already died, then our work here is done.
   5930                     }
   5931                 } else {
   5932                     Slog.w(TAG, "Process/uid not found attempting kill of "
   5933                             + processName + " / " + uid);
   5934                 }
   5935             }
   5936         } else {
   5937             throw new SecurityException(callerUid + " cannot kill app process: " +
   5938                     processName);
   5939         }
   5940     }
   5941 
   5942     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
   5943         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
   5944                 false, true, false, false, UserHandle.getUserId(uid), reason);
   5945     }
   5946 
   5947     private void finishForceStopPackageLocked(final String packageName, int uid) {
   5948         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
   5949                 Uri.fromParts("package", packageName, null));
   5950         if (!mProcessesReady) {
   5951             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   5952                     | Intent.FLAG_RECEIVER_FOREGROUND);
   5953         }
   5954         intent.putExtra(Intent.EXTRA_UID, uid);
   5955         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
   5956         broadcastIntentLocked(null, null, intent,
   5957                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   5958                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
   5959     }
   5960 
   5961 
   5962     private final boolean killPackageProcessesLocked(String packageName, int appId,
   5963             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
   5964             boolean doit, boolean evenPersistent, String reason) {
   5965         ArrayList<ProcessRecord> procs = new ArrayList<>();
   5966 
   5967         // Remove all processes this package may have touched: all with the
   5968         // same UID (except for the system or root user), and all whose name
   5969         // matches the package name.
   5970         final int NP = mProcessNames.getMap().size();
   5971         for (int ip=0; ip<NP; ip++) {
   5972             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   5973             final int NA = apps.size();
   5974             for (int ia=0; ia<NA; ia++) {
   5975                 ProcessRecord app = apps.valueAt(ia);
   5976                 if (app.persistent && !evenPersistent) {
   5977                     // we don't kill persistent processes
   5978                     continue;
   5979                 }
   5980                 if (app.removed) {
   5981                     if (doit) {
   5982                         procs.add(app);
   5983                     }
   5984                     continue;
   5985                 }
   5986 
   5987                 // Skip process if it doesn't meet our oom adj requirement.
   5988                 if (app.setAdj < minOomAdj) {
   5989                     continue;
   5990                 }
   5991 
   5992                 // If no package is specified, we call all processes under the
   5993                 // give user id.
   5994                 if (packageName == null) {
   5995                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
   5996                         continue;
   5997                     }
   5998                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
   5999                         continue;
   6000                     }
   6001                 // Package has been specified, we want to hit all processes
   6002                 // that match it.  We need to qualify this by the processes
   6003                 // that are running under the specified app and user ID.
   6004                 } else {
   6005                     final boolean isDep = app.pkgDeps != null
   6006                             && app.pkgDeps.contains(packageName);
   6007                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
   6008                         continue;
   6009                     }
   6010                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
   6011                         continue;
   6012                     }
   6013                     if (!app.pkgList.containsKey(packageName) && !isDep) {
   6014                         continue;
   6015                     }
   6016                 }
   6017 
   6018                 // Process has passed all conditions, kill it!
   6019                 if (!doit) {
   6020                     return true;
   6021                 }
   6022                 app.removed = true;
   6023                 procs.add(app);
   6024             }
   6025         }
   6026 
   6027         int N = procs.size();
   6028         for (int i=0; i<N; i++) {
   6029             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
   6030         }
   6031         updateOomAdjLocked();
   6032         return N > 0;
   6033     }
   6034 
   6035     private void cleanupDisabledPackageComponentsLocked(
   6036             String packageName, int userId, boolean killProcess, String[] changedClasses) {
   6037 
   6038         Set<String> disabledClasses = null;
   6039         boolean packageDisabled = false;
   6040         IPackageManager pm = AppGlobals.getPackageManager();
   6041 
   6042         if (changedClasses == null) {
   6043             // Nothing changed...
   6044             return;
   6045         }
   6046 
   6047         // Determine enable/disable state of the package and its components.
   6048         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
   6049         for (int i = changedClasses.length - 1; i >= 0; i--) {
   6050             final String changedClass = changedClasses[i];
   6051 
   6052             if (changedClass.equals(packageName)) {
   6053                 try {
   6054                     // Entire package setting changed
   6055                     enabled = pm.getApplicationEnabledSetting(packageName,
   6056                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
   6057                 } catch (Exception e) {
   6058                     // No such package/component; probably racing with uninstall.  In any
   6059                     // event it means we have nothing further to do here.
   6060                     return;
   6061                 }
   6062                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
   6063                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
   6064                 if (packageDisabled) {
   6065                     // Entire package is disabled.
   6066                     // No need to continue to check component states.
   6067                     disabledClasses = null;
   6068                     break;
   6069                 }
   6070             } else {
   6071                 try {
   6072                     enabled = pm.getComponentEnabledSetting(
   6073                             new ComponentName(packageName, changedClass),
   6074                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
   6075                 } catch (Exception e) {
   6076                     // As above, probably racing with uninstall.
   6077                     return;
   6078                 }
   6079                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
   6080                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
   6081                     if (disabledClasses == null) {
   6082                         disabledClasses = new ArraySet<>(changedClasses.length);
   6083                     }
   6084                     disabledClasses.add(changedClass);
   6085                 }
   6086             }
   6087         }
   6088 
   6089         if (!packageDisabled && disabledClasses == null) {
   6090             // Nothing to do here...
   6091             return;
   6092         }
   6093 
   6094         // Clean-up disabled activities.
   6095         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
   6096                 packageName, disabledClasses, true, false, userId) && mBooted) {
   6097             mStackSupervisor.resumeFocusedStackTopActivityLocked();
   6098             mStackSupervisor.scheduleIdleLocked();
   6099         }
   6100 
   6101         // Clean-up disabled tasks
   6102         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
   6103 
   6104         // Clean-up disabled services.
   6105         mServices.bringDownDisabledPackageServicesLocked(
   6106                 packageName, disabledClasses, userId, false, killProcess, true);
   6107 
   6108         // Clean-up disabled providers.
   6109         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
   6110         mProviderMap.collectPackageProvidersLocked(
   6111                 packageName, disabledClasses, true, false, userId, providers);
   6112         for (int i = providers.size() - 1; i >= 0; i--) {
   6113             removeDyingProviderLocked(null, providers.get(i), true);
   6114         }
   6115 
   6116         // Clean-up disabled broadcast receivers.
   6117         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
   6118             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
   6119                     packageName, disabledClasses, userId, true);
   6120         }
   6121 
   6122     }
   6123 
   6124     final boolean clearBroadcastQueueForUserLocked(int userId) {
   6125         boolean didSomething = false;
   6126         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
   6127             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
   6128                     null, null, userId, true);
   6129         }
   6130         return didSomething;
   6131     }
   6132 
   6133     final boolean forceStopPackageLocked(String packageName, int appId,
   6134             boolean callerWillRestart, boolean purgeCache, boolean doit,
   6135             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
   6136         int i;
   6137 
   6138         if (userId == UserHandle.USER_ALL && packageName == null) {
   6139             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
   6140         }
   6141 
   6142         if (appId < 0 && packageName != null) {
   6143             try {
   6144                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
   6145                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
   6146             } catch (RemoteException e) {
   6147             }
   6148         }
   6149 
   6150         if (doit) {
   6151             if (packageName != null) {
   6152                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
   6153                         + " user=" + userId + ": " + reason);
   6154             } else {
   6155                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
   6156             }
   6157 
   6158             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
   6159         }
   6160 
   6161         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
   6162                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
   6163                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
   6164 
   6165         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
   6166                 packageName, null, doit, evenPersistent, userId)) {
   6167             if (!doit) {
   6168                 return true;
   6169             }
   6170             didSomething = true;
   6171         }
   6172 
   6173         if (mServices.bringDownDisabledPackageServicesLocked(
   6174                 packageName, null, userId, evenPersistent, true, doit)) {
   6175             if (!doit) {
   6176                 return true;
   6177             }
   6178             didSomething = true;
   6179         }
   6180 
   6181         if (packageName == null) {
   6182             // Remove all sticky broadcasts from this user.
   6183             mStickyBroadcasts.remove(userId);
   6184         }
   6185 
   6186         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
   6187         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
   6188                 userId, providers)) {
   6189             if (!doit) {
   6190                 return true;
   6191             }
   6192             didSomething = true;
   6193         }
   6194         for (i = providers.size() - 1; i >= 0; i--) {
   6195             removeDyingProviderLocked(null, providers.get(i), true);
   6196         }
   6197 
   6198         // Remove transient permissions granted from/to this package/user
   6199         removeUriPermissionsForPackageLocked(packageName, userId, false);
   6200 
   6201         if (doit) {
   6202             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
   6203                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
   6204                         packageName, null, userId, doit);
   6205             }
   6206         }
   6207 
   6208         if (packageName == null || uninstalling) {
   6209             // Remove pending intents.  For now we only do this when force
   6210             // stopping users, because we have some problems when doing this
   6211             // for packages -- app widgets are not currently cleaned up for
   6212             // such packages, so they can be left with bad pending intents.
   6213             if (mIntentSenderRecords.size() > 0) {
   6214                 Iterator<WeakReference<PendingIntentRecord>> it
   6215                         = mIntentSenderRecords.values().iterator();
   6216                 while (it.hasNext()) {
   6217                     WeakReference<PendingIntentRecord> wpir = it.next();
   6218                     if (wpir == null) {
   6219                         it.remove();
   6220                         continue;
   6221                     }
   6222                     PendingIntentRecord pir = wpir.get();
   6223                     if (pir == null) {
   6224                         it.remove();
   6225                         continue;
   6226                     }
   6227                     if (packageName == null) {
   6228                         // Stopping user, remove all objects for the user.
   6229                         if (pir.key.userId != userId) {
   6230                             // Not the same user, skip it.
   6231                             continue;
   6232                         }
   6233                     } else {
   6234                         if (UserHandle.getAppId(pir.uid) != appId) {
   6235                             // Different app id, skip it.
   6236                             continue;
   6237                         }
   6238                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
   6239                             // Different user, skip it.
   6240                             continue;
   6241                         }
   6242                         if (!pir.key.packageName.equals(packageName)) {
   6243                             // Different package, skip it.
   6244                             continue;
   6245                         }
   6246                     }
   6247                     if (!doit) {
   6248                         return true;
   6249                     }
   6250                     didSomething = true;
   6251                     it.remove();
   6252                     pir.canceled = true;
   6253                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
   6254                         pir.key.activity.pendingResults.remove(pir.ref);
   6255                     }
   6256                 }
   6257             }
   6258         }
   6259 
   6260         if (doit) {
   6261             if (purgeCache && packageName != null) {
   6262                 AttributeCache ac = AttributeCache.instance();
   6263                 if (ac != null) {
   6264                     ac.removePackage(packageName);
   6265                 }
   6266             }
   6267             if (mBooted) {
   6268                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
   6269                 mStackSupervisor.scheduleIdleLocked();
   6270             }
   6271         }
   6272 
   6273         return didSomething;
   6274     }
   6275 
   6276     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
   6277         ProcessRecord old = mProcessNames.remove(name, uid);
   6278         if (old != null) {
   6279             old.uidRecord.numProcs--;
   6280             if (old.uidRecord.numProcs == 0) {
   6281                 // No more processes using this uid, tell clients it is gone.
   6282                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   6283                         "No more processes in " + old.uidRecord);
   6284                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
   6285                 mActiveUids.remove(uid);
   6286                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
   6287             }
   6288             old.uidRecord = null;
   6289         }
   6290         mIsolatedProcesses.remove(uid);
   6291         return old;
   6292     }
   6293 
   6294     private final void addProcessNameLocked(ProcessRecord proc) {
   6295         // We shouldn't already have a process under this name, but just in case we
   6296         // need to clean up whatever may be there now.
   6297         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
   6298         if (old == proc && proc.persistent) {
   6299             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
   6300             Slog.w(TAG, "Re-adding persistent process " + proc);
   6301         } else if (old != null) {
   6302             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
   6303         }
   6304         UidRecord uidRec = mActiveUids.get(proc.uid);
   6305         if (uidRec == null) {
   6306             uidRec = new UidRecord(proc.uid);
   6307             // This is the first appearance of the uid, report it now!
   6308             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   6309                     "Creating new process uid: " + uidRec);
   6310             mActiveUids.put(proc.uid, uidRec);
   6311             noteUidProcessState(uidRec.uid, uidRec.curProcState);
   6312             enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
   6313         }
   6314         proc.uidRecord = uidRec;
   6315 
   6316         // Reset render thread tid if it was already set, so new process can set it again.
   6317         proc.renderThreadTid = 0;
   6318         uidRec.numProcs++;
   6319         mProcessNames.put(proc.processName, proc.uid, proc);
   6320         if (proc.isolated) {
   6321             mIsolatedProcesses.put(proc.uid, proc);
   6322         }
   6323     }
   6324 
   6325     boolean removeProcessLocked(ProcessRecord app,
   6326             boolean callerWillRestart, boolean allowRestart, String reason) {
   6327         final String name = app.processName;
   6328         final int uid = app.uid;
   6329         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
   6330             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
   6331 
   6332         ProcessRecord old = mProcessNames.get(name, uid);
   6333         if (old != app) {
   6334             // This process is no longer active, so nothing to do.
   6335             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
   6336             return false;
   6337         }
   6338         removeProcessNameLocked(name, uid);
   6339         if (mHeavyWeightProcess == app) {
   6340             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   6341                     mHeavyWeightProcess.userId, 0));
   6342             mHeavyWeightProcess = null;
   6343         }
   6344         boolean needRestart = false;
   6345         if (app.pid > 0 && app.pid != MY_PID) {
   6346             int pid = app.pid;
   6347             synchronized (mPidsSelfLocked) {
   6348                 mPidsSelfLocked.remove(pid);
   6349                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   6350             }
   6351             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   6352             if (app.isolated) {
   6353                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   6354             }
   6355             boolean willRestart = false;
   6356             if (app.persistent && !app.isolated) {
   6357                 if (!callerWillRestart) {
   6358                     willRestart = true;
   6359                 } else {
   6360                     needRestart = true;
   6361                 }
   6362             }
   6363             app.kill(reason, true);
   6364             handleAppDiedLocked(app, willRestart, allowRestart);
   6365             if (willRestart) {
   6366                 removeLruProcessLocked(app);
   6367                 addAppLocked(app.info, false, null /* ABI override */);
   6368             }
   6369         } else {
   6370             mRemovedProcesses.add(app);
   6371         }
   6372 
   6373         return needRestart;
   6374     }
   6375 
   6376     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
   6377         cleanupAppInLaunchingProvidersLocked(app, true);
   6378         removeProcessLocked(app, false, true, "timeout publishing content providers");
   6379     }
   6380 
   6381     private final void processStartTimedOutLocked(ProcessRecord app) {
   6382         final int pid = app.pid;
   6383         boolean gone = false;
   6384         synchronized (mPidsSelfLocked) {
   6385             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
   6386             if (knownApp != null && knownApp.thread == null) {
   6387                 mPidsSelfLocked.remove(pid);
   6388                 gone = true;
   6389             }
   6390         }
   6391 
   6392         if (gone) {
   6393             Slog.w(TAG, "Process " + app + " failed to attach");
   6394             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
   6395                     pid, app.uid, app.processName);
   6396             removeProcessNameLocked(app.processName, app.uid);
   6397             if (mHeavyWeightProcess == app) {
   6398                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   6399                         mHeavyWeightProcess.userId, 0));
   6400                 mHeavyWeightProcess = null;
   6401             }
   6402             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   6403             if (app.isolated) {
   6404                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   6405             }
   6406             // Take care of any launching providers waiting for this process.
   6407             cleanupAppInLaunchingProvidersLocked(app, true);
   6408             // Take care of any services that are waiting for the process.
   6409             mServices.processStartTimedOutLocked(app);
   6410             app.kill("start timeout", true);
   6411             removeLruProcessLocked(app);
   6412             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
   6413                 Slog.w(TAG, "Unattached app died before backup, skipping");
   6414                 try {
   6415                     IBackupManager bm = IBackupManager.Stub.asInterface(
   6416                             ServiceManager.getService(Context.BACKUP_SERVICE));
   6417                     bm.agentDisconnected(app.info.packageName);
   6418                 } catch (RemoteException e) {
   6419                     // Can't happen; the backup manager is local
   6420                 }
   6421             }
   6422             if (isPendingBroadcastProcessLocked(pid)) {
   6423                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   6424                 skipPendingBroadcastLocked(pid);
   6425             }
   6426         } else {
   6427             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
   6428         }
   6429     }
   6430 
   6431     private final boolean attachApplicationLocked(IApplicationThread thread,
   6432             int pid) {
   6433 
   6434         // Find the application record that is being attached...  either via
   6435         // the pid if we are running in multiple processes, or just pull the
   6436         // next app record if we are emulating process with anonymous threads.
   6437         ProcessRecord app;
   6438         if (pid != MY_PID && pid >= 0) {
   6439             synchronized (mPidsSelfLocked) {
   6440                 app = mPidsSelfLocked.get(pid);
   6441             }
   6442         } else {
   6443             app = null;
   6444         }
   6445 
   6446         if (app == null) {
   6447             Slog.w(TAG, "No pending application record for pid " + pid
   6448                     + " (IApplicationThread " + thread + "); dropping process");
   6449             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
   6450             if (pid > 0 && pid != MY_PID) {
   6451                 Process.killProcessQuiet(pid);
   6452                 //TODO: killProcessGroup(app.info.uid, pid);
   6453             } else {
   6454                 try {
   6455                     thread.scheduleExit();
   6456                 } catch (Exception e) {
   6457                     // Ignore exceptions.
   6458                 }
   6459             }
   6460             return false;
   6461         }
   6462 
   6463         // If this application record is still attached to a previous
   6464         // process, clean it up now.
   6465         if (app.thread != null) {
   6466             handleAppDiedLocked(app, true, true);
   6467         }
   6468 
   6469         // Tell the process all about itself.
   6470 
   6471         if (DEBUG_ALL) Slog.v(
   6472                 TAG, "Binding process pid " + pid + " to record " + app);
   6473 
   6474         final String processName = app.processName;
   6475         try {
   6476             AppDeathRecipient adr = new AppDeathRecipient(
   6477                     app, pid, thread);
   6478             thread.asBinder().linkToDeath(adr, 0);
   6479             app.deathRecipient = adr;
   6480         } catch (RemoteException e) {
   6481             app.resetPackageList(mProcessStats);
   6482             startProcessLocked(app, "link fail", processName);
   6483             return false;
   6484         }
   6485 
   6486         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
   6487 
   6488         app.makeActive(thread, mProcessStats);
   6489         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
   6490         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   6491         app.forcingToForeground = null;
   6492         updateProcessForegroundLocked(app, false, false);
   6493         app.hasShownUi = false;
   6494         app.debugging = false;
   6495         app.cached = false;
   6496         app.killedByAm = false;
   6497 
   6498         // We carefully use the same state that PackageManager uses for
   6499         // filtering, since we use this flag to decide if we need to install
   6500         // providers when user is unlocked later
   6501         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
   6502 
   6503         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   6504 
   6505         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
   6506         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
   6507 
   6508         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
   6509             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
   6510             msg.obj = app;
   6511             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
   6512         }
   6513 
   6514         if (!normalMode) {
   6515             Slog.i(TAG, "Launching preboot mode app: " + app);
   6516         }
   6517 
   6518         if (DEBUG_ALL) Slog.v(
   6519             TAG, "New app record " + app
   6520             + " thread=" + thread.asBinder() + " pid=" + pid);
   6521         try {
   6522             int testMode = IApplicationThread.DEBUG_OFF;
   6523             if (mDebugApp != null && mDebugApp.equals(processName)) {
   6524                 testMode = mWaitForDebugger
   6525                     ? IApplicationThread.DEBUG_WAIT
   6526                     : IApplicationThread.DEBUG_ON;
   6527                 app.debugging = true;
   6528                 if (mDebugTransient) {
   6529                     mDebugApp = mOrigDebugApp;
   6530                     mWaitForDebugger = mOrigWaitForDebugger;
   6531                 }
   6532             }
   6533             String profileFile = app.instrumentationProfileFile;
   6534             ParcelFileDescriptor profileFd = null;
   6535             int samplingInterval = 0;
   6536             boolean profileAutoStop = false;
   6537             if (mProfileApp != null && mProfileApp.equals(processName)) {
   6538                 mProfileProc = app;
   6539                 profileFile = mProfileFile;
   6540                 profileFd = mProfileFd;
   6541                 samplingInterval = mSamplingInterval;
   6542                 profileAutoStop = mAutoStopProfiler;
   6543             }
   6544             boolean enableTrackAllocation = false;
   6545             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
   6546                 enableTrackAllocation = true;
   6547                 mTrackAllocationApp = null;
   6548             }
   6549 
   6550             // If the app is being launched for restore or full backup, set it up specially
   6551             boolean isRestrictedBackupMode = false;
   6552             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
   6553                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
   6554                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
   6555                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
   6556                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
   6557             }
   6558 
   6559             if (app.instrumentationClass != null) {
   6560                 notifyPackageUse(app.instrumentationClass.getPackageName(),
   6561                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
   6562             }
   6563             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
   6564                     + processName + " with config " + mConfiguration);
   6565             ApplicationInfo appInfo = app.instrumentationInfo != null
   6566                     ? app.instrumentationInfo : app.info;
   6567             app.compat = compatibilityInfoForPackageLocked(appInfo);
   6568             if (profileFd != null) {
   6569                 profileFd = profileFd.dup();
   6570             }
   6571             ProfilerInfo profilerInfo = profileFile == null ? null
   6572                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
   6573             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
   6574                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
   6575                     app.instrumentationUiAutomationConnection, testMode,
   6576                     mBinderTransactionTrackingEnabled, enableTrackAllocation,
   6577                     isRestrictedBackupMode || !normalMode, app.persistent,
   6578                     new Configuration(mConfiguration), app.compat,
   6579                     getCommonServicesLocked(app.isolated),
   6580                     mCoreSettingsObserver.getCoreSettingsLocked());
   6581             updateLruProcessLocked(app, false, null);
   6582             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
   6583         } catch (Exception e) {
   6584             // todo: Yikes!  What should we do?  For now we will try to
   6585             // start another process, but that could easily get us in
   6586             // an infinite loop of restarting processes...
   6587             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
   6588 
   6589             app.resetPackageList(mProcessStats);
   6590             app.unlinkDeathRecipient();
   6591             startProcessLocked(app, "bind fail", processName);
   6592             return false;
   6593         }
   6594 
   6595         // Remove this record from the list of starting applications.
   6596         mPersistentStartingProcesses.remove(app);
   6597         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
   6598                 "Attach application locked removing on hold: " + app);
   6599         mProcessesOnHold.remove(app);
   6600 
   6601         boolean badApp = false;
   6602         boolean didSomething = false;
   6603 
   6604         // See if the top visible activity is waiting to run in this process...
   6605         if (normalMode) {
   6606             try {
   6607                 if (mStackSupervisor.attachApplicationLocked(app)) {
   6608                     didSomething = true;
   6609                 }
   6610             } catch (Exception e) {
   6611                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
   6612                 badApp = true;
   6613             }
   6614         }
   6615 
   6616         // Find any services that should be running in this process...
   6617         if (!badApp) {
   6618             try {
   6619                 didSomething |= mServices.attachApplicationLocked(app, processName);
   6620             } catch (Exception e) {
   6621                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
   6622                 badApp = true;
   6623             }
   6624         }
   6625 
   6626         // Check if a next-broadcast receiver is in this process...
   6627         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
   6628             try {
   6629                 didSomething |= sendPendingBroadcastsLocked(app);
   6630             } catch (Exception e) {
   6631                 // If the app died trying to launch the receiver we declare it 'bad'
   6632                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
   6633                 badApp = true;
   6634             }
   6635         }
   6636 
   6637         // Check whether the next backup agent is in this process...
   6638         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
   6639             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
   6640                     "New app is backup target, launching agent for " + app);
   6641             notifyPackageUse(mBackupTarget.appInfo.packageName,
   6642                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
   6643             try {
   6644                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
   6645                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
   6646                         mBackupTarget.backupMode);
   6647             } catch (Exception e) {
   6648                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
   6649                 badApp = true;
   6650             }
   6651         }
   6652 
   6653         if (badApp) {
   6654             app.kill("error during init", true);
   6655             handleAppDiedLocked(app, false, true);
   6656             return false;
   6657         }
   6658 
   6659         if (!didSomething) {
   6660             updateOomAdjLocked();
   6661         }
   6662 
   6663         return true;
   6664     }
   6665 
   6666     @Override
   6667     public final void attachApplication(IApplicationThread thread) {
   6668         synchronized (this) {
   6669             int callingPid = Binder.getCallingPid();
   6670             final long origId = Binder.clearCallingIdentity();
   6671             attachApplicationLocked(thread, callingPid);
   6672             Binder.restoreCallingIdentity(origId);
   6673         }
   6674     }
   6675 
   6676     @Override
   6677     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
   6678         final long origId = Binder.clearCallingIdentity();
   6679         synchronized (this) {
   6680             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6681             if (stack != null) {
   6682                 ActivityRecord r =
   6683                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
   6684                 if (stopProfiling) {
   6685                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
   6686                         try {
   6687                             mProfileFd.close();
   6688                         } catch (IOException e) {
   6689                         }
   6690                         clearProfilerLocked();
   6691                     }
   6692                 }
   6693             }
   6694         }
   6695         Binder.restoreCallingIdentity(origId);
   6696     }
   6697 
   6698     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
   6699         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
   6700                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
   6701     }
   6702 
   6703     void enableScreenAfterBoot() {
   6704         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
   6705                 SystemClock.uptimeMillis());
   6706         mWindowManager.enableScreenAfterBoot();
   6707 
   6708         synchronized (this) {
   6709             updateEventDispatchingLocked();
   6710         }
   6711     }
   6712 
   6713     @Override
   6714     public void showBootMessage(final CharSequence msg, final boolean always) {
   6715         if (Binder.getCallingUid() != Process.myUid()) {
   6716             throw new SecurityException();
   6717         }
   6718         mWindowManager.showBootMessage(msg, always);
   6719     }
   6720 
   6721     @Override
   6722     public void keyguardWaitingForActivityDrawn() {
   6723         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
   6724         final long token = Binder.clearCallingIdentity();
   6725         try {
   6726             synchronized (this) {
   6727                 if (DEBUG_LOCKSCREEN) logLockScreen("");
   6728                 mWindowManager.keyguardWaitingForActivityDrawn();
   6729                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
   6730                     mLockScreenShown = LOCK_SCREEN_LEAVING;
   6731                     updateSleepIfNeededLocked();
   6732                 }
   6733             }
   6734         } finally {
   6735             Binder.restoreCallingIdentity(token);
   6736         }
   6737     }
   6738 
   6739     @Override
   6740     public void keyguardGoingAway(int flags) {
   6741         enforceNotIsolatedCaller("keyguardGoingAway");
   6742         final long token = Binder.clearCallingIdentity();
   6743         try {
   6744             synchronized (this) {
   6745                 if (DEBUG_LOCKSCREEN) logLockScreen("");
   6746                 mWindowManager.keyguardGoingAway(flags);
   6747                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
   6748                     mLockScreenShown = LOCK_SCREEN_HIDDEN;
   6749                     updateSleepIfNeededLocked();
   6750 
   6751                     // Some stack visibility might change (e.g. docked stack)
   6752                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   6753                     applyVrModeIfNeededLocked(mFocusedActivity, true);
   6754                 }
   6755             }
   6756         } finally {
   6757             Binder.restoreCallingIdentity(token);
   6758         }
   6759     }
   6760 
   6761     final void finishBooting() {
   6762         synchronized (this) {
   6763             if (!mBootAnimationComplete) {
   6764                 mCallFinishBooting = true;
   6765                 return;
   6766             }
   6767             mCallFinishBooting = false;
   6768         }
   6769 
   6770         ArraySet<String> completedIsas = new ArraySet<String>();
   6771         for (String abi : Build.SUPPORTED_ABIS) {
   6772             Process.establishZygoteConnectionForAbi(abi);
   6773             final String instructionSet = VMRuntime.getInstructionSet(abi);
   6774             if (!completedIsas.contains(instructionSet)) {
   6775                 try {
   6776                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
   6777                 } catch (InstallerException e) {
   6778                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
   6779                             e.getMessage() +")");
   6780                 }
   6781                 completedIsas.add(instructionSet);
   6782             }
   6783         }
   6784 
   6785         IntentFilter pkgFilter = new IntentFilter();
   6786         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
   6787         pkgFilter.addDataScheme("package");
   6788         mContext.registerReceiver(new BroadcastReceiver() {
   6789             @Override
   6790             public void onReceive(Context context, Intent intent) {
   6791                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
   6792                 if (pkgs != null) {
   6793                     for (String pkg : pkgs) {
   6794                         synchronized (ActivityManagerService.this) {
   6795                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
   6796                                     0, "query restart")) {
   6797                                 setResultCode(Activity.RESULT_OK);
   6798                                 return;
   6799                             }
   6800                         }
   6801                     }
   6802                 }
   6803             }
   6804         }, pkgFilter);
   6805 
   6806         IntentFilter dumpheapFilter = new IntentFilter();
   6807         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
   6808         mContext.registerReceiver(new BroadcastReceiver() {
   6809             @Override
   6810             public void onReceive(Context context, Intent intent) {
   6811                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
   6812                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
   6813                 } else {
   6814                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
   6815                 }
   6816             }
   6817         }, dumpheapFilter);
   6818 
   6819         // Let system services know.
   6820         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
   6821 
   6822         synchronized (this) {
   6823             // Ensure that any processes we had put on hold are now started
   6824             // up.
   6825             final int NP = mProcessesOnHold.size();
   6826             if (NP > 0) {
   6827                 ArrayList<ProcessRecord> procs =
   6828                     new ArrayList<ProcessRecord>(mProcessesOnHold);
   6829                 for (int ip=0; ip<NP; ip++) {
   6830                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
   6831                             + procs.get(ip));
   6832                     startProcessLocked(procs.get(ip), "on-hold", null);
   6833                 }
   6834             }
   6835 
   6836             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   6837                 // Start looking for apps that are abusing wake locks.
   6838                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   6839                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   6840                 // Tell anyone interested that we are done booting!
   6841                 SystemProperties.set("sys.boot_completed", "1");
   6842 
   6843                 // And trigger dev.bootcomplete if we are not showing encryption progress
   6844                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
   6845                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
   6846                     SystemProperties.set("dev.bootcomplete", "1");
   6847                 }
   6848                 mUserController.sendBootCompletedLocked(
   6849                         new IIntentReceiver.Stub() {
   6850                             @Override
   6851                             public void performReceive(Intent intent, int resultCode,
   6852                                     String data, Bundle extras, boolean ordered,
   6853                                     boolean sticky, int sendingUser) {
   6854                                 synchronized (ActivityManagerService.this) {
   6855                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
   6856                                             true, false);
   6857                                 }
   6858                             }
   6859                         });
   6860                 scheduleStartProfilesLocked();
   6861             }
   6862         }
   6863     }
   6864 
   6865     @Override
   6866     public void bootAnimationComplete() {
   6867         final boolean callFinishBooting;
   6868         synchronized (this) {
   6869             callFinishBooting = mCallFinishBooting;
   6870             mBootAnimationComplete = true;
   6871         }
   6872         if (callFinishBooting) {
   6873             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
   6874             finishBooting();
   6875             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   6876         }
   6877     }
   6878 
   6879     final void ensureBootCompleted() {
   6880         boolean booting;
   6881         boolean enableScreen;
   6882         synchronized (this) {
   6883             booting = mBooting;
   6884             mBooting = false;
   6885             enableScreen = !mBooted;
   6886             mBooted = true;
   6887         }
   6888 
   6889         if (booting) {
   6890             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
   6891             finishBooting();
   6892             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   6893         }
   6894 
   6895         if (enableScreen) {
   6896             enableScreenAfterBoot();
   6897         }
   6898     }
   6899 
   6900     @Override
   6901     public final void activityResumed(IBinder token) {
   6902         final long origId = Binder.clearCallingIdentity();
   6903         synchronized(this) {
   6904             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6905             if (stack != null) {
   6906                 stack.activityResumedLocked(token);
   6907             }
   6908         }
   6909         Binder.restoreCallingIdentity(origId);
   6910     }
   6911 
   6912     @Override
   6913     public final void activityPaused(IBinder token) {
   6914         final long origId = Binder.clearCallingIdentity();
   6915         synchronized(this) {
   6916             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6917             if (stack != null) {
   6918                 stack.activityPausedLocked(token, false);
   6919             }
   6920         }
   6921         Binder.restoreCallingIdentity(origId);
   6922     }
   6923 
   6924     @Override
   6925     public final void activityStopped(IBinder token, Bundle icicle,
   6926             PersistableBundle persistentState, CharSequence description) {
   6927         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
   6928 
   6929         // Refuse possible leaked file descriptors
   6930         if (icicle != null && icicle.hasFileDescriptors()) {
   6931             throw new IllegalArgumentException("File descriptors passed in Bundle");
   6932         }
   6933 
   6934         final long origId = Binder.clearCallingIdentity();
   6935 
   6936         synchronized (this) {
   6937             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   6938             if (r != null) {
   6939                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
   6940             }
   6941         }
   6942 
   6943         trimApplications();
   6944 
   6945         Binder.restoreCallingIdentity(origId);
   6946     }
   6947 
   6948     @Override
   6949     public final void activityDestroyed(IBinder token) {
   6950         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
   6951         synchronized (this) {
   6952             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6953             if (stack != null) {
   6954                 stack.activityDestroyedLocked(token, "activityDestroyed");
   6955             }
   6956         }
   6957     }
   6958 
   6959     @Override
   6960     public final void activityRelaunched(IBinder token) {
   6961         final long origId = Binder.clearCallingIdentity();
   6962         synchronized (this) {
   6963             mStackSupervisor.activityRelaunchedLocked(token);
   6964         }
   6965         Binder.restoreCallingIdentity(origId);
   6966     }
   6967 
   6968     @Override
   6969     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
   6970             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
   6971         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
   6972                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
   6973         synchronized (this) {
   6974             ActivityRecord record = ActivityRecord.isInStackLocked(token);
   6975             if (record == null) {
   6976                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
   6977                         + "found for: " + token);
   6978             }
   6979             record.setSizeConfigurations(horizontalSizeConfiguration,
   6980                     verticalSizeConfigurations, smallestSizeConfigurations);
   6981         }
   6982     }
   6983 
   6984     @Override
   6985     public final void backgroundResourcesReleased(IBinder token) {
   6986         final long origId = Binder.clearCallingIdentity();
   6987         try {
   6988             synchronized (this) {
   6989                 ActivityStack stack = ActivityRecord.getStackLocked(token);
   6990                 if (stack != null) {
   6991                     stack.backgroundResourcesReleased();
   6992                 }
   6993             }
   6994         } finally {
   6995             Binder.restoreCallingIdentity(origId);
   6996         }
   6997     }
   6998 
   6999     @Override
   7000     public final void notifyLaunchTaskBehindComplete(IBinder token) {
   7001         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
   7002     }
   7003 
   7004     @Override
   7005     public final void notifyEnterAnimationComplete(IBinder token) {
   7006         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
   7007     }
   7008 
   7009     @Override
   7010     public String getCallingPackage(IBinder token) {
   7011         synchronized (this) {
   7012             ActivityRecord r = getCallingRecordLocked(token);
   7013             return r != null ? r.info.packageName : null;
   7014         }
   7015     }
   7016 
   7017     @Override
   7018     public ComponentName getCallingActivity(IBinder token) {
   7019         synchronized (this) {
   7020             ActivityRecord r = getCallingRecordLocked(token);
   7021             return r != null ? r.intent.getComponent() : null;
   7022         }
   7023     }
   7024 
   7025     private ActivityRecord getCallingRecordLocked(IBinder token) {
   7026         ActivityRecord r = ActivityRecord.isInStackLocked(token);
   7027         if (r == null) {
   7028             return null;
   7029         }
   7030         return r.resultTo;
   7031     }
   7032 
   7033     @Override
   7034     public ComponentName getActivityClassForToken(IBinder token) {
   7035         synchronized(this) {
   7036             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   7037             if (r == null) {
   7038                 return null;
   7039             }
   7040             return r.intent.getComponent();
   7041         }
   7042     }
   7043 
   7044     @Override
   7045     public String getPackageForToken(IBinder token) {
   7046         synchronized(this) {
   7047             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   7048             if (r == null) {
   7049                 return null;
   7050             }
   7051             return r.packageName;
   7052         }
   7053     }
   7054 
   7055     @Override
   7056     public boolean isRootVoiceInteraction(IBinder token) {
   7057         synchronized(this) {
   7058             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   7059             if (r == null) {
   7060                 return false;
   7061             }
   7062             return r.rootVoiceInteraction;
   7063         }
   7064     }
   7065 
   7066     @Override
   7067     public IIntentSender getIntentSender(int type,
   7068             String packageName, IBinder token, String resultWho,
   7069             int requestCode, Intent[] intents, String[] resolvedTypes,
   7070             int flags, Bundle bOptions, int userId) {
   7071         enforceNotIsolatedCaller("getIntentSender");
   7072         // Refuse possible leaked file descriptors
   7073         if (intents != null) {
   7074             if (intents.length < 1) {
   7075                 throw new IllegalArgumentException("Intents array length must be >= 1");
   7076             }
   7077             for (int i=0; i<intents.length; i++) {
   7078                 Intent intent = intents[i];
   7079                 if (intent != null) {
   7080                     if (intent.hasFileDescriptors()) {
   7081                         throw new IllegalArgumentException("File descriptors passed in Intent");
   7082                     }
   7083                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
   7084                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   7085                         throw new IllegalArgumentException(
   7086                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   7087                     }
   7088                     intents[i] = new Intent(intent);
   7089                 }
   7090             }
   7091             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
   7092                 throw new IllegalArgumentException(
   7093                         "Intent array length does not match resolvedTypes length");
   7094             }
   7095         }
   7096         if (bOptions != null) {
   7097             if (bOptions.hasFileDescriptors()) {
   7098                 throw new IllegalArgumentException("File descriptors passed in options");
   7099             }
   7100         }
   7101 
   7102         synchronized(this) {
   7103             int callingUid = Binder.getCallingUid();
   7104             int origUserId = userId;
   7105             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
   7106                     type == ActivityManager.INTENT_SENDER_BROADCAST,
   7107                     ALLOW_NON_FULL, "getIntentSender", null);
   7108             if (origUserId == UserHandle.USER_CURRENT) {
   7109                 // We don't want to evaluate this until the pending intent is
   7110                 // actually executed.  However, we do want to always do the
   7111                 // security checking for it above.
   7112                 userId = UserHandle.USER_CURRENT;
   7113             }
   7114             try {
   7115                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   7116                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
   7117                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
   7118                     if (!UserHandle.isSameApp(callingUid, uid)) {
   7119                         String msg = "Permission Denial: getIntentSender() from pid="
   7120                             + Binder.getCallingPid()
   7121                             + ", uid=" + Binder.getCallingUid()
   7122                             + ", (need uid=" + uid + ")"
   7123                             + " is not allowed to send as package " + packageName;
   7124                         Slog.w(TAG, msg);
   7125                         throw new SecurityException(msg);
   7126                     }
   7127                 }
   7128 
   7129                 return getIntentSenderLocked(type, packageName, callingUid, userId,
   7130                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
   7131 
   7132             } catch (RemoteException e) {
   7133                 throw new SecurityException(e);
   7134             }
   7135         }
   7136     }
   7137 
   7138     IIntentSender getIntentSenderLocked(int type, String packageName,
   7139             int callingUid, int userId, IBinder token, String resultWho,
   7140             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
   7141             Bundle bOptions) {
   7142         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
   7143         ActivityRecord activity = null;
   7144         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   7145             activity = ActivityRecord.isInStackLocked(token);
   7146             if (activity == null) {
   7147                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
   7148                 return null;
   7149             }
   7150             if (activity.finishing) {
   7151                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
   7152                 return null;
   7153             }
   7154         }
   7155 
   7156         // We're going to be splicing together extras before sending, so we're
   7157         // okay poking into any contained extras.
   7158         if (intents != null) {
   7159             for (int i = 0; i < intents.length; i++) {
   7160                 intents[i].setDefusable(true);
   7161             }
   7162         }
   7163         Bundle.setDefusable(bOptions, true);
   7164 
   7165         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
   7166         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
   7167         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
   7168         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
   7169                 |PendingIntent.FLAG_UPDATE_CURRENT);
   7170 
   7171         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
   7172                 type, packageName, activity, resultWho,
   7173                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
   7174         WeakReference<PendingIntentRecord> ref;
   7175         ref = mIntentSenderRecords.get(key);
   7176         PendingIntentRecord rec = ref != null ? ref.get() : null;
   7177         if (rec != null) {
   7178             if (!cancelCurrent) {
   7179                 if (updateCurrent) {
   7180                     if (rec.key.requestIntent != null) {
   7181                         rec.key.requestIntent.replaceExtras(intents != null ?
   7182                                 intents[intents.length - 1] : null);
   7183                     }
   7184                     if (intents != null) {
   7185                         intents[intents.length-1] = rec.key.requestIntent;
   7186                         rec.key.allIntents = intents;
   7187                         rec.key.allResolvedTypes = resolvedTypes;
   7188                     } else {
   7189                         rec.key.allIntents = null;
   7190                         rec.key.allResolvedTypes = null;
   7191                     }
   7192                 }
   7193                 return rec;
   7194             }
   7195             rec.canceled = true;
   7196             mIntentSenderRecords.remove(key);
   7197         }
   7198         if (noCreate) {
   7199             return rec;
   7200         }
   7201         rec = new PendingIntentRecord(this, key, callingUid);
   7202         mIntentSenderRecords.put(key, rec.ref);
   7203         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   7204             if (activity.pendingResults == null) {
   7205                 activity.pendingResults
   7206                         = new HashSet<WeakReference<PendingIntentRecord>>();
   7207             }
   7208             activity.pendingResults.add(rec.ref);
   7209         }
   7210         return rec;
   7211     }
   7212 
   7213     @Override
   7214     public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
   7215             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
   7216         if (target instanceof PendingIntentRecord) {
   7217             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
   7218                     finishedReceiver, requiredPermission, options);
   7219         } else {
   7220             if (intent == null) {
   7221                 // Weird case: someone has given us their own custom IIntentSender, and now
   7222                 // they have someone else trying to send to it but of course this isn't
   7223                 // really a PendingIntent, so there is no base Intent, and the caller isn't
   7224                 // supplying an Intent... but we never want to dispatch a null Intent to
   7225                 // a receiver, so um...  let's make something up.
   7226                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
   7227                 intent = new Intent(Intent.ACTION_MAIN);
   7228             }
   7229             try {
   7230                 target.send(code, intent, resolvedType, null, requiredPermission, options);
   7231             } catch (RemoteException e) {
   7232             }
   7233             // Platform code can rely on getting a result back when the send is done, but if
   7234             // this intent sender is from outside of the system we can't rely on it doing that.
   7235             // So instead we don't give it the result receiver, and instead just directly
   7236             // report the finish immediately.
   7237             if (finishedReceiver != null) {
   7238                 try {
   7239                     finishedReceiver.performReceive(intent, 0,
   7240                             null, null, false, false, UserHandle.getCallingUserId());
   7241                 } catch (RemoteException e) {
   7242                 }
   7243             }
   7244             return 0;
   7245         }
   7246     }
   7247 
   7248     /**
   7249      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
   7250      *
   7251      * <p>{@code callerUid} must be allowed to request such whitelist by calling
   7252      * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
   7253      */
   7254     void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
   7255         if (DEBUG_WHITELISTS) {
   7256             Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
   7257                     + targetUid + ", " + duration + ")");
   7258         }
   7259         synchronized (mPidsSelfLocked) {
   7260             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
   7261             if (pr == null) {
   7262                 Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
   7263                 return;
   7264             }
   7265             if (!pr.whitelistManager) {
   7266                 if (DEBUG_WHITELISTS) {
   7267                     Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
   7268                             + callerPid + " is not allowed");
   7269                 }
   7270                 return;
   7271             }
   7272         }
   7273 
   7274         final long token = Binder.clearCallingIdentity();
   7275         try {
   7276             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
   7277                     true, "pe from uid:" + callerUid);
   7278         } finally {
   7279             Binder.restoreCallingIdentity(token);
   7280         }
   7281     }
   7282 
   7283     @Override
   7284     public void cancelIntentSender(IIntentSender sender) {
   7285         if (!(sender instanceof PendingIntentRecord)) {
   7286             return;
   7287         }
   7288         synchronized(this) {
   7289             PendingIntentRecord rec = (PendingIntentRecord)sender;
   7290             try {
   7291                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
   7292                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
   7293                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
   7294                     String msg = "Permission Denial: cancelIntentSender() from pid="
   7295                         + Binder.getCallingPid()
   7296                         + ", uid=" + Binder.getCallingUid()
   7297                         + " is not allowed to cancel packges "
   7298                         + rec.key.packageName;
   7299                     Slog.w(TAG, msg);
   7300                     throw new SecurityException(msg);
   7301                 }
   7302             } catch (RemoteException e) {
   7303                 throw new SecurityException(e);
   7304             }
   7305             cancelIntentSenderLocked(rec, true);
   7306         }
   7307     }
   7308 
   7309     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
   7310         rec.canceled = true;
   7311         mIntentSenderRecords.remove(rec.key);
   7312         if (cleanActivity && rec.key.activity != null) {
   7313             rec.key.activity.pendingResults.remove(rec.ref);
   7314         }
   7315     }
   7316 
   7317     @Override
   7318     public String getPackageForIntentSender(IIntentSender pendingResult) {
   7319         if (!(pendingResult instanceof PendingIntentRecord)) {
   7320             return null;
   7321         }
   7322         try {
   7323             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   7324             return res.key.packageName;
   7325         } catch (ClassCastException e) {
   7326         }
   7327         return null;
   7328     }
   7329 
   7330     @Override
   7331     public int getUidForIntentSender(IIntentSender sender) {
   7332         if (sender instanceof PendingIntentRecord) {
   7333             try {
   7334                 PendingIntentRecord res = (PendingIntentRecord)sender;
   7335                 return res.uid;
   7336             } catch (ClassCastException e) {
   7337             }
   7338         }
   7339         return -1;
   7340     }
   7341 
   7342     @Override
   7343     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
   7344         if (!(pendingResult instanceof PendingIntentRecord)) {
   7345             return false;
   7346         }
   7347         try {
   7348             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   7349             if (res.key.allIntents == null) {
   7350                 return false;
   7351             }
   7352             for (int i=0; i<res.key.allIntents.length; i++) {
   7353                 Intent intent = res.key.allIntents[i];
   7354                 if (intent.getPackage() != null && intent.getComponent() != null) {
   7355                     return false;
   7356                 }
   7357             }
   7358             return true;
   7359         } catch (ClassCastException e) {
   7360         }
   7361         return false;
   7362     }
   7363 
   7364     @Override
   7365     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
   7366         if (!(pendingResult instanceof PendingIntentRecord)) {
   7367             return false;
   7368         }
   7369         try {
   7370             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   7371             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
   7372                 return true;
   7373             }
   7374             return false;
   7375         } catch (ClassCastException e) {
   7376         }
   7377         return false;
   7378     }
   7379 
   7380     @Override
   7381     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
   7382         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
   7383                 "getIntentForIntentSender()");
   7384         if (!(pendingResult instanceof PendingIntentRecord)) {
   7385             return null;
   7386         }
   7387         try {
   7388             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   7389             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
   7390         } catch (ClassCastException e) {
   7391         }
   7392         return null;
   7393     }
   7394 
   7395     @Override
   7396     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
   7397         if (!(pendingResult instanceof PendingIntentRecord)) {
   7398             return null;
   7399         }
   7400         try {
   7401             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   7402             synchronized (this) {
   7403                 return getTagForIntentSenderLocked(res, prefix);
   7404             }
   7405         } catch (ClassCastException e) {
   7406         }
   7407         return null;
   7408     }
   7409 
   7410     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
   7411         final Intent intent = res.key.requestIntent;
   7412         if (intent != null) {
   7413             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
   7414                     || res.lastTagPrefix.equals(prefix))) {
   7415                 return res.lastTag;
   7416             }
   7417             res.lastTagPrefix = prefix;
   7418             final StringBuilder sb = new StringBuilder(128);
   7419             if (prefix != null) {
   7420                 sb.append(prefix);
   7421             }
   7422             if (intent.getAction() != null) {
   7423                 sb.append(intent.getAction());
   7424             } else if (intent.getComponent() != null) {
   7425                 intent.getComponent().appendShortString(sb);
   7426             } else {
   7427                 sb.append("?");
   7428             }
   7429             return res.lastTag = sb.toString();
   7430         }
   7431         return null;
   7432     }
   7433 
   7434     @Override
   7435     public void setProcessLimit(int max) {
   7436         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   7437                 "setProcessLimit()");
   7438         synchronized (this) {
   7439             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
   7440             mProcessLimitOverride = max;
   7441         }
   7442         trimApplications();
   7443     }
   7444 
   7445     @Override
   7446     public int getProcessLimit() {
   7447         synchronized (this) {
   7448             return mProcessLimitOverride;
   7449         }
   7450     }
   7451 
   7452     void foregroundTokenDied(ForegroundToken token) {
   7453         synchronized (ActivityManagerService.this) {
   7454             synchronized (mPidsSelfLocked) {
   7455                 ForegroundToken cur
   7456                     = mForegroundProcesses.get(token.pid);
   7457                 if (cur != token) {
   7458                     return;
   7459                 }
   7460                 mForegroundProcesses.remove(token.pid);
   7461                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
   7462                 if (pr == null) {
   7463                     return;
   7464                 }
   7465                 pr.forcingToForeground = null;
   7466                 updateProcessForegroundLocked(pr, false, false);
   7467             }
   7468             updateOomAdjLocked();
   7469         }
   7470     }
   7471 
   7472     @Override
   7473     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
   7474         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   7475                 "setProcessForeground()");
   7476         synchronized(this) {
   7477             boolean changed = false;
   7478 
   7479             synchronized (mPidsSelfLocked) {
   7480                 ProcessRecord pr = mPidsSelfLocked.get(pid);
   7481                 if (pr == null && isForeground) {
   7482                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
   7483                     return;
   7484                 }
   7485                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
   7486                 if (oldToken != null) {
   7487                     oldToken.token.unlinkToDeath(oldToken, 0);
   7488                     mForegroundProcesses.remove(pid);
   7489                     if (pr != null) {
   7490                         pr.forcingToForeground = null;
   7491                     }
   7492                     changed = true;
   7493                 }
   7494                 if (isForeground && token != null) {
   7495                     ForegroundToken newToken = new ForegroundToken() {
   7496                         @Override
   7497                         public void binderDied() {
   7498                             foregroundTokenDied(this);
   7499                         }
   7500                     };
   7501                     newToken.pid = pid;
   7502                     newToken.token = token;
   7503                     try {
   7504                         token.linkToDeath(newToken, 0);
   7505                         mForegroundProcesses.put(pid, newToken);
   7506                         pr.forcingToForeground = token;
   7507                         changed = true;
   7508                     } catch (RemoteException e) {
   7509                         // If the process died while doing this, we will later
   7510                         // do the cleanup with the process death link.
   7511                     }
   7512                 }
   7513             }
   7514 
   7515             if (changed) {
   7516                 updateOomAdjLocked();
   7517             }
   7518         }
   7519     }
   7520 
   7521     @Override
   7522     public boolean isAppForeground(int uid) throws RemoteException {
   7523         synchronized (this) {
   7524             UidRecord uidRec = mActiveUids.get(uid);
   7525             if (uidRec == null || uidRec.idle) {
   7526                 return false;
   7527             }
   7528             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   7529         }
   7530     }
   7531 
   7532     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
   7533     // be guarded by permission checking.
   7534     int getUidState(int uid) {
   7535         synchronized (this) {
   7536             UidRecord uidRec = mActiveUids.get(uid);
   7537             return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
   7538         }
   7539     }
   7540 
   7541     @Override
   7542     public boolean isInMultiWindowMode(IBinder token) {
   7543         final long origId = Binder.clearCallingIdentity();
   7544         try {
   7545             synchronized(this) {
   7546                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   7547                 if (r == null) {
   7548                     return false;
   7549                 }
   7550                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
   7551                 return !r.task.mFullscreen;
   7552             }
   7553         } finally {
   7554             Binder.restoreCallingIdentity(origId);
   7555         }
   7556     }
   7557 
   7558     @Override
   7559     public boolean isInPictureInPictureMode(IBinder token) {
   7560         final long origId = Binder.clearCallingIdentity();
   7561         try {
   7562             synchronized(this) {
   7563                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
   7564                 if (stack == null) {
   7565                     return false;
   7566                 }
   7567                 return stack.mStackId == PINNED_STACK_ID;
   7568             }
   7569         } finally {
   7570             Binder.restoreCallingIdentity(origId);
   7571         }
   7572     }
   7573 
   7574     @Override
   7575     public void enterPictureInPictureMode(IBinder token) {
   7576         final long origId = Binder.clearCallingIdentity();
   7577         try {
   7578             synchronized(this) {
   7579                 if (!mSupportsPictureInPicture) {
   7580                     throw new IllegalStateException("enterPictureInPictureMode: "
   7581                             + "Device doesn't support picture-in-picture mode.");
   7582                 }
   7583 
   7584                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   7585 
   7586                 if (r == null) {
   7587                     throw new IllegalStateException("enterPictureInPictureMode: "
   7588                             + "Can't find activity for token=" + token);
   7589                 }
   7590 
   7591                 if (!r.supportsPictureInPicture()) {
   7592                     throw new IllegalArgumentException("enterPictureInPictureMode: "
   7593                             + "Picture-In-Picture not supported for r=" + r);
   7594                 }
   7595 
   7596                 // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
   7597                 // current bounds.
   7598                 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
   7599                 final Rect bounds = (pinnedStack != null)
   7600                         ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
   7601 
   7602                 mStackSupervisor.moveActivityToPinnedStackLocked(
   7603                         r, "enterPictureInPictureMode", bounds);
   7604             }
   7605         } finally {
   7606             Binder.restoreCallingIdentity(origId);
   7607         }
   7608     }
   7609 
   7610     // =========================================================
   7611     // PROCESS INFO
   7612     // =========================================================
   7613 
   7614     static class ProcessInfoService extends IProcessInfoService.Stub {
   7615         final ActivityManagerService mActivityManagerService;
   7616         ProcessInfoService(ActivityManagerService activityManagerService) {
   7617             mActivityManagerService = activityManagerService;
   7618         }
   7619 
   7620         @Override
   7621         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
   7622             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
   7623                     /*in*/ pids, /*out*/ states, null);
   7624         }
   7625 
   7626         @Override
   7627         public void getProcessStatesAndOomScoresFromPids(
   7628                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
   7629             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
   7630                     /*in*/ pids, /*out*/ states, /*out*/ scores);
   7631         }
   7632     }
   7633 
   7634     /**
   7635      * For each PID in the given input array, write the current process state
   7636      * for that process into the states array, or -1 to indicate that no
   7637      * process with the given PID exists. If scores array is provided, write
   7638      * the oom score for the process into the scores array, with INVALID_ADJ
   7639      * indicating the PID doesn't exist.
   7640      */
   7641     public void getProcessStatesAndOomScoresForPIDs(
   7642             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
   7643         if (scores != null) {
   7644             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
   7645                     "getProcessStatesAndOomScoresForPIDs()");
   7646         }
   7647 
   7648         if (pids == null) {
   7649             throw new NullPointerException("pids");
   7650         } else if (states == null) {
   7651             throw new NullPointerException("states");
   7652         } else if (pids.length != states.length) {
   7653             throw new IllegalArgumentException("pids and states arrays have different lengths!");
   7654         } else if (scores != null && pids.length != scores.length) {
   7655             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
   7656         }
   7657 
   7658         synchronized (mPidsSelfLocked) {
   7659             for (int i = 0; i < pids.length; i++) {
   7660                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
   7661                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
   7662                         pr.curProcState;
   7663                 if (scores != null) {
   7664                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
   7665                 }
   7666             }
   7667         }
   7668     }
   7669 
   7670     // =========================================================
   7671     // PERMISSIONS
   7672     // =========================================================
   7673 
   7674     static class PermissionController extends IPermissionController.Stub {
   7675         ActivityManagerService mActivityManagerService;
   7676         PermissionController(ActivityManagerService activityManagerService) {
   7677             mActivityManagerService = activityManagerService;
   7678         }
   7679 
   7680         @Override
   7681         public boolean checkPermission(String permission, int pid, int uid) {
   7682             return mActivityManagerService.checkPermission(permission, pid,
   7683                     uid) == PackageManager.PERMISSION_GRANTED;
   7684         }
   7685 
   7686         @Override
   7687         public String[] getPackagesForUid(int uid) {
   7688             return mActivityManagerService.mContext.getPackageManager()
   7689                     .getPackagesForUid(uid);
   7690         }
   7691 
   7692         @Override
   7693         public boolean isRuntimePermission(String permission) {
   7694             try {
   7695                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
   7696                         .getPermissionInfo(permission, 0);
   7697                 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
   7698             } catch (NameNotFoundException nnfe) {
   7699                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
   7700             }
   7701             return false;
   7702         }
   7703     }
   7704 
   7705     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
   7706         @Override
   7707         public int checkComponentPermission(String permission, int pid, int uid,
   7708                 int owningUid, boolean exported) {
   7709             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
   7710                     owningUid, exported);
   7711         }
   7712 
   7713         @Override
   7714         public Object getAMSLock() {
   7715             return ActivityManagerService.this;
   7716         }
   7717     }
   7718 
   7719     /**
   7720      * This can be called with or without the global lock held.
   7721      */
   7722     int checkComponentPermission(String permission, int pid, int uid,
   7723             int owningUid, boolean exported) {
   7724         if (pid == MY_PID) {
   7725             return PackageManager.PERMISSION_GRANTED;
   7726         }
   7727         return ActivityManager.checkComponentPermission(permission, uid,
   7728                 owningUid, exported);
   7729     }
   7730 
   7731     /**
   7732      * As the only public entry point for permissions checking, this method
   7733      * can enforce the semantic that requesting a check on a null global
   7734      * permission is automatically denied.  (Internally a null permission
   7735      * string is used when calling {@link #checkComponentPermission} in cases
   7736      * when only uid-based security is needed.)
   7737      *
   7738      * This can be called with or without the global lock held.
   7739      */
   7740     @Override
   7741     public int checkPermission(String permission, int pid, int uid) {
   7742         if (permission == null) {
   7743             return PackageManager.PERMISSION_DENIED;
   7744         }
   7745         return checkComponentPermission(permission, pid, uid, -1, true);
   7746     }
   7747 
   7748     @Override
   7749     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
   7750         if (permission == null) {
   7751             return PackageManager.PERMISSION_DENIED;
   7752         }
   7753 
   7754         // We might be performing an operation on behalf of an indirect binder
   7755         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
   7756         // client identity accordingly before proceeding.
   7757         Identity tlsIdentity = sCallerIdentity.get();
   7758         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
   7759             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
   7760                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
   7761             uid = tlsIdentity.uid;
   7762             pid = tlsIdentity.pid;
   7763         }
   7764 
   7765         return checkComponentPermission(permission, pid, uid, -1, true);
   7766     }
   7767 
   7768     /**
   7769      * Binder IPC calls go through the public entry point.
   7770      * This can be called with or without the global lock held.
   7771      */
   7772     int checkCallingPermission(String permission) {
   7773         return checkPermission(permission,
   7774                 Binder.getCallingPid(),
   7775                 UserHandle.getAppId(Binder.getCallingUid()));
   7776     }
   7777 
   7778     /**
   7779      * This can be called with or without the global lock held.
   7780      */
   7781     void enforceCallingPermission(String permission, String func) {
   7782         if (checkCallingPermission(permission)
   7783                 == PackageManager.PERMISSION_GRANTED) {
   7784             return;
   7785         }
   7786 
   7787         String msg = "Permission Denial: " + func + " from pid="
   7788                 + Binder.getCallingPid()
   7789                 + ", uid=" + Binder.getCallingUid()
   7790                 + " requires " + permission;
   7791         Slog.w(TAG, msg);
   7792         throw new SecurityException(msg);
   7793     }
   7794 
   7795     /**
   7796      * Determine if UID is holding permissions required to access {@link Uri} in
   7797      * the given {@link ProviderInfo}. Final permission checking is always done
   7798      * in {@link ContentProvider}.
   7799      */
   7800     private final boolean checkHoldingPermissionsLocked(
   7801             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
   7802         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   7803                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
   7804         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
   7805             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
   7806                     != PERMISSION_GRANTED) {
   7807                 return false;
   7808             }
   7809         }
   7810         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
   7811     }
   7812 
   7813     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
   7814             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
   7815         if (pi.applicationInfo.uid == uid) {
   7816             return true;
   7817         } else if (!pi.exported) {
   7818             return false;
   7819         }
   7820 
   7821         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
   7822         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
   7823         try {
   7824             // check if target holds top-level <provider> permissions
   7825             if (!readMet && pi.readPermission != null && considerUidPermissions
   7826                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
   7827                 readMet = true;
   7828             }
   7829             if (!writeMet && pi.writePermission != null && considerUidPermissions
   7830                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
   7831                 writeMet = true;
   7832             }
   7833 
   7834             // track if unprotected read/write is allowed; any denied
   7835             // <path-permission> below removes this ability
   7836             boolean allowDefaultRead = pi.readPermission == null;
   7837             boolean allowDefaultWrite = pi.writePermission == null;
   7838 
   7839             // check if target holds any <path-permission> that match uri
   7840             final PathPermission[] pps = pi.pathPermissions;
   7841             if (pps != null) {
   7842                 final String path = grantUri.uri.getPath();
   7843                 int i = pps.length;
   7844                 while (i > 0 && (!readMet || !writeMet)) {
   7845                     i--;
   7846                     PathPermission pp = pps[i];
   7847                     if (pp.match(path)) {
   7848                         if (!readMet) {
   7849                             final String pprperm = pp.getReadPermission();
   7850                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   7851                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
   7852                                     + ": match=" + pp.match(path)
   7853                                     + " check=" + pm.checkUidPermission(pprperm, uid));
   7854                             if (pprperm != null) {
   7855                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
   7856                                         == PERMISSION_GRANTED) {
   7857                                     readMet = true;
   7858                                 } else {
   7859                                     allowDefaultRead = false;
   7860                                 }
   7861                             }
   7862                         }
   7863                         if (!writeMet) {
   7864                             final String ppwperm = pp.getWritePermission();
   7865                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   7866                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
   7867                                     + ": match=" + pp.match(path)
   7868                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
   7869                             if (ppwperm != null) {
   7870                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
   7871                                         == PERMISSION_GRANTED) {
   7872                                     writeMet = true;
   7873                                 } else {
   7874                                     allowDefaultWrite = false;
   7875                                 }
   7876                             }
   7877                         }
   7878                     }
   7879                 }
   7880             }
   7881 
   7882             // grant unprotected <provider> read/write, if not blocked by
   7883             // <path-permission> above
   7884             if (allowDefaultRead) readMet = true;
   7885             if (allowDefaultWrite) writeMet = true;
   7886 
   7887         } catch (RemoteException e) {
   7888             return false;
   7889         }
   7890 
   7891         return readMet && writeMet;
   7892     }
   7893 
   7894     public int getAppStartMode(int uid, String packageName) {
   7895         synchronized (this) {
   7896             return checkAllowBackgroundLocked(uid, packageName, -1, true);
   7897         }
   7898     }
   7899 
   7900     int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
   7901             boolean allowWhenForeground) {
   7902         UidRecord uidRec = mActiveUids.get(uid);
   7903         if (!mLenientBackgroundCheck) {
   7904             if (!allowWhenForeground || uidRec == null
   7905                     || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   7906                 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
   7907                         packageName) != AppOpsManager.MODE_ALLOWED) {
   7908                     return ActivityManager.APP_START_MODE_DELAYED;
   7909                 }
   7910             }
   7911 
   7912         } else if (uidRec == null || uidRec.idle) {
   7913             if (callingPid >= 0) {
   7914                 ProcessRecord proc;
   7915                 synchronized (mPidsSelfLocked) {
   7916                     proc = mPidsSelfLocked.get(callingPid);
   7917                 }
   7918                 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
   7919                     // Whoever is instigating this is in the foreground, so we will allow it
   7920                     // to go through.
   7921                     return ActivityManager.APP_START_MODE_NORMAL;
   7922                 }
   7923             }
   7924             if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
   7925                     != AppOpsManager.MODE_ALLOWED) {
   7926                 return ActivityManager.APP_START_MODE_DELAYED;
   7927             }
   7928         }
   7929         return ActivityManager.APP_START_MODE_NORMAL;
   7930     }
   7931 
   7932     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
   7933         ProviderInfo pi = null;
   7934         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
   7935         if (cpr != null) {
   7936             pi = cpr.info;
   7937         } else {
   7938             try {
   7939                 pi = AppGlobals.getPackageManager().resolveContentProvider(
   7940                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
   7941                         userHandle);
   7942             } catch (RemoteException ex) {
   7943             }
   7944         }
   7945         return pi;
   7946     }
   7947 
   7948     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
   7949         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
   7950         if (targetUris != null) {
   7951             return targetUris.get(grantUri);
   7952         }
   7953         return null;
   7954     }
   7955 
   7956     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
   7957             String targetPkg, int targetUid, GrantUri grantUri) {
   7958         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
   7959         if (targetUris == null) {
   7960             targetUris = Maps.newArrayMap();
   7961             mGrantedUriPermissions.put(targetUid, targetUris);
   7962         }
   7963 
   7964         UriPermission perm = targetUris.get(grantUri);
   7965         if (perm == null) {
   7966             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
   7967             targetUris.put(grantUri, perm);
   7968         }
   7969 
   7970         return perm;
   7971     }
   7972 
   7973     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
   7974             final int modeFlags) {
   7975         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
   7976         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
   7977                 : UriPermission.STRENGTH_OWNED;
   7978 
   7979         // Root gets to do everything.
   7980         if (uid == 0) {
   7981             return true;
   7982         }
   7983 
   7984         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   7985         if (perms == null) return false;
   7986 
   7987         // First look for exact match
   7988         final UriPermission exactPerm = perms.get(grantUri);
   7989         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
   7990             return true;
   7991         }
   7992 
   7993         // No exact match, look for prefixes
   7994         final int N = perms.size();
   7995         for (int i = 0; i < N; i++) {
   7996             final UriPermission perm = perms.valueAt(i);
   7997             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
   7998                     && perm.getStrength(modeFlags) >= minStrength) {
   7999                 return true;
   8000             }
   8001         }
   8002 
   8003         return false;
   8004     }
   8005 
   8006     /**
   8007      * @param uri This uri must NOT contain an embedded userId.
   8008      * @param userId The userId in which the uri is to be resolved.
   8009      */
   8010     @Override
   8011     public int checkUriPermission(Uri uri, int pid, int uid,
   8012             final int modeFlags, int userId, IBinder callerToken) {
   8013         enforceNotIsolatedCaller("checkUriPermission");
   8014 
   8015         // Another redirected-binder-call permissions check as in
   8016         // {@link checkPermissionWithToken}.
   8017         Identity tlsIdentity = sCallerIdentity.get();
   8018         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
   8019             uid = tlsIdentity.uid;
   8020             pid = tlsIdentity.pid;
   8021         }
   8022 
   8023         // Our own process gets to do everything.
   8024         if (pid == MY_PID) {
   8025             return PackageManager.PERMISSION_GRANTED;
   8026         }
   8027         synchronized (this) {
   8028             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
   8029                     ? PackageManager.PERMISSION_GRANTED
   8030                     : PackageManager.PERMISSION_DENIED;
   8031         }
   8032     }
   8033 
   8034     /**
   8035      * Check if the targetPkg can be granted permission to access uri by
   8036      * the callingUid using the given modeFlags.  Throws a security exception
   8037      * if callingUid is not allowed to do this.  Returns the uid of the target
   8038      * if the URI permission grant should be performed; returns -1 if it is not
   8039      * needed (for example targetPkg already has permission to access the URI).
   8040      * If you already know the uid of the target, you can supply it in
   8041      * lastTargetUid else set that to -1.
   8042      */
   8043     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
   8044             final int modeFlags, int lastTargetUid) {
   8045         if (!Intent.isAccessUriMode(modeFlags)) {
   8046             return -1;
   8047         }
   8048 
   8049         if (targetPkg != null) {
   8050             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8051                     "Checking grant " + targetPkg + " permission to " + grantUri);
   8052         }
   8053 
   8054         final IPackageManager pm = AppGlobals.getPackageManager();
   8055 
   8056         // If this is not a content: uri, we can't do anything with it.
   8057         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
   8058             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8059                     "Can't grant URI permission for non-content URI: " + grantUri);
   8060             return -1;
   8061         }
   8062 
   8063         final String authority = grantUri.uri.getAuthority();
   8064         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
   8065                 MATCH_DEBUG_TRIAGED_MISSING);
   8066         if (pi == null) {
   8067             Slog.w(TAG, "No content provider found for permission check: " +
   8068                     grantUri.uri.toSafeString());
   8069             return -1;
   8070         }
   8071 
   8072         int targetUid = lastTargetUid;
   8073         if (targetUid < 0 && targetPkg != null) {
   8074             try {
   8075                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
   8076                         UserHandle.getUserId(callingUid));
   8077                 if (targetUid < 0) {
   8078                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8079                             "Can't grant URI permission no uid for: " + targetPkg);
   8080                     return -1;
   8081                 }
   8082             } catch (RemoteException ex) {
   8083                 return -1;
   8084             }
   8085         }
   8086 
   8087         if (targetUid >= 0) {
   8088             // First...  does the target actually need this permission?
   8089             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
   8090                 // No need to grant the target this permission.
   8091                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8092                         "Target " + targetPkg + " already has full permission to " + grantUri);
   8093                 return -1;
   8094             }
   8095         } else {
   8096             // First...  there is no target package, so can anyone access it?
   8097             boolean allowed = pi.exported;
   8098             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   8099                 if (pi.readPermission != null) {
   8100                     allowed = false;
   8101                 }
   8102             }
   8103             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   8104                 if (pi.writePermission != null) {
   8105                     allowed = false;
   8106                 }
   8107             }
   8108             if (allowed) {
   8109                 return -1;
   8110             }
   8111         }
   8112 
   8113         /* There is a special cross user grant if:
   8114          * - The target is on another user.
   8115          * - Apps on the current user can access the uri without any uid permissions.
   8116          * In this case, we grant a uri permission, even if the ContentProvider does not normally
   8117          * grant uri permissions.
   8118          */
   8119         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
   8120                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
   8121                 modeFlags, false /*without considering the uid permissions*/);
   8122 
   8123         // Second...  is the provider allowing granting of URI permissions?
   8124         if (!specialCrossUserGrant) {
   8125             if (!pi.grantUriPermissions) {
   8126                 throw new SecurityException("Provider " + pi.packageName
   8127                         + "/" + pi.name
   8128                         + " does not allow granting of Uri permissions (uri "
   8129                         + grantUri + ")");
   8130             }
   8131             if (pi.uriPermissionPatterns != null) {
   8132                 final int N = pi.uriPermissionPatterns.length;
   8133                 boolean allowed = false;
   8134                 for (int i=0; i<N; i++) {
   8135                     if (pi.uriPermissionPatterns[i] != null
   8136                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
   8137                         allowed = true;
   8138                         break;
   8139                     }
   8140                 }
   8141                 if (!allowed) {
   8142                     throw new SecurityException("Provider " + pi.packageName
   8143                             + "/" + pi.name
   8144                             + " does not allow granting of permission to path of Uri "
   8145                             + grantUri);
   8146                 }
   8147             }
   8148         }
   8149 
   8150         // Third...  does the caller itself have permission to access
   8151         // this uri?
   8152         if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
   8153             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
   8154                 // Require they hold a strong enough Uri permission
   8155                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
   8156                     throw new SecurityException("Uid " + callingUid
   8157                             + " does not have permission to uri " + grantUri);
   8158                 }
   8159             }
   8160         }
   8161         return targetUid;
   8162     }
   8163 
   8164     /**
   8165      * @param uri This uri must NOT contain an embedded userId.
   8166      * @param userId The userId in which the uri is to be resolved.
   8167      */
   8168     @Override
   8169     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
   8170             final int modeFlags, int userId) {
   8171         enforceNotIsolatedCaller("checkGrantUriPermission");
   8172         synchronized(this) {
   8173             return checkGrantUriPermissionLocked(callingUid, targetPkg,
   8174                     new GrantUri(userId, uri, false), modeFlags, -1);
   8175         }
   8176     }
   8177 
   8178     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
   8179             final int modeFlags, UriPermissionOwner owner) {
   8180         if (!Intent.isAccessUriMode(modeFlags)) {
   8181             return;
   8182         }
   8183 
   8184         // So here we are: the caller has the assumed permission
   8185         // to the uri, and the target doesn't.  Let's now give this to
   8186         // the target.
   8187 
   8188         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8189                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
   8190 
   8191         final String authority = grantUri.uri.getAuthority();
   8192         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
   8193                 MATCH_DEBUG_TRIAGED_MISSING);
   8194         if (pi == null) {
   8195             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
   8196             return;
   8197         }
   8198 
   8199         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
   8200             grantUri.prefix = true;
   8201         }
   8202         final UriPermission perm = findOrCreateUriPermissionLocked(
   8203                 pi.packageName, targetPkg, targetUid, grantUri);
   8204         perm.grantModes(modeFlags, owner);
   8205     }
   8206 
   8207     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
   8208             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
   8209         if (targetPkg == null) {
   8210             throw new NullPointerException("targetPkg");
   8211         }
   8212         int targetUid;
   8213         final IPackageManager pm = AppGlobals.getPackageManager();
   8214         try {
   8215             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
   8216         } catch (RemoteException ex) {
   8217             return;
   8218         }
   8219 
   8220         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
   8221                 targetUid);
   8222         if (targetUid < 0) {
   8223             return;
   8224         }
   8225 
   8226         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
   8227                 owner);
   8228     }
   8229 
   8230     static class NeededUriGrants extends ArrayList<GrantUri> {
   8231         final String targetPkg;
   8232         final int targetUid;
   8233         final int flags;
   8234 
   8235         NeededUriGrants(String targetPkg, int targetUid, int flags) {
   8236             this.targetPkg = targetPkg;
   8237             this.targetUid = targetUid;
   8238             this.flags = flags;
   8239         }
   8240     }
   8241 
   8242     /**
   8243      * Like checkGrantUriPermissionLocked, but takes an Intent.
   8244      */
   8245     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
   8246             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
   8247         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8248                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
   8249                 + " clip=" + (intent != null ? intent.getClipData() : null)
   8250                 + " from " + intent + "; flags=0x"
   8251                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
   8252 
   8253         if (targetPkg == null) {
   8254             throw new NullPointerException("targetPkg");
   8255         }
   8256 
   8257         if (intent == null) {
   8258             return null;
   8259         }
   8260         Uri data = intent.getData();
   8261         ClipData clip = intent.getClipData();
   8262         if (data == null && clip == null) {
   8263             return null;
   8264         }
   8265         // Default userId for uris in the intent (if they don't specify it themselves)
   8266         int contentUserHint = intent.getContentUserHint();
   8267         if (contentUserHint == UserHandle.USER_CURRENT) {
   8268             contentUserHint = UserHandle.getUserId(callingUid);
   8269         }
   8270         final IPackageManager pm = AppGlobals.getPackageManager();
   8271         int targetUid;
   8272         if (needed != null) {
   8273             targetUid = needed.targetUid;
   8274         } else {
   8275             try {
   8276                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
   8277                         targetUserId);
   8278             } catch (RemoteException ex) {
   8279                 return null;
   8280             }
   8281             if (targetUid < 0) {
   8282                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8283                         "Can't grant URI permission no uid for: " + targetPkg
   8284                         + " on user " + targetUserId);
   8285                 return null;
   8286             }
   8287         }
   8288         if (data != null) {
   8289             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
   8290             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
   8291                     targetUid);
   8292             if (targetUid > 0) {
   8293                 if (needed == null) {
   8294                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
   8295                 }
   8296                 needed.add(grantUri);
   8297             }
   8298         }
   8299         if (clip != null) {
   8300             for (int i=0; i<clip.getItemCount(); i++) {
   8301                 Uri uri = clip.getItemAt(i).getUri();
   8302                 if (uri != null) {
   8303                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
   8304                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
   8305                             targetUid);
   8306                     if (targetUid > 0) {
   8307                         if (needed == null) {
   8308                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
   8309                         }
   8310                         needed.add(grantUri);
   8311                     }
   8312                 } else {
   8313                     Intent clipIntent = clip.getItemAt(i).getIntent();
   8314                     if (clipIntent != null) {
   8315                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
   8316                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
   8317                         if (newNeeded != null) {
   8318                             needed = newNeeded;
   8319                         }
   8320                     }
   8321                 }
   8322             }
   8323         }
   8324 
   8325         return needed;
   8326     }
   8327 
   8328     /**
   8329      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
   8330      */
   8331     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
   8332             UriPermissionOwner owner) {
   8333         if (needed != null) {
   8334             for (int i=0; i<needed.size(); i++) {
   8335                 GrantUri grantUri = needed.get(i);
   8336                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
   8337                         grantUri, needed.flags, owner);
   8338             }
   8339         }
   8340     }
   8341 
   8342     void grantUriPermissionFromIntentLocked(int callingUid,
   8343             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
   8344         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
   8345                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
   8346         if (needed == null) {
   8347             return;
   8348         }
   8349 
   8350         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
   8351     }
   8352 
   8353     /**
   8354      * @param uri This uri must NOT contain an embedded userId.
   8355      * @param userId The userId in which the uri is to be resolved.
   8356      */
   8357     @Override
   8358     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
   8359             final int modeFlags, int userId) {
   8360         enforceNotIsolatedCaller("grantUriPermission");
   8361         GrantUri grantUri = new GrantUri(userId, uri, false);
   8362         synchronized(this) {
   8363             final ProcessRecord r = getRecordForAppLocked(caller);
   8364             if (r == null) {
   8365                 throw new SecurityException("Unable to find app for caller "
   8366                         + caller
   8367                         + " when granting permission to uri " + grantUri);
   8368             }
   8369             if (targetPkg == null) {
   8370                 throw new IllegalArgumentException("null target");
   8371             }
   8372             if (grantUri == null) {
   8373                 throw new IllegalArgumentException("null uri");
   8374             }
   8375 
   8376             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
   8377                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
   8378                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
   8379                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
   8380 
   8381             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
   8382                     UserHandle.getUserId(r.uid));
   8383         }
   8384     }
   8385 
   8386     void removeUriPermissionIfNeededLocked(UriPermission perm) {
   8387         if (perm.modeFlags == 0) {
   8388             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
   8389                     perm.targetUid);
   8390             if (perms != null) {
   8391                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8392                         "Removing " + perm.targetUid + " permission to " + perm.uri);
   8393 
   8394                 perms.remove(perm.uri);
   8395                 if (perms.isEmpty()) {
   8396                     mGrantedUriPermissions.remove(perm.targetUid);
   8397                 }
   8398             }
   8399         }
   8400     }
   8401 
   8402     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
   8403         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8404                 "Revoking all granted permissions to " + grantUri);
   8405 
   8406         final IPackageManager pm = AppGlobals.getPackageManager();
   8407         final String authority = grantUri.uri.getAuthority();
   8408         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
   8409                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
   8410         if (pi == null) {
   8411             Slog.w(TAG, "No content provider found for permission revoke: "
   8412                     + grantUri.toSafeString());
   8413             return;
   8414         }
   8415 
   8416         // Does the caller have this permission on the URI?
   8417         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
   8418             // If they don't have direct access to the URI, then revoke any
   8419             // ownerless URI permissions that have been granted to them.
   8420             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   8421             if (perms != null) {
   8422                 boolean persistChanged = false;
   8423                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
   8424                     final UriPermission perm = it.next();
   8425                     if (perm.uri.sourceUserId == grantUri.sourceUserId
   8426                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
   8427                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8428                                 "Revoking non-owned " + perm.targetUid
   8429                                 + " permission to " + perm.uri);
   8430                         persistChanged |= perm.revokeModes(
   8431                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
   8432                         if (perm.modeFlags == 0) {
   8433                             it.remove();
   8434                         }
   8435                     }
   8436                 }
   8437                 if (perms.isEmpty()) {
   8438                     mGrantedUriPermissions.remove(callingUid);
   8439                 }
   8440                 if (persistChanged) {
   8441                     schedulePersistUriGrants();
   8442                 }
   8443             }
   8444             return;
   8445         }
   8446 
   8447         boolean persistChanged = false;
   8448 
   8449         // Go through all of the permissions and remove any that match.
   8450         int N = mGrantedUriPermissions.size();
   8451         for (int i = 0; i < N; i++) {
   8452             final int targetUid = mGrantedUriPermissions.keyAt(i);
   8453             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   8454 
   8455             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
   8456                 final UriPermission perm = it.next();
   8457                 if (perm.uri.sourceUserId == grantUri.sourceUserId
   8458                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
   8459                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8460                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
   8461                     persistChanged |= perm.revokeModes(
   8462                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
   8463                     if (perm.modeFlags == 0) {
   8464                         it.remove();
   8465                     }
   8466                 }
   8467             }
   8468 
   8469             if (perms.isEmpty()) {
   8470                 mGrantedUriPermissions.remove(targetUid);
   8471                 N--;
   8472                 i--;
   8473             }
   8474         }
   8475 
   8476         if (persistChanged) {
   8477             schedulePersistUriGrants();
   8478         }
   8479     }
   8480 
   8481     /**
   8482      * @param uri This uri must NOT contain an embedded userId.
   8483      * @param userId The userId in which the uri is to be resolved.
   8484      */
   8485     @Override
   8486     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
   8487             int userId) {
   8488         enforceNotIsolatedCaller("revokeUriPermission");
   8489         synchronized(this) {
   8490             final ProcessRecord r = getRecordForAppLocked(caller);
   8491             if (r == null) {
   8492                 throw new SecurityException("Unable to find app for caller "
   8493                         + caller
   8494                         + " when revoking permission to uri " + uri);
   8495             }
   8496             if (uri == null) {
   8497                 Slog.w(TAG, "revokeUriPermission: null uri");
   8498                 return;
   8499             }
   8500 
   8501             if (!Intent.isAccessUriMode(modeFlags)) {
   8502                 return;
   8503             }
   8504 
   8505             final String authority = uri.getAuthority();
   8506             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
   8507                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
   8508             if (pi == null) {
   8509                 Slog.w(TAG, "No content provider found for permission revoke: "
   8510                         + uri.toSafeString());
   8511                 return;
   8512             }
   8513 
   8514             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
   8515         }
   8516     }
   8517 
   8518     /**
   8519      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
   8520      * given package.
   8521      *
   8522      * @param packageName Package name to match, or {@code null} to apply to all
   8523      *            packages.
   8524      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
   8525      *            to all users.
   8526      * @param persistable If persistable grants should be removed.
   8527      */
   8528     private void removeUriPermissionsForPackageLocked(
   8529             String packageName, int userHandle, boolean persistable) {
   8530         if (userHandle == UserHandle.USER_ALL && packageName == null) {
   8531             throw new IllegalArgumentException("Must narrow by either package or user");
   8532         }
   8533 
   8534         boolean persistChanged = false;
   8535 
   8536         int N = mGrantedUriPermissions.size();
   8537         for (int i = 0; i < N; i++) {
   8538             final int targetUid = mGrantedUriPermissions.keyAt(i);
   8539             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   8540 
   8541             // Only inspect grants matching user
   8542             if (userHandle == UserHandle.USER_ALL
   8543                     || userHandle == UserHandle.getUserId(targetUid)) {
   8544                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
   8545                     final UriPermission perm = it.next();
   8546 
   8547                     // Only inspect grants matching package
   8548                     if (packageName == null || perm.sourcePkg.equals(packageName)
   8549                             || perm.targetPkg.equals(packageName)) {
   8550                         persistChanged |= perm.revokeModes(persistable
   8551                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
   8552 
   8553                         // Only remove when no modes remain; any persisted grants
   8554                         // will keep this alive.
   8555                         if (perm.modeFlags == 0) {
   8556                             it.remove();
   8557                         }
   8558                     }
   8559                 }
   8560 
   8561                 if (perms.isEmpty()) {
   8562                     mGrantedUriPermissions.remove(targetUid);
   8563                     N--;
   8564                     i--;
   8565                 }
   8566             }
   8567         }
   8568 
   8569         if (persistChanged) {
   8570             schedulePersistUriGrants();
   8571         }
   8572     }
   8573 
   8574     @Override
   8575     public IBinder newUriPermissionOwner(String name) {
   8576         enforceNotIsolatedCaller("newUriPermissionOwner");
   8577         synchronized(this) {
   8578             UriPermissionOwner owner = new UriPermissionOwner(this, name);
   8579             return owner.getExternalTokenLocked();
   8580         }
   8581     }
   8582 
   8583     @Override
   8584     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
   8585         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
   8586         synchronized(this) {
   8587             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
   8588             if (r == null) {
   8589                 throw new IllegalArgumentException("Activity does not exist; token="
   8590                         + activityToken);
   8591             }
   8592             return r.getUriPermissionsLocked().getExternalTokenLocked();
   8593         }
   8594     }
   8595     /**
   8596      * @param uri This uri must NOT contain an embedded userId.
   8597      * @param sourceUserId The userId in which the uri is to be resolved.
   8598      * @param targetUserId The userId of the app that receives the grant.
   8599      */
   8600     @Override
   8601     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
   8602             final int modeFlags, int sourceUserId, int targetUserId) {
   8603         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
   8604                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
   8605                 "grantUriPermissionFromOwner", null);
   8606         synchronized(this) {
   8607             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   8608             if (owner == null) {
   8609                 throw new IllegalArgumentException("Unknown owner: " + token);
   8610             }
   8611             if (fromUid != Binder.getCallingUid()) {
   8612                 if (Binder.getCallingUid() != Process.myUid()) {
   8613                     // Only system code can grant URI permissions on behalf
   8614                     // of other users.
   8615                     throw new SecurityException("nice try");
   8616                 }
   8617             }
   8618             if (targetPkg == null) {
   8619                 throw new IllegalArgumentException("null target");
   8620             }
   8621             if (uri == null) {
   8622                 throw new IllegalArgumentException("null uri");
   8623             }
   8624 
   8625             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
   8626                     modeFlags, owner, targetUserId);
   8627         }
   8628     }
   8629 
   8630     /**
   8631      * @param uri This uri must NOT contain an embedded userId.
   8632      * @param userId The userId in which the uri is to be resolved.
   8633      */
   8634     @Override
   8635     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
   8636         synchronized(this) {
   8637             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   8638             if (owner == null) {
   8639                 throw new IllegalArgumentException("Unknown owner: " + token);
   8640             }
   8641 
   8642             if (uri == null) {
   8643                 owner.removeUriPermissionsLocked(mode);
   8644             } else {
   8645                 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
   8646                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
   8647             }
   8648         }
   8649     }
   8650 
   8651     private void schedulePersistUriGrants() {
   8652         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
   8653             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
   8654                     10 * DateUtils.SECOND_IN_MILLIS);
   8655         }
   8656     }
   8657 
   8658     private void writeGrantedUriPermissions() {
   8659         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
   8660 
   8661         // Snapshot permissions so we can persist without lock
   8662         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
   8663         synchronized (this) {
   8664             final int size = mGrantedUriPermissions.size();
   8665             for (int i = 0; i < size; i++) {
   8666                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   8667                 for (UriPermission perm : perms.values()) {
   8668                     if (perm.persistedModeFlags != 0) {
   8669                         persist.add(perm.snapshot());
   8670                     }
   8671                 }
   8672             }
   8673         }
   8674 
   8675         FileOutputStream fos = null;
   8676         try {
   8677             fos = mGrantFile.startWrite();
   8678 
   8679             XmlSerializer out = new FastXmlSerializer();
   8680             out.setOutput(fos, StandardCharsets.UTF_8.name());
   8681             out.startDocument(null, true);
   8682             out.startTag(null, TAG_URI_GRANTS);
   8683             for (UriPermission.Snapshot perm : persist) {
   8684                 out.startTag(null, TAG_URI_GRANT);
   8685                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
   8686                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
   8687                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
   8688                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
   8689                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
   8690                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
   8691                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
   8692                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
   8693                 out.endTag(null, TAG_URI_GRANT);
   8694             }
   8695             out.endTag(null, TAG_URI_GRANTS);
   8696             out.endDocument();
   8697 
   8698             mGrantFile.finishWrite(fos);
   8699         } catch (IOException e) {
   8700             if (fos != null) {
   8701                 mGrantFile.failWrite(fos);
   8702             }
   8703         }
   8704     }
   8705 
   8706     private void readGrantedUriPermissionsLocked() {
   8707         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
   8708 
   8709         final long now = System.currentTimeMillis();
   8710 
   8711         FileInputStream fis = null;
   8712         try {
   8713             fis = mGrantFile.openRead();
   8714             final XmlPullParser in = Xml.newPullParser();
   8715             in.setInput(fis, StandardCharsets.UTF_8.name());
   8716 
   8717             int type;
   8718             while ((type = in.next()) != END_DOCUMENT) {
   8719                 final String tag = in.getName();
   8720                 if (type == START_TAG) {
   8721                     if (TAG_URI_GRANT.equals(tag)) {
   8722                         final int sourceUserId;
   8723                         final int targetUserId;
   8724                         final int userHandle = readIntAttribute(in,
   8725                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
   8726                         if (userHandle != UserHandle.USER_NULL) {
   8727                             // For backwards compatibility.
   8728                             sourceUserId = userHandle;
   8729                             targetUserId = userHandle;
   8730                         } else {
   8731                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
   8732                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
   8733                         }
   8734                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
   8735                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
   8736                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
   8737                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
   8738                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
   8739                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
   8740 
   8741                         // Sanity check that provider still belongs to source package
   8742                         // Both direct boot aware and unaware packages are fine as we
   8743                         // will do filtering at query time to avoid multiple parsing.
   8744                         final ProviderInfo pi = getProviderInfoLocked(
   8745                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
   8746                                         | MATCH_DIRECT_BOOT_UNAWARE);
   8747                         if (pi != null && sourcePkg.equals(pi.packageName)) {
   8748                             int targetUid = -1;
   8749                             try {
   8750                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
   8751                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
   8752                             } catch (RemoteException e) {
   8753                             }
   8754                             if (targetUid != -1) {
   8755                                 final UriPermission perm = findOrCreateUriPermissionLocked(
   8756                                         sourcePkg, targetPkg, targetUid,
   8757                                         new GrantUri(sourceUserId, uri, prefix));
   8758                                 perm.initPersistedModes(modeFlags, createdTime);
   8759                             }
   8760                         } else {
   8761                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
   8762                                     + " but instead found " + pi);
   8763                         }
   8764                     }
   8765                 }
   8766             }
   8767         } catch (FileNotFoundException e) {
   8768             // Missing grants is okay
   8769         } catch (IOException e) {
   8770             Slog.wtf(TAG, "Failed reading Uri grants", e);
   8771         } catch (XmlPullParserException e) {
   8772             Slog.wtf(TAG, "Failed reading Uri grants", e);
   8773         } finally {
   8774             IoUtils.closeQuietly(fis);
   8775         }
   8776     }
   8777 
   8778     /**
   8779      * @param uri This uri must NOT contain an embedded userId.
   8780      * @param userId The userId in which the uri is to be resolved.
   8781      */
   8782     @Override
   8783     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
   8784         enforceNotIsolatedCaller("takePersistableUriPermission");
   8785 
   8786         Preconditions.checkFlagsArgument(modeFlags,
   8787                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   8788 
   8789         synchronized (this) {
   8790             final int callingUid = Binder.getCallingUid();
   8791             boolean persistChanged = false;
   8792             GrantUri grantUri = new GrantUri(userId, uri, false);
   8793 
   8794             UriPermission exactPerm = findUriPermissionLocked(callingUid,
   8795                     new GrantUri(userId, uri, false));
   8796             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
   8797                     new GrantUri(userId, uri, true));
   8798 
   8799             final boolean exactValid = (exactPerm != null)
   8800                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
   8801             final boolean prefixValid = (prefixPerm != null)
   8802                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
   8803 
   8804             if (!(exactValid || prefixValid)) {
   8805                 throw new SecurityException("No persistable permission grants found for UID "
   8806                         + callingUid + " and Uri " + grantUri.toSafeString());
   8807             }
   8808 
   8809             if (exactValid) {
   8810                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
   8811             }
   8812             if (prefixValid) {
   8813                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
   8814             }
   8815 
   8816             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
   8817 
   8818             if (persistChanged) {
   8819                 schedulePersistUriGrants();
   8820             }
   8821         }
   8822     }
   8823 
   8824     /**
   8825      * @param uri This uri must NOT contain an embedded userId.
   8826      * @param userId The userId in which the uri is to be resolved.
   8827      */
   8828     @Override
   8829     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
   8830         enforceNotIsolatedCaller("releasePersistableUriPermission");
   8831 
   8832         Preconditions.checkFlagsArgument(modeFlags,
   8833                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   8834 
   8835         synchronized (this) {
   8836             final int callingUid = Binder.getCallingUid();
   8837             boolean persistChanged = false;
   8838 
   8839             UriPermission exactPerm = findUriPermissionLocked(callingUid,
   8840                     new GrantUri(userId, uri, false));
   8841             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
   8842                     new GrantUri(userId, uri, true));
   8843             if (exactPerm == null && prefixPerm == null) {
   8844                 throw new SecurityException("No permission grants found for UID " + callingUid
   8845                         + " and Uri " + uri.toSafeString());
   8846             }
   8847 
   8848             if (exactPerm != null) {
   8849                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
   8850                 removeUriPermissionIfNeededLocked(exactPerm);
   8851             }
   8852             if (prefixPerm != null) {
   8853                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
   8854                 removeUriPermissionIfNeededLocked(prefixPerm);
   8855             }
   8856 
   8857             if (persistChanged) {
   8858                 schedulePersistUriGrants();
   8859             }
   8860         }
   8861     }
   8862 
   8863     /**
   8864      * Prune any older {@link UriPermission} for the given UID until outstanding
   8865      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
   8866      *
   8867      * @return if any mutations occured that require persisting.
   8868      */
   8869     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
   8870         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   8871         if (perms == null) return false;
   8872         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
   8873 
   8874         final ArrayList<UriPermission> persisted = Lists.newArrayList();
   8875         for (UriPermission perm : perms.values()) {
   8876             if (perm.persistedModeFlags != 0) {
   8877                 persisted.add(perm);
   8878             }
   8879         }
   8880 
   8881         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
   8882         if (trimCount <= 0) return false;
   8883 
   8884         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
   8885         for (int i = 0; i < trimCount; i++) {
   8886             final UriPermission perm = persisted.get(i);
   8887 
   8888             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8889                     "Trimming grant created at " + perm.persistedCreateTime);
   8890 
   8891             perm.releasePersistableModes(~0);
   8892             removeUriPermissionIfNeededLocked(perm);
   8893         }
   8894 
   8895         return true;
   8896     }
   8897 
   8898     @Override
   8899     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
   8900             String packageName, boolean incoming) {
   8901         enforceNotIsolatedCaller("getPersistedUriPermissions");
   8902         Preconditions.checkNotNull(packageName, "packageName");
   8903 
   8904         final int callingUid = Binder.getCallingUid();
   8905         final int callingUserId = UserHandle.getUserId(callingUid);
   8906         final IPackageManager pm = AppGlobals.getPackageManager();
   8907         try {
   8908             final int packageUid = pm.getPackageUid(packageName,
   8909                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
   8910             if (packageUid != callingUid) {
   8911                 throw new SecurityException(
   8912                         "Package " + packageName + " does not belong to calling UID " + callingUid);
   8913             }
   8914         } catch (RemoteException e) {
   8915             throw new SecurityException("Failed to verify package name ownership");
   8916         }
   8917 
   8918         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
   8919         synchronized (this) {
   8920             if (incoming) {
   8921                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
   8922                         callingUid);
   8923                 if (perms == null) {
   8924                     Slog.w(TAG, "No permission grants found for " + packageName);
   8925                 } else {
   8926                     for (UriPermission perm : perms.values()) {
   8927                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
   8928                             result.add(perm.buildPersistedPublicApiObject());
   8929                         }
   8930                     }
   8931                 }
   8932             } else {
   8933                 final int size = mGrantedUriPermissions.size();
   8934                 for (int i = 0; i < size; i++) {
   8935                     final ArrayMap<GrantUri, UriPermission> perms =
   8936                             mGrantedUriPermissions.valueAt(i);
   8937                     for (UriPermission perm : perms.values()) {
   8938                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
   8939                             result.add(perm.buildPersistedPublicApiObject());
   8940                         }
   8941                     }
   8942                 }
   8943             }
   8944         }
   8945         return new ParceledListSlice<android.content.UriPermission>(result);
   8946     }
   8947 
   8948     @Override
   8949     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
   8950             String packageName, int userId) {
   8951         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
   8952                 "getGrantedUriPermissions");
   8953 
   8954         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
   8955         synchronized (this) {
   8956             final int size = mGrantedUriPermissions.size();
   8957             for (int i = 0; i < size; i++) {
   8958                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   8959                 for (UriPermission perm : perms.values()) {
   8960                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
   8961                             && perm.persistedModeFlags != 0) {
   8962                         result.add(perm.buildPersistedPublicApiObject());
   8963                     }
   8964                 }
   8965             }
   8966         }
   8967         return new ParceledListSlice<android.content.UriPermission>(result);
   8968     }
   8969 
   8970     @Override
   8971     public void clearGrantedUriPermissions(String packageName, int userId) {
   8972         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
   8973                 "clearGrantedUriPermissions");
   8974         removeUriPermissionsForPackageLocked(packageName, userId, true);
   8975     }
   8976 
   8977     @Override
   8978     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
   8979         synchronized (this) {
   8980             ProcessRecord app =
   8981                 who != null ? getRecordForAppLocked(who) : null;
   8982             if (app == null) return;
   8983 
   8984             Message msg = Message.obtain();
   8985             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
   8986             msg.obj = app;
   8987             msg.arg1 = waiting ? 1 : 0;
   8988             mUiHandler.sendMessage(msg);
   8989         }
   8990     }
   8991 
   8992     @Override
   8993     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
   8994         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
   8995         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
   8996         outInfo.availMem = Process.getFreeMemory();
   8997         outInfo.totalMem = Process.getTotalMemory();
   8998         outInfo.threshold = homeAppMem;
   8999         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
   9000         outInfo.hiddenAppThreshold = cachedAppMem;
   9001         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
   9002                 ProcessList.SERVICE_ADJ);
   9003         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
   9004                 ProcessList.VISIBLE_APP_ADJ);
   9005         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
   9006                 ProcessList.FOREGROUND_APP_ADJ);
   9007     }
   9008 
   9009     // =========================================================
   9010     // TASK MANAGEMENT
   9011     // =========================================================
   9012 
   9013     @Override
   9014     public List<IAppTask> getAppTasks(String callingPackage) {
   9015         int callingUid = Binder.getCallingUid();
   9016         long ident = Binder.clearCallingIdentity();
   9017 
   9018         synchronized(this) {
   9019             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
   9020             try {
   9021                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
   9022 
   9023                 final int N = mRecentTasks.size();
   9024                 for (int i = 0; i < N; i++) {
   9025                     TaskRecord tr = mRecentTasks.get(i);
   9026                     // Skip tasks that do not match the caller.  We don't need to verify
   9027                     // callingPackage, because we are also limiting to callingUid and know
   9028                     // that will limit to the correct security sandbox.
   9029                     if (tr.effectiveUid != callingUid) {
   9030                         continue;
   9031                     }
   9032                     Intent intent = tr.getBaseIntent();
   9033                     if (intent == null ||
   9034                             !callingPackage.equals(intent.getComponent().getPackageName())) {
   9035                         continue;
   9036                     }
   9037                     ActivityManager.RecentTaskInfo taskInfo =
   9038                             createRecentTaskInfoFromTaskRecord(tr);
   9039                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
   9040                     list.add(taskImpl);
   9041                 }
   9042             } finally {
   9043                 Binder.restoreCallingIdentity(ident);
   9044             }
   9045             return list;
   9046         }
   9047     }
   9048 
   9049     @Override
   9050     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
   9051         final int callingUid = Binder.getCallingUid();
   9052         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
   9053 
   9054         synchronized(this) {
   9055             if (DEBUG_ALL) Slog.v(
   9056                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
   9057 
   9058             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
   9059                     callingUid);
   9060 
   9061             // TODO: Improve with MRU list from all ActivityStacks.
   9062             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
   9063         }
   9064 
   9065         return list;
   9066     }
   9067 
   9068     /**
   9069      * Creates a new RecentTaskInfo from a TaskRecord.
   9070      */
   9071     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
   9072         // Update the task description to reflect any changes in the task stack
   9073         tr.updateTaskDescription();
   9074 
   9075         // Compose the recent task info
   9076         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
   9077         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
   9078         rti.persistentId = tr.taskId;
   9079         rti.baseIntent = new Intent(tr.getBaseIntent());
   9080         rti.origActivity = tr.origActivity;
   9081         rti.realActivity = tr.realActivity;
   9082         rti.description = tr.lastDescription;
   9083         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
   9084         rti.userId = tr.userId;
   9085         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
   9086         rti.firstActiveTime = tr.firstActiveTime;
   9087         rti.lastActiveTime = tr.lastActiveTime;
   9088         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
   9089         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
   9090         rti.numActivities = 0;
   9091         if (tr.mBounds != null) {
   9092             rti.bounds = new Rect(tr.mBounds);
   9093         }
   9094         rti.isDockable = tr.canGoInDockedStack();
   9095         rti.resizeMode = tr.mResizeMode;
   9096 
   9097         ActivityRecord base = null;
   9098         ActivityRecord top = null;
   9099         ActivityRecord tmp;
   9100 
   9101         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
   9102             tmp = tr.mActivities.get(i);
   9103             if (tmp.finishing) {
   9104                 continue;
   9105             }
   9106             base = tmp;
   9107             if (top == null || (top.state == ActivityState.INITIALIZING)) {
   9108                 top = base;
   9109             }
   9110             rti.numActivities++;
   9111         }
   9112 
   9113         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
   9114         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
   9115 
   9116         return rti;
   9117     }
   9118 
   9119     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
   9120         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
   9121                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
   9122         if (!allowed) {
   9123             if (checkPermission(android.Manifest.permission.GET_TASKS,
   9124                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
   9125                 // Temporary compatibility: some existing apps on the system image may
   9126                 // still be requesting the old permission and not switched to the new
   9127                 // one; if so, we'll still allow them full access.  This means we need
   9128                 // to see if they are holding the old permission and are a system app.
   9129                 try {
   9130                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
   9131                         allowed = true;
   9132                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
   9133                                 + " is using old GET_TASKS but privileged; allowing");
   9134                     }
   9135                 } catch (RemoteException e) {
   9136                 }
   9137             }
   9138         }
   9139         if (!allowed) {
   9140             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
   9141                     + " does not hold REAL_GET_TASKS; limiting output");
   9142         }
   9143         return allowed;
   9144     }
   9145 
   9146     @Override
   9147     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
   9148             int userId) {
   9149         final int callingUid = Binder.getCallingUid();
   9150         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
   9151                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
   9152 
   9153         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
   9154         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
   9155         synchronized (this) {
   9156             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
   9157                     callingUid);
   9158             final boolean detailed = checkCallingPermission(
   9159                     android.Manifest.permission.GET_DETAILED_TASKS)
   9160                     == PackageManager.PERMISSION_GRANTED;
   9161 
   9162             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
   9163                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
   9164                 return ParceledListSlice.emptyList();
   9165             }
   9166             mRecentTasks.loadUserRecentsLocked(userId);
   9167 
   9168             final int recentsCount = mRecentTasks.size();
   9169             ArrayList<ActivityManager.RecentTaskInfo> res =
   9170                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
   9171 
   9172             final Set<Integer> includedUsers;
   9173             if (includeProfiles) {
   9174                 includedUsers = mUserController.getProfileIds(userId);
   9175             } else {
   9176                 includedUsers = new HashSet<>();
   9177             }
   9178             includedUsers.add(Integer.valueOf(userId));
   9179 
   9180             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
   9181                 TaskRecord tr = mRecentTasks.get(i);
   9182                 // Only add calling user or related users recent tasks
   9183                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
   9184                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
   9185                     continue;
   9186                 }
   9187 
   9188                 if (tr.realActivitySuspended) {
   9189                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
   9190                     continue;
   9191                 }
   9192 
   9193                 // Return the entry if desired by the caller.  We always return
   9194                 // the first entry, because callers always expect this to be the
   9195                 // foreground app.  We may filter others if the caller has
   9196                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
   9197                 // we should exclude the entry.
   9198 
   9199                 if (i == 0
   9200                         || withExcluded
   9201                         || (tr.intent == null)
   9202                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
   9203                                 == 0)) {
   9204                     if (!allowed) {
   9205                         // If the caller doesn't have the GET_TASKS permission, then only
   9206                         // allow them to see a small subset of tasks -- their own and home.
   9207                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
   9208                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
   9209                             continue;
   9210                         }
   9211                     }
   9212                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
   9213                         if (tr.stack != null && tr.stack.isHomeStack()) {
   9214                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9215                                     "Skipping, home stack task: " + tr);
   9216                             continue;
   9217                         }
   9218                     }
   9219                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
   9220                         final ActivityStack stack = tr.stack;
   9221                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
   9222                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9223                                     "Skipping, top task in docked stack: " + tr);
   9224                             continue;
   9225                         }
   9226                     }
   9227                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
   9228                         if (tr.stack != null && tr.stack.isPinnedStack()) {
   9229                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9230                                     "Skipping, pinned stack task: " + tr);
   9231                             continue;
   9232                         }
   9233                     }
   9234                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
   9235                         // Don't include auto remove tasks that are finished or finishing.
   9236                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9237                                 "Skipping, auto-remove without activity: " + tr);
   9238                         continue;
   9239                     }
   9240                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
   9241                             && !tr.isAvailable) {
   9242                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9243                                 "Skipping, unavail real act: " + tr);
   9244                         continue;
   9245                     }
   9246 
   9247                     if (!tr.mUserSetupComplete) {
   9248                         // Don't include task launched while user is not done setting-up.
   9249                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9250                                 "Skipping, user setup not complete: " + tr);
   9251                         continue;
   9252                     }
   9253 
   9254                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
   9255                     if (!detailed) {
   9256                         rti.baseIntent.replaceExtras((Bundle)null);
   9257                     }
   9258 
   9259                     res.add(rti);
   9260                     maxNum--;
   9261                 }
   9262             }
   9263             return new ParceledListSlice<>(res);
   9264         }
   9265     }
   9266 
   9267     @Override
   9268     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
   9269         synchronized (this) {
   9270             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
   9271                     "getTaskThumbnail()");
   9272             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
   9273                     id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
   9274             if (tr != null) {
   9275                 return tr.getTaskThumbnailLocked();
   9276             }
   9277         }
   9278         return null;
   9279     }
   9280 
   9281     @Override
   9282     public int addAppTask(IBinder activityToken, Intent intent,
   9283             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
   9284         final int callingUid = Binder.getCallingUid();
   9285         final long callingIdent = Binder.clearCallingIdentity();
   9286 
   9287         try {
   9288             synchronized (this) {
   9289                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
   9290                 if (r == null) {
   9291                     throw new IllegalArgumentException("Activity does not exist; token="
   9292                             + activityToken);
   9293                 }
   9294                 ComponentName comp = intent.getComponent();
   9295                 if (comp == null) {
   9296                     throw new IllegalArgumentException("Intent " + intent
   9297                             + " must specify explicit component");
   9298                 }
   9299                 if (thumbnail.getWidth() != mThumbnailWidth
   9300                         || thumbnail.getHeight() != mThumbnailHeight) {
   9301                     throw new IllegalArgumentException("Bad thumbnail size: got "
   9302                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
   9303                             + mThumbnailWidth + "x" + mThumbnailHeight);
   9304                 }
   9305                 if (intent.getSelector() != null) {
   9306                     intent.setSelector(null);
   9307                 }
   9308                 if (intent.getSourceBounds() != null) {
   9309                     intent.setSourceBounds(null);
   9310                 }
   9311                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
   9312                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
   9313                         // The caller has added this as an auto-remove task...  that makes no
   9314                         // sense, so turn off auto-remove.
   9315                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
   9316                     }
   9317                 }
   9318                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
   9319                     mLastAddedTaskActivity = null;
   9320                 }
   9321                 ActivityInfo ainfo = mLastAddedTaskActivity;
   9322                 if (ainfo == null) {
   9323                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
   9324                             comp, 0, UserHandle.getUserId(callingUid));
   9325                     if (ainfo.applicationInfo.uid != callingUid) {
   9326                         throw new SecurityException(
   9327                                 "Can't add task for another application: target uid="
   9328                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
   9329                     }
   9330                 }
   9331 
   9332                 // Use the full screen as the context for the task thumbnail
   9333                 final Point displaySize = new Point();
   9334                 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
   9335                 r.task.stack.getDisplaySize(displaySize);
   9336                 thumbnailInfo.taskWidth = displaySize.x;
   9337                 thumbnailInfo.taskHeight = displaySize.y;
   9338                 thumbnailInfo.screenOrientation = mConfiguration.orientation;
   9339 
   9340                 TaskRecord task = new TaskRecord(this,
   9341                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
   9342                         ainfo, intent, description, thumbnailInfo);
   9343 
   9344                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
   9345                 if (trimIdx >= 0) {
   9346                     // If this would have caused a trim, then we'll abort because that
   9347                     // means it would be added at the end of the list but then just removed.
   9348                     return INVALID_TASK_ID;
   9349                 }
   9350 
   9351                 final int N = mRecentTasks.size();
   9352                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
   9353                     final TaskRecord tr = mRecentTasks.remove(N - 1);
   9354                     tr.removedFromRecents();
   9355                 }
   9356 
   9357                 task.inRecents = true;
   9358                 mRecentTasks.add(task);
   9359                 r.task.stack.addTask(task, false, "addAppTask");
   9360 
   9361                 task.setLastThumbnailLocked(thumbnail);
   9362                 task.freeLastThumbnail();
   9363 
   9364                 return task.taskId;
   9365             }
   9366         } finally {
   9367             Binder.restoreCallingIdentity(callingIdent);
   9368         }
   9369     }
   9370 
   9371     @Override
   9372     public Point getAppTaskThumbnailSize() {
   9373         synchronized (this) {
   9374             return new Point(mThumbnailWidth,  mThumbnailHeight);
   9375         }
   9376     }
   9377 
   9378     @Override
   9379     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
   9380         synchronized (this) {
   9381             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   9382             if (r != null) {
   9383                 r.setTaskDescription(td);
   9384                 r.task.updateTaskDescription();
   9385             }
   9386         }
   9387     }
   9388 
   9389     @Override
   9390     public void setTaskResizeable(int taskId, int resizeableMode) {
   9391         synchronized (this) {
   9392             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
   9393                     taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
   9394             if (task == null) {
   9395                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
   9396                 return;
   9397             }
   9398             if (task.mResizeMode != resizeableMode) {
   9399                 task.mResizeMode = resizeableMode;
   9400                 mWindowManager.setTaskResizeable(taskId, resizeableMode);
   9401                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   9402                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
   9403             }
   9404         }
   9405     }
   9406 
   9407     @Override
   9408     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
   9409         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
   9410         long ident = Binder.clearCallingIdentity();
   9411         try {
   9412             synchronized (this) {
   9413                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   9414                 if (task == null) {
   9415                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
   9416                     return;
   9417                 }
   9418                 int stackId = task.stack.mStackId;
   9419                 // We allow the task to scroll instead of resizing if this is a non-resizeable task
   9420                 // in crop windows resize mode or if the task size is affected by the docked stack
   9421                 // changing size. No need to update configuration.
   9422                 if (bounds != null && task.inCropWindowsResizeMode()
   9423                         && mStackSupervisor.isStackDockedInEffect(stackId)) {
   9424                     mWindowManager.scrollTask(task.taskId, bounds);
   9425                     return;
   9426                 }
   9427 
   9428                 // Place the task in the right stack if it isn't there already based on
   9429                 // the requested bounds.
   9430                 // The stack transition logic is:
   9431                 // - a null bounds on a freeform task moves that task to fullscreen
   9432                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
   9433                 //   that task to freeform
   9434                 // - otherwise the task is not moved
   9435                 if (!StackId.isTaskResizeAllowed(stackId)) {
   9436                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
   9437                 }
   9438                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
   9439                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
   9440                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
   9441                     stackId = FREEFORM_WORKSPACE_STACK_ID;
   9442                 }
   9443                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
   9444                 if (stackId != task.stack.mStackId) {
   9445                     mStackSupervisor.moveTaskToStackUncheckedLocked(
   9446                             task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
   9447                     preserveWindow = false;
   9448                 }
   9449 
   9450                 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
   9451                         false /* deferResume */);
   9452             }
   9453         } finally {
   9454             Binder.restoreCallingIdentity(ident);
   9455         }
   9456     }
   9457 
   9458     @Override
   9459     public Rect getTaskBounds(int taskId) {
   9460         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
   9461         long ident = Binder.clearCallingIdentity();
   9462         Rect rect = new Rect();
   9463         try {
   9464             synchronized (this) {
   9465                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
   9466                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
   9467                 if (task == null) {
   9468                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
   9469                     return rect;
   9470                 }
   9471                 if (task.stack != null) {
   9472                     // Return the bounds from window manager since it will be adjusted for various
   9473                     // things like the presense of a docked stack for tasks that aren't resizeable.
   9474                     mWindowManager.getTaskBounds(task.taskId, rect);
   9475                 } else {
   9476                     // Task isn't in window manager yet since it isn't associated with a stack.
   9477                     // Return the persist value from activity manager
   9478                     if (task.mBounds != null) {
   9479                         rect.set(task.mBounds);
   9480                     } else if (task.mLastNonFullscreenBounds != null) {
   9481                         rect.set(task.mLastNonFullscreenBounds);
   9482                     }
   9483                 }
   9484             }
   9485         } finally {
   9486             Binder.restoreCallingIdentity(ident);
   9487         }
   9488         return rect;
   9489     }
   9490 
   9491     @Override
   9492     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
   9493         if (userId != UserHandle.getCallingUserId()) {
   9494             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   9495                     "getTaskDescriptionIcon");
   9496         }
   9497         final File passedIconFile = new File(filePath);
   9498         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
   9499                 passedIconFile.getName());
   9500         if (!legitIconFile.getPath().equals(filePath)
   9501                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
   9502             throw new IllegalArgumentException("Bad file path: " + filePath
   9503                     + " passed for userId " + userId);
   9504         }
   9505         return mRecentTasks.getTaskDescriptionIcon(filePath);
   9506     }
   9507 
   9508     @Override
   9509     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
   9510             throws RemoteException {
   9511         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
   9512                 opts.getCustomInPlaceResId() == 0) {
   9513             throw new IllegalArgumentException("Expected in-place ActivityOption " +
   9514                     "with valid animation");
   9515         }
   9516         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
   9517         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
   9518                 opts.getCustomInPlaceResId());
   9519         mWindowManager.executeAppTransition();
   9520     }
   9521 
   9522     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
   9523             boolean removeFromRecents) {
   9524         if (removeFromRecents) {
   9525             mRecentTasks.remove(tr);
   9526             tr.removedFromRecents();
   9527         }
   9528         ComponentName component = tr.getBaseIntent().getComponent();
   9529         if (component == null) {
   9530             Slog.w(TAG, "No component for base intent of task: " + tr);
   9531             return;
   9532         }
   9533 
   9534         // Find any running services associated with this app and stop if needed.
   9535         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
   9536 
   9537         if (!killProcess) {
   9538             return;
   9539         }
   9540 
   9541         // Determine if the process(es) for this task should be killed.
   9542         final String pkg = component.getPackageName();
   9543         ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
   9544         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
   9545         for (int i = 0; i < pmap.size(); i++) {
   9546 
   9547             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
   9548             for (int j = 0; j < uids.size(); j++) {
   9549                 ProcessRecord proc = uids.valueAt(j);
   9550                 if (proc.userId != tr.userId) {
   9551                     // Don't kill process for a different user.
   9552                     continue;
   9553                 }
   9554                 if (proc == mHomeProcess) {
   9555                     // Don't kill the home process along with tasks from the same package.
   9556                     continue;
   9557                 }
   9558                 if (!proc.pkgList.containsKey(pkg)) {
   9559                     // Don't kill process that is not associated with this task.
   9560                     continue;
   9561                 }
   9562 
   9563                 for (int k = 0; k < proc.activities.size(); k++) {
   9564                     TaskRecord otherTask = proc.activities.get(k).task;
   9565                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
   9566                         // Don't kill process(es) that has an activity in a different task that is
   9567                         // also in recents.
   9568                         return;
   9569                     }
   9570                 }
   9571 
   9572                 if (proc.foregroundServices) {
   9573                     // Don't kill process(es) with foreground service.
   9574                     return;
   9575                 }
   9576 
   9577                 // Add process to kill list.
   9578                 procsToKill.add(proc);
   9579             }
   9580         }
   9581 
   9582         // Kill the running processes.
   9583         for (int i = 0; i < procsToKill.size(); i++) {
   9584             ProcessRecord pr = procsToKill.get(i);
   9585             if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   9586                     && pr.curReceiver == null) {
   9587                 pr.kill("remove task", true);
   9588             } else {
   9589                 // We delay killing processes that are not in the background or running a receiver.
   9590                 pr.waitingToKill = "remove task";
   9591             }
   9592         }
   9593     }
   9594 
   9595     private void removeTasksByPackageNameLocked(String packageName, int userId) {
   9596         // Remove all tasks with activities in the specified package from the list of recent tasks
   9597         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
   9598             TaskRecord tr = mRecentTasks.get(i);
   9599             if (tr.userId != userId) continue;
   9600 
   9601             ComponentName cn = tr.intent.getComponent();
   9602             if (cn != null && cn.getPackageName().equals(packageName)) {
   9603                 // If the package name matches, remove the task.
   9604                 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
   9605             }
   9606         }
   9607     }
   9608 
   9609     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
   9610             int userId) {
   9611 
   9612         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
   9613             TaskRecord tr = mRecentTasks.get(i);
   9614             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
   9615                 continue;
   9616             }
   9617 
   9618             ComponentName cn = tr.intent.getComponent();
   9619             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
   9620                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
   9621             if (sameComponent) {
   9622                 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
   9623             }
   9624         }
   9625     }
   9626 
   9627     /**
   9628      * Removes the task with the specified task id.
   9629      *
   9630      * @param taskId Identifier of the task to be removed.
   9631      * @param killProcess Kill any process associated with the task if possible.
   9632      * @param removeFromRecents Whether to also remove the task from recents.
   9633      * @return Returns true if the given task was found and removed.
   9634      */
   9635     private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
   9636             boolean removeFromRecents) {
   9637         final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
   9638                 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
   9639         if (tr != null) {
   9640             tr.removeTaskActivitiesLocked();
   9641             cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
   9642             if (tr.isPersistable) {
   9643                 notifyTaskPersisterLocked(null, true);
   9644             }
   9645             return true;
   9646         }
   9647         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
   9648         return false;
   9649     }
   9650 
   9651     @Override
   9652     public void removeStack(int stackId) {
   9653         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
   9654         if (stackId == HOME_STACK_ID) {
   9655             throw new IllegalArgumentException("Removing home stack is not allowed.");
   9656         }
   9657 
   9658         synchronized (this) {
   9659             final long ident = Binder.clearCallingIdentity();
   9660             try {
   9661                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
   9662                 if (stack == null) {
   9663                     return;
   9664                 }
   9665                 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
   9666                 for (int i = tasks.size() - 1; i >= 0; i--) {
   9667                     removeTaskByIdLocked(
   9668                             tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
   9669                 }
   9670             } finally {
   9671                 Binder.restoreCallingIdentity(ident);
   9672             }
   9673         }
   9674     }
   9675 
   9676     @Override
   9677     public boolean removeTask(int taskId) {
   9678         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
   9679         synchronized (this) {
   9680             final long ident = Binder.clearCallingIdentity();
   9681             try {
   9682                 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
   9683             } finally {
   9684                 Binder.restoreCallingIdentity(ident);
   9685             }
   9686         }
   9687     }
   9688 
   9689     /**
   9690      * TODO: Add mController hook
   9691      */
   9692     @Override
   9693     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
   9694         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
   9695 
   9696         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
   9697         synchronized(this) {
   9698             moveTaskToFrontLocked(taskId, flags, bOptions);
   9699         }
   9700     }
   9701 
   9702     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
   9703         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
   9704 
   9705         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   9706                 Binder.getCallingUid(), -1, -1, "Task to front")) {
   9707             ActivityOptions.abort(options);
   9708             return;
   9709         }
   9710         final long origId = Binder.clearCallingIdentity();
   9711         try {
   9712             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   9713             if (task == null) {
   9714                 Slog.d(TAG, "Could not find task for id: "+ taskId);
   9715                 return;
   9716             }
   9717             if (mStackSupervisor.isLockTaskModeViolation(task)) {
   9718                 mStackSupervisor.showLockTaskToast();
   9719                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
   9720                 return;
   9721             }
   9722             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
   9723             if (prev != null && prev.isRecentsActivity()) {
   9724                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
   9725             }
   9726             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
   9727                     false /* forceNonResizable */);
   9728         } finally {
   9729             Binder.restoreCallingIdentity(origId);
   9730         }
   9731         ActivityOptions.abort(options);
   9732     }
   9733 
   9734     /**
   9735      * Moves an activity, and all of the other activities within the same task, to the bottom
   9736      * of the history stack.  The activity's order within the task is unchanged.
   9737      *
   9738      * @param token A reference to the activity we wish to move
   9739      * @param nonRoot If false then this only works if the activity is the root
   9740      *                of a task; if true it will work for any activity in a task.
   9741      * @return Returns true if the move completed, false if not.
   9742      */
   9743     @Override
   9744     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
   9745         enforceNotIsolatedCaller("moveActivityTaskToBack");
   9746         synchronized(this) {
   9747             final long origId = Binder.clearCallingIdentity();
   9748             try {
   9749                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
   9750                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   9751                 if (task != null) {
   9752                     if (mStackSupervisor.isLockedTask(task)) {
   9753                         mStackSupervisor.showLockTaskToast();
   9754                         return false;
   9755                     }
   9756                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
   9757                 }
   9758             } finally {
   9759                 Binder.restoreCallingIdentity(origId);
   9760             }
   9761         }
   9762         return false;
   9763     }
   9764 
   9765     @Override
   9766     public void moveTaskBackwards(int task) {
   9767         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   9768                 "moveTaskBackwards()");
   9769 
   9770         synchronized(this) {
   9771             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   9772                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
   9773                 return;
   9774             }
   9775             final long origId = Binder.clearCallingIdentity();
   9776             moveTaskBackwardsLocked(task);
   9777             Binder.restoreCallingIdentity(origId);
   9778         }
   9779     }
   9780 
   9781     private final void moveTaskBackwardsLocked(int task) {
   9782         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
   9783     }
   9784 
   9785     @Override
   9786     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
   9787             IActivityContainerCallback callback) throws RemoteException {
   9788         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
   9789         synchronized (this) {
   9790             if (parentActivityToken == null) {
   9791                 throw new IllegalArgumentException("parent token must not be null");
   9792             }
   9793             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
   9794             if (r == null) {
   9795                 return null;
   9796             }
   9797             if (callback == null) {
   9798                 throw new IllegalArgumentException("callback must not be null");
   9799             }
   9800             return mStackSupervisor.createVirtualActivityContainer(r, callback);
   9801         }
   9802     }
   9803 
   9804     @Override
   9805     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
   9806         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
   9807         synchronized (this) {
   9808             mStackSupervisor.deleteActivityContainer(container);
   9809         }
   9810     }
   9811 
   9812     @Override
   9813     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
   9814         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
   9815         synchronized (this) {
   9816             final int stackId = mStackSupervisor.getNextStackId();
   9817             final ActivityStack stack =
   9818                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
   9819             if (stack == null) {
   9820                 return null;
   9821             }
   9822             return stack.mActivityContainer;
   9823         }
   9824     }
   9825 
   9826     @Override
   9827     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
   9828         synchronized (this) {
   9829             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
   9830             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
   9831                 return stack.mActivityContainer.getDisplayId();
   9832             }
   9833             return Display.DEFAULT_DISPLAY;
   9834         }
   9835     }
   9836 
   9837     @Override
   9838     public int getActivityStackId(IBinder token) throws RemoteException {
   9839         synchronized (this) {
   9840             ActivityStack stack = ActivityRecord.getStackLocked(token);
   9841             if (stack == null) {
   9842                 return INVALID_STACK_ID;
   9843             }
   9844             return stack.mStackId;
   9845         }
   9846     }
   9847 
   9848     @Override
   9849     public void exitFreeformMode(IBinder token) throws RemoteException {
   9850         synchronized (this) {
   9851             long ident = Binder.clearCallingIdentity();
   9852             try {
   9853                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   9854                 if (r == null) {
   9855                     throw new IllegalArgumentException(
   9856                             "exitFreeformMode: No activity record matching token=" + token);
   9857                 }
   9858                 final ActivityStack stack = r.getStackLocked(token);
   9859                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
   9860                     throw new IllegalStateException(
   9861                             "exitFreeformMode: You can only go fullscreen from freeform.");
   9862                 }
   9863                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
   9864                 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
   9865                         ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
   9866             } finally {
   9867                 Binder.restoreCallingIdentity(ident);
   9868             }
   9869         }
   9870     }
   9871 
   9872     @Override
   9873     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
   9874         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
   9875         if (stackId == HOME_STACK_ID) {
   9876             throw new IllegalArgumentException(
   9877                     "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
   9878         }
   9879         synchronized (this) {
   9880             long ident = Binder.clearCallingIdentity();
   9881             try {
   9882                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
   9883                         + " to stackId=" + stackId + " toTop=" + toTop);
   9884                 if (stackId == DOCKED_STACK_ID) {
   9885                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
   9886                             null /* initialBounds */);
   9887                 }
   9888                 boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
   9889                         !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
   9890                 if (result && stackId == DOCKED_STACK_ID) {
   9891                     // If task moved to docked stack - show recents if needed.
   9892                     mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
   9893                             "moveTaskToDockedStack");
   9894                 }
   9895             } finally {
   9896                 Binder.restoreCallingIdentity(ident);
   9897             }
   9898         }
   9899     }
   9900 
   9901     @Override
   9902     public void swapDockedAndFullscreenStack() throws RemoteException {
   9903         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
   9904         synchronized (this) {
   9905             long ident = Binder.clearCallingIdentity();
   9906             try {
   9907                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
   9908                         FULLSCREEN_WORKSPACE_STACK_ID);
   9909                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
   9910                         : null;
   9911                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
   9912                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
   9913                         : null;
   9914                 if (topTask == null || tasks == null || tasks.size() == 0) {
   9915                     Slog.w(TAG,
   9916                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
   9917                     return;
   9918                 }
   9919 
   9920                 // TODO: App transition
   9921                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
   9922 
   9923                 // Defer the resume so resume/pausing while moving stacks is dangerous.
   9924                 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
   9925                         false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
   9926                         ANIMATE, true /* deferResume */);
   9927                 final int size = tasks.size();
   9928                 for (int i = 0; i < size; i++) {
   9929                     final int id = tasks.get(i).taskId;
   9930                     if (id == topTask.taskId) {
   9931                         continue;
   9932                     }
   9933                     mStackSupervisor.moveTaskToStackLocked(id,
   9934                             FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
   9935                             "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
   9936                 }
   9937 
   9938                 // Because we deferred the resume, to avoid conflicts with stack switches while
   9939                 // resuming, we need to do it after all the tasks are moved.
   9940                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   9941                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
   9942 
   9943                 mWindowManager.executeAppTransition();
   9944             } finally {
   9945                 Binder.restoreCallingIdentity(ident);
   9946             }
   9947         }
   9948     }
   9949 
   9950     /**
   9951      * Moves the input task to the docked stack.
   9952      *
   9953      * @param taskId Id of task to move.
   9954      * @param createMode The mode the docked stack should be created in if it doesn't exist
   9955      *                   already. See
   9956      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
   9957      *                   and
   9958      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
   9959      * @param toTop If the task and stack should be moved to the top.
   9960      * @param animate Whether we should play an animation for the moving the task
   9961      * @param initialBounds If the docked stack gets created, it will use these bounds for the
   9962      *                      docked stack. Pass {@code null} to use default bounds.
   9963      */
   9964     @Override
   9965     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
   9966             Rect initialBounds, boolean moveHomeStackFront) {
   9967         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
   9968         synchronized (this) {
   9969             long ident = Binder.clearCallingIdentity();
   9970             try {
   9971                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
   9972                         + " to createMode=" + createMode + " toTop=" + toTop);
   9973                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
   9974                 final boolean moved = mStackSupervisor.moveTaskToStackLocked(
   9975                         taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
   9976                         animate, DEFER_RESUME);
   9977                 if (moved) {
   9978                     if (moveHomeStackFront) {
   9979                         mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
   9980                     }
   9981                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   9982                 }
   9983                 return moved;
   9984             } finally {
   9985                 Binder.restoreCallingIdentity(ident);
   9986             }
   9987         }
   9988     }
   9989 
   9990     /**
   9991      * Moves the top activity in the input stackId to the pinned stack.
   9992      *
   9993      * @param stackId Id of stack to move the top activity to pinned stack.
   9994      * @param bounds Bounds to use for pinned stack.
   9995      *
   9996      * @return True if the top activity of the input stack was successfully moved to the pinned
   9997      *          stack.
   9998      */
   9999     @Override
   10000     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
   10001         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
   10002         synchronized (this) {
   10003             if (!mSupportsPictureInPicture) {
   10004                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
   10005                         + "Device doesn't support picture-in-pciture mode");
   10006             }
   10007 
   10008             long ident = Binder.clearCallingIdentity();
   10009             try {
   10010                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
   10011             } finally {
   10012                 Binder.restoreCallingIdentity(ident);
   10013             }
   10014         }
   10015     }
   10016 
   10017     @Override
   10018     public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
   10019             boolean preserveWindows, boolean animate, int animationDuration) {
   10020         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
   10021         long ident = Binder.clearCallingIdentity();
   10022         try {
   10023             synchronized (this) {
   10024                 if (animate) {
   10025                     if (stackId == PINNED_STACK_ID) {
   10026                         mWindowManager.animateResizePinnedStack(bounds, animationDuration);
   10027                     } else {
   10028                         throw new IllegalArgumentException("Stack: " + stackId
   10029                                 + " doesn't support animated resize.");
   10030                     }
   10031                 } else {
   10032                     mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
   10033                             null /* tempTaskInsetBounds */, preserveWindows,
   10034                             allowResizeInDockedMode, !DEFER_RESUME);
   10035                 }
   10036             }
   10037         } finally {
   10038             Binder.restoreCallingIdentity(ident);
   10039         }
   10040     }
   10041 
   10042     @Override
   10043     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
   10044             Rect tempDockedTaskInsetBounds,
   10045             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
   10046         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   10047                 "resizeDockedStack()");
   10048         long ident = Binder.clearCallingIdentity();
   10049         try {
   10050             synchronized (this) {
   10051                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
   10052                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
   10053                         PRESERVE_WINDOWS);
   10054             }
   10055         } finally {
   10056             Binder.restoreCallingIdentity(ident);
   10057         }
   10058     }
   10059 
   10060     @Override
   10061     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
   10062         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   10063                 "resizePinnedStack()");
   10064         final long ident = Binder.clearCallingIdentity();
   10065         try {
   10066             synchronized (this) {
   10067                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
   10068             }
   10069         } finally {
   10070             Binder.restoreCallingIdentity(ident);
   10071         }
   10072     }
   10073 
   10074     @Override
   10075     public void positionTaskInStack(int taskId, int stackId, int position) {
   10076         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
   10077         if (stackId == HOME_STACK_ID) {
   10078             throw new IllegalArgumentException(
   10079                     "positionTaskInStack: Attempt to change the position of task "
   10080                     + taskId + " in/to home stack");
   10081         }
   10082         synchronized (this) {
   10083             long ident = Binder.clearCallingIdentity();
   10084             try {
   10085                 if (DEBUG_STACK) Slog.d(TAG_STACK,
   10086                         "positionTaskInStack: positioning task=" + taskId
   10087                         + " in stackId=" + stackId + " at position=" + position);
   10088                 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
   10089             } finally {
   10090                 Binder.restoreCallingIdentity(ident);
   10091             }
   10092         }
   10093     }
   10094 
   10095     @Override
   10096     public List<StackInfo> getAllStackInfos() {
   10097         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
   10098         long ident = Binder.clearCallingIdentity();
   10099         try {
   10100             synchronized (this) {
   10101                 return mStackSupervisor.getAllStackInfosLocked();
   10102             }
   10103         } finally {
   10104             Binder.restoreCallingIdentity(ident);
   10105         }
   10106     }
   10107 
   10108     @Override
   10109     public StackInfo getStackInfo(int stackId) {
   10110         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
   10111         long ident = Binder.clearCallingIdentity();
   10112         try {
   10113             synchronized (this) {
   10114                 return mStackSupervisor.getStackInfoLocked(stackId);
   10115             }
   10116         } finally {
   10117             Binder.restoreCallingIdentity(ident);
   10118         }
   10119     }
   10120 
   10121     @Override
   10122     public boolean isInHomeStack(int taskId) {
   10123         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
   10124         long ident = Binder.clearCallingIdentity();
   10125         try {
   10126             synchronized (this) {
   10127                 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
   10128                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
   10129                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
   10130             }
   10131         } finally {
   10132             Binder.restoreCallingIdentity(ident);
   10133         }
   10134     }
   10135 
   10136     @Override
   10137     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
   10138         synchronized(this) {
   10139             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
   10140         }
   10141     }
   10142 
   10143     @Override
   10144     public void updateDeviceOwner(String packageName) {
   10145         final int callingUid = Binder.getCallingUid();
   10146         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   10147             throw new SecurityException("updateDeviceOwner called from non-system process");
   10148         }
   10149         synchronized (this) {
   10150             mDeviceOwnerName = packageName;
   10151         }
   10152     }
   10153 
   10154     @Override
   10155     public void updateLockTaskPackages(int userId, String[] packages) {
   10156         final int callingUid = Binder.getCallingUid();
   10157         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   10158             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
   10159                     "updateLockTaskPackages()");
   10160         }
   10161         synchronized (this) {
   10162             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
   10163                     Arrays.toString(packages));
   10164             mLockTaskPackages.put(userId, packages);
   10165             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
   10166         }
   10167     }
   10168 
   10169 
   10170     void startLockTaskModeLocked(TaskRecord task) {
   10171         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
   10172         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
   10173             return;
   10174         }
   10175 
   10176         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
   10177         // is initiated by system after the pinning request was shown and locked mode is initiated
   10178         // by an authorized app directly
   10179         final int callingUid = Binder.getCallingUid();
   10180         boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
   10181         long ident = Binder.clearCallingIdentity();
   10182         try {
   10183             if (!isSystemInitiated) {
   10184                 task.mLockTaskUid = callingUid;
   10185                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
   10186                     // startLockTask() called by app and task mode is lockTaskModeDefault.
   10187                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
   10188                     StatusBarManagerInternal statusBarManager =
   10189                             LocalServices.getService(StatusBarManagerInternal.class);
   10190                     if (statusBarManager != null) {
   10191                         statusBarManager.showScreenPinningRequest(task.taskId);
   10192                     }
   10193                     return;
   10194                 }
   10195 
   10196                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
   10197                 if (stack == null || task != stack.topTask()) {
   10198                     throw new IllegalArgumentException("Invalid task, not in foreground");
   10199                 }
   10200             }
   10201             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
   10202                     "Locking fully");
   10203             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
   10204                     ActivityManager.LOCK_TASK_MODE_PINNED :
   10205                     ActivityManager.LOCK_TASK_MODE_LOCKED,
   10206                     "startLockTask", true);
   10207         } finally {
   10208             Binder.restoreCallingIdentity(ident);
   10209         }
   10210     }
   10211 
   10212     @Override
   10213     public void startLockTaskMode(int taskId) {
   10214         synchronized (this) {
   10215             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   10216             if (task != null) {
   10217                 startLockTaskModeLocked(task);
   10218             }
   10219         }
   10220     }
   10221 
   10222     @Override
   10223     public void startLockTaskMode(IBinder token) {
   10224         synchronized (this) {
   10225             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   10226             if (r == null) {
   10227                 return;
   10228             }
   10229             final TaskRecord task = r.task;
   10230             if (task != null) {
   10231                 startLockTaskModeLocked(task);
   10232             }
   10233         }
   10234     }
   10235 
   10236     @Override
   10237     public void startSystemLockTaskMode(int taskId) throws RemoteException {
   10238         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
   10239         // This makes inner call to look as if it was initiated by system.
   10240         long ident = Binder.clearCallingIdentity();
   10241         try {
   10242             synchronized (this) {
   10243                 startLockTaskMode(taskId);
   10244             }
   10245         } finally {
   10246             Binder.restoreCallingIdentity(ident);
   10247         }
   10248     }
   10249 
   10250     @Override
   10251     public void stopLockTaskMode() {
   10252         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
   10253         if (lockTask == null) {
   10254             // Our work here is done.
   10255             return;
   10256         }
   10257 
   10258         final int callingUid = Binder.getCallingUid();
   10259         final int lockTaskUid = lockTask.mLockTaskUid;
   10260         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
   10261         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
   10262             // Done.
   10263             return;
   10264         } else {
   10265             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
   10266             // It is possible lockTaskMode was started by the system process because
   10267             // android:lockTaskMode is set to a locking value in the application manifest
   10268             // instead of the app calling startLockTaskMode. In this case
   10269             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
   10270             // {@link TaskRecord.effectiveUid} instead. Also caller with
   10271             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
   10272             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
   10273                     && callingUid != lockTaskUid
   10274                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
   10275                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
   10276                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
   10277             }
   10278         }
   10279         long ident = Binder.clearCallingIdentity();
   10280         try {
   10281             Log.d(TAG, "stopLockTaskMode");
   10282             // Stop lock task
   10283             synchronized (this) {
   10284                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
   10285                         "stopLockTask", true);
   10286             }
   10287             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
   10288             if (tm != null) {
   10289                 tm.showInCallScreen(false);
   10290             }
   10291         } finally {
   10292             Binder.restoreCallingIdentity(ident);
   10293         }
   10294     }
   10295 
   10296     /**
   10297      * This API should be called by SystemUI only when user perform certain action to dismiss
   10298      * lock task mode. We should only dismiss pinned lock task mode in this case.
   10299      */
   10300     @Override
   10301     public void stopSystemLockTaskMode() throws RemoteException {
   10302         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
   10303             stopLockTaskMode();
   10304         } else {
   10305             mStackSupervisor.showLockTaskToast();
   10306         }
   10307     }
   10308 
   10309     @Override
   10310     public boolean isInLockTaskMode() {
   10311         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
   10312     }
   10313 
   10314     @Override
   10315     public int getLockTaskModeState() {
   10316         synchronized (this) {
   10317             return mStackSupervisor.getLockTaskModeState();
   10318         }
   10319     }
   10320 
   10321     @Override
   10322     public void showLockTaskEscapeMessage(IBinder token) {
   10323         synchronized (this) {
   10324             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   10325             if (r == null) {
   10326                 return;
   10327             }
   10328             mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
   10329         }
   10330     }
   10331 
   10332     // =========================================================
   10333     // CONTENT PROVIDERS
   10334     // =========================================================
   10335 
   10336     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
   10337         List<ProviderInfo> providers = null;
   10338         try {
   10339             providers = AppGlobals.getPackageManager()
   10340                     .queryContentProviders(app.processName, app.uid,
   10341                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
   10342                                     | MATCH_DEBUG_TRIAGED_MISSING)
   10343                     .getList();
   10344         } catch (RemoteException ex) {
   10345         }
   10346         if (DEBUG_MU) Slog.v(TAG_MU,
   10347                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
   10348         int userId = app.userId;
   10349         if (providers != null) {
   10350             int N = providers.size();
   10351             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
   10352             for (int i=0; i<N; i++) {
   10353                 // TODO: keep logic in sync with installEncryptionUnawareProviders
   10354                 ProviderInfo cpi =
   10355                     (ProviderInfo)providers.get(i);
   10356                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   10357                         cpi.name, cpi.flags);
   10358                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
   10359                     // This is a singleton provider, but a user besides the
   10360                     // default user is asking to initialize a process it runs
   10361                     // in...  well, no, it doesn't actually run in this process,
   10362                     // it runs in the process of the default user.  Get rid of it.
   10363                     providers.remove(i);
   10364                     N--;
   10365                     i--;
   10366                     continue;
   10367                 }
   10368 
   10369                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   10370                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
   10371                 if (cpr == null) {
   10372                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
   10373                     mProviderMap.putProviderByClass(comp, cpr);
   10374                 }
   10375                 if (DEBUG_MU) Slog.v(TAG_MU,
   10376                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
   10377                 app.pubProviders.put(cpi.name, cpr);
   10378                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
   10379                     // Don't add this if it is a platform component that is marked
   10380                     // to run in multiple processes, because this is actually
   10381                     // part of the framework so doesn't make sense to track as a
   10382                     // separate apk in the process.
   10383                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
   10384                             mProcessStats);
   10385                 }
   10386                 notifyPackageUse(cpi.applicationInfo.packageName,
   10387                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
   10388             }
   10389         }
   10390         return providers;
   10391     }
   10392 
   10393     /**
   10394      * Check if {@link ProcessRecord} has a possible chance at accessing the
   10395      * given {@link ProviderInfo}. Final permission checking is always done
   10396      * in {@link ContentProvider}.
   10397      */
   10398     private final String checkContentProviderPermissionLocked(
   10399             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
   10400         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
   10401         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
   10402         boolean checkedGrants = false;
   10403         if (checkUser) {
   10404             // Looking for cross-user grants before enforcing the typical cross-users permissions
   10405             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
   10406             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
   10407                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
   10408                     return null;
   10409                 }
   10410                 checkedGrants = true;
   10411             }
   10412             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
   10413                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
   10414             if (userId != tmpTargetUserId) {
   10415                 // When we actually went to determine the final targer user ID, this ended
   10416                 // up different than our initial check for the authority.  This is because
   10417                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
   10418                 // SELF.  So we need to re-check the grants again.
   10419                 checkedGrants = false;
   10420             }
   10421         }
   10422         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
   10423                 cpi.applicationInfo.uid, cpi.exported)
   10424                 == PackageManager.PERMISSION_GRANTED) {
   10425             return null;
   10426         }
   10427         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
   10428                 cpi.applicationInfo.uid, cpi.exported)
   10429                 == PackageManager.PERMISSION_GRANTED) {
   10430             return null;
   10431         }
   10432 
   10433         PathPermission[] pps = cpi.pathPermissions;
   10434         if (pps != null) {
   10435             int i = pps.length;
   10436             while (i > 0) {
   10437                 i--;
   10438                 PathPermission pp = pps[i];
   10439                 String pprperm = pp.getReadPermission();
   10440                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
   10441                         cpi.applicationInfo.uid, cpi.exported)
   10442                         == PackageManager.PERMISSION_GRANTED) {
   10443                     return null;
   10444                 }
   10445                 String ppwperm = pp.getWritePermission();
   10446                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
   10447                         cpi.applicationInfo.uid, cpi.exported)
   10448                         == PackageManager.PERMISSION_GRANTED) {
   10449                     return null;
   10450                 }
   10451             }
   10452         }
   10453         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
   10454             return null;
   10455         }
   10456 
   10457         String msg;
   10458         if (!cpi.exported) {
   10459             msg = "Permission Denial: opening provider " + cpi.name
   10460                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   10461                     + ", uid=" + callingUid + ") that is not exported from uid "
   10462                     + cpi.applicationInfo.uid;
   10463         } else {
   10464             msg = "Permission Denial: opening provider " + cpi.name
   10465                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   10466                     + ", uid=" + callingUid + ") requires "
   10467                     + cpi.readPermission + " or " + cpi.writePermission;
   10468         }
   10469         Slog.w(TAG, msg);
   10470         return msg;
   10471     }
   10472 
   10473     /**
   10474      * Returns if the ContentProvider has granted a uri to callingUid
   10475      */
   10476     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
   10477         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   10478         if (perms != null) {
   10479             for (int i=perms.size()-1; i>=0; i--) {
   10480                 GrantUri grantUri = perms.keyAt(i);
   10481                 if (grantUri.sourceUserId == userId || !checkUser) {
   10482                     if (matchesProvider(grantUri.uri, cpi)) {
   10483                         return true;
   10484                     }
   10485                 }
   10486             }
   10487         }
   10488         return false;
   10489     }
   10490 
   10491     /**
   10492      * Returns true if the uri authority is one of the authorities specified in the provider.
   10493      */
   10494     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
   10495         String uriAuth = uri.getAuthority();
   10496         String cpiAuth = cpi.authority;
   10497         if (cpiAuth.indexOf(';') == -1) {
   10498             return cpiAuth.equals(uriAuth);
   10499         }
   10500         String[] cpiAuths = cpiAuth.split(";");
   10501         int length = cpiAuths.length;
   10502         for (int i = 0; i < length; i++) {
   10503             if (cpiAuths[i].equals(uriAuth)) return true;
   10504         }
   10505         return false;
   10506     }
   10507 
   10508     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
   10509             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   10510         if (r != null) {
   10511             for (int i=0; i<r.conProviders.size(); i++) {
   10512                 ContentProviderConnection conn = r.conProviders.get(i);
   10513                 if (conn.provider == cpr) {
   10514                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
   10515                             "Adding provider requested by "
   10516                             + r.processName + " from process "
   10517                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   10518                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   10519                     if (stable) {
   10520                         conn.stableCount++;
   10521                         conn.numStableIncs++;
   10522                     } else {
   10523                         conn.unstableCount++;
   10524                         conn.numUnstableIncs++;
   10525                     }
   10526                     return conn;
   10527                 }
   10528             }
   10529             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
   10530             if (stable) {
   10531                 conn.stableCount = 1;
   10532                 conn.numStableIncs = 1;
   10533             } else {
   10534                 conn.unstableCount = 1;
   10535                 conn.numUnstableIncs = 1;
   10536             }
   10537             cpr.connections.add(conn);
   10538             r.conProviders.add(conn);
   10539             startAssociationLocked(r.uid, r.processName, r.curProcState,
   10540                     cpr.uid, cpr.name, cpr.info.processName);
   10541             return conn;
   10542         }
   10543         cpr.addExternalProcessHandleLocked(externalProcessToken);
   10544         return null;
   10545     }
   10546 
   10547     boolean decProviderCountLocked(ContentProviderConnection conn,
   10548             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   10549         if (conn != null) {
   10550             cpr = conn.provider;
   10551             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
   10552                     "Removing provider requested by "
   10553                     + conn.client.processName + " from process "
   10554                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   10555                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   10556             if (stable) {
   10557                 conn.stableCount--;
   10558             } else {
   10559                 conn.unstableCount--;
   10560             }
   10561             if (conn.stableCount == 0 && conn.unstableCount == 0) {
   10562                 cpr.connections.remove(conn);
   10563                 conn.client.conProviders.remove(conn);
   10564                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   10565                     // The client is more important than last activity -- note the time this
   10566                     // is happening, so we keep the old provider process around a bit as last
   10567                     // activity to avoid thrashing it.
   10568                     if (cpr.proc != null) {
   10569                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
   10570                     }
   10571                 }
   10572                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
   10573                 return true;
   10574             }
   10575             return false;
   10576         }
   10577         cpr.removeExternalProcessHandleLocked(externalProcessToken);
   10578         return false;
   10579     }
   10580 
   10581     private void checkTime(long startTime, String where) {
   10582         long now = SystemClock.uptimeMillis();
   10583         if ((now-startTime) > 50) {
   10584             // If we are taking more than 50ms, log about it.
   10585             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
   10586         }
   10587     }
   10588 
   10589     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
   10590             PROC_SPACE_TERM,
   10591             PROC_SPACE_TERM|PROC_PARENS,
   10592             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
   10593     };
   10594 
   10595     private final long[] mProcessStateStatsLongs = new long[1];
   10596 
   10597     boolean isProcessAliveLocked(ProcessRecord proc) {
   10598         if (proc.procStatFile == null) {
   10599             proc.procStatFile = "/proc/" + proc.pid + "/stat";
   10600         }
   10601         mProcessStateStatsLongs[0] = 0;
   10602         if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
   10603                 mProcessStateStatsLongs, null)) {
   10604             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
   10605             return false;
   10606         }
   10607         final long state = mProcessStateStatsLongs[0];
   10608         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
   10609                 + (char)state);
   10610         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
   10611     }
   10612 
   10613     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
   10614             String name, IBinder token, boolean stable, int userId) {
   10615         ContentProviderRecord cpr;
   10616         ContentProviderConnection conn = null;
   10617         ProviderInfo cpi = null;
   10618 
   10619         synchronized(this) {
   10620             long startTime = SystemClock.uptimeMillis();
   10621 
   10622             ProcessRecord r = null;
   10623             if (caller != null) {
   10624                 r = getRecordForAppLocked(caller);
   10625                 if (r == null) {
   10626                     throw new SecurityException(
   10627                             "Unable to find app for caller " + caller
   10628                           + " (pid=" + Binder.getCallingPid()
   10629                           + ") when getting content provider " + name);
   10630                 }
   10631             }
   10632 
   10633             boolean checkCrossUser = true;
   10634 
   10635             checkTime(startTime, "getContentProviderImpl: getProviderByName");
   10636 
   10637             // First check if this content provider has been published...
   10638             cpr = mProviderMap.getProviderByName(name, userId);
   10639             // If that didn't work, check if it exists for user 0 and then
   10640             // verify that it's a singleton provider before using it.
   10641             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
   10642                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
   10643                 if (cpr != null) {
   10644                     cpi = cpr.info;
   10645                     if (isSingleton(cpi.processName, cpi.applicationInfo,
   10646                             cpi.name, cpi.flags)
   10647                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
   10648                         userId = UserHandle.USER_SYSTEM;
   10649                         checkCrossUser = false;
   10650                     } else {
   10651                         cpr = null;
   10652                         cpi = null;
   10653                     }
   10654                 }
   10655             }
   10656 
   10657             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
   10658             if (providerRunning) {
   10659                 cpi = cpr.info;
   10660                 String msg;
   10661                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
   10662                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
   10663                         != null) {
   10664                     throw new SecurityException(msg);
   10665                 }
   10666                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
   10667 
   10668                 if (r != null && cpr.canRunHere(r)) {
   10669                     // This provider has been published or is in the process
   10670                     // of being published...  but it is also allowed to run
   10671                     // in the caller's process, so don't make a connection
   10672                     // and just let the caller instantiate its own instance.
   10673                     ContentProviderHolder holder = cpr.newHolder(null);
   10674                     // don't give caller the provider object, it needs
   10675                     // to make its own.
   10676                     holder.provider = null;
   10677                     return holder;
   10678                 }
   10679 
   10680                 final long origId = Binder.clearCallingIdentity();
   10681 
   10682                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
   10683 
   10684                 // In this case the provider instance already exists, so we can
   10685                 // return it right away.
   10686                 conn = incProviderCountLocked(r, cpr, token, stable);
   10687                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
   10688                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   10689                         // If this is a perceptible app accessing the provider,
   10690                         // make sure to count it as being accessed and thus
   10691                         // back up on the LRU list.  This is good because
   10692                         // content providers are often expensive to start.
   10693                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
   10694                         updateLruProcessLocked(cpr.proc, false, null);
   10695                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
   10696                     }
   10697                 }
   10698 
   10699                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
   10700                 final int verifiedAdj = cpr.proc.verifiedAdj;
   10701                 boolean success = updateOomAdjLocked(cpr.proc);
   10702                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
   10703                 // if the process has been successfully adjusted.  So to reduce races with
   10704                 // it, we will check whether the process still exists.  Note that this doesn't
   10705                 // completely get rid of races with LMK killing the process, but should make
   10706                 // them much smaller.
   10707                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
   10708                     success = false;
   10709                 }
   10710                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
   10711                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
   10712                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
   10713                 // NOTE: there is still a race here where a signal could be
   10714                 // pending on the process even though we managed to update its
   10715                 // adj level.  Not sure what to do about this, but at least
   10716                 // the race is now smaller.
   10717                 if (!success) {
   10718                     // Uh oh...  it looks like the provider's process
   10719                     // has been killed on us.  We need to wait for a new
   10720                     // process to be started, and make sure its death
   10721                     // doesn't kill our process.
   10722                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
   10723                             + " is crashing; detaching " + r);
   10724                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
   10725                     checkTime(startTime, "getContentProviderImpl: before appDied");
   10726                     appDiedLocked(cpr.proc);
   10727                     checkTime(startTime, "getContentProviderImpl: after appDied");
   10728                     if (!lastRef) {
   10729                         // This wasn't the last ref our process had on
   10730                         // the provider...  we have now been killed, bail.
   10731                         return null;
   10732                     }
   10733                     providerRunning = false;
   10734                     conn = null;
   10735                 } else {
   10736                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
   10737                 }
   10738 
   10739                 Binder.restoreCallingIdentity(origId);
   10740             }
   10741 
   10742             if (!providerRunning) {
   10743                 try {
   10744                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
   10745                     cpi = AppGlobals.getPackageManager().
   10746                         resolveContentProvider(name,
   10747                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
   10748                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
   10749                 } catch (RemoteException ex) {
   10750                 }
   10751                 if (cpi == null) {
   10752                     return null;
   10753                 }
   10754                 // If the provider is a singleton AND
   10755                 // (it's a call within the same user || the provider is a
   10756                 // privileged app)
   10757                 // Then allow connecting to the singleton provider
   10758                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   10759                         cpi.name, cpi.flags)
   10760                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
   10761                 if (singleton) {
   10762                     userId = UserHandle.USER_SYSTEM;
   10763                 }
   10764                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
   10765                 checkTime(startTime, "getContentProviderImpl: got app info for user");
   10766 
   10767                 String msg;
   10768                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
   10769                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
   10770                         != null) {
   10771                     throw new SecurityException(msg);
   10772                 }
   10773                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
   10774 
   10775                 if (!mProcessesReady
   10776                         && !cpi.processName.equals("system")) {
   10777                     // If this content provider does not run in the system
   10778                     // process, and the system is not yet ready to run other
   10779                     // processes, then fail fast instead of hanging.
   10780                     throw new IllegalArgumentException(
   10781                             "Attempt to launch content provider before system ready");
   10782                 }
   10783 
   10784                 // Make sure that the user who owns this provider is running.  If not,
   10785                 // we don't want to allow it to run.
   10786                 if (!mUserController.isUserRunningLocked(userId, 0)) {
   10787                     Slog.w(TAG, "Unable to launch app "
   10788                             + cpi.applicationInfo.packageName + "/"
   10789                             + cpi.applicationInfo.uid + " for provider "
   10790                             + name + ": user " + userId + " is stopped");
   10791                     return null;
   10792                 }
   10793 
   10794                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   10795                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
   10796                 cpr = mProviderMap.getProviderByClass(comp, userId);
   10797                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
   10798                 final boolean firstClass = cpr == null;
   10799                 if (firstClass) {
   10800                     final long ident = Binder.clearCallingIdentity();
   10801 
   10802                     // If permissions need a review before any of the app components can run,
   10803                     // we return no provider and launch a review activity if the calling app
   10804                     // is in the foreground.
   10805                     if (Build.PERMISSIONS_REVIEW_REQUIRED) {
   10806                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
   10807                             return null;
   10808                         }
   10809                     }
   10810 
   10811                     try {
   10812                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
   10813                         ApplicationInfo ai =
   10814                             AppGlobals.getPackageManager().
   10815                                 getApplicationInfo(
   10816                                         cpi.applicationInfo.packageName,
   10817                                         STOCK_PM_FLAGS, userId);
   10818                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
   10819                         if (ai == null) {
   10820                             Slog.w(TAG, "No package info for content provider "
   10821                                     + cpi.name);
   10822                             return null;
   10823                         }
   10824                         ai = getAppInfoForUser(ai, userId);
   10825                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
   10826                     } catch (RemoteException ex) {
   10827                         // pm is in same process, this will never happen.
   10828                     } finally {
   10829                         Binder.restoreCallingIdentity(ident);
   10830                     }
   10831                 }
   10832 
   10833                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
   10834 
   10835                 if (r != null && cpr.canRunHere(r)) {
   10836                     // If this is a multiprocess provider, then just return its
   10837                     // info and allow the caller to instantiate it.  Only do
   10838                     // this if the provider is the same user as the caller's
   10839                     // process, or can run as root (so can be in any process).
   10840                     return cpr.newHolder(null);
   10841                 }
   10842 
   10843                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
   10844                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
   10845                             + cpr.info.name + " callers=" + Debug.getCallers(6));
   10846 
   10847                 // This is single process, and our app is now connecting to it.
   10848                 // See if we are already in the process of launching this
   10849                 // provider.
   10850                 final int N = mLaunchingProviders.size();
   10851                 int i;
   10852                 for (i = 0; i < N; i++) {
   10853                     if (mLaunchingProviders.get(i) == cpr) {
   10854                         break;
   10855                     }
   10856                 }
   10857 
   10858                 // If the provider is not already being launched, then get it
   10859                 // started.
   10860                 if (i >= N) {
   10861                     final long origId = Binder.clearCallingIdentity();
   10862 
   10863                     try {
   10864                         // Content provider is now in use, its package can't be stopped.
   10865                         try {
   10866                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
   10867                             AppGlobals.getPackageManager().setPackageStoppedState(
   10868                                     cpr.appInfo.packageName, false, userId);
   10869                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
   10870                         } catch (RemoteException e) {
   10871                         } catch (IllegalArgumentException e) {
   10872                             Slog.w(TAG, "Failed trying to unstop package "
   10873                                     + cpr.appInfo.packageName + ": " + e);
   10874                         }
   10875 
   10876                         // Use existing process if already started
   10877                         checkTime(startTime, "getContentProviderImpl: looking for process record");
   10878                         ProcessRecord proc = getProcessRecordLocked(
   10879                                 cpi.processName, cpr.appInfo.uid, false);
   10880                         if (proc != null && proc.thread != null && !proc.killed) {
   10881                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
   10882                                     "Installing in existing process " + proc);
   10883                             if (!proc.pubProviders.containsKey(cpi.name)) {
   10884                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
   10885                                 proc.pubProviders.put(cpi.name, cpr);
   10886                                 try {
   10887                                     proc.thread.scheduleInstallProvider(cpi);
   10888                                 } catch (RemoteException e) {
   10889                                 }
   10890                             }
   10891                         } else {
   10892                             checkTime(startTime, "getContentProviderImpl: before start process");
   10893                             proc = startProcessLocked(cpi.processName,
   10894                                     cpr.appInfo, false, 0, "content provider",
   10895                                     new ComponentName(cpi.applicationInfo.packageName,
   10896                                             cpi.name), false, false, false);
   10897                             checkTime(startTime, "getContentProviderImpl: after start process");
   10898                             if (proc == null) {
   10899                                 Slog.w(TAG, "Unable to launch app "
   10900                                         + cpi.applicationInfo.packageName + "/"
   10901                                         + cpi.applicationInfo.uid + " for provider "
   10902                                         + name + ": process is bad");
   10903                                 return null;
   10904                             }
   10905                         }
   10906                         cpr.launchingApp = proc;
   10907                         mLaunchingProviders.add(cpr);
   10908                     } finally {
   10909                         Binder.restoreCallingIdentity(origId);
   10910                     }
   10911                 }
   10912 
   10913                 checkTime(startTime, "getContentProviderImpl: updating data structures");
   10914 
   10915                 // Make sure the provider is published (the same provider class
   10916                 // may be published under multiple names).
   10917                 if (firstClass) {
   10918                     mProviderMap.putProviderByClass(comp, cpr);
   10919                 }
   10920 
   10921                 mProviderMap.putProviderByName(name, cpr);
   10922                 conn = incProviderCountLocked(r, cpr, token, stable);
   10923                 if (conn != null) {
   10924                     conn.waiting = true;
   10925                 }
   10926             }
   10927             checkTime(startTime, "getContentProviderImpl: done!");
   10928         }
   10929 
   10930         // Wait for the provider to be published...
   10931         synchronized (cpr) {
   10932             while (cpr.provider == null) {
   10933                 if (cpr.launchingApp == null) {
   10934                     Slog.w(TAG, "Unable to launch app "
   10935                             + cpi.applicationInfo.packageName + "/"
   10936                             + cpi.applicationInfo.uid + " for provider "
   10937                             + name + ": launching app became null");
   10938                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
   10939                             UserHandle.getUserId(cpi.applicationInfo.uid),
   10940                             cpi.applicationInfo.packageName,
   10941                             cpi.applicationInfo.uid, name);
   10942                     return null;
   10943                 }
   10944                 try {
   10945                     if (DEBUG_MU) Slog.v(TAG_MU,
   10946                             "Waiting to start provider " + cpr
   10947                             + " launchingApp=" + cpr.launchingApp);
   10948                     if (conn != null) {
   10949                         conn.waiting = true;
   10950                     }
   10951                     cpr.wait();
   10952                 } catch (InterruptedException ex) {
   10953                 } finally {
   10954                     if (conn != null) {
   10955                         conn.waiting = false;
   10956                     }
   10957                 }
   10958             }
   10959         }
   10960         return cpr != null ? cpr.newHolder(conn) : null;
   10961     }
   10962 
   10963     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
   10964             ProcessRecord r, final int userId) {
   10965         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
   10966                 cpi.packageName, userId)) {
   10967 
   10968             final boolean callerForeground = r == null || r.setSchedGroup
   10969                     != ProcessList.SCHED_GROUP_BACKGROUND;
   10970 
   10971             // Show a permission review UI only for starting from a foreground app
   10972             if (!callerForeground) {
   10973                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
   10974                         + cpi.packageName + " requires a permissions review");
   10975                 return false;
   10976             }
   10977 
   10978             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
   10979             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
   10980                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
   10981             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
   10982 
   10983             if (DEBUG_PERMISSIONS_REVIEW) {
   10984                 Slog.i(TAG, "u" + userId + " Launching permission review "
   10985                         + "for package " + cpi.packageName);
   10986             }
   10987 
   10988             final UserHandle userHandle = new UserHandle(userId);
   10989             mHandler.post(new Runnable() {
   10990                 @Override
   10991                 public void run() {
   10992                     mContext.startActivityAsUser(intent, userHandle);
   10993                 }
   10994             });
   10995 
   10996             return false;
   10997         }
   10998 
   10999         return true;
   11000     }
   11001 
   11002     PackageManagerInternal getPackageManagerInternalLocked() {
   11003         if (mPackageManagerInt == null) {
   11004             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
   11005         }
   11006         return mPackageManagerInt;
   11007     }
   11008 
   11009     @Override
   11010     public final ContentProviderHolder getContentProvider(
   11011             IApplicationThread caller, String name, int userId, boolean stable) {
   11012         enforceNotIsolatedCaller("getContentProvider");
   11013         if (caller == null) {
   11014             String msg = "null IApplicationThread when getting content provider "
   11015                     + name;
   11016             Slog.w(TAG, msg);
   11017             throw new SecurityException(msg);
   11018         }
   11019         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
   11020         // with cross-user grant.
   11021         return getContentProviderImpl(caller, name, null, stable, userId);
   11022     }
   11023 
   11024     public ContentProviderHolder getContentProviderExternal(
   11025             String name, int userId, IBinder token) {
   11026         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   11027             "Do not have permission in call getContentProviderExternal()");
   11028         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   11029                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
   11030         return getContentProviderExternalUnchecked(name, token, userId);
   11031     }
   11032 
   11033     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
   11034             IBinder token, int userId) {
   11035         return getContentProviderImpl(null, name, token, true, userId);
   11036     }
   11037 
   11038     /**
   11039      * Drop a content provider from a ProcessRecord's bookkeeping
   11040      */
   11041     public void removeContentProvider(IBinder connection, boolean stable) {
   11042         enforceNotIsolatedCaller("removeContentProvider");
   11043         long ident = Binder.clearCallingIdentity();
   11044         try {
   11045             synchronized (this) {
   11046                 ContentProviderConnection conn;
   11047                 try {
   11048                     conn = (ContentProviderConnection)connection;
   11049                 } catch (ClassCastException e) {
   11050                     String msg ="removeContentProvider: " + connection
   11051                             + " not a ContentProviderConnection";
   11052                     Slog.w(TAG, msg);
   11053                     throw new IllegalArgumentException(msg);
   11054                 }
   11055                 if (conn == null) {
   11056                     throw new NullPointerException("connection is null");
   11057                 }
   11058                 if (decProviderCountLocked(conn, null, null, stable)) {
   11059                     updateOomAdjLocked();
   11060                 }
   11061             }
   11062         } finally {
   11063             Binder.restoreCallingIdentity(ident);
   11064         }
   11065     }
   11066 
   11067     public void removeContentProviderExternal(String name, IBinder token) {
   11068         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   11069             "Do not have permission in call removeContentProviderExternal()");
   11070         int userId = UserHandle.getCallingUserId();
   11071         long ident = Binder.clearCallingIdentity();
   11072         try {
   11073             removeContentProviderExternalUnchecked(name, token, userId);
   11074         } finally {
   11075             Binder.restoreCallingIdentity(ident);
   11076         }
   11077     }
   11078 
   11079     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
   11080         synchronized (this) {
   11081             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
   11082             if(cpr == null) {
   11083                 //remove from mProvidersByClass
   11084                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
   11085                 return;
   11086             }
   11087 
   11088             //update content provider record entry info
   11089             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
   11090             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
   11091             if (localCpr.hasExternalProcessHandles()) {
   11092                 if (localCpr.removeExternalProcessHandleLocked(token)) {
   11093                     updateOomAdjLocked();
   11094                 } else {
   11095                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
   11096                             + " with no external reference for token: "
   11097                             + token + ".");
   11098                 }
   11099             } else {
   11100                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
   11101                         + " with no external references.");
   11102             }
   11103         }
   11104     }
   11105 
   11106     public final void publishContentProviders(IApplicationThread caller,
   11107             List<ContentProviderHolder> providers) {
   11108         if (providers == null) {
   11109             return;
   11110         }
   11111 
   11112         enforceNotIsolatedCaller("publishContentProviders");
   11113         synchronized (this) {
   11114             final ProcessRecord r = getRecordForAppLocked(caller);
   11115             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
   11116             if (r == null) {
   11117                 throw new SecurityException(
   11118                         "Unable to find app for caller " + caller
   11119                       + " (pid=" + Binder.getCallingPid()
   11120                       + ") when publishing content providers");
   11121             }
   11122 
   11123             final long origId = Binder.clearCallingIdentity();
   11124 
   11125             final int N = providers.size();
   11126             for (int i = 0; i < N; i++) {
   11127                 ContentProviderHolder src = providers.get(i);
   11128                 if (src == null || src.info == null || src.provider == null) {
   11129                     continue;
   11130                 }
   11131                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
   11132                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
   11133                 if (dst != null) {
   11134                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
   11135                     mProviderMap.putProviderByClass(comp, dst);
   11136                     String names[] = dst.info.authority.split(";");
   11137                     for (int j = 0; j < names.length; j++) {
   11138                         mProviderMap.putProviderByName(names[j], dst);
   11139                     }
   11140 
   11141                     int launchingCount = mLaunchingProviders.size();
   11142                     int j;
   11143                     boolean wasInLaunchingProviders = false;
   11144                     for (j = 0; j < launchingCount; j++) {
   11145                         if (mLaunchingProviders.get(j) == dst) {
   11146                             mLaunchingProviders.remove(j);
   11147                             wasInLaunchingProviders = true;
   11148                             j--;
   11149                             launchingCount--;
   11150                         }
   11151                     }
   11152                     if (wasInLaunchingProviders) {
   11153                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
   11154                     }
   11155                     synchronized (dst) {
   11156                         dst.provider = src.provider;
   11157                         dst.proc = r;
   11158                         dst.notifyAll();
   11159                     }
   11160                     updateOomAdjLocked(r);
   11161                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
   11162                             src.info.authority);
   11163                 }
   11164             }
   11165 
   11166             Binder.restoreCallingIdentity(origId);
   11167         }
   11168     }
   11169 
   11170     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
   11171         ContentProviderConnection conn;
   11172         try {
   11173             conn = (ContentProviderConnection)connection;
   11174         } catch (ClassCastException e) {
   11175             String msg ="refContentProvider: " + connection
   11176                     + " not a ContentProviderConnection";
   11177             Slog.w(TAG, msg);
   11178             throw new IllegalArgumentException(msg);
   11179         }
   11180         if (conn == null) {
   11181             throw new NullPointerException("connection is null");
   11182         }
   11183 
   11184         synchronized (this) {
   11185             if (stable > 0) {
   11186                 conn.numStableIncs += stable;
   11187             }
   11188             stable = conn.stableCount + stable;
   11189             if (stable < 0) {
   11190                 throw new IllegalStateException("stableCount < 0: " + stable);
   11191             }
   11192 
   11193             if (unstable > 0) {
   11194                 conn.numUnstableIncs += unstable;
   11195             }
   11196             unstable = conn.unstableCount + unstable;
   11197             if (unstable < 0) {
   11198                 throw new IllegalStateException("unstableCount < 0: " + unstable);
   11199             }
   11200 
   11201             if ((stable+unstable) <= 0) {
   11202                 throw new IllegalStateException("ref counts can't go to zero here: stable="
   11203                         + stable + " unstable=" + unstable);
   11204             }
   11205             conn.stableCount = stable;
   11206             conn.unstableCount = unstable;
   11207             return !conn.dead;
   11208         }
   11209     }
   11210 
   11211     public void unstableProviderDied(IBinder connection) {
   11212         ContentProviderConnection conn;
   11213         try {
   11214             conn = (ContentProviderConnection)connection;
   11215         } catch (ClassCastException e) {
   11216             String msg ="refContentProvider: " + connection
   11217                     + " not a ContentProviderConnection";
   11218             Slog.w(TAG, msg);
   11219             throw new IllegalArgumentException(msg);
   11220         }
   11221         if (conn == null) {
   11222             throw new NullPointerException("connection is null");
   11223         }
   11224 
   11225         // Safely retrieve the content provider associated with the connection.
   11226         IContentProvider provider;
   11227         synchronized (this) {
   11228             provider = conn.provider.provider;
   11229         }
   11230 
   11231         if (provider == null) {
   11232             // Um, yeah, we're way ahead of you.
   11233             return;
   11234         }
   11235 
   11236         // Make sure the caller is being honest with us.
   11237         if (provider.asBinder().pingBinder()) {
   11238             // Er, no, still looks good to us.
   11239             synchronized (this) {
   11240                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
   11241                         + " says " + conn + " died, but we don't agree");
   11242                 return;
   11243             }
   11244         }
   11245 
   11246         // Well look at that!  It's dead!
   11247         synchronized (this) {
   11248             if (conn.provider.provider != provider) {
   11249                 // But something changed...  good enough.
   11250                 return;
   11251             }
   11252 
   11253             ProcessRecord proc = conn.provider.proc;
   11254             if (proc == null || proc.thread == null) {
   11255                 // Seems like the process is already cleaned up.
   11256                 return;
   11257             }
   11258 
   11259             // As far as we're concerned, this is just like receiving a
   11260             // death notification...  just a bit prematurely.
   11261             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
   11262                     + ") early provider death");
   11263             final long ident = Binder.clearCallingIdentity();
   11264             try {
   11265                 appDiedLocked(proc);
   11266             } finally {
   11267                 Binder.restoreCallingIdentity(ident);
   11268             }
   11269         }
   11270     }
   11271 
   11272     @Override
   11273     public void appNotRespondingViaProvider(IBinder connection) {
   11274         enforceCallingPermission(
   11275                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
   11276 
   11277         final ContentProviderConnection conn = (ContentProviderConnection) connection;
   11278         if (conn == null) {
   11279             Slog.w(TAG, "ContentProviderConnection is null");
   11280             return;
   11281         }
   11282 
   11283         final ProcessRecord host = conn.provider.proc;
   11284         if (host == null) {
   11285             Slog.w(TAG, "Failed to find hosting ProcessRecord");
   11286             return;
   11287         }
   11288 
   11289         mHandler.post(new Runnable() {
   11290             @Override
   11291             public void run() {
   11292                 mAppErrors.appNotResponding(host, null, null, false,
   11293                         "ContentProvider not responding");
   11294             }
   11295         });
   11296     }
   11297 
   11298     public final void installSystemProviders() {
   11299         List<ProviderInfo> providers;
   11300         synchronized (this) {
   11301             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
   11302             providers = generateApplicationProvidersLocked(app);
   11303             if (providers != null) {
   11304                 for (int i=providers.size()-1; i>=0; i--) {
   11305                     ProviderInfo pi = (ProviderInfo)providers.get(i);
   11306                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   11307                         Slog.w(TAG, "Not installing system proc provider " + pi.name
   11308                                 + ": not system .apk");
   11309                         providers.remove(i);
   11310                     }
   11311                 }
   11312             }
   11313         }
   11314         if (providers != null) {
   11315             mSystemThread.installSystemProviders(providers);
   11316         }
   11317 
   11318         mCoreSettingsObserver = new CoreSettingsObserver(this);
   11319         mFontScaleSettingObserver = new FontScaleSettingObserver();
   11320 
   11321         //mUsageStatsService.monitorPackages();
   11322     }
   11323 
   11324     private void startPersistentApps(int matchFlags) {
   11325         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
   11326 
   11327         synchronized (this) {
   11328             try {
   11329                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
   11330                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
   11331                 for (ApplicationInfo app : apps) {
   11332                     if (!"android".equals(app.packageName)) {
   11333                         addAppLocked(app, false, null /* ABI override */);
   11334                     }
   11335                 }
   11336             } catch (RemoteException ex) {
   11337             }
   11338         }
   11339     }
   11340 
   11341     /**
   11342      * When a user is unlocked, we need to install encryption-unaware providers
   11343      * belonging to any running apps.
   11344      */
   11345     private void installEncryptionUnawareProviders(int userId) {
   11346         // We're only interested in providers that are encryption unaware, and
   11347         // we don't care about uninstalled apps, since there's no way they're
   11348         // running at this point.
   11349         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
   11350 
   11351         synchronized (this) {
   11352             final int NP = mProcessNames.getMap().size();
   11353             for (int ip = 0; ip < NP; ip++) {
   11354                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   11355                 final int NA = apps.size();
   11356                 for (int ia = 0; ia < NA; ia++) {
   11357                     final ProcessRecord app = apps.valueAt(ia);
   11358                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
   11359 
   11360                     final int NG = app.pkgList.size();
   11361                     for (int ig = 0; ig < NG; ig++) {
   11362                         try {
   11363                             final String pkgName = app.pkgList.keyAt(ig);
   11364                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
   11365                                     .getPackageInfo(pkgName, matchFlags, userId);
   11366                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
   11367                                 for (ProviderInfo pi : pkgInfo.providers) {
   11368                                     // TODO: keep in sync with generateApplicationProvidersLocked
   11369                                     final boolean processMatch = Objects.equals(pi.processName,
   11370                                             app.processName) || pi.multiprocess;
   11371                                     final boolean userMatch = isSingleton(pi.processName,
   11372                                             pi.applicationInfo, pi.name, pi.flags)
   11373                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
   11374                                     if (processMatch && userMatch) {
   11375                                         Log.v(TAG, "Installing " + pi);
   11376                                         app.thread.scheduleInstallProvider(pi);
   11377                                     } else {
   11378                                         Log.v(TAG, "Skipping " + pi);
   11379                                     }
   11380                                 }
   11381                             }
   11382                         } catch (RemoteException ignored) {
   11383                         }
   11384                     }
   11385                 }
   11386             }
   11387         }
   11388     }
   11389 
   11390     /**
   11391      * Allows apps to retrieve the MIME type of a URI.
   11392      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
   11393      * users, then it does not need permission to access the ContentProvider.
   11394      * Either, it needs cross-user uri grants.
   11395      *
   11396      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
   11397      *
   11398      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
   11399      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
   11400      */
   11401     public String getProviderMimeType(Uri uri, int userId) {
   11402         enforceNotIsolatedCaller("getProviderMimeType");
   11403         final String name = uri.getAuthority();
   11404         int callingUid = Binder.getCallingUid();
   11405         int callingPid = Binder.getCallingPid();
   11406         long ident = 0;
   11407         boolean clearedIdentity = false;
   11408         synchronized (this) {
   11409             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
   11410         }
   11411         if (canClearIdentity(callingPid, callingUid, userId)) {
   11412             clearedIdentity = true;
   11413             ident = Binder.clearCallingIdentity();
   11414         }
   11415         ContentProviderHolder holder = null;
   11416         try {
   11417             holder = getContentProviderExternalUnchecked(name, null, userId);
   11418             if (holder != null) {
   11419                 return holder.provider.getType(uri);
   11420             }
   11421         } catch (RemoteException e) {
   11422             Log.w(TAG, "Content provider dead retrieving " + uri, e);
   11423             return null;
   11424         } catch (Exception e) {
   11425             Log.w(TAG, "Exception while determining type of " + uri, e);
   11426             return null;
   11427         } finally {
   11428             // We need to clear the identity to call removeContentProviderExternalUnchecked
   11429             if (!clearedIdentity) {
   11430                 ident = Binder.clearCallingIdentity();
   11431             }
   11432             try {
   11433                 if (holder != null) {
   11434                     removeContentProviderExternalUnchecked(name, null, userId);
   11435                 }
   11436             } finally {
   11437                 Binder.restoreCallingIdentity(ident);
   11438             }
   11439         }
   11440 
   11441         return null;
   11442     }
   11443 
   11444     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
   11445         if (UserHandle.getUserId(callingUid) == userId) {
   11446             return true;
   11447         }
   11448         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
   11449                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
   11450                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
   11451                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
   11452                 return true;
   11453         }
   11454         return false;
   11455     }
   11456 
   11457     // =========================================================
   11458     // GLOBAL MANAGEMENT
   11459     // =========================================================
   11460 
   11461     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
   11462             boolean isolated, int isolatedUid) {
   11463         String proc = customProcess != null ? customProcess : info.processName;
   11464         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   11465         final int userId = UserHandle.getUserId(info.uid);
   11466         int uid = info.uid;
   11467         if (isolated) {
   11468             if (isolatedUid == 0) {
   11469                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
   11470                 while (true) {
   11471                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
   11472                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
   11473                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
   11474                     }
   11475                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
   11476                     mNextIsolatedProcessUid++;
   11477                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
   11478                         // No process for this uid, use it.
   11479                         break;
   11480                     }
   11481                     stepsLeft--;
   11482                     if (stepsLeft <= 0) {
   11483                         return null;
   11484                     }
   11485                 }
   11486             } else {
   11487                 // Special case for startIsolatedProcess (internal only), where
   11488                 // the uid of the isolated process is specified by the caller.
   11489                 uid = isolatedUid;
   11490             }
   11491 
   11492             // Register the isolated UID with this application so BatteryStats knows to
   11493             // attribute resource usage to the application.
   11494             //
   11495             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
   11496             // about the process state of the isolated UID *before* it is registered with the
   11497             // owning application.
   11498             mBatteryStatsService.addIsolatedUid(uid, info.uid);
   11499         }
   11500         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
   11501         if (!mBooted && !mBooting
   11502                 && userId == UserHandle.USER_SYSTEM
   11503                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
   11504             r.persistent = true;
   11505         }
   11506         addProcessNameLocked(r);
   11507         return r;
   11508     }
   11509 
   11510     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
   11511             String abiOverride) {
   11512         ProcessRecord app;
   11513         if (!isolated) {
   11514             app = getProcessRecordLocked(info.processName, info.uid, true);
   11515         } else {
   11516             app = null;
   11517         }
   11518 
   11519         if (app == null) {
   11520             app = newProcessRecordLocked(info, null, isolated, 0);
   11521             updateLruProcessLocked(app, false, null);
   11522             updateOomAdjLocked();
   11523         }
   11524 
   11525         // This package really, really can not be stopped.
   11526         try {
   11527             AppGlobals.getPackageManager().setPackageStoppedState(
   11528                     info.packageName, false, UserHandle.getUserId(app.uid));
   11529         } catch (RemoteException e) {
   11530         } catch (IllegalArgumentException e) {
   11531             Slog.w(TAG, "Failed trying to unstop package "
   11532                     + info.packageName + ": " + e);
   11533         }
   11534 
   11535         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
   11536             app.persistent = true;
   11537             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
   11538         }
   11539         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
   11540             mPersistentStartingProcesses.add(app);
   11541             startProcessLocked(app, "added application", app.processName, abiOverride,
   11542                     null /* entryPoint */, null /* entryPointArgs */);
   11543         }
   11544 
   11545         return app;
   11546     }
   11547 
   11548     public void unhandledBack() {
   11549         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
   11550                 "unhandledBack()");
   11551 
   11552         synchronized(this) {
   11553             final long origId = Binder.clearCallingIdentity();
   11554             try {
   11555                 getFocusedStack().unhandledBackLocked();
   11556             } finally {
   11557                 Binder.restoreCallingIdentity(origId);
   11558             }
   11559         }
   11560     }
   11561 
   11562     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
   11563         enforceNotIsolatedCaller("openContentUri");
   11564         final int userId = UserHandle.getCallingUserId();
   11565         String name = uri.getAuthority();
   11566         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
   11567         ParcelFileDescriptor pfd = null;
   11568         if (cph != null) {
   11569             // We record the binder invoker's uid in thread-local storage before
   11570             // going to the content provider to open the file.  Later, in the code
   11571             // that handles all permissions checks, we look for this uid and use
   11572             // that rather than the Activity Manager's own uid.  The effect is that
   11573             // we do the check against the caller's permissions even though it looks
   11574             // to the content provider like the Activity Manager itself is making
   11575             // the request.
   11576             Binder token = new Binder();
   11577             sCallerIdentity.set(new Identity(
   11578                     token, Binder.getCallingPid(), Binder.getCallingUid()));
   11579             try {
   11580                 pfd = cph.provider.openFile(null, uri, "r", null, token);
   11581             } catch (FileNotFoundException e) {
   11582                 // do nothing; pfd will be returned null
   11583             } finally {
   11584                 // Ensure that whatever happens, we clean up the identity state
   11585                 sCallerIdentity.remove();
   11586                 // Ensure we're done with the provider.
   11587                 removeContentProviderExternalUnchecked(name, null, userId);
   11588             }
   11589         } else {
   11590             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
   11591         }
   11592         return pfd;
   11593     }
   11594 
   11595     // Actually is sleeping or shutting down or whatever else in the future
   11596     // is an inactive state.
   11597     boolean isSleepingOrShuttingDownLocked() {
   11598         return isSleepingLocked() || mShuttingDown;
   11599     }
   11600 
   11601     boolean isShuttingDownLocked() {
   11602         return mShuttingDown;
   11603     }
   11604 
   11605     boolean isSleepingLocked() {
   11606         return mSleeping;
   11607     }
   11608 
   11609     void onWakefulnessChanged(int wakefulness) {
   11610         synchronized(this) {
   11611             mWakefulness = wakefulness;
   11612             updateSleepIfNeededLocked();
   11613         }
   11614     }
   11615 
   11616     void finishRunningVoiceLocked() {
   11617         if (mRunningVoice != null) {
   11618             mRunningVoice = null;
   11619             mVoiceWakeLock.release();
   11620             updateSleepIfNeededLocked();
   11621         }
   11622     }
   11623 
   11624     void startTimeTrackingFocusedActivityLocked() {
   11625         if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
   11626             mCurAppTimeTracker.start(mFocusedActivity.packageName);
   11627         }
   11628     }
   11629 
   11630     void updateSleepIfNeededLocked() {
   11631         if (mSleeping && !shouldSleepLocked()) {
   11632             mSleeping = false;
   11633             startTimeTrackingFocusedActivityLocked();
   11634             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
   11635             mStackSupervisor.comeOutOfSleepIfNeededLocked();
   11636             updateOomAdjLocked();
   11637         } else if (!mSleeping && shouldSleepLocked()) {
   11638             mSleeping = true;
   11639             if (mCurAppTimeTracker != null) {
   11640                 mCurAppTimeTracker.stop();
   11641             }
   11642             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
   11643             mStackSupervisor.goingToSleepLocked();
   11644             updateOomAdjLocked();
   11645 
   11646             // Initialize the wake times of all processes.
   11647             checkExcessivePowerUsageLocked(false);
   11648             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   11649             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   11650             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   11651         }
   11652     }
   11653 
   11654     private boolean shouldSleepLocked() {
   11655         // Resume applications while running a voice interactor.
   11656         if (mRunningVoice != null) {
   11657             return false;
   11658         }
   11659 
   11660         // TODO: Transform the lock screen state into a sleep token instead.
   11661         switch (mWakefulness) {
   11662             case PowerManagerInternal.WAKEFULNESS_AWAKE:
   11663             case PowerManagerInternal.WAKEFULNESS_DREAMING:
   11664             case PowerManagerInternal.WAKEFULNESS_DOZING:
   11665                 // Pause applications whenever the lock screen is shown or any sleep
   11666                 // tokens have been acquired.
   11667                 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
   11668             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
   11669             default:
   11670                 // If we're asleep then pause applications unconditionally.
   11671                 return true;
   11672         }
   11673     }
   11674 
   11675     /** Pokes the task persister. */
   11676     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
   11677         mRecentTasks.notifyTaskPersisterLocked(task, flush);
   11678     }
   11679 
   11680     /** Notifies all listeners when the task stack has changed. */
   11681     void notifyTaskStackChangedLocked() {
   11682         mHandler.sendEmptyMessage(LOG_STACK_STATE);
   11683         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
   11684         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
   11685         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
   11686     }
   11687 
   11688     /** Notifies all listeners when an Activity is pinned. */
   11689     void notifyActivityPinnedLocked() {
   11690         mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
   11691         mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
   11692     }
   11693 
   11694     /**
   11695      * Notifies all listeners when an attempt was made to start an an activity that is already
   11696      * running in the pinned stack and the activity was not actually started, but the task is
   11697      * either brought to the front or a new Intent is delivered to it.
   11698      */
   11699     void notifyPinnedActivityRestartAttemptLocked() {
   11700         mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
   11701         mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
   11702     }
   11703 
   11704     /** Notifies all listeners when the pinned stack animation ends. */
   11705     @Override
   11706     public void notifyPinnedStackAnimationEnded() {
   11707         synchronized (this) {
   11708             mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
   11709             mHandler.obtainMessage(
   11710                     NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
   11711         }
   11712     }
   11713 
   11714     @Override
   11715     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
   11716         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
   11717     }
   11718 
   11719     @Override
   11720     public boolean shutdown(int timeout) {
   11721         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
   11722                 != PackageManager.PERMISSION_GRANTED) {
   11723             throw new SecurityException("Requires permission "
   11724                     + android.Manifest.permission.SHUTDOWN);
   11725         }
   11726 
   11727         boolean timedout = false;
   11728 
   11729         synchronized(this) {
   11730             mShuttingDown = true;
   11731             updateEventDispatchingLocked();
   11732             timedout = mStackSupervisor.shutdownLocked(timeout);
   11733         }
   11734 
   11735         mAppOpsService.shutdown();
   11736         if (mUsageStatsService != null) {
   11737             mUsageStatsService.prepareShutdown();
   11738         }
   11739         mBatteryStatsService.shutdown();
   11740         synchronized (this) {
   11741             mProcessStats.shutdownLocked();
   11742             notifyTaskPersisterLocked(null, true);
   11743         }
   11744 
   11745         return timedout;
   11746     }
   11747 
   11748     public final void activitySlept(IBinder token) {
   11749         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
   11750 
   11751         final long origId = Binder.clearCallingIdentity();
   11752 
   11753         synchronized (this) {
   11754             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   11755             if (r != null) {
   11756                 mStackSupervisor.activitySleptLocked(r);
   11757             }
   11758         }
   11759 
   11760         Binder.restoreCallingIdentity(origId);
   11761     }
   11762 
   11763     private String lockScreenShownToString() {
   11764         switch (mLockScreenShown) {
   11765             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
   11766             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
   11767             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
   11768             default: return "Unknown=" + mLockScreenShown;
   11769         }
   11770     }
   11771 
   11772     void logLockScreen(String msg) {
   11773         if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
   11774                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
   11775                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
   11776                 + " mSleeping=" + mSleeping);
   11777     }
   11778 
   11779     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
   11780         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
   11781         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
   11782         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
   11783             boolean wasRunningVoice = mRunningVoice != null;
   11784             mRunningVoice = session;
   11785             if (!wasRunningVoice) {
   11786                 mVoiceWakeLock.acquire();
   11787                 updateSleepIfNeededLocked();
   11788             }
   11789         }
   11790     }
   11791 
   11792     private void updateEventDispatchingLocked() {
   11793         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
   11794     }
   11795 
   11796     public void setLockScreenShown(boolean showing, boolean occluded) {
   11797         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   11798                 != PackageManager.PERMISSION_GRANTED) {
   11799             throw new SecurityException("Requires permission "
   11800                     + android.Manifest.permission.DEVICE_POWER);
   11801         }
   11802 
   11803         synchronized(this) {
   11804             long ident = Binder.clearCallingIdentity();
   11805             try {
   11806                 if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
   11807                 mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
   11808                 if (showing && occluded) {
   11809                     // The lock screen is currently showing, but is occluded by a window that can
   11810                     // show on top of the lock screen. In this can we want to dismiss the docked
   11811                     // stack since it will be complicated/risky to try to put the activity on top
   11812                     // of the lock screen in the right fullscreen configuration.
   11813                     mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
   11814                             mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
   11815                 }
   11816 
   11817                 updateSleepIfNeededLocked();
   11818             } finally {
   11819                 Binder.restoreCallingIdentity(ident);
   11820             }
   11821         }
   11822     }
   11823 
   11824     @Override
   11825     public void notifyLockedProfile(@UserIdInt int userId) {
   11826         try {
   11827             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
   11828                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
   11829             }
   11830         } catch (RemoteException ex) {
   11831             throw new SecurityException("Fail to check is caller a privileged app", ex);
   11832         }
   11833 
   11834         synchronized (this) {
   11835             if (mStackSupervisor.isUserLockedProfile(userId)) {
   11836                 final long ident = Binder.clearCallingIdentity();
   11837                 try {
   11838                     final int currentUserId = mUserController.getCurrentUserIdLocked();
   11839 
   11840                     // Drop locked freeform tasks out into the fullscreen stack.
   11841                     // TODO: Redact the tasks in place. It's much better to keep them on the screen
   11842                     //       where they were before, but in an obscured state.
   11843                     mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
   11844 
   11845                     if (mUserController.isLockScreenDisabled(currentUserId)) {
   11846                         // If there is no device lock, we will show the profile's credential page.
   11847                         mActivityStarter.showConfirmDeviceCredential(userId);
   11848                     } else {
   11849                         // Showing launcher to avoid user entering credential twice.
   11850                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
   11851                     }
   11852                 } finally {
   11853                     Binder.restoreCallingIdentity(ident);
   11854                 }
   11855             }
   11856         }
   11857     }
   11858 
   11859     @Override
   11860     public void startConfirmDeviceCredentialIntent(Intent intent) {
   11861         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
   11862         synchronized (this) {
   11863             final long ident = Binder.clearCallingIdentity();
   11864             try {
   11865                 mActivityStarter.startConfirmCredentialIntent(intent);
   11866             } finally {
   11867                 Binder.restoreCallingIdentity(ident);
   11868             }
   11869         }
   11870     }
   11871 
   11872     @Override
   11873     public void stopAppSwitches() {
   11874         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   11875                 != PackageManager.PERMISSION_GRANTED) {
   11876             throw new SecurityException("viewquires permission "
   11877                     + android.Manifest.permission.STOP_APP_SWITCHES);
   11878         }
   11879 
   11880         synchronized(this) {
   11881             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
   11882                     + APP_SWITCH_DELAY_TIME;
   11883             mDidAppSwitch = false;
   11884             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   11885             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   11886             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
   11887         }
   11888     }
   11889 
   11890     public void resumeAppSwitches() {
   11891         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   11892                 != PackageManager.PERMISSION_GRANTED) {
   11893             throw new SecurityException("Requires permission "
   11894                     + android.Manifest.permission.STOP_APP_SWITCHES);
   11895         }
   11896 
   11897         synchronized(this) {
   11898             // Note that we don't execute any pending app switches... we will
   11899             // let those wait until either the timeout, or the next start
   11900             // activity request.
   11901             mAppSwitchesAllowedTime = 0;
   11902         }
   11903     }
   11904 
   11905     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
   11906             int callingPid, int callingUid, String name) {
   11907         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
   11908             return true;
   11909         }
   11910 
   11911         int perm = checkComponentPermission(
   11912                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
   11913                 sourceUid, -1, true);
   11914         if (perm == PackageManager.PERMISSION_GRANTED) {
   11915             return true;
   11916         }
   11917 
   11918         // If the actual IPC caller is different from the logical source, then
   11919         // also see if they are allowed to control app switches.
   11920         if (callingUid != -1 && callingUid != sourceUid) {
   11921             perm = checkComponentPermission(
   11922                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
   11923                     callingUid, -1, true);
   11924             if (perm == PackageManager.PERMISSION_GRANTED) {
   11925                 return true;
   11926             }
   11927         }
   11928 
   11929         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
   11930         return false;
   11931     }
   11932 
   11933     public void setDebugApp(String packageName, boolean waitForDebugger,
   11934             boolean persistent) {
   11935         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   11936                 "setDebugApp()");
   11937 
   11938         long ident = Binder.clearCallingIdentity();
   11939         try {
   11940             // Note that this is not really thread safe if there are multiple
   11941             // callers into it at the same time, but that's not a situation we
   11942             // care about.
   11943             if (persistent) {
   11944                 final ContentResolver resolver = mContext.getContentResolver();
   11945                 Settings.Global.putString(
   11946                     resolver, Settings.Global.DEBUG_APP,
   11947                     packageName);
   11948                 Settings.Global.putInt(
   11949                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
   11950                     waitForDebugger ? 1 : 0);
   11951             }
   11952 
   11953             synchronized (this) {
   11954                 if (!persistent) {
   11955                     mOrigDebugApp = mDebugApp;
   11956                     mOrigWaitForDebugger = mWaitForDebugger;
   11957                 }
   11958                 mDebugApp = packageName;
   11959                 mWaitForDebugger = waitForDebugger;
   11960                 mDebugTransient = !persistent;
   11961                 if (packageName != null) {
   11962                     forceStopPackageLocked(packageName, -1, false, false, true, true,
   11963                             false, UserHandle.USER_ALL, "set debug app");
   11964                 }
   11965             }
   11966         } finally {
   11967             Binder.restoreCallingIdentity(ident);
   11968         }
   11969     }
   11970 
   11971     void setTrackAllocationApp(ApplicationInfo app, String processName) {
   11972         synchronized (this) {
   11973             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   11974             if (!isDebuggable) {
   11975                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   11976                     throw new SecurityException("Process not debuggable: " + app.packageName);
   11977                 }
   11978             }
   11979 
   11980             mTrackAllocationApp = processName;
   11981         }
   11982     }
   11983 
   11984     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
   11985         synchronized (this) {
   11986             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   11987             if (!isDebuggable) {
   11988                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   11989                     throw new SecurityException("Process not debuggable: " + app.packageName);
   11990                 }
   11991             }
   11992             mProfileApp = processName;
   11993             mProfileFile = profilerInfo.profileFile;
   11994             if (mProfileFd != null) {
   11995                 try {
   11996                     mProfileFd.close();
   11997                 } catch (IOException e) {
   11998                 }
   11999                 mProfileFd = null;
   12000             }
   12001             mProfileFd = profilerInfo.profileFd;
   12002             mSamplingInterval = profilerInfo.samplingInterval;
   12003             mAutoStopProfiler = profilerInfo.autoStopProfiler;
   12004             mProfileType = 0;
   12005         }
   12006     }
   12007 
   12008     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
   12009         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   12010         if (!isDebuggable) {
   12011             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   12012                 throw new SecurityException("Process not debuggable: " + app.packageName);
   12013             }
   12014         }
   12015         mNativeDebuggingApp = processName;
   12016     }
   12017 
   12018     @Override
   12019     public void setAlwaysFinish(boolean enabled) {
   12020         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
   12021                 "setAlwaysFinish()");
   12022 
   12023         long ident = Binder.clearCallingIdentity();
   12024         try {
   12025             Settings.Global.putInt(
   12026                     mContext.getContentResolver(),
   12027                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
   12028 
   12029             synchronized (this) {
   12030                 mAlwaysFinishActivities = enabled;
   12031             }
   12032         } finally {
   12033             Binder.restoreCallingIdentity(ident);
   12034         }
   12035     }
   12036 
   12037     @Override
   12038     public void setLenientBackgroundCheck(boolean enabled) {
   12039         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   12040                 "setLenientBackgroundCheck()");
   12041 
   12042         long ident = Binder.clearCallingIdentity();
   12043         try {
   12044             Settings.Global.putInt(
   12045                     mContext.getContentResolver(),
   12046                     Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
   12047 
   12048             synchronized (this) {
   12049                 mLenientBackgroundCheck = enabled;
   12050             }
   12051         } finally {
   12052             Binder.restoreCallingIdentity(ident);
   12053         }
   12054     }
   12055 
   12056     @Override
   12057     public void setActivityController(IActivityController controller, boolean imAMonkey) {
   12058         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   12059                 "setActivityController()");
   12060         synchronized (this) {
   12061             mController = controller;
   12062             mControllerIsAMonkey = imAMonkey;
   12063             Watchdog.getInstance().setActivityController(controller);
   12064         }
   12065     }
   12066 
   12067     @Override
   12068     public void setUserIsMonkey(boolean userIsMonkey) {
   12069         synchronized (this) {
   12070             synchronized (mPidsSelfLocked) {
   12071                 final int callingPid = Binder.getCallingPid();
   12072                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
   12073                 if (precessRecord == null) {
   12074                     throw new SecurityException("Unknown process: " + callingPid);
   12075                 }
   12076                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
   12077                     throw new SecurityException("Only an instrumentation process "
   12078                             + "with a UiAutomation can call setUserIsMonkey");
   12079                 }
   12080             }
   12081             mUserIsMonkey = userIsMonkey;
   12082         }
   12083     }
   12084 
   12085     @Override
   12086     public boolean isUserAMonkey() {
   12087         synchronized (this) {
   12088             // If there is a controller also implies the user is a monkey.
   12089             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
   12090         }
   12091     }
   12092 
   12093     public void requestBugReport(int bugreportType) {
   12094         String service = null;
   12095         switch (bugreportType) {
   12096             case ActivityManager.BUGREPORT_OPTION_FULL:
   12097                 service = "bugreport";
   12098                 break;
   12099             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
   12100                 service = "bugreportplus";
   12101                 break;
   12102             case ActivityManager.BUGREPORT_OPTION_REMOTE:
   12103                 service = "bugreportremote";
   12104                 break;
   12105             case ActivityManager.BUGREPORT_OPTION_WEAR:
   12106                 service = "bugreportwear";
   12107                 break;
   12108         }
   12109         if (service == null) {
   12110             throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
   12111                     + bugreportType);
   12112         }
   12113         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
   12114         SystemProperties.set("ctl.start", service);
   12115     }
   12116 
   12117     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
   12118         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
   12119     }
   12120 
   12121     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
   12122         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
   12123             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
   12124         }
   12125         return KEY_DISPATCHING_TIMEOUT;
   12126     }
   12127 
   12128     @Override
   12129     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
   12130         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   12131                 != PackageManager.PERMISSION_GRANTED) {
   12132             throw new SecurityException("Requires permission "
   12133                     + android.Manifest.permission.FILTER_EVENTS);
   12134         }
   12135         ProcessRecord proc;
   12136         long timeout;
   12137         synchronized (this) {
   12138             synchronized (mPidsSelfLocked) {
   12139                 proc = mPidsSelfLocked.get(pid);
   12140             }
   12141             timeout = getInputDispatchingTimeoutLocked(proc);
   12142         }
   12143 
   12144         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
   12145             return -1;
   12146         }
   12147 
   12148         return timeout;
   12149     }
   12150 
   12151     /**
   12152      * Handle input dispatching timeouts.
   12153      * Returns whether input dispatching should be aborted or not.
   12154      */
   12155     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
   12156             final ActivityRecord activity, final ActivityRecord parent,
   12157             final boolean aboveSystem, String reason) {
   12158         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   12159                 != PackageManager.PERMISSION_GRANTED) {
   12160             throw new SecurityException("Requires permission "
   12161                     + android.Manifest.permission.FILTER_EVENTS);
   12162         }
   12163 
   12164         final String annotation;
   12165         if (reason == null) {
   12166             annotation = "Input dispatching timed out";
   12167         } else {
   12168             annotation = "Input dispatching timed out (" + reason + ")";
   12169         }
   12170 
   12171         if (proc != null) {
   12172             synchronized (this) {
   12173                 if (proc.debugging) {
   12174                     return false;
   12175                 }
   12176 
   12177                 if (mDidDexOpt) {
   12178                     // Give more time since we were dexopting.
   12179                     mDidDexOpt = false;
   12180                     return false;
   12181                 }
   12182 
   12183                 if (proc.instrumentationClass != null) {
   12184                     Bundle info = new Bundle();
   12185                     info.putString("shortMsg", "keyDispatchingTimedOut");
   12186                     info.putString("longMsg", annotation);
   12187                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
   12188                     return true;
   12189                 }
   12190             }
   12191             mHandler.post(new Runnable() {
   12192                 @Override
   12193                 public void run() {
   12194                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
   12195                 }
   12196             });
   12197         }
   12198 
   12199         return true;
   12200     }
   12201 
   12202     @Override
   12203     public Bundle getAssistContextExtras(int requestType) {
   12204         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
   12205                 null, null, true /* focused */, true /* newSessionId */,
   12206                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
   12207         if (pae == null) {
   12208             return null;
   12209         }
   12210         synchronized (pae) {
   12211             while (!pae.haveResult) {
   12212                 try {
   12213                     pae.wait();
   12214                 } catch (InterruptedException e) {
   12215                 }
   12216             }
   12217         }
   12218         synchronized (this) {
   12219             buildAssistBundleLocked(pae, pae.result);
   12220             mPendingAssistExtras.remove(pae);
   12221             mUiHandler.removeCallbacks(pae);
   12222         }
   12223         return pae.extras;
   12224     }
   12225 
   12226     @Override
   12227     public boolean isAssistDataAllowedOnCurrentActivity() {
   12228         int userId;
   12229         synchronized (this) {
   12230             userId = mUserController.getCurrentUserIdLocked();
   12231             ActivityRecord activity = getFocusedStack().topActivity();
   12232             if (activity == null) {
   12233                 return false;
   12234             }
   12235             userId = activity.userId;
   12236         }
   12237         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
   12238                 Context.DEVICE_POLICY_SERVICE);
   12239         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
   12240     }
   12241 
   12242     @Override
   12243     public boolean showAssistFromActivity(IBinder token, Bundle args) {
   12244         long ident = Binder.clearCallingIdentity();
   12245         try {
   12246             synchronized (this) {
   12247                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
   12248                 ActivityRecord top = getFocusedStack().topActivity();
   12249                 if (top != caller) {
   12250                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
   12251                             + " is not current top " + top);
   12252                     return false;
   12253                 }
   12254                 if (!top.nowVisible) {
   12255                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
   12256                             + " is not visible");
   12257                     return false;
   12258                 }
   12259             }
   12260             AssistUtils utils = new AssistUtils(mContext);
   12261             return utils.showSessionForActiveService(args,
   12262                     VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
   12263         } finally {
   12264             Binder.restoreCallingIdentity(ident);
   12265         }
   12266     }
   12267 
   12268     @Override
   12269     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
   12270             Bundle receiverExtras,
   12271             IBinder activityToken, boolean focused, boolean newSessionId) {
   12272         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
   12273                 activityToken, focused, newSessionId,
   12274                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
   12275                 != null;
   12276     }
   12277 
   12278     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
   12279             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
   12280             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
   12281         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
   12282                 "enqueueAssistContext()");
   12283         synchronized (this) {
   12284             ActivityRecord activity = getFocusedStack().topActivity();
   12285             if (activity == null) {
   12286                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
   12287                 return null;
   12288             }
   12289             if (activity.app == null || activity.app.thread == null) {
   12290                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
   12291                 return null;
   12292             }
   12293             if (focused) {
   12294                 if (activityToken != null) {
   12295                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
   12296                     if (activity != caller) {
   12297                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
   12298                                 + " is not current top " + activity);
   12299                         return null;
   12300                     }
   12301                 }
   12302             } else {
   12303                 activity = ActivityRecord.forTokenLocked(activityToken);
   12304                 if (activity == null) {
   12305                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
   12306                             + " couldn't be found");
   12307                     return null;
   12308                 }
   12309             }
   12310 
   12311             PendingAssistExtras pae;
   12312             Bundle extras = new Bundle();
   12313             if (args != null) {
   12314                 extras.putAll(args);
   12315             }
   12316             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
   12317             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
   12318             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
   12319                     userHandle);
   12320             // Increment the sessionId if necessary
   12321             if (newSessionId) {
   12322                 mViSessionId++;
   12323             }
   12324             try {
   12325                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
   12326                         requestType, mViSessionId);
   12327                 mPendingAssistExtras.add(pae);
   12328                 mUiHandler.postDelayed(pae, timeout);
   12329             } catch (RemoteException e) {
   12330                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
   12331                 return null;
   12332             }
   12333             return pae;
   12334         }
   12335     }
   12336 
   12337     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
   12338         IResultReceiver receiver;
   12339         synchronized (this) {
   12340             mPendingAssistExtras.remove(pae);
   12341             receiver = pae.receiver;
   12342         }
   12343         if (receiver != null) {
   12344             // Caller wants result sent back to them.
   12345             Bundle sendBundle = new Bundle();
   12346             // At least return the receiver extras
   12347             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
   12348                     pae.receiverExtras);
   12349             try {
   12350                 pae.receiver.send(0, sendBundle);
   12351             } catch (RemoteException e) {
   12352             }
   12353         }
   12354     }
   12355 
   12356     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
   12357         if (result != null) {
   12358             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
   12359         }
   12360         if (pae.hint != null) {
   12361             pae.extras.putBoolean(pae.hint, true);
   12362         }
   12363     }
   12364 
   12365     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
   12366             AssistContent content, Uri referrer) {
   12367         PendingAssistExtras pae = (PendingAssistExtras)token;
   12368         synchronized (pae) {
   12369             pae.result = extras;
   12370             pae.structure = structure;
   12371             pae.content = content;
   12372             if (referrer != null) {
   12373                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
   12374             }
   12375             pae.haveResult = true;
   12376             pae.notifyAll();
   12377             if (pae.intent == null && pae.receiver == null) {
   12378                 // Caller is just waiting for the result.
   12379                 return;
   12380             }
   12381         }
   12382 
   12383         // We are now ready to launch the assist activity.
   12384         IResultReceiver sendReceiver = null;
   12385         Bundle sendBundle = null;
   12386         synchronized (this) {
   12387             buildAssistBundleLocked(pae, extras);
   12388             boolean exists = mPendingAssistExtras.remove(pae);
   12389             mUiHandler.removeCallbacks(pae);
   12390             if (!exists) {
   12391                 // Timed out.
   12392                 return;
   12393             }
   12394             if ((sendReceiver=pae.receiver) != null) {
   12395                 // Caller wants result sent back to them.
   12396                 sendBundle = new Bundle();
   12397                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
   12398                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
   12399                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
   12400                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
   12401                         pae.receiverExtras);
   12402             }
   12403         }
   12404         if (sendReceiver != null) {
   12405             try {
   12406                 sendReceiver.send(0, sendBundle);
   12407             } catch (RemoteException e) {
   12408             }
   12409             return;
   12410         }
   12411 
   12412         long ident = Binder.clearCallingIdentity();
   12413         try {
   12414             pae.intent.replaceExtras(pae.extras);
   12415             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
   12416                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
   12417                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
   12418             closeSystemDialogs("assist");
   12419             try {
   12420                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
   12421             } catch (ActivityNotFoundException e) {
   12422                 Slog.w(TAG, "No activity to handle assist action.", e);
   12423             }
   12424         } finally {
   12425             Binder.restoreCallingIdentity(ident);
   12426         }
   12427     }
   12428 
   12429     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
   12430             Bundle args) {
   12431         return enqueueAssistContext(requestType, intent, hint, null, null, null,
   12432                 true /* focused */, true /* newSessionId */,
   12433                 userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
   12434     }
   12435 
   12436     public void registerProcessObserver(IProcessObserver observer) {
   12437         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   12438                 "registerProcessObserver()");
   12439         synchronized (this) {
   12440             mProcessObservers.register(observer);
   12441         }
   12442     }
   12443 
   12444     @Override
   12445     public void unregisterProcessObserver(IProcessObserver observer) {
   12446         synchronized (this) {
   12447             mProcessObservers.unregister(observer);
   12448         }
   12449     }
   12450 
   12451     @Override
   12452     public void registerUidObserver(IUidObserver observer, int which) {
   12453         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   12454                 "registerUidObserver()");
   12455         synchronized (this) {
   12456             mUidObservers.register(observer, which);
   12457         }
   12458     }
   12459 
   12460     @Override
   12461     public void unregisterUidObserver(IUidObserver observer) {
   12462         synchronized (this) {
   12463             mUidObservers.unregister(observer);
   12464         }
   12465     }
   12466 
   12467     @Override
   12468     public boolean convertFromTranslucent(IBinder token) {
   12469         final long origId = Binder.clearCallingIdentity();
   12470         try {
   12471             synchronized (this) {
   12472                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12473                 if (r == null) {
   12474                     return false;
   12475                 }
   12476                 final boolean translucentChanged = r.changeWindowTranslucency(true);
   12477                 if (translucentChanged) {
   12478                     r.task.stack.releaseBackgroundResources(r);
   12479                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   12480                 }
   12481                 mWindowManager.setAppFullscreen(token, true);
   12482                 return translucentChanged;
   12483             }
   12484         } finally {
   12485             Binder.restoreCallingIdentity(origId);
   12486         }
   12487     }
   12488 
   12489     @Override
   12490     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
   12491         final long origId = Binder.clearCallingIdentity();
   12492         try {
   12493             synchronized (this) {
   12494                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12495                 if (r == null) {
   12496                     return false;
   12497                 }
   12498                 int index = r.task.mActivities.lastIndexOf(r);
   12499                 if (index > 0) {
   12500                     ActivityRecord under = r.task.mActivities.get(index - 1);
   12501                     under.returningOptions = options;
   12502                 }
   12503                 final boolean translucentChanged = r.changeWindowTranslucency(false);
   12504                 if (translucentChanged) {
   12505                     r.task.stack.convertActivityToTranslucent(r);
   12506                 }
   12507                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   12508                 mWindowManager.setAppFullscreen(token, false);
   12509                 return translucentChanged;
   12510             }
   12511         } finally {
   12512             Binder.restoreCallingIdentity(origId);
   12513         }
   12514     }
   12515 
   12516     @Override
   12517     public boolean requestVisibleBehind(IBinder token, boolean visible) {
   12518         final long origId = Binder.clearCallingIdentity();
   12519         try {
   12520             synchronized (this) {
   12521                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12522                 if (r != null) {
   12523                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
   12524                 }
   12525             }
   12526             return false;
   12527         } finally {
   12528             Binder.restoreCallingIdentity(origId);
   12529         }
   12530     }
   12531 
   12532     @Override
   12533     public boolean isBackgroundVisibleBehind(IBinder token) {
   12534         final long origId = Binder.clearCallingIdentity();
   12535         try {
   12536             synchronized (this) {
   12537                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
   12538                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
   12539                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
   12540                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
   12541                 return visible;
   12542             }
   12543         } finally {
   12544             Binder.restoreCallingIdentity(origId);
   12545         }
   12546     }
   12547 
   12548     @Override
   12549     public ActivityOptions getActivityOptions(IBinder token) {
   12550         final long origId = Binder.clearCallingIdentity();
   12551         try {
   12552             synchronized (this) {
   12553                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12554                 if (r != null) {
   12555                     final ActivityOptions activityOptions = r.pendingOptions;
   12556                     r.pendingOptions = null;
   12557                     return activityOptions;
   12558                 }
   12559                 return null;
   12560             }
   12561         } finally {
   12562             Binder.restoreCallingIdentity(origId);
   12563         }
   12564     }
   12565 
   12566     @Override
   12567     public void setImmersive(IBinder token, boolean immersive) {
   12568         synchronized(this) {
   12569             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12570             if (r == null) {
   12571                 throw new IllegalArgumentException();
   12572             }
   12573             r.immersive = immersive;
   12574 
   12575             // update associated state if we're frontmost
   12576             if (r == mFocusedActivity) {
   12577                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
   12578                 applyUpdateLockStateLocked(r);
   12579             }
   12580         }
   12581     }
   12582 
   12583     @Override
   12584     public boolean isImmersive(IBinder token) {
   12585         synchronized (this) {
   12586             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12587             if (r == null) {
   12588                 throw new IllegalArgumentException();
   12589             }
   12590             return r.immersive;
   12591         }
   12592     }
   12593 
   12594     public void setVrThread(int tid) {
   12595         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
   12596             throw new UnsupportedOperationException("VR mode not supported on this device!");
   12597         }
   12598 
   12599         synchronized (this) {
   12600             ProcessRecord proc;
   12601             synchronized (mPidsSelfLocked) {
   12602                 final int pid = Binder.getCallingPid();
   12603                 proc = mPidsSelfLocked.get(pid);
   12604 
   12605                 if (proc != null && mInVrMode && tid >= 0) {
   12606                     // ensure the tid belongs to the process
   12607                     if (!Process.isThreadInProcess(pid, tid)) {
   12608                         throw new IllegalArgumentException("VR thread does not belong to process");
   12609                     }
   12610 
   12611                     // reset existing VR thread to CFS if this thread still exists and belongs to
   12612                     // the calling process
   12613                     if (proc.vrThreadTid != 0
   12614                             && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
   12615                         try {
   12616                             Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
   12617                         } catch (IllegalArgumentException e) {
   12618                             // Ignore this.  Only occurs in race condition where previous VR thread
   12619                             // was destroyed during this method call.
   12620                         }
   12621                     }
   12622 
   12623                     proc.vrThreadTid = tid;
   12624 
   12625                     // promote to FIFO now if the tid is non-zero
   12626                     try {
   12627                         if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
   12628                             proc.vrThreadTid > 0) {
   12629                             Process.setThreadScheduler(proc.vrThreadTid,
   12630                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
   12631                         }
   12632                     } catch (IllegalArgumentException e) {
   12633                         Slog.e(TAG, "Failed to set scheduling policy, thread does"
   12634                                + " not exist:\n" + e);
   12635                     }
   12636                 }
   12637             }
   12638         }
   12639     }
   12640 
   12641     @Override
   12642     public void setRenderThread(int tid) {
   12643         synchronized (this) {
   12644             ProcessRecord proc;
   12645             synchronized (mPidsSelfLocked) {
   12646                 int pid = Binder.getCallingPid();
   12647                 proc = mPidsSelfLocked.get(pid);
   12648                 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
   12649                     // ensure the tid belongs to the process
   12650                     if (!Process.isThreadInProcess(pid, tid)) {
   12651                         throw new IllegalArgumentException(
   12652                             "Render thread does not belong to process");
   12653                     }
   12654                     proc.renderThreadTid = tid;
   12655                     if (DEBUG_OOM_ADJ) {
   12656                         Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
   12657                     }
   12658                     // promote to FIFO now
   12659                     if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
   12660                         if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
   12661                         if (mUseFifoUiScheduling) {
   12662                             Process.setThreadScheduler(proc.renderThreadTid,
   12663                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
   12664                         } else {
   12665                             Process.setThreadPriority(proc.renderThreadTid, -10);
   12666                         }
   12667                     }
   12668                 } else {
   12669                     if (DEBUG_OOM_ADJ) {
   12670                         Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
   12671                                "PID: " + pid + ", TID: " + tid + " FIFO: " +
   12672                                mUseFifoUiScheduling);
   12673                     }
   12674                 }
   12675             }
   12676         }
   12677     }
   12678 
   12679     @Override
   12680     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
   12681         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
   12682             throw new UnsupportedOperationException("VR mode not supported on this device!");
   12683         }
   12684 
   12685         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
   12686 
   12687         ActivityRecord r;
   12688         synchronized (this) {
   12689             r = ActivityRecord.isInStackLocked(token);
   12690         }
   12691 
   12692         if (r == null) {
   12693             throw new IllegalArgumentException();
   12694         }
   12695 
   12696         int err;
   12697         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
   12698                 VrManagerInternal.NO_ERROR) {
   12699             return err;
   12700         }
   12701 
   12702         synchronized(this) {
   12703             r.requestedVrComponent = (enabled) ? packageName : null;
   12704 
   12705             // Update associated state if this activity is currently focused
   12706             if (r == mFocusedActivity) {
   12707                 applyUpdateVrModeLocked(r);
   12708             }
   12709             return 0;
   12710         }
   12711     }
   12712 
   12713     @Override
   12714     public boolean isVrModePackageEnabled(ComponentName packageName) {
   12715         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
   12716             throw new UnsupportedOperationException("VR mode not supported on this device!");
   12717         }
   12718 
   12719         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
   12720 
   12721         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
   12722                 VrManagerInternal.NO_ERROR;
   12723     }
   12724 
   12725     public boolean isTopActivityImmersive() {
   12726         enforceNotIsolatedCaller("startActivity");
   12727         synchronized (this) {
   12728             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
   12729             return (r != null) ? r.immersive : false;
   12730         }
   12731     }
   12732 
   12733     @Override
   12734     public boolean isTopOfTask(IBinder token) {
   12735         synchronized (this) {
   12736             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12737             if (r == null) {
   12738                 throw new IllegalArgumentException();
   12739             }
   12740             return r.task.getTopActivity() == r;
   12741         }
   12742     }
   12743 
   12744     @Override
   12745     public void setHasTopUi(boolean hasTopUi) throws RemoteException {
   12746         if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
   12747             String msg = "Permission Denial: setHasTopUi() from pid="
   12748                     + Binder.getCallingPid()
   12749                     + ", uid=" + Binder.getCallingUid()
   12750                     + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
   12751             Slog.w(TAG, msg);
   12752             throw new SecurityException(msg);
   12753         }
   12754         final int pid = Binder.getCallingPid();
   12755         final long origId = Binder.clearCallingIdentity();
   12756         try {
   12757             synchronized (this) {
   12758                 boolean changed = false;
   12759                 ProcessRecord pr;
   12760                 synchronized (mPidsSelfLocked) {
   12761                     pr = mPidsSelfLocked.get(pid);
   12762                     if (pr == null) {
   12763                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
   12764                         return;
   12765                     }
   12766                     if (pr.hasTopUi != hasTopUi) {
   12767                         Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
   12768                         pr.hasTopUi = hasTopUi;
   12769                         changed = true;
   12770                     }
   12771                 }
   12772                 if (changed) {
   12773                     updateOomAdjLocked(pr);
   12774                 }
   12775             }
   12776         } finally {
   12777             Binder.restoreCallingIdentity(origId);
   12778         }
   12779     }
   12780 
   12781     public final void enterSafeMode() {
   12782         synchronized(this) {
   12783             // It only makes sense to do this before the system is ready
   12784             // and started launching other packages.
   12785             if (!mSystemReady) {
   12786                 try {
   12787                     AppGlobals.getPackageManager().enterSafeMode();
   12788                 } catch (RemoteException e) {
   12789                 }
   12790             }
   12791 
   12792             mSafeMode = true;
   12793         }
   12794     }
   12795 
   12796     public final void showSafeModeOverlay() {
   12797         View v = LayoutInflater.from(mContext).inflate(
   12798                 com.android.internal.R.layout.safe_mode, null);
   12799         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
   12800         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
   12801         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
   12802         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
   12803         lp.gravity = Gravity.BOTTOM | Gravity.START;
   12804         lp.format = v.getBackground().getOpacity();
   12805         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
   12806                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
   12807         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
   12808         ((WindowManager)mContext.getSystemService(
   12809                 Context.WINDOW_SERVICE)).addView(v, lp);
   12810     }
   12811 
   12812     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
   12813         if (sender != null && !(sender instanceof PendingIntentRecord)) {
   12814             return;
   12815         }
   12816         final PendingIntentRecord rec = (PendingIntentRecord)sender;
   12817         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   12818         synchronized (stats) {
   12819             if (mBatteryStatsService.isOnBattery()) {
   12820                 mBatteryStatsService.enforceCallingPermission();
   12821                 int MY_UID = Binder.getCallingUid();
   12822                 final int uid;
   12823                 if (sender == null) {
   12824                     uid = sourceUid;
   12825                 } else {
   12826                     uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   12827                 }
   12828                 BatteryStatsImpl.Uid.Pkg pkg =
   12829                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
   12830                             sourcePkg != null ? sourcePkg : rec.key.packageName);
   12831                 pkg.noteWakeupAlarmLocked(tag);
   12832             }
   12833         }
   12834     }
   12835 
   12836     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
   12837         if (sender != null && !(sender instanceof PendingIntentRecord)) {
   12838             return;
   12839         }
   12840         final PendingIntentRecord rec = (PendingIntentRecord)sender;
   12841         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   12842         synchronized (stats) {
   12843             mBatteryStatsService.enforceCallingPermission();
   12844             int MY_UID = Binder.getCallingUid();
   12845             final int uid;
   12846             if (sender == null) {
   12847                 uid = sourceUid;
   12848             } else {
   12849                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   12850             }
   12851             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
   12852         }
   12853     }
   12854 
   12855     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
   12856         if (sender != null && !(sender instanceof PendingIntentRecord)) {
   12857             return;
   12858         }
   12859         final PendingIntentRecord rec = (PendingIntentRecord)sender;
   12860         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   12861         synchronized (stats) {
   12862             mBatteryStatsService.enforceCallingPermission();
   12863             int MY_UID = Binder.getCallingUid();
   12864             final int uid;
   12865             if (sender == null) {
   12866                 uid = sourceUid;
   12867             } else {
   12868                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   12869             }
   12870             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
   12871         }
   12872     }
   12873 
   12874     public boolean killPids(int[] pids, String pReason, boolean secure) {
   12875         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   12876             throw new SecurityException("killPids only available to the system");
   12877         }
   12878         String reason = (pReason == null) ? "Unknown" : pReason;
   12879         // XXX Note: don't acquire main activity lock here, because the window
   12880         // manager calls in with its locks held.
   12881 
   12882         boolean killed = false;
   12883         synchronized (mPidsSelfLocked) {
   12884             int worstType = 0;
   12885             for (int i=0; i<pids.length; i++) {
   12886                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   12887                 if (proc != null) {
   12888                     int type = proc.setAdj;
   12889                     if (type > worstType) {
   12890                         worstType = type;
   12891                     }
   12892                 }
   12893             }
   12894 
   12895             // If the worst oom_adj is somewhere in the cached proc LRU range,
   12896             // then constrain it so we will kill all cached procs.
   12897             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
   12898                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
   12899                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
   12900             }
   12901 
   12902             // If this is not a secure call, don't let it kill processes that
   12903             // are important.
   12904             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
   12905                 worstType = ProcessList.SERVICE_ADJ;
   12906             }
   12907 
   12908             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
   12909             for (int i=0; i<pids.length; i++) {
   12910                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   12911                 if (proc == null) {
   12912                     continue;
   12913                 }
   12914                 int adj = proc.setAdj;
   12915                 if (adj >= worstType && !proc.killedByAm) {
   12916                     proc.kill(reason, true);
   12917                     killed = true;
   12918                 }
   12919             }
   12920         }
   12921         return killed;
   12922     }
   12923 
   12924     @Override
   12925     public void killUid(int appId, int userId, String reason) {
   12926         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
   12927         synchronized (this) {
   12928             final long identity = Binder.clearCallingIdentity();
   12929             try {
   12930                 killPackageProcessesLocked(null, appId, userId,
   12931                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
   12932                         reason != null ? reason : "kill uid");
   12933             } finally {
   12934                 Binder.restoreCallingIdentity(identity);
   12935             }
   12936         }
   12937     }
   12938 
   12939     @Override
   12940     public boolean killProcessesBelowForeground(String reason) {
   12941         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   12942             throw new SecurityException("killProcessesBelowForeground() only available to system");
   12943         }
   12944 
   12945         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
   12946     }
   12947 
   12948     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
   12949         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   12950             throw new SecurityException("killProcessesBelowAdj() only available to system");
   12951         }
   12952 
   12953         boolean killed = false;
   12954         synchronized (mPidsSelfLocked) {
   12955             final int size = mPidsSelfLocked.size();
   12956             for (int i = 0; i < size; i++) {
   12957                 final int pid = mPidsSelfLocked.keyAt(i);
   12958                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   12959                 if (proc == null) continue;
   12960 
   12961                 final int adj = proc.setAdj;
   12962                 if (adj > belowAdj && !proc.killedByAm) {
   12963                     proc.kill(reason, true);
   12964                     killed = true;
   12965                 }
   12966             }
   12967         }
   12968         return killed;
   12969     }
   12970 
   12971     @Override
   12972     public void hang(final IBinder who, boolean allowRestart) {
   12973         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   12974                 != PackageManager.PERMISSION_GRANTED) {
   12975             throw new SecurityException("Requires permission "
   12976                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   12977         }
   12978 
   12979         final IBinder.DeathRecipient death = new DeathRecipient() {
   12980             @Override
   12981             public void binderDied() {
   12982                 synchronized (this) {
   12983                     notifyAll();
   12984                 }
   12985             }
   12986         };
   12987 
   12988         try {
   12989             who.linkToDeath(death, 0);
   12990         } catch (RemoteException e) {
   12991             Slog.w(TAG, "hang: given caller IBinder is already dead.");
   12992             return;
   12993         }
   12994 
   12995         synchronized (this) {
   12996             Watchdog.getInstance().setAllowRestart(allowRestart);
   12997             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
   12998             synchronized (death) {
   12999                 while (who.isBinderAlive()) {
   13000                     try {
   13001                         death.wait();
   13002                     } catch (InterruptedException e) {
   13003                     }
   13004                 }
   13005             }
   13006             Watchdog.getInstance().setAllowRestart(true);
   13007         }
   13008     }
   13009 
   13010     @Override
   13011     public void restart() {
   13012         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   13013                 != PackageManager.PERMISSION_GRANTED) {
   13014             throw new SecurityException("Requires permission "
   13015                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   13016         }
   13017 
   13018         Log.i(TAG, "Sending shutdown broadcast...");
   13019 
   13020         BroadcastReceiver br = new BroadcastReceiver() {
   13021             @Override public void onReceive(Context context, Intent intent) {
   13022                 // Now the broadcast is done, finish up the low-level shutdown.
   13023                 Log.i(TAG, "Shutting down activity manager...");
   13024                 shutdown(10000);
   13025                 Log.i(TAG, "Shutdown complete, restarting!");
   13026                 Process.killProcess(Process.myPid());
   13027                 System.exit(10);
   13028             }
   13029         };
   13030 
   13031         // First send the high-level shut down broadcast.
   13032         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
   13033         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   13034         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
   13035         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
   13036         mContext.sendOrderedBroadcastAsUser(intent,
   13037                 UserHandle.ALL, null, br, mHandler, 0, null, null);
   13038         */
   13039         br.onReceive(mContext, intent);
   13040     }
   13041 
   13042     private long getLowRamTimeSinceIdle(long now) {
   13043         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
   13044     }
   13045 
   13046     @Override
   13047     public void performIdleMaintenance() {
   13048         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   13049                 != PackageManager.PERMISSION_GRANTED) {
   13050             throw new SecurityException("Requires permission "
   13051                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   13052         }
   13053 
   13054         synchronized (this) {
   13055             final long now = SystemClock.uptimeMillis();
   13056             final long timeSinceLastIdle = now - mLastIdleTime;
   13057             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
   13058             mLastIdleTime = now;
   13059             mLowRamTimeSinceLastIdle = 0;
   13060             if (mLowRamStartTime != 0) {
   13061                 mLowRamStartTime = now;
   13062             }
   13063 
   13064             StringBuilder sb = new StringBuilder(128);
   13065             sb.append("Idle maintenance over ");
   13066             TimeUtils.formatDuration(timeSinceLastIdle, sb);
   13067             sb.append(" low RAM for ");
   13068             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
   13069             Slog.i(TAG, sb.toString());
   13070 
   13071             // If at least 1/3 of our time since the last idle period has been spent
   13072             // with RAM low, then we want to kill processes.
   13073             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
   13074 
   13075             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   13076                 ProcessRecord proc = mLruProcesses.get(i);
   13077                 if (proc.notCachedSinceIdle) {
   13078                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
   13079                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
   13080                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
   13081                         if (doKilling && proc.initialIdlePss != 0
   13082                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
   13083                             sb = new StringBuilder(128);
   13084                             sb.append("Kill");
   13085                             sb.append(proc.processName);
   13086                             sb.append(" in idle maint: pss=");
   13087                             sb.append(proc.lastPss);
   13088                             sb.append(", swapPss=");
   13089                             sb.append(proc.lastSwapPss);
   13090                             sb.append(", initialPss=");
   13091                             sb.append(proc.initialIdlePss);
   13092                             sb.append(", period=");
   13093                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
   13094                             sb.append(", lowRamPeriod=");
   13095                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
   13096                             Slog.wtfQuiet(TAG, sb.toString());
   13097                             proc.kill("idle maint (pss " + proc.lastPss
   13098                                     + " from " + proc.initialIdlePss + ")", true);
   13099                         }
   13100                     }
   13101                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
   13102                         && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
   13103                     proc.notCachedSinceIdle = true;
   13104                     proc.initialIdlePss = 0;
   13105                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
   13106                             mTestPssMode, isSleepingLocked(), now);
   13107                 }
   13108             }
   13109 
   13110             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
   13111             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
   13112         }
   13113     }
   13114 
   13115     @Override
   13116     public void sendIdleJobTrigger() {
   13117         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   13118                 != PackageManager.PERMISSION_GRANTED) {
   13119             throw new SecurityException("Requires permission "
   13120                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   13121         }
   13122 
   13123         final long ident = Binder.clearCallingIdentity();
   13124         try {
   13125             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
   13126                     .setPackage("android")
   13127                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   13128             broadcastIntent(null, intent, null, null, 0, null, null, null,
   13129                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
   13130         } finally {
   13131             Binder.restoreCallingIdentity(ident);
   13132         }
   13133     }
   13134 
   13135     private void retrieveSettings() {
   13136         final ContentResolver resolver = mContext.getContentResolver();
   13137         final boolean freeformWindowManagement =
   13138                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
   13139                         || Settings.Global.getInt(
   13140                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
   13141         final boolean supportsPictureInPicture =
   13142                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
   13143 
   13144         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
   13145         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
   13146         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
   13147         final boolean alwaysFinishActivities =
   13148                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
   13149         final boolean lenientBackgroundCheck =
   13150                 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
   13151         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
   13152         final boolean forceResizable = Settings.Global.getInt(
   13153                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
   13154         final boolean supportsLeanbackOnly =
   13155                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
   13156 
   13157         // Transfer any global setting for forcing RTL layout, into a System Property
   13158         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
   13159 
   13160         final Configuration configuration = new Configuration();
   13161         Settings.System.getConfiguration(resolver, configuration);
   13162         if (forceRtl) {
   13163             // This will take care of setting the correct layout direction flags
   13164             configuration.setLayoutDirection(configuration.locale);
   13165         }
   13166 
   13167         synchronized (this) {
   13168             mDebugApp = mOrigDebugApp = debugApp;
   13169             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
   13170             mAlwaysFinishActivities = alwaysFinishActivities;
   13171             mLenientBackgroundCheck = lenientBackgroundCheck;
   13172             mSupportsLeanbackOnly = supportsLeanbackOnly;
   13173             mForceResizableActivities = forceResizable;
   13174             mWindowManager.setForceResizableTasks(mForceResizableActivities);
   13175             if (supportsMultiWindow || forceResizable) {
   13176                 mSupportsMultiWindow = true;
   13177                 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
   13178                 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
   13179             } else {
   13180                 mSupportsMultiWindow = false;
   13181                 mSupportsFreeformWindowManagement = false;
   13182                 mSupportsPictureInPicture = false;
   13183             }
   13184             // This happens before any activities are started, so we can
   13185             // change mConfiguration in-place.
   13186             updateConfigurationLocked(configuration, null, true);
   13187             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
   13188                     "Initial config: " + mConfiguration);
   13189 
   13190             // Load resources only after the current configuration has been set.
   13191             final Resources res = mContext.getResources();
   13192             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
   13193             mThumbnailWidth = res.getDimensionPixelSize(
   13194                     com.android.internal.R.dimen.thumbnail_width);
   13195             mThumbnailHeight = res.getDimensionPixelSize(
   13196                     com.android.internal.R.dimen.thumbnail_height);
   13197             mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
   13198                     com.android.internal.R.string.config_defaultPictureInPictureBounds));
   13199             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
   13200                     com.android.internal.R.string.config_appsNotReportingCrashes));
   13201             if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
   13202                 mFullscreenThumbnailScale = (float) res
   13203                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
   13204                     (float) mConfiguration.screenWidthDp;
   13205             } else {
   13206                 mFullscreenThumbnailScale = res.getFraction(
   13207                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
   13208             }
   13209         }
   13210     }
   13211 
   13212     public boolean testIsSystemReady() {
   13213         // no need to synchronize(this) just to read & return the value
   13214         return mSystemReady;
   13215     }
   13216 
   13217     public void systemReady(final Runnable goingCallback) {
   13218         synchronized(this) {
   13219             if (mSystemReady) {
   13220                 // If we're done calling all the receivers, run the next "boot phase" passed in
   13221                 // by the SystemServer
   13222                 if (goingCallback != null) {
   13223                     goingCallback.run();
   13224                 }
   13225                 return;
   13226             }
   13227 
   13228             mLocalDeviceIdleController
   13229                     = LocalServices.getService(DeviceIdleController.LocalService.class);
   13230 
   13231             // Make sure we have the current profile info, since it is needed for security checks.
   13232             mUserController.onSystemReady();
   13233             mRecentTasks.onSystemReadyLocked();
   13234             mAppOpsService.systemReady();
   13235             mSystemReady = true;
   13236         }
   13237 
   13238         ArrayList<ProcessRecord> procsToKill = null;
   13239         synchronized(mPidsSelfLocked) {
   13240             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
   13241                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   13242                 if (!isAllowedWhileBooting(proc.info)){
   13243                     if (procsToKill == null) {
   13244                         procsToKill = new ArrayList<ProcessRecord>();
   13245                     }
   13246                     procsToKill.add(proc);
   13247                 }
   13248             }
   13249         }
   13250 
   13251         synchronized(this) {
   13252             if (procsToKill != null) {
   13253                 for (int i=procsToKill.size()-1; i>=0; i--) {
   13254                     ProcessRecord proc = procsToKill.get(i);
   13255                     Slog.i(TAG, "Removing system update proc: " + proc);
   13256                     removeProcessLocked(proc, true, false, "system update done");
   13257                 }
   13258             }
   13259 
   13260             // Now that we have cleaned up any update processes, we
   13261             // are ready to start launching real processes and know that
   13262             // we won't trample on them any more.
   13263             mProcessesReady = true;
   13264         }
   13265 
   13266         Slog.i(TAG, "System now ready");
   13267         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
   13268             SystemClock.uptimeMillis());
   13269 
   13270         synchronized(this) {
   13271             // Make sure we have no pre-ready processes sitting around.
   13272 
   13273             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   13274                 ResolveInfo ri = mContext.getPackageManager()
   13275                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
   13276                                 STOCK_PM_FLAGS);
   13277                 CharSequence errorMsg = null;
   13278                 if (ri != null) {
   13279                     ActivityInfo ai = ri.activityInfo;
   13280                     ApplicationInfo app = ai.applicationInfo;
   13281                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   13282                         mTopAction = Intent.ACTION_FACTORY_TEST;
   13283                         mTopData = null;
   13284                         mTopComponent = new ComponentName(app.packageName,
   13285                                 ai.name);
   13286                     } else {
   13287                         errorMsg = mContext.getResources().getText(
   13288                                 com.android.internal.R.string.factorytest_not_system);
   13289                     }
   13290                 } else {
   13291                     errorMsg = mContext.getResources().getText(
   13292                             com.android.internal.R.string.factorytest_no_action);
   13293                 }
   13294                 if (errorMsg != null) {
   13295                     mTopAction = null;
   13296                     mTopData = null;
   13297                     mTopComponent = null;
   13298                     Message msg = Message.obtain();
   13299                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
   13300                     msg.getData().putCharSequence("msg", errorMsg);
   13301                     mUiHandler.sendMessage(msg);
   13302                 }
   13303             }
   13304         }
   13305 
   13306         retrieveSettings();
   13307         final int currentUserId;
   13308         synchronized (this) {
   13309             currentUserId = mUserController.getCurrentUserIdLocked();
   13310             readGrantedUriPermissionsLocked();
   13311         }
   13312 
   13313         if (goingCallback != null) goingCallback.run();
   13314 
   13315         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
   13316                 Integer.toString(currentUserId), currentUserId);
   13317         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
   13318                 Integer.toString(currentUserId), currentUserId);
   13319         mSystemServiceManager.startUser(currentUserId);
   13320 
   13321         synchronized (this) {
   13322             // Only start up encryption-aware persistent apps; once user is
   13323             // unlocked we'll come back around and start unaware apps
   13324             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
   13325 
   13326             // Start up initial activity.
   13327             mBooting = true;
   13328             // Enable home activity for system user, so that the system can always boot
   13329             if (UserManager.isSplitSystemUser()) {
   13330                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
   13331                 try {
   13332                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
   13333                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
   13334                             UserHandle.USER_SYSTEM);
   13335                 } catch (RemoteException e) {
   13336                     throw e.rethrowAsRuntimeException();
   13337                 }
   13338             }
   13339             startHomeActivityLocked(currentUserId, "systemReady");
   13340 
   13341             try {
   13342                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
   13343                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
   13344                             + " data partition or your device will be unstable.");
   13345                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
   13346                 }
   13347             } catch (RemoteException e) {
   13348             }
   13349 
   13350             if (!Build.isBuildConsistent()) {
   13351                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
   13352                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
   13353             }
   13354 
   13355             long ident = Binder.clearCallingIdentity();
   13356             try {
   13357                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
   13358                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   13359                         | Intent.FLAG_RECEIVER_FOREGROUND);
   13360                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
   13361                 broadcastIntentLocked(null, null, intent,
   13362                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   13363                         null, false, false, MY_PID, Process.SYSTEM_UID,
   13364                         currentUserId);
   13365                 intent = new Intent(Intent.ACTION_USER_STARTING);
   13366                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   13367                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
   13368                 broadcastIntentLocked(null, null, intent,
   13369                         null, new IIntentReceiver.Stub() {
   13370                             @Override
   13371                             public void performReceive(Intent intent, int resultCode, String data,
   13372                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
   13373                                     throws RemoteException {
   13374                             }
   13375                         }, 0, null, null,
   13376                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
   13377                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   13378             } catch (Throwable t) {
   13379                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
   13380             } finally {
   13381                 Binder.restoreCallingIdentity(ident);
   13382             }
   13383             mStackSupervisor.resumeFocusedStackTopActivityLocked();
   13384             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
   13385         }
   13386     }
   13387 
   13388     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
   13389         synchronized (this) {
   13390             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
   13391         }
   13392     }
   13393 
   13394     void skipCurrentReceiverLocked(ProcessRecord app) {
   13395         for (BroadcastQueue queue : mBroadcastQueues) {
   13396             queue.skipCurrentReceiverLocked(app);
   13397         }
   13398     }
   13399 
   13400     /**
   13401      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
   13402      * The application process will exit immediately after this call returns.
   13403      * @param app object of the crashing app, null for the system server
   13404      * @param crashInfo describing the exception
   13405      */
   13406     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
   13407         ProcessRecord r = findAppProcess(app, "Crash");
   13408         final String processName = app == null ? "system_server"
   13409                 : (r == null ? "unknown" : r.processName);
   13410 
   13411         handleApplicationCrashInner("crash", r, processName, crashInfo);
   13412     }
   13413 
   13414     /* Native crash reporting uses this inner version because it needs to be somewhat
   13415      * decoupled from the AM-managed cleanup lifecycle
   13416      */
   13417     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
   13418             ApplicationErrorReport.CrashInfo crashInfo) {
   13419         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
   13420                 UserHandle.getUserId(Binder.getCallingUid()), processName,
   13421                 r == null ? -1 : r.info.flags,
   13422                 crashInfo.exceptionClassName,
   13423                 crashInfo.exceptionMessage,
   13424                 crashInfo.throwFileName,
   13425                 crashInfo.throwLineNumber);
   13426 
   13427         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
   13428 
   13429         mAppErrors.crashApplication(r, crashInfo);
   13430     }
   13431 
   13432     public void handleApplicationStrictModeViolation(
   13433             IBinder app,
   13434             int violationMask,
   13435             StrictMode.ViolationInfo info) {
   13436         ProcessRecord r = findAppProcess(app, "StrictMode");
   13437         if (r == null) {
   13438             return;
   13439         }
   13440 
   13441         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
   13442             Integer stackFingerprint = info.hashCode();
   13443             boolean logIt = true;
   13444             synchronized (mAlreadyLoggedViolatedStacks) {
   13445                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
   13446                     logIt = false;
   13447                     // TODO: sub-sample into EventLog for these, with
   13448                     // the info.durationMillis?  Then we'd get
   13449                     // the relative pain numbers, without logging all
   13450                     // the stack traces repeatedly.  We'd want to do
   13451                     // likewise in the client code, which also does
   13452                     // dup suppression, before the Binder call.
   13453                 } else {
   13454                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
   13455                         mAlreadyLoggedViolatedStacks.clear();
   13456                     }
   13457                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
   13458                 }
   13459             }
   13460             if (logIt) {
   13461                 logStrictModeViolationToDropBox(r, info);
   13462             }
   13463         }
   13464 
   13465         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
   13466             AppErrorResult result = new AppErrorResult();
   13467             synchronized (this) {
   13468                 final long origId = Binder.clearCallingIdentity();
   13469 
   13470                 Message msg = Message.obtain();
   13471                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
   13472                 HashMap<String, Object> data = new HashMap<String, Object>();
   13473                 data.put("result", result);
   13474                 data.put("app", r);
   13475                 data.put("violationMask", violationMask);
   13476                 data.put("info", info);
   13477                 msg.obj = data;
   13478                 mUiHandler.sendMessage(msg);
   13479 
   13480                 Binder.restoreCallingIdentity(origId);
   13481             }
   13482             int res = result.get();
   13483             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
   13484         }
   13485     }
   13486 
   13487     // Depending on the policy in effect, there could be a bunch of
   13488     // these in quick succession so we try to batch these together to
   13489     // minimize disk writes, number of dropbox entries, and maximize
   13490     // compression, by having more fewer, larger records.
   13491     private void logStrictModeViolationToDropBox(
   13492             ProcessRecord process,
   13493             StrictMode.ViolationInfo info) {
   13494         if (info == null) {
   13495             return;
   13496         }
   13497         final boolean isSystemApp = process == null ||
   13498                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
   13499                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
   13500         final String processName = process == null ? "unknown" : process.processName;
   13501         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
   13502         final DropBoxManager dbox = (DropBoxManager)
   13503                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   13504 
   13505         // Exit early if the dropbox isn't configured to accept this report type.
   13506         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   13507 
   13508         boolean bufferWasEmpty;
   13509         boolean needsFlush;
   13510         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
   13511         synchronized (sb) {
   13512             bufferWasEmpty = sb.length() == 0;
   13513             appendDropBoxProcessHeaders(process, processName, sb);
   13514             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   13515             sb.append("System-App: ").append(isSystemApp).append("\n");
   13516             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
   13517             if (info.violationNumThisLoop != 0) {
   13518                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
   13519             }
   13520             if (info.numAnimationsRunning != 0) {
   13521                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
   13522             }
   13523             if (info.broadcastIntentAction != null) {
   13524                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
   13525             }
   13526             if (info.durationMillis != -1) {
   13527                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
   13528             }
   13529             if (info.numInstances != -1) {
   13530                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
   13531             }
   13532             if (info.tags != null) {
   13533                 for (String tag : info.tags) {
   13534                     sb.append("Span-Tag: ").append(tag).append("\n");
   13535                 }
   13536             }
   13537             sb.append("\n");
   13538             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
   13539                 sb.append(info.crashInfo.stackTrace);
   13540                 sb.append("\n");
   13541             }
   13542             if (info.message != null) {
   13543                 sb.append(info.message);
   13544                 sb.append("\n");
   13545             }
   13546 
   13547             // Only buffer up to ~64k.  Various logging bits truncate
   13548             // things at 128k.
   13549             needsFlush = (sb.length() > 64 * 1024);
   13550         }
   13551 
   13552         // Flush immediately if the buffer's grown too large, or this
   13553         // is a non-system app.  Non-system apps are isolated with a
   13554         // different tag & policy and not batched.
   13555         //
   13556         // Batching is useful during internal testing with
   13557         // StrictMode settings turned up high.  Without batching,
   13558         // thousands of separate files could be created on boot.
   13559         if (!isSystemApp || needsFlush) {
   13560             new Thread("Error dump: " + dropboxTag) {
   13561                 @Override
   13562                 public void run() {
   13563                     String report;
   13564                     synchronized (sb) {
   13565                         report = sb.toString();
   13566                         sb.delete(0, sb.length());
   13567                         sb.trimToSize();
   13568                     }
   13569                     if (report.length() != 0) {
   13570                         dbox.addText(dropboxTag, report);
   13571                     }
   13572                 }
   13573             }.start();
   13574             return;
   13575         }
   13576 
   13577         // System app batching:
   13578         if (!bufferWasEmpty) {
   13579             // An existing dropbox-writing thread is outstanding, so
   13580             // we don't need to start it up.  The existing thread will
   13581             // catch the buffer appends we just did.
   13582             return;
   13583         }
   13584 
   13585         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
   13586         // (After this point, we shouldn't access AMS internal data structures.)
   13587         new Thread("Error dump: " + dropboxTag) {
   13588             @Override
   13589             public void run() {
   13590                 // 5 second sleep to let stacks arrive and be batched together
   13591                 try {
   13592                     Thread.sleep(5000);  // 5 seconds
   13593                 } catch (InterruptedException e) {}
   13594 
   13595                 String errorReport;
   13596                 synchronized (mStrictModeBuffer) {
   13597                     errorReport = mStrictModeBuffer.toString();
   13598                     if (errorReport.length() == 0) {
   13599                         return;
   13600                     }
   13601                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
   13602                     mStrictModeBuffer.trimToSize();
   13603                 }
   13604                 dbox.addText(dropboxTag, errorReport);
   13605             }
   13606         }.start();
   13607     }
   13608 
   13609     /**
   13610      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
   13611      * @param app object of the crashing app, null for the system server
   13612      * @param tag reported by the caller
   13613      * @param system whether this wtf is coming from the system
   13614      * @param crashInfo describing the context of the error
   13615      * @return true if the process should exit immediately (WTF is fatal)
   13616      */
   13617     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
   13618             final ApplicationErrorReport.CrashInfo crashInfo) {
   13619         final int callingUid = Binder.getCallingUid();
   13620         final int callingPid = Binder.getCallingPid();
   13621 
   13622         if (system) {
   13623             // If this is coming from the system, we could very well have low-level
   13624             // system locks held, so we want to do this all asynchronously.  And we
   13625             // never want this to become fatal, so there is that too.
   13626             mHandler.post(new Runnable() {
   13627                 @Override public void run() {
   13628                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
   13629                 }
   13630             });
   13631             return false;
   13632         }
   13633 
   13634         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
   13635                 crashInfo);
   13636 
   13637         if (r != null && r.pid != Process.myPid() &&
   13638                 Settings.Global.getInt(mContext.getContentResolver(),
   13639                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
   13640             mAppErrors.crashApplication(r, crashInfo);
   13641             return true;
   13642         } else {
   13643             return false;
   13644         }
   13645     }
   13646 
   13647     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
   13648             final ApplicationErrorReport.CrashInfo crashInfo) {
   13649         final ProcessRecord r = findAppProcess(app, "WTF");
   13650         final String processName = app == null ? "system_server"
   13651                 : (r == null ? "unknown" : r.processName);
   13652 
   13653         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
   13654                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
   13655 
   13656         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
   13657 
   13658         return r;
   13659     }
   13660 
   13661     /**
   13662      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
   13663      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
   13664      */
   13665     private ProcessRecord findAppProcess(IBinder app, String reason) {
   13666         if (app == null) {
   13667             return null;
   13668         }
   13669 
   13670         synchronized (this) {
   13671             final int NP = mProcessNames.getMap().size();
   13672             for (int ip=0; ip<NP; ip++) {
   13673                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   13674                 final int NA = apps.size();
   13675                 for (int ia=0; ia<NA; ia++) {
   13676                     ProcessRecord p = apps.valueAt(ia);
   13677                     if (p.thread != null && p.thread.asBinder() == app) {
   13678                         return p;
   13679                     }
   13680                 }
   13681             }
   13682 
   13683             Slog.w(TAG, "Can't find mystery application for " + reason
   13684                     + " from pid=" + Binder.getCallingPid()
   13685                     + " uid=" + Binder.getCallingUid() + ": " + app);
   13686             return null;
   13687         }
   13688     }
   13689 
   13690     /**
   13691      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
   13692      * to append various headers to the dropbox log text.
   13693      */
   13694     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
   13695             StringBuilder sb) {
   13696         // Watchdog thread ends up invoking this function (with
   13697         // a null ProcessRecord) to add the stack file to dropbox.
   13698         // Do not acquire a lock on this (am) in such cases, as it
   13699         // could cause a potential deadlock, if and when watchdog
   13700         // is invoked due to unavailability of lock on am and it
   13701         // would prevent watchdog from killing system_server.
   13702         if (process == null) {
   13703             sb.append("Process: ").append(processName).append("\n");
   13704             return;
   13705         }
   13706         // Note: ProcessRecord 'process' is guarded by the service
   13707         // instance.  (notably process.pkgList, which could otherwise change
   13708         // concurrently during execution of this method)
   13709         synchronized (this) {
   13710             sb.append("Process: ").append(processName).append("\n");
   13711             int flags = process.info.flags;
   13712             IPackageManager pm = AppGlobals.getPackageManager();
   13713             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
   13714             for (int ip=0; ip<process.pkgList.size(); ip++) {
   13715                 String pkg = process.pkgList.keyAt(ip);
   13716                 sb.append("Package: ").append(pkg);
   13717                 try {
   13718                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
   13719                     if (pi != null) {
   13720                         sb.append(" v").append(pi.versionCode);
   13721                         if (pi.versionName != null) {
   13722                             sb.append(" (").append(pi.versionName).append(")");
   13723                         }
   13724                     }
   13725                 } catch (RemoteException e) {
   13726                     Slog.e(TAG, "Error getting package info: " + pkg, e);
   13727                 }
   13728                 sb.append("\n");
   13729             }
   13730         }
   13731     }
   13732 
   13733     private static String processClass(ProcessRecord process) {
   13734         if (process == null || process.pid == MY_PID) {
   13735             return "system_server";
   13736         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   13737             return "system_app";
   13738         } else {
   13739             return "data_app";
   13740         }
   13741     }
   13742 
   13743     private volatile long mWtfClusterStart;
   13744     private volatile int mWtfClusterCount;
   13745 
   13746     /**
   13747      * Write a description of an error (crash, WTF, ANR) to the drop box.
   13748      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
   13749      * @param process which caused the error, null means the system server
   13750      * @param activity which triggered the error, null if unknown
   13751      * @param parent activity related to the error, null if unknown
   13752      * @param subject line related to the error, null if absent
   13753      * @param report in long form describing the error, null if absent
   13754      * @param dataFile text file to include in the report, null if none
   13755      * @param crashInfo giving an application stack trace, null if absent
   13756      */
   13757     public void addErrorToDropBox(String eventType,
   13758             ProcessRecord process, String processName, ActivityRecord activity,
   13759             ActivityRecord parent, String subject,
   13760             final String report, final File dataFile,
   13761             final ApplicationErrorReport.CrashInfo crashInfo) {
   13762         // NOTE -- this must never acquire the ActivityManagerService lock,
   13763         // otherwise the watchdog may be prevented from resetting the system.
   13764 
   13765         final String dropboxTag = processClass(process) + "_" + eventType;
   13766         final DropBoxManager dbox = (DropBoxManager)
   13767                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   13768 
   13769         // Exit early if the dropbox isn't configured to accept this report type.
   13770         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   13771 
   13772         // Rate-limit how often we're willing to do the heavy lifting below to
   13773         // collect and record logs; currently 5 logs per 10 second period.
   13774         final long now = SystemClock.elapsedRealtime();
   13775         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
   13776             mWtfClusterStart = now;
   13777             mWtfClusterCount = 1;
   13778         } else {
   13779             if (mWtfClusterCount++ >= 5) return;
   13780         }
   13781 
   13782         final StringBuilder sb = new StringBuilder(1024);
   13783         appendDropBoxProcessHeaders(process, processName, sb);
   13784         if (process != null) {
   13785             sb.append("Foreground: ")
   13786                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
   13787                     .append("\n");
   13788         }
   13789         if (activity != null) {
   13790             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
   13791         }
   13792         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
   13793             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
   13794         }
   13795         if (parent != null && parent != activity) {
   13796             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
   13797         }
   13798         if (subject != null) {
   13799             sb.append("Subject: ").append(subject).append("\n");
   13800         }
   13801         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   13802         if (Debug.isDebuggerConnected()) {
   13803             sb.append("Debugger: Connected\n");
   13804         }
   13805         sb.append("\n");
   13806 
   13807         // Do the rest in a worker thread to avoid blocking the caller on I/O
   13808         // (After this point, we shouldn't access AMS internal data structures.)
   13809         Thread worker = new Thread("Error dump: " + dropboxTag) {
   13810             @Override
   13811             public void run() {
   13812                 if (report != null) {
   13813                     sb.append(report);
   13814                 }
   13815 
   13816                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
   13817                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
   13818                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
   13819                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
   13820 
   13821                 if (dataFile != null && maxDataFileSize > 0) {
   13822                     try {
   13823                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
   13824                                     "\n\n[[TRUNCATED]]"));
   13825                     } catch (IOException e) {
   13826                         Slog.e(TAG, "Error reading " + dataFile, e);
   13827                     }
   13828                 }
   13829                 if (crashInfo != null && crashInfo.stackTrace != null) {
   13830                     sb.append(crashInfo.stackTrace);
   13831                 }
   13832 
   13833                 if (lines > 0) {
   13834                     sb.append("\n");
   13835 
   13836                     // Merge several logcat streams, and take the last N lines
   13837                     InputStreamReader input = null;
   13838                     try {
   13839                         java.lang.Process logcat = new ProcessBuilder(
   13840                                 "/system/bin/timeout", "-k", "15s", "10s",
   13841                                 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
   13842                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
   13843                                         .redirectErrorStream(true).start();
   13844 
   13845                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
   13846                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
   13847                         input = new InputStreamReader(logcat.getInputStream());
   13848 
   13849                         int num;
   13850                         char[] buf = new char[8192];
   13851                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
   13852                     } catch (IOException e) {
   13853                         Slog.e(TAG, "Error running logcat", e);
   13854                     } finally {
   13855                         if (input != null) try { input.close(); } catch (IOException e) {}
   13856                     }
   13857                 }
   13858 
   13859                 dbox.addText(dropboxTag, sb.toString());
   13860             }
   13861         };
   13862 
   13863         if (process == null) {
   13864             // If process is null, we are being called from some internal code
   13865             // and may be about to die -- run this synchronously.
   13866             worker.run();
   13867         } else {
   13868             worker.start();
   13869         }
   13870     }
   13871 
   13872     @Override
   13873     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
   13874         enforceNotIsolatedCaller("getProcessesInErrorState");
   13875         // assume our apps are happy - lazy create the list
   13876         List<ActivityManager.ProcessErrorStateInfo> errList = null;
   13877 
   13878         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
   13879                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
   13880         int userId = UserHandle.getUserId(Binder.getCallingUid());
   13881 
   13882         synchronized (this) {
   13883 
   13884             // iterate across all processes
   13885             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   13886                 ProcessRecord app = mLruProcesses.get(i);
   13887                 if (!allUsers && app.userId != userId) {
   13888                     continue;
   13889                 }
   13890                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
   13891                     // This one's in trouble, so we'll generate a report for it
   13892                     // crashes are higher priority (in case there's a crash *and* an anr)
   13893                     ActivityManager.ProcessErrorStateInfo report = null;
   13894                     if (app.crashing) {
   13895                         report = app.crashingReport;
   13896                     } else if (app.notResponding) {
   13897                         report = app.notRespondingReport;
   13898                     }
   13899 
   13900                     if (report != null) {
   13901                         if (errList == null) {
   13902                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
   13903                         }
   13904                         errList.add(report);
   13905                     } else {
   13906                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
   13907                                 " crashing = " + app.crashing +
   13908                                 " notResponding = " + app.notResponding);
   13909                     }
   13910                 }
   13911             }
   13912         }
   13913 
   13914         return errList;
   13915     }
   13916 
   13917     static int procStateToImportance(int procState, int memAdj,
   13918             ActivityManager.RunningAppProcessInfo currApp) {
   13919         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
   13920         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
   13921             currApp.lru = memAdj;
   13922         } else {
   13923             currApp.lru = 0;
   13924         }
   13925         return imp;
   13926     }
   13927 
   13928     private void fillInProcMemInfo(ProcessRecord app,
   13929             ActivityManager.RunningAppProcessInfo outInfo) {
   13930         outInfo.pid = app.pid;
   13931         outInfo.uid = app.info.uid;
   13932         if (mHeavyWeightProcess == app) {
   13933             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
   13934         }
   13935         if (app.persistent) {
   13936             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
   13937         }
   13938         if (app.activities.size() > 0) {
   13939             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
   13940         }
   13941         outInfo.lastTrimLevel = app.trimMemoryLevel;
   13942         int adj = app.curAdj;
   13943         int procState = app.curProcState;
   13944         outInfo.importance = procStateToImportance(procState, adj, outInfo);
   13945         outInfo.importanceReasonCode = app.adjTypeCode;
   13946         outInfo.processState = app.curProcState;
   13947     }
   13948 
   13949     @Override
   13950     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
   13951         enforceNotIsolatedCaller("getRunningAppProcesses");
   13952 
   13953         final int callingUid = Binder.getCallingUid();
   13954 
   13955         // Lazy instantiation of list
   13956         List<ActivityManager.RunningAppProcessInfo> runList = null;
   13957         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
   13958                 callingUid) == PackageManager.PERMISSION_GRANTED;
   13959         final int userId = UserHandle.getUserId(callingUid);
   13960         final boolean allUids = isGetTasksAllowed(
   13961                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
   13962 
   13963         synchronized (this) {
   13964             // Iterate across all processes
   13965             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   13966                 ProcessRecord app = mLruProcesses.get(i);
   13967                 if ((!allUsers && app.userId != userId)
   13968                         || (!allUids && app.uid != callingUid)) {
   13969                     continue;
   13970                 }
   13971                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
   13972                     // Generate process state info for running application
   13973                     ActivityManager.RunningAppProcessInfo currApp =
   13974                         new ActivityManager.RunningAppProcessInfo(app.processName,
   13975                                 app.pid, app.getPackageList());
   13976                     fillInProcMemInfo(app, currApp);
   13977                     if (app.adjSource instanceof ProcessRecord) {
   13978                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
   13979                         currApp.importanceReasonImportance =
   13980                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
   13981                                         app.adjSourceProcState);
   13982                     } else if (app.adjSource instanceof ActivityRecord) {
   13983                         ActivityRecord r = (ActivityRecord)app.adjSource;
   13984                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
   13985                     }
   13986                     if (app.adjTarget instanceof ComponentName) {
   13987                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
   13988                     }
   13989                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
   13990                     //        + " lru=" + currApp.lru);
   13991                     if (runList == null) {
   13992                         runList = new ArrayList<>();
   13993                     }
   13994                     runList.add(currApp);
   13995                 }
   13996             }
   13997         }
   13998         return runList;
   13999     }
   14000 
   14001     @Override
   14002     public List<ApplicationInfo> getRunningExternalApplications() {
   14003         enforceNotIsolatedCaller("getRunningExternalApplications");
   14004         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
   14005         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
   14006         if (runningApps != null && runningApps.size() > 0) {
   14007             Set<String> extList = new HashSet<String>();
   14008             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
   14009                 if (app.pkgList != null) {
   14010                     for (String pkg : app.pkgList) {
   14011                         extList.add(pkg);
   14012                     }
   14013                 }
   14014             }
   14015             IPackageManager pm = AppGlobals.getPackageManager();
   14016             for (String pkg : extList) {
   14017                 try {
   14018                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
   14019                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
   14020                         retList.add(info);
   14021                     }
   14022                 } catch (RemoteException e) {
   14023                 }
   14024             }
   14025         }
   14026         return retList;
   14027     }
   14028 
   14029     @Override
   14030     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
   14031         enforceNotIsolatedCaller("getMyMemoryState");
   14032         synchronized (this) {
   14033             ProcessRecord proc;
   14034             synchronized (mPidsSelfLocked) {
   14035                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   14036             }
   14037             fillInProcMemInfo(proc, outInfo);
   14038         }
   14039     }
   14040 
   14041     @Override
   14042     public int getMemoryTrimLevel() {
   14043         enforceNotIsolatedCaller("getMyMemoryState");
   14044         synchronized (this) {
   14045             return mLastMemoryLevel;
   14046         }
   14047     }
   14048 
   14049     @Override
   14050     public void onShellCommand(FileDescriptor in, FileDescriptor out,
   14051             FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
   14052         (new ActivityManagerShellCommand(this, false)).exec(
   14053                 this, in, out, err, args, resultReceiver);
   14054     }
   14055 
   14056     @Override
   14057     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   14058         if (checkCallingPermission(android.Manifest.permission.DUMP)
   14059                 != PackageManager.PERMISSION_GRANTED) {
   14060             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   14061                     + Binder.getCallingPid()
   14062                     + ", uid=" + Binder.getCallingUid()
   14063                     + " without permission "
   14064                     + android.Manifest.permission.DUMP);
   14065             return;
   14066         }
   14067 
   14068         boolean dumpAll = false;
   14069         boolean dumpClient = false;
   14070         boolean dumpCheckin = false;
   14071         boolean dumpCheckinFormat = false;
   14072         String dumpPackage = null;
   14073 
   14074         int opti = 0;
   14075         while (opti < args.length) {
   14076             String opt = args[opti];
   14077             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   14078                 break;
   14079             }
   14080             opti++;
   14081             if ("-a".equals(opt)) {
   14082                 dumpAll = true;
   14083             } else if ("-c".equals(opt)) {
   14084                 dumpClient = true;
   14085             } else if ("-p".equals(opt)) {
   14086                 if (opti < args.length) {
   14087                     dumpPackage = args[opti];
   14088                     opti++;
   14089                 } else {
   14090                     pw.println("Error: -p option requires package argument");
   14091                     return;
   14092                 }
   14093                 dumpClient = true;
   14094             } else if ("--checkin".equals(opt)) {
   14095                 dumpCheckin = dumpCheckinFormat = true;
   14096             } else if ("-C".equals(opt)) {
   14097                 dumpCheckinFormat = true;
   14098             } else if ("-h".equals(opt)) {
   14099                 ActivityManagerShellCommand.dumpHelp(pw, true);
   14100                 return;
   14101             } else {
   14102                 pw.println("Unknown argument: " + opt + "; use -h for help");
   14103             }
   14104         }
   14105 
   14106         long origId = Binder.clearCallingIdentity();
   14107         boolean more = false;
   14108         // Is the caller requesting to dump a particular piece of data?
   14109         if (opti < args.length) {
   14110             String cmd = args[opti];
   14111             opti++;
   14112             if ("activities".equals(cmd) || "a".equals(cmd)) {
   14113                 synchronized (this) {
   14114                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
   14115                 }
   14116             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
   14117                 synchronized (this) {
   14118                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
   14119                 }
   14120             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
   14121                 String[] newArgs;
   14122                 String name;
   14123                 if (opti >= args.length) {
   14124                     name = null;
   14125                     newArgs = EMPTY_STRING_ARRAY;
   14126                 } else {
   14127                     dumpPackage = args[opti];
   14128                     opti++;
   14129                     newArgs = new String[args.length - opti];
   14130                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   14131                             args.length - opti);
   14132                 }
   14133                 synchronized (this) {
   14134                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
   14135                 }
   14136             } else if ("broadcast-stats".equals(cmd)) {
   14137                 String[] newArgs;
   14138                 String name;
   14139                 if (opti >= args.length) {
   14140                     name = null;
   14141                     newArgs = EMPTY_STRING_ARRAY;
   14142                 } else {
   14143                     dumpPackage = args[opti];
   14144                     opti++;
   14145                     newArgs = new String[args.length - opti];
   14146                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   14147                             args.length - opti);
   14148                 }
   14149                 synchronized (this) {
   14150                     if (dumpCheckinFormat) {
   14151                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
   14152                                 dumpPackage);
   14153                     } else {
   14154                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
   14155                     }
   14156                 }
   14157             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
   14158                 String[] newArgs;
   14159                 String name;
   14160                 if (opti >= args.length) {
   14161                     name = null;
   14162                     newArgs = EMPTY_STRING_ARRAY;
   14163                 } else {
   14164                     dumpPackage = args[opti];
   14165                     opti++;
   14166                     newArgs = new String[args.length - opti];
   14167                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   14168                             args.length - opti);
   14169                 }
   14170                 synchronized (this) {
   14171                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
   14172                 }
   14173             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
   14174                 String[] newArgs;
   14175                 String name;
   14176                 if (opti >= args.length) {
   14177                     name = null;
   14178                     newArgs = EMPTY_STRING_ARRAY;
   14179                 } else {
   14180                     dumpPackage = args[opti];
   14181                     opti++;
   14182                     newArgs = new String[args.length - opti];
   14183                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   14184                             args.length - opti);
   14185                 }
   14186                 synchronized (this) {
   14187                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
   14188                 }
   14189             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
   14190                 synchronized (this) {
   14191                     dumpOomLocked(fd, pw, args, opti, true);
   14192                 }
   14193             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
   14194                 synchronized (this) {
   14195                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
   14196                 }
   14197             } else if ("provider".equals(cmd)) {
   14198                 String[] newArgs;
   14199                 String name;
   14200                 if (opti >= args.length) {
   14201                     name = null;
   14202                     newArgs = EMPTY_STRING_ARRAY;
   14203                 } else {
   14204                     name = args[opti];
   14205                     opti++;
   14206                     newArgs = new String[args.length - opti];
   14207                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   14208                 }
   14209                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
   14210                     pw.println("No providers match: " + name);
   14211                     pw.println("Use -h for help.");
   14212                 }
   14213             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
   14214                 synchronized (this) {
   14215                     dumpProvidersLocked(fd, pw, args, opti, true, null);
   14216                 }
   14217             } else if ("service".equals(cmd)) {
   14218                 String[] newArgs;
   14219                 String name;
   14220                 if (opti >= args.length) {
   14221                     name = null;
   14222                     newArgs = EMPTY_STRING_ARRAY;
   14223                 } else {
   14224                     name = args[opti];
   14225                     opti++;
   14226                     newArgs = new String[args.length - opti];
   14227                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   14228                             args.length - opti);
   14229                 }
   14230                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
   14231                     pw.println("No services match: " + name);
   14232                     pw.println("Use -h for help.");
   14233                 }
   14234             } else if ("package".equals(cmd)) {
   14235                 String[] newArgs;
   14236                 if (opti >= args.length) {
   14237                     pw.println("package: no package name specified");
   14238                     pw.println("Use -h for help.");
   14239                 } else {
   14240                     dumpPackage = args[opti];
   14241                     opti++;
   14242                     newArgs = new String[args.length - opti];
   14243                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   14244                             args.length - opti);
   14245                     args = newArgs;
   14246                     opti = 0;
   14247                     more = true;
   14248                 }
   14249             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
   14250                 synchronized (this) {
   14251                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
   14252                 }
   14253             } else if ("services".equals(cmd) || "s".equals(cmd)) {
   14254                 if (dumpClient) {
   14255                     ActiveServices.ServiceDumper dumper;
   14256                     synchronized (this) {
   14257                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
   14258                                 dumpPackage);
   14259                     }
   14260                     dumper.dumpWithClient();
   14261                 } else {
   14262                     synchronized (this) {
   14263                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
   14264                                 dumpPackage).dumpLocked();
   14265                     }
   14266                 }
   14267             } else if ("locks".equals(cmd)) {
   14268                 LockGuard.dump(fd, pw, args);
   14269             } else {
   14270                 // Dumping a single activity?
   14271                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
   14272                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
   14273                     int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
   14274                     if (res < 0) {
   14275                         pw.println("Bad activity command, or no activities match: " + cmd);
   14276                         pw.println("Use -h for help.");
   14277                     }
   14278                 }
   14279             }
   14280             if (!more) {
   14281                 Binder.restoreCallingIdentity(origId);
   14282                 return;
   14283             }
   14284         }
   14285 
   14286         // No piece of data specified, dump everything.
   14287         if (dumpCheckinFormat) {
   14288             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
   14289         } else if (dumpClient) {
   14290             ActiveServices.ServiceDumper sdumper;
   14291             synchronized (this) {
   14292                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14293                 pw.println();
   14294                 if (dumpAll) {
   14295                     pw.println("-------------------------------------------------------------------------------");
   14296                 }
   14297                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14298                 pw.println();
   14299                 if (dumpAll) {
   14300                     pw.println("-------------------------------------------------------------------------------");
   14301                 }
   14302                 if (dumpAll || dumpPackage != null) {
   14303                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14304                     pw.println();
   14305                     if (dumpAll) {
   14306                         pw.println("-------------------------------------------------------------------------------");
   14307                     }
   14308                 }
   14309                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14310                 pw.println();
   14311                 if (dumpAll) {
   14312                     pw.println("-------------------------------------------------------------------------------");
   14313                 }
   14314                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14315                 pw.println();
   14316                 if (dumpAll) {
   14317                     pw.println("-------------------------------------------------------------------------------");
   14318                 }
   14319                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
   14320                         dumpPackage);
   14321             }
   14322             sdumper.dumpWithClient();
   14323             pw.println();
   14324             synchronized (this) {
   14325                 if (dumpAll) {
   14326                     pw.println("-------------------------------------------------------------------------------");
   14327                 }
   14328                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14329                 pw.println();
   14330                 if (dumpAll) {
   14331                     pw.println("-------------------------------------------------------------------------------");
   14332                 }
   14333                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   14334                 if (mAssociations.size() > 0) {
   14335                     pw.println();
   14336                     if (dumpAll) {
   14337                         pw.println("-------------------------------------------------------------------------------");
   14338                     }
   14339                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   14340                 }
   14341                 pw.println();
   14342                 if (dumpAll) {
   14343                     pw.println("-------------------------------------------------------------------------------");
   14344                 }
   14345                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14346             }
   14347 
   14348         } else {
   14349             synchronized (this) {
   14350                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14351                 pw.println();
   14352                 if (dumpAll) {
   14353                     pw.println("-------------------------------------------------------------------------------");
   14354                 }
   14355                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14356                 pw.println();
   14357                 if (dumpAll) {
   14358                     pw.println("-------------------------------------------------------------------------------");
   14359                 }
   14360                 if (dumpAll || dumpPackage != null) {
   14361                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14362                     pw.println();
   14363                     if (dumpAll) {
   14364                         pw.println("-------------------------------------------------------------------------------");
   14365                     }
   14366                 }
   14367                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14368                 pw.println();
   14369                 if (dumpAll) {
   14370                     pw.println("-------------------------------------------------------------------------------");
   14371                 }
   14372                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14373                 pw.println();
   14374                 if (dumpAll) {
   14375                     pw.println("-------------------------------------------------------------------------------");
   14376                 }
   14377                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
   14378                         .dumpLocked();
   14379                 pw.println();
   14380                 if (dumpAll) {
   14381                     pw.println("-------------------------------------------------------------------------------");
   14382                 }
   14383                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14384                 pw.println();
   14385                 if (dumpAll) {
   14386                     pw.println("-------------------------------------------------------------------------------");
   14387                 }
   14388                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   14389                 if (mAssociations.size() > 0) {
   14390                     pw.println();
   14391                     if (dumpAll) {
   14392                         pw.println("-------------------------------------------------------------------------------");
   14393                     }
   14394                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   14395                 }
   14396                 pw.println();
   14397                 if (dumpAll) {
   14398                     pw.println("-------------------------------------------------------------------------------");
   14399                 }
   14400                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   14401             }
   14402         }
   14403         Binder.restoreCallingIdentity(origId);
   14404     }
   14405 
   14406     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   14407             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   14408         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
   14409 
   14410         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
   14411                 dumpPackage);
   14412         boolean needSep = printedAnything;
   14413 
   14414         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
   14415                 dumpPackage, needSep, "  mFocusedActivity: ");
   14416         if (printed) {
   14417             printedAnything = true;
   14418             needSep = false;
   14419         }
   14420 
   14421         if (dumpPackage == null) {
   14422             if (needSep) {
   14423                 pw.println();
   14424             }
   14425             needSep = true;
   14426             printedAnything = true;
   14427             mStackSupervisor.dump(pw, "  ");
   14428         }
   14429 
   14430         if (!printedAnything) {
   14431             pw.println("  (nothing)");
   14432         }
   14433     }
   14434 
   14435     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   14436             int opti, boolean dumpAll, String dumpPackage) {
   14437         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
   14438 
   14439         boolean printedAnything = false;
   14440 
   14441         if (mRecentTasks != null && mRecentTasks.size() > 0) {
   14442             boolean printedHeader = false;
   14443 
   14444             final int N = mRecentTasks.size();
   14445             for (int i=0; i<N; i++) {
   14446                 TaskRecord tr = mRecentTasks.get(i);
   14447                 if (dumpPackage != null) {
   14448                     if (tr.realActivity == null ||
   14449                             !dumpPackage.equals(tr.realActivity)) {
   14450                         continue;
   14451                     }
   14452                 }
   14453                 if (!printedHeader) {
   14454                     pw.println("  Recent tasks:");
   14455                     printedHeader = true;
   14456                     printedAnything = true;
   14457                 }
   14458                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
   14459                         pw.println(tr);
   14460                 if (dumpAll) {
   14461                     mRecentTasks.get(i).dump(pw, "    ");
   14462                 }
   14463             }
   14464         }
   14465 
   14466         if (!printedAnything) {
   14467             pw.println("  (nothing)");
   14468         }
   14469     }
   14470 
   14471     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   14472             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   14473         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
   14474 
   14475         int dumpUid = 0;
   14476         if (dumpPackage != null) {
   14477             IPackageManager pm = AppGlobals.getPackageManager();
   14478             try {
   14479                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
   14480             } catch (RemoteException e) {
   14481             }
   14482         }
   14483 
   14484         boolean printedAnything = false;
   14485 
   14486         final long now = SystemClock.uptimeMillis();
   14487 
   14488         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
   14489             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
   14490                     = mAssociations.valueAt(i1);
   14491             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
   14492                 SparseArray<ArrayMap<String, Association>> sourceUids
   14493                         = targetComponents.valueAt(i2);
   14494                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
   14495                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
   14496                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
   14497                         Association ass = sourceProcesses.valueAt(i4);
   14498                         if (dumpPackage != null) {
   14499                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
   14500                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
   14501                                 continue;
   14502                             }
   14503                         }
   14504                         printedAnything = true;
   14505                         pw.print("  ");
   14506                         pw.print(ass.mTargetProcess);
   14507                         pw.print("/");
   14508                         UserHandle.formatUid(pw, ass.mTargetUid);
   14509                         pw.print(" <- ");
   14510                         pw.print(ass.mSourceProcess);
   14511                         pw.print("/");
   14512                         UserHandle.formatUid(pw, ass.mSourceUid);
   14513                         pw.println();
   14514                         pw.print("    via ");
   14515                         pw.print(ass.mTargetComponent.flattenToShortString());
   14516                         pw.println();
   14517                         pw.print("    ");
   14518                         long dur = ass.mTime;
   14519                         if (ass.mNesting > 0) {
   14520                             dur += now - ass.mStartTime;
   14521                         }
   14522                         TimeUtils.formatDuration(dur, pw);
   14523                         pw.print(" (");
   14524                         pw.print(ass.mCount);
   14525                         pw.print(" times)");
   14526                         pw.print("  ");
   14527                         for (int i=0; i<ass.mStateTimes.length; i++) {
   14528                             long amt = ass.mStateTimes[i];
   14529                             if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
   14530                                 amt += now - ass.mLastStateUptime;
   14531                             }
   14532                             if (amt != 0) {
   14533                                 pw.print(" ");
   14534                                 pw.print(ProcessList.makeProcStateString(
   14535                                             i + ActivityManager.MIN_PROCESS_STATE));
   14536                                 pw.print("=");
   14537                                 TimeUtils.formatDuration(amt, pw);
   14538                                 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
   14539                                     pw.print("*");
   14540                                 }
   14541                             }
   14542                         }
   14543                         pw.println();
   14544                         if (ass.mNesting > 0) {
   14545                             pw.print("    Currently active: ");
   14546                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
   14547                             pw.println();
   14548                         }
   14549                     }
   14550                 }
   14551             }
   14552 
   14553         }
   14554 
   14555         if (!printedAnything) {
   14556             pw.println("  (nothing)");
   14557         }
   14558     }
   14559 
   14560     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
   14561             String header, boolean needSep) {
   14562         boolean printed = false;
   14563         int whichAppId = -1;
   14564         if (dumpPackage != null) {
   14565             try {
   14566                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
   14567                         dumpPackage, 0);
   14568                 whichAppId = UserHandle.getAppId(info.uid);
   14569             } catch (NameNotFoundException e) {
   14570                 e.printStackTrace();
   14571             }
   14572         }
   14573         for (int i=0; i<uids.size(); i++) {
   14574             UidRecord uidRec = uids.valueAt(i);
   14575             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
   14576                 continue;
   14577             }
   14578             if (!printed) {
   14579                 printed = true;
   14580                 if (needSep) {
   14581                     pw.println();
   14582                 }
   14583                 pw.print("  ");
   14584                 pw.println(header);
   14585                 needSep = true;
   14586             }
   14587             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
   14588             pw.print(": "); pw.println(uidRec);
   14589         }
   14590         return printed;
   14591     }
   14592 
   14593     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   14594             int opti, boolean dumpAll, String dumpPackage) {
   14595         boolean needSep = false;
   14596         boolean printedAnything = false;
   14597         int numPers = 0;
   14598 
   14599         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
   14600 
   14601         if (dumpAll) {
   14602             final int NP = mProcessNames.getMap().size();
   14603             for (int ip=0; ip<NP; ip++) {
   14604                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
   14605                 final int NA = procs.size();
   14606                 for (int ia=0; ia<NA; ia++) {
   14607                     ProcessRecord r = procs.valueAt(ia);
   14608                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   14609                         continue;
   14610                     }
   14611                     if (!needSep) {
   14612                         pw.println("  All known processes:");
   14613                         needSep = true;
   14614                         printedAnything = true;
   14615                     }
   14616                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
   14617                         pw.print(" UID "); pw.print(procs.keyAt(ia));
   14618                         pw.print(" "); pw.println(r);
   14619                     r.dump(pw, "    ");
   14620                     if (r.persistent) {
   14621                         numPers++;
   14622                     }
   14623                 }
   14624             }
   14625         }
   14626 
   14627         if (mIsolatedProcesses.size() > 0) {
   14628             boolean printed = false;
   14629             for (int i=0; i<mIsolatedProcesses.size(); i++) {
   14630                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
   14631                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   14632                     continue;
   14633                 }
   14634                 if (!printed) {
   14635                     if (needSep) {
   14636                         pw.println();
   14637                     }
   14638                     pw.println("  Isolated process list (sorted by uid):");
   14639                     printedAnything = true;
   14640                     printed = true;
   14641                     needSep = true;
   14642                 }
   14643                 pw.println(String.format("%sIsolated #%2d: %s",
   14644                         "    ", i, r.toString()));
   14645             }
   14646         }
   14647 
   14648         if (mActiveUids.size() > 0) {
   14649             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
   14650                 printedAnything = needSep = true;
   14651             }
   14652         }
   14653         if (mValidateUids.size() > 0) {
   14654             if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
   14655                 printedAnything = needSep = true;
   14656             }
   14657         }
   14658 
   14659         if (mLruProcesses.size() > 0) {
   14660             if (needSep) {
   14661                 pw.println();
   14662             }
   14663             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
   14664                     pw.print(" total, non-act at ");
   14665                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   14666                     pw.print(", non-svc at ");
   14667                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   14668                     pw.println("):");
   14669             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
   14670             needSep = true;
   14671             printedAnything = true;
   14672         }
   14673 
   14674         if (dumpAll || dumpPackage != null) {
   14675             synchronized (mPidsSelfLocked) {
   14676                 boolean printed = false;
   14677                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   14678                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
   14679                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   14680                         continue;
   14681                     }
   14682                     if (!printed) {
   14683                         if (needSep) pw.println();
   14684                         needSep = true;
   14685                         pw.println("  PID mappings:");
   14686                         printed = true;
   14687                         printedAnything = true;
   14688                     }
   14689                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
   14690                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
   14691                 }
   14692             }
   14693         }
   14694 
   14695         if (mForegroundProcesses.size() > 0) {
   14696             synchronized (mPidsSelfLocked) {
   14697                 boolean printed = false;
   14698                 for (int i=0; i<mForegroundProcesses.size(); i++) {
   14699                     ProcessRecord r = mPidsSelfLocked.get(
   14700                             mForegroundProcesses.valueAt(i).pid);
   14701                     if (dumpPackage != null && (r == null
   14702                             || !r.pkgList.containsKey(dumpPackage))) {
   14703                         continue;
   14704                     }
   14705                     if (!printed) {
   14706                         if (needSep) pw.println();
   14707                         needSep = true;
   14708                         pw.println("  Foreground Processes:");
   14709                         printed = true;
   14710                         printedAnything = true;
   14711                     }
   14712                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
   14713                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
   14714                 }
   14715             }
   14716         }
   14717 
   14718         if (mPersistentStartingProcesses.size() > 0) {
   14719             if (needSep) pw.println();
   14720             needSep = true;
   14721             printedAnything = true;
   14722             pw.println("  Persisent processes that are starting:");
   14723             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
   14724                     "Starting Norm", "Restarting PERS", dumpPackage);
   14725         }
   14726 
   14727         if (mRemovedProcesses.size() > 0) {
   14728             if (needSep) pw.println();
   14729             needSep = true;
   14730             printedAnything = true;
   14731             pw.println("  Processes that are being removed:");
   14732             dumpProcessList(pw, this, mRemovedProcesses, "    ",
   14733                     "Removed Norm", "Removed PERS", dumpPackage);
   14734         }
   14735 
   14736         if (mProcessesOnHold.size() > 0) {
   14737             if (needSep) pw.println();
   14738             needSep = true;
   14739             printedAnything = true;
   14740             pw.println("  Processes that are on old until the system is ready:");
   14741             dumpProcessList(pw, this, mProcessesOnHold, "    ",
   14742                     "OnHold Norm", "OnHold PERS", dumpPackage);
   14743         }
   14744 
   14745         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
   14746 
   14747         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
   14748         if (needSep) {
   14749             printedAnything = true;
   14750         }
   14751 
   14752         if (dumpPackage == null) {
   14753             pw.println();
   14754             needSep = false;
   14755             mUserController.dump(pw, dumpAll);
   14756         }
   14757         if (mHomeProcess != null && (dumpPackage == null
   14758                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
   14759             if (needSep) {
   14760                 pw.println();
   14761                 needSep = false;
   14762             }
   14763             pw.println("  mHomeProcess: " + mHomeProcess);
   14764         }
   14765         if (mPreviousProcess != null && (dumpPackage == null
   14766                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
   14767             if (needSep) {
   14768                 pw.println();
   14769                 needSep = false;
   14770             }
   14771             pw.println("  mPreviousProcess: " + mPreviousProcess);
   14772         }
   14773         if (dumpAll) {
   14774             StringBuilder sb = new StringBuilder(128);
   14775             sb.append("  mPreviousProcessVisibleTime: ");
   14776             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
   14777             pw.println(sb);
   14778         }
   14779         if (mHeavyWeightProcess != null && (dumpPackage == null
   14780                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
   14781             if (needSep) {
   14782                 pw.println();
   14783                 needSep = false;
   14784             }
   14785             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   14786         }
   14787         if (dumpPackage == null) {
   14788             pw.println("  mConfiguration: " + mConfiguration);
   14789         }
   14790         if (dumpAll) {
   14791             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
   14792             if (mCompatModePackages.getPackages().size() > 0) {
   14793                 boolean printed = false;
   14794                 for (Map.Entry<String, Integer> entry
   14795                         : mCompatModePackages.getPackages().entrySet()) {
   14796                     String pkg = entry.getKey();
   14797                     int mode = entry.getValue();
   14798                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
   14799                         continue;
   14800                     }
   14801                     if (!printed) {
   14802                         pw.println("  mScreenCompatPackages:");
   14803                         printed = true;
   14804                     }
   14805                     pw.print("    "); pw.print(pkg); pw.print(": ");
   14806                             pw.print(mode); pw.println();
   14807                 }
   14808             }
   14809         }
   14810         if (dumpPackage == null) {
   14811             pw.println("  mWakefulness="
   14812                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
   14813             pw.println("  mSleepTokens=" + mSleepTokens);
   14814             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
   14815                     + lockScreenShownToString());
   14816             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
   14817             if (mRunningVoice != null) {
   14818                 pw.println("  mRunningVoice=" + mRunningVoice);
   14819                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
   14820             }
   14821         }
   14822         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
   14823                 || mOrigWaitForDebugger) {
   14824             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
   14825                     || dumpPackage.equals(mOrigDebugApp)) {
   14826                 if (needSep) {
   14827                     pw.println();
   14828                     needSep = false;
   14829                 }
   14830                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
   14831                         + " mDebugTransient=" + mDebugTransient
   14832                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
   14833             }
   14834         }
   14835         if (mCurAppTimeTracker != null) {
   14836             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
   14837         }
   14838         if (mMemWatchProcesses.getMap().size() > 0) {
   14839             pw.println("  Mem watch processes:");
   14840             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
   14841                     = mMemWatchProcesses.getMap();
   14842             for (int i=0; i<procs.size(); i++) {
   14843                 final String proc = procs.keyAt(i);
   14844                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
   14845                 for (int j=0; j<uids.size(); j++) {
   14846                     if (needSep) {
   14847                         pw.println();
   14848                         needSep = false;
   14849                     }
   14850                     StringBuilder sb = new StringBuilder();
   14851                     sb.append("    ").append(proc).append('/');
   14852                     UserHandle.formatUid(sb, uids.keyAt(j));
   14853                     Pair<Long, String> val = uids.valueAt(j);
   14854                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
   14855                     if (val.second != null) {
   14856                         sb.append(", report to ").append(val.second);
   14857                     }
   14858                     pw.println(sb.toString());
   14859                 }
   14860             }
   14861             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
   14862             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
   14863             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
   14864                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
   14865         }
   14866         if (mTrackAllocationApp != null) {
   14867             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
   14868                 if (needSep) {
   14869                     pw.println();
   14870                     needSep = false;
   14871                 }
   14872                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
   14873             }
   14874         }
   14875         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
   14876                 || mProfileFd != null) {
   14877             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
   14878                 if (needSep) {
   14879                     pw.println();
   14880                     needSep = false;
   14881                 }
   14882                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
   14883                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
   14884                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
   14885                         + mAutoStopProfiler);
   14886                 pw.println("  mProfileType=" + mProfileType);
   14887             }
   14888         }
   14889         if (mNativeDebuggingApp != null) {
   14890             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
   14891                 if (needSep) {
   14892                     pw.println();
   14893                     needSep = false;
   14894                 }
   14895                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
   14896             }
   14897         }
   14898         if (dumpPackage == null) {
   14899             if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
   14900                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
   14901                         + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
   14902             }
   14903             if (mController != null) {
   14904                 pw.println("  mController=" + mController
   14905                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
   14906             }
   14907             if (dumpAll) {
   14908                 pw.println("  Total persistent processes: " + numPers);
   14909                 pw.println("  mProcessesReady=" + mProcessesReady
   14910                         + " mSystemReady=" + mSystemReady
   14911                         + " mBooted=" + mBooted
   14912                         + " mFactoryTest=" + mFactoryTest);
   14913                 pw.println("  mBooting=" + mBooting
   14914                         + " mCallFinishBooting=" + mCallFinishBooting
   14915                         + " mBootAnimationComplete=" + mBootAnimationComplete);
   14916                 pw.print("  mLastPowerCheckRealtime=");
   14917                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
   14918                         pw.println("");
   14919                 pw.print("  mLastPowerCheckUptime=");
   14920                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
   14921                         pw.println("");
   14922                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
   14923                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
   14924                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
   14925                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
   14926                         + " (" + mLruProcesses.size() + " total)"
   14927                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
   14928                         + " mNumServiceProcs=" + mNumServiceProcs
   14929                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
   14930                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
   14931                         + " mLastMemoryLevel=" + mLastMemoryLevel
   14932                         + " mLastNumProcesses=" + mLastNumProcesses);
   14933                 long now = SystemClock.uptimeMillis();
   14934                 pw.print("  mLastIdleTime=");
   14935                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
   14936                         pw.print(" mLowRamSinceLastIdle=");
   14937                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
   14938                         pw.println();
   14939             }
   14940         }
   14941 
   14942         if (!printedAnything) {
   14943             pw.println("  (nothing)");
   14944         }
   14945     }
   14946 
   14947     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
   14948             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
   14949         if (mProcessesToGc.size() > 0) {
   14950             boolean printed = false;
   14951             long now = SystemClock.uptimeMillis();
   14952             for (int i=0; i<mProcessesToGc.size(); i++) {
   14953                 ProcessRecord proc = mProcessesToGc.get(i);
   14954                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
   14955                     continue;
   14956                 }
   14957                 if (!printed) {
   14958                     if (needSep) pw.println();
   14959                     needSep = true;
   14960                     pw.println("  Processes that are waiting to GC:");
   14961                     printed = true;
   14962                 }
   14963                 pw.print("    Process "); pw.println(proc);
   14964                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
   14965                         pw.print(", last gced=");
   14966                         pw.print(now-proc.lastRequestedGc);
   14967                         pw.print(" ms ago, last lowMem=");
   14968                         pw.print(now-proc.lastLowMemory);
   14969                         pw.println(" ms ago");
   14970 
   14971             }
   14972         }
   14973         return needSep;
   14974     }
   14975 
   14976     void printOomLevel(PrintWriter pw, String name, int adj) {
   14977         pw.print("    ");
   14978         if (adj >= 0) {
   14979             pw.print(' ');
   14980             if (adj < 10) pw.print(' ');
   14981         } else {
   14982             if (adj > -10) pw.print(' ');
   14983         }
   14984         pw.print(adj);
   14985         pw.print(": ");
   14986         pw.print(name);
   14987         pw.print(" (");
   14988         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
   14989         pw.println(")");
   14990     }
   14991 
   14992     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   14993             int opti, boolean dumpAll) {
   14994         boolean needSep = false;
   14995 
   14996         if (mLruProcesses.size() > 0) {
   14997             if (needSep) pw.println();
   14998             needSep = true;
   14999             pw.println("  OOM levels:");
   15000             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
   15001             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
   15002             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
   15003             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
   15004             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
   15005             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
   15006             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
   15007             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
   15008             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
   15009             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
   15010             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
   15011             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
   15012             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
   15013             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
   15014 
   15015             if (needSep) pw.println();
   15016             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
   15017                     pw.print(" total, non-act at ");
   15018                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   15019                     pw.print(", non-svc at ");
   15020                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   15021                     pw.println("):");
   15022             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
   15023             needSep = true;
   15024         }
   15025 
   15026         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
   15027 
   15028         pw.println();
   15029         pw.println("  mHomeProcess: " + mHomeProcess);
   15030         pw.println("  mPreviousProcess: " + mPreviousProcess);
   15031         if (mHeavyWeightProcess != null) {
   15032             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   15033         }
   15034 
   15035         return true;
   15036     }
   15037 
   15038     /**
   15039      * There are three ways to call this:
   15040      *  - no provider specified: dump all the providers
   15041      *  - a flattened component name that matched an existing provider was specified as the
   15042      *    first arg: dump that one provider
   15043      *  - the first arg isn't the flattened component name of an existing provider:
   15044      *    dump all providers whose component contains the first arg as a substring
   15045      */
   15046     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   15047             int opti, boolean dumpAll) {
   15048         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
   15049     }
   15050 
   15051     static class ItemMatcher {
   15052         ArrayList<ComponentName> components;
   15053         ArrayList<String> strings;
   15054         ArrayList<Integer> objects;
   15055         boolean all;
   15056 
   15057         ItemMatcher() {
   15058             all = true;
   15059         }
   15060 
   15061         void build(String name) {
   15062             ComponentName componentName = ComponentName.unflattenFromString(name);
   15063             if (componentName != null) {
   15064                 if (components == null) {
   15065                     components = new ArrayList<ComponentName>();
   15066                 }
   15067                 components.add(componentName);
   15068                 all = false;
   15069             } else {
   15070                 int objectId = 0;
   15071                 // Not a '/' separated full component name; maybe an object ID?
   15072                 try {
   15073                     objectId = Integer.parseInt(name, 16);
   15074                     if (objects == null) {
   15075                         objects = new ArrayList<Integer>();
   15076                     }
   15077                     objects.add(objectId);
   15078                     all = false;
   15079                 } catch (RuntimeException e) {
   15080                     // Not an integer; just do string match.
   15081                     if (strings == null) {
   15082                         strings = new ArrayList<String>();
   15083                     }
   15084                     strings.add(name);
   15085                     all = false;
   15086                 }
   15087             }
   15088         }
   15089 
   15090         int build(String[] args, int opti) {
   15091             for (; opti<args.length; opti++) {
   15092                 String name = args[opti];
   15093                 if ("--".equals(name)) {
   15094                     return opti+1;
   15095                 }
   15096                 build(name);
   15097             }
   15098             return opti;
   15099         }
   15100 
   15101         boolean match(Object object, ComponentName comp) {
   15102             if (all) {
   15103                 return true;
   15104             }
   15105             if (components != null) {
   15106                 for (int i=0; i<components.size(); i++) {
   15107                     if (components.get(i).equals(comp)) {
   15108                         return true;
   15109                     }
   15110                 }
   15111             }
   15112             if (objects != null) {
   15113                 for (int i=0; i<objects.size(); i++) {
   15114                     if (System.identityHashCode(object) == objects.get(i)) {
   15115                         return true;
   15116                     }
   15117                 }
   15118             }
   15119             if (strings != null) {
   15120                 String flat = comp.flattenToString();
   15121                 for (int i=0; i<strings.size(); i++) {
   15122                     if (flat.contains(strings.get(i))) {
   15123                         return true;
   15124                     }
   15125                 }
   15126             }
   15127             return false;
   15128         }
   15129     }
   15130 
   15131     /**
   15132      * There are three things that cmd can be:
   15133      *  - a flattened component name that matches an existing activity
   15134      *  - the cmd arg isn't the flattened component name of an existing activity:
   15135      *    dump all activity whose component contains the cmd as a substring
   15136      *  - A hex number of the ActivityRecord object instance.
   15137      */
   15138     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   15139             int opti, boolean dumpAll) {
   15140         ArrayList<ActivityRecord> activities;
   15141 
   15142         synchronized (this) {
   15143             activities = mStackSupervisor.getDumpActivitiesLocked(name);
   15144         }
   15145 
   15146         if (activities.size() <= 0) {
   15147             return false;
   15148         }
   15149 
   15150         String[] newArgs = new String[args.length - opti];
   15151         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   15152 
   15153         TaskRecord lastTask = null;
   15154         boolean needSep = false;
   15155         for (int i=activities.size()-1; i>=0; i--) {
   15156             ActivityRecord r = activities.get(i);
   15157             if (needSep) {
   15158                 pw.println();
   15159             }
   15160             needSep = true;
   15161             synchronized (this) {
   15162                 if (lastTask != r.task) {
   15163                     lastTask = r.task;
   15164                     pw.print("TASK "); pw.print(lastTask.affinity);
   15165                             pw.print(" id="); pw.println(lastTask.taskId);
   15166                     if (dumpAll) {
   15167                         lastTask.dump(pw, "  ");
   15168                     }
   15169                 }
   15170             }
   15171             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
   15172         }
   15173         return true;
   15174     }
   15175 
   15176     /**
   15177      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
   15178      * there is a thread associated with the activity.
   15179      */
   15180     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
   15181             final ActivityRecord r, String[] args, boolean dumpAll) {
   15182         String innerPrefix = prefix + "  ";
   15183         synchronized (this) {
   15184             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
   15185                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
   15186                     pw.print(" pid=");
   15187                     if (r.app != null) pw.println(r.app.pid);
   15188                     else pw.println("(not running)");
   15189             if (dumpAll) {
   15190                 r.dump(pw, innerPrefix);
   15191             }
   15192         }
   15193         if (r.app != null && r.app.thread != null) {
   15194             // flush anything that is already in the PrintWriter since the thread is going
   15195             // to write to the file descriptor directly
   15196             pw.flush();
   15197             try {
   15198                 TransferPipe tp = new TransferPipe();
   15199                 try {
   15200                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   15201                             r.appToken, innerPrefix, args);
   15202                     tp.go(fd);
   15203                 } finally {
   15204                     tp.kill();
   15205                 }
   15206             } catch (IOException e) {
   15207                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   15208             } catch (RemoteException e) {
   15209                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   15210             }
   15211         }
   15212     }
   15213 
   15214     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15215             int opti, boolean dumpAll, String dumpPackage) {
   15216         boolean needSep = false;
   15217         boolean onlyHistory = false;
   15218         boolean printedAnything = false;
   15219 
   15220         if ("history".equals(dumpPackage)) {
   15221             if (opti < args.length && "-s".equals(args[opti])) {
   15222                 dumpAll = false;
   15223             }
   15224             onlyHistory = true;
   15225             dumpPackage = null;
   15226         }
   15227 
   15228         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
   15229         if (!onlyHistory && dumpAll) {
   15230             if (mRegisteredReceivers.size() > 0) {
   15231                 boolean printed = false;
   15232                 Iterator it = mRegisteredReceivers.values().iterator();
   15233                 while (it.hasNext()) {
   15234                     ReceiverList r = (ReceiverList)it.next();
   15235                     if (dumpPackage != null && (r.app == null ||
   15236                             !dumpPackage.equals(r.app.info.packageName))) {
   15237                         continue;
   15238                     }
   15239                     if (!printed) {
   15240                         pw.println("  Registered Receivers:");
   15241                         needSep = true;
   15242                         printed = true;
   15243                         printedAnything = true;
   15244                     }
   15245                     pw.print("  * "); pw.println(r);
   15246                     r.dump(pw, "    ");
   15247                 }
   15248             }
   15249 
   15250             if (mReceiverResolver.dump(pw, needSep ?
   15251                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
   15252                     "    ", dumpPackage, false, false)) {
   15253                 needSep = true;
   15254                 printedAnything = true;
   15255             }
   15256         }
   15257 
   15258         for (BroadcastQueue q : mBroadcastQueues) {
   15259             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
   15260             printedAnything |= needSep;
   15261         }
   15262 
   15263         needSep = true;
   15264 
   15265         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
   15266             for (int user=0; user<mStickyBroadcasts.size(); user++) {
   15267                 if (needSep) {
   15268                     pw.println();
   15269                 }
   15270                 needSep = true;
   15271                 printedAnything = true;
   15272                 pw.print("  Sticky broadcasts for user ");
   15273                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
   15274                 StringBuilder sb = new StringBuilder(128);
   15275                 for (Map.Entry<String, ArrayList<Intent>> ent
   15276                         : mStickyBroadcasts.valueAt(user).entrySet()) {
   15277                     pw.print("  * Sticky action "); pw.print(ent.getKey());
   15278                     if (dumpAll) {
   15279                         pw.println(":");
   15280                         ArrayList<Intent> intents = ent.getValue();
   15281                         final int N = intents.size();
   15282                         for (int i=0; i<N; i++) {
   15283                             sb.setLength(0);
   15284                             sb.append("    Intent: ");
   15285                             intents.get(i).toShortString(sb, false, true, false, false);
   15286                             pw.println(sb.toString());
   15287                             Bundle bundle = intents.get(i).getExtras();
   15288                             if (bundle != null) {
   15289                                 pw.print("      ");
   15290                                 pw.println(bundle.toString());
   15291                             }
   15292                         }
   15293                     } else {
   15294                         pw.println("");
   15295                     }
   15296                 }
   15297             }
   15298         }
   15299 
   15300         if (!onlyHistory && dumpAll) {
   15301             pw.println();
   15302             for (BroadcastQueue queue : mBroadcastQueues) {
   15303                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
   15304                         + queue.mBroadcastsScheduled);
   15305             }
   15306             pw.println("  mHandler:");
   15307             mHandler.dump(new PrintWriterPrinter(pw), "    ");
   15308             needSep = true;
   15309             printedAnything = true;
   15310         }
   15311 
   15312         if (!printedAnything) {
   15313             pw.println("  (nothing)");
   15314         }
   15315     }
   15316 
   15317     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15318             int opti, boolean dumpAll, String dumpPackage) {
   15319         if (mCurBroadcastStats == null) {
   15320             return;
   15321         }
   15322 
   15323         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
   15324         final long now = SystemClock.elapsedRealtime();
   15325         if (mLastBroadcastStats != null) {
   15326             pw.print("  Last stats (from ");
   15327             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
   15328             pw.print(" to ");
   15329             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
   15330             pw.print(", ");
   15331             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
   15332                     - mLastBroadcastStats.mStartUptime, pw);
   15333             pw.println(" uptime):");
   15334             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
   15335                 pw.println("    (nothing)");
   15336             }
   15337             pw.println();
   15338         }
   15339         pw.print("  Current stats (from ");
   15340         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
   15341         pw.print(" to now, ");
   15342         TimeUtils.formatDuration(SystemClock.uptimeMillis()
   15343                 - mCurBroadcastStats.mStartUptime, pw);
   15344         pw.println(" uptime):");
   15345         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
   15346             pw.println("    (nothing)");
   15347         }
   15348     }
   15349 
   15350     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15351             int opti, boolean fullCheckin, String dumpPackage) {
   15352         if (mCurBroadcastStats == null) {
   15353             return;
   15354         }
   15355 
   15356         if (mLastBroadcastStats != null) {
   15357             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
   15358             if (fullCheckin) {
   15359                 mLastBroadcastStats = null;
   15360                 return;
   15361             }
   15362         }
   15363         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
   15364         if (fullCheckin) {
   15365             mCurBroadcastStats = null;
   15366         }
   15367     }
   15368 
   15369     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15370             int opti, boolean dumpAll, String dumpPackage) {
   15371         boolean needSep;
   15372         boolean printedAnything = false;
   15373 
   15374         ItemMatcher matcher = new ItemMatcher();
   15375         matcher.build(args, opti);
   15376 
   15377         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
   15378 
   15379         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
   15380         printedAnything |= needSep;
   15381 
   15382         if (mLaunchingProviders.size() > 0) {
   15383             boolean printed = false;
   15384             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
   15385                 ContentProviderRecord r = mLaunchingProviders.get(i);
   15386                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
   15387                     continue;
   15388                 }
   15389                 if (!printed) {
   15390                     if (needSep) pw.println();
   15391                     needSep = true;
   15392                     pw.println("  Launching content providers:");
   15393                     printed = true;
   15394                     printedAnything = true;
   15395                 }
   15396                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
   15397                         pw.println(r);
   15398             }
   15399         }
   15400 
   15401         if (!printedAnything) {
   15402             pw.println("  (nothing)");
   15403         }
   15404     }
   15405 
   15406     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15407             int opti, boolean dumpAll, String dumpPackage) {
   15408         boolean needSep = false;
   15409         boolean printedAnything = false;
   15410 
   15411         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
   15412 
   15413         if (mGrantedUriPermissions.size() > 0) {
   15414             boolean printed = false;
   15415             int dumpUid = -2;
   15416             if (dumpPackage != null) {
   15417                 try {
   15418                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
   15419                             MATCH_UNINSTALLED_PACKAGES, 0);
   15420                 } catch (NameNotFoundException e) {
   15421                     dumpUid = -1;
   15422                 }
   15423             }
   15424             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
   15425                 int uid = mGrantedUriPermissions.keyAt(i);
   15426                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
   15427                     continue;
   15428                 }
   15429                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   15430                 if (!printed) {
   15431                     if (needSep) pw.println();
   15432                     needSep = true;
   15433                     pw.println("  Granted Uri Permissions:");
   15434                     printed = true;
   15435                     printedAnything = true;
   15436                 }
   15437                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
   15438                 for (UriPermission perm : perms.values()) {
   15439                     pw.print("    "); pw.println(perm);
   15440                     if (dumpAll) {
   15441                         perm.dump(pw, "      ");
   15442                     }
   15443                 }
   15444             }
   15445         }
   15446 
   15447         if (!printedAnything) {
   15448             pw.println("  (nothing)");
   15449         }
   15450     }
   15451 
   15452     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15453             int opti, boolean dumpAll, String dumpPackage) {
   15454         boolean printed = false;
   15455 
   15456         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
   15457 
   15458         if (mIntentSenderRecords.size() > 0) {
   15459             Iterator<WeakReference<PendingIntentRecord>> it
   15460                     = mIntentSenderRecords.values().iterator();
   15461             while (it.hasNext()) {
   15462                 WeakReference<PendingIntentRecord> ref = it.next();
   15463                 PendingIntentRecord rec = ref != null ? ref.get(): null;
   15464                 if (dumpPackage != null && (rec == null
   15465                         || !dumpPackage.equals(rec.key.packageName))) {
   15466                     continue;
   15467                 }
   15468                 printed = true;
   15469                 if (rec != null) {
   15470                     pw.print("  * "); pw.println(rec);
   15471                     if (dumpAll) {
   15472                         rec.dump(pw, "    ");
   15473                     }
   15474                 } else {
   15475                     pw.print("  * "); pw.println(ref);
   15476                 }
   15477             }
   15478         }
   15479 
   15480         if (!printed) {
   15481             pw.println("  (nothing)");
   15482         }
   15483     }
   15484 
   15485     private static final int dumpProcessList(PrintWriter pw,
   15486             ActivityManagerService service, List list,
   15487             String prefix, String normalLabel, String persistentLabel,
   15488             String dumpPackage) {
   15489         int numPers = 0;
   15490         final int N = list.size()-1;
   15491         for (int i=N; i>=0; i--) {
   15492             ProcessRecord r = (ProcessRecord)list.get(i);
   15493             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   15494                 continue;
   15495             }
   15496             pw.println(String.format("%s%s #%2d: %s",
   15497                     prefix, (r.persistent ? persistentLabel : normalLabel),
   15498                     i, r.toString()));
   15499             if (r.persistent) {
   15500                 numPers++;
   15501             }
   15502         }
   15503         return numPers;
   15504     }
   15505 
   15506     private static final boolean dumpProcessOomList(PrintWriter pw,
   15507             ActivityManagerService service, List<ProcessRecord> origList,
   15508             String prefix, String normalLabel, String persistentLabel,
   15509             boolean inclDetails, String dumpPackage) {
   15510 
   15511         ArrayList<Pair<ProcessRecord, Integer>> list
   15512                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
   15513         for (int i=0; i<origList.size(); i++) {
   15514             ProcessRecord r = origList.get(i);
   15515             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   15516                 continue;
   15517             }
   15518             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
   15519         }
   15520 
   15521         if (list.size() <= 0) {
   15522             return false;
   15523         }
   15524 
   15525         Comparator<Pair<ProcessRecord, Integer>> comparator
   15526                 = new Comparator<Pair<ProcessRecord, Integer>>() {
   15527             @Override
   15528             public int compare(Pair<ProcessRecord, Integer> object1,
   15529                     Pair<ProcessRecord, Integer> object2) {
   15530                 if (object1.first.setAdj != object2.first.setAdj) {
   15531                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
   15532                 }
   15533                 if (object1.first.setProcState != object2.first.setProcState) {
   15534                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
   15535                 }
   15536                 if (object1.second.intValue() != object2.second.intValue()) {
   15537                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
   15538                 }
   15539                 return 0;
   15540             }
   15541         };
   15542 
   15543         Collections.sort(list, comparator);
   15544 
   15545         final long curRealtime = SystemClock.elapsedRealtime();
   15546         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
   15547         final long curUptime = SystemClock.uptimeMillis();
   15548         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
   15549 
   15550         for (int i=list.size()-1; i>=0; i--) {
   15551             ProcessRecord r = list.get(i).first;
   15552             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
   15553             char schedGroup;
   15554             switch (r.setSchedGroup) {
   15555                 case ProcessList.SCHED_GROUP_BACKGROUND:
   15556                     schedGroup = 'B';
   15557                     break;
   15558                 case ProcessList.SCHED_GROUP_DEFAULT:
   15559                     schedGroup = 'F';
   15560                     break;
   15561                 case ProcessList.SCHED_GROUP_TOP_APP:
   15562                     schedGroup = 'T';
   15563                     break;
   15564                 default:
   15565                     schedGroup = '?';
   15566                     break;
   15567             }
   15568             char foreground;
   15569             if (r.foregroundActivities) {
   15570                 foreground = 'A';
   15571             } else if (r.foregroundServices) {
   15572                 foreground = 'S';
   15573             } else {
   15574                 foreground = ' ';
   15575             }
   15576             String procState = ProcessList.makeProcStateString(r.curProcState);
   15577             pw.print(prefix);
   15578             pw.print(r.persistent ? persistentLabel : normalLabel);
   15579             pw.print(" #");
   15580             int num = (origList.size()-1)-list.get(i).second;
   15581             if (num < 10) pw.print(' ');
   15582             pw.print(num);
   15583             pw.print(": ");
   15584             pw.print(oomAdj);
   15585             pw.print(' ');
   15586             pw.print(schedGroup);
   15587             pw.print('/');
   15588             pw.print(foreground);
   15589             pw.print('/');
   15590             pw.print(procState);
   15591             pw.print(" trm:");
   15592             if (r.trimMemoryLevel < 10) pw.print(' ');
   15593             pw.print(r.trimMemoryLevel);
   15594             pw.print(' ');
   15595             pw.print(r.toShortString());
   15596             pw.print(" (");
   15597             pw.print(r.adjType);
   15598             pw.println(')');
   15599             if (r.adjSource != null || r.adjTarget != null) {
   15600                 pw.print(prefix);
   15601                 pw.print("    ");
   15602                 if (r.adjTarget instanceof ComponentName) {
   15603                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
   15604                 } else if (r.adjTarget != null) {
   15605                     pw.print(r.adjTarget.toString());
   15606                 } else {
   15607                     pw.print("{null}");
   15608                 }
   15609                 pw.print("<=");
   15610                 if (r.adjSource instanceof ProcessRecord) {
   15611                     pw.print("Proc{");
   15612                     pw.print(((ProcessRecord)r.adjSource).toShortString());
   15613                     pw.println("}");
   15614                 } else if (r.adjSource != null) {
   15615                     pw.println(r.adjSource.toString());
   15616                 } else {
   15617                     pw.println("{null}");
   15618                 }
   15619             }
   15620             if (inclDetails) {
   15621                 pw.print(prefix);
   15622                 pw.print("    ");
   15623                 pw.print("oom: max="); pw.print(r.maxAdj);
   15624                 pw.print(" curRaw="); pw.print(r.curRawAdj);
   15625                 pw.print(" setRaw="); pw.print(r.setRawAdj);
   15626                 pw.print(" cur="); pw.print(r.curAdj);
   15627                 pw.print(" set="); pw.println(r.setAdj);
   15628                 pw.print(prefix);
   15629                 pw.print("    ");
   15630                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
   15631                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
   15632                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
   15633                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
   15634                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
   15635                 pw.println();
   15636                 pw.print(prefix);
   15637                 pw.print("    ");
   15638                 pw.print("cached="); pw.print(r.cached);
   15639                 pw.print(" empty="); pw.print(r.empty);
   15640                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
   15641 
   15642                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
   15643                     if (r.lastWakeTime != 0) {
   15644                         long wtime;
   15645                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
   15646                         synchronized (stats) {
   15647                             wtime = stats.getProcessWakeTime(r.info.uid,
   15648                                     r.pid, curRealtime);
   15649                         }
   15650                         long timeUsed = wtime - r.lastWakeTime;
   15651                         pw.print(prefix);
   15652                         pw.print("    ");
   15653                         pw.print("keep awake over ");
   15654                         TimeUtils.formatDuration(realtimeSince, pw);
   15655                         pw.print(" used ");
   15656                         TimeUtils.formatDuration(timeUsed, pw);
   15657                         pw.print(" (");
   15658                         pw.print((timeUsed*100)/realtimeSince);
   15659                         pw.println("%)");
   15660                     }
   15661                     if (r.lastCpuTime != 0) {
   15662                         long timeUsed = r.curCpuTime - r.lastCpuTime;
   15663                         pw.print(prefix);
   15664                         pw.print("    ");
   15665                         pw.print("run cpu over ");
   15666                         TimeUtils.formatDuration(uptimeSince, pw);
   15667                         pw.print(" used ");
   15668                         TimeUtils.formatDuration(timeUsed, pw);
   15669                         pw.print(" (");
   15670                         pw.print((timeUsed*100)/uptimeSince);
   15671                         pw.println("%)");
   15672                     }
   15673                 }
   15674             }
   15675         }
   15676         return true;
   15677     }
   15678 
   15679     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
   15680             String[] args) {
   15681         ArrayList<ProcessRecord> procs;
   15682         synchronized (this) {
   15683             if (args != null && args.length > start
   15684                     && args[start].charAt(0) != '-') {
   15685                 procs = new ArrayList<ProcessRecord>();
   15686                 int pid = -1;
   15687                 try {
   15688                     pid = Integer.parseInt(args[start]);
   15689                 } catch (NumberFormatException e) {
   15690                 }
   15691                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   15692                     ProcessRecord proc = mLruProcesses.get(i);
   15693                     if (proc.pid == pid) {
   15694                         procs.add(proc);
   15695                     } else if (allPkgs && proc.pkgList != null
   15696                             && proc.pkgList.containsKey(args[start])) {
   15697                         procs.add(proc);
   15698                     } else if (proc.processName.equals(args[start])) {
   15699                         procs.add(proc);
   15700                     }
   15701                 }
   15702                 if (procs.size() <= 0) {
   15703                     return null;
   15704                 }
   15705             } else {
   15706                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
   15707             }
   15708         }
   15709         return procs;
   15710     }
   15711 
   15712     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
   15713             PrintWriter pw, String[] args) {
   15714         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
   15715         if (procs == null) {
   15716             pw.println("No process found for: " + args[0]);
   15717             return;
   15718         }
   15719 
   15720         long uptime = SystemClock.uptimeMillis();
   15721         long realtime = SystemClock.elapsedRealtime();
   15722         pw.println("Applications Graphics Acceleration Info:");
   15723         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   15724 
   15725         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   15726             ProcessRecord r = procs.get(i);
   15727             if (r.thread != null) {
   15728                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
   15729                 pw.flush();
   15730                 try {
   15731                     TransferPipe tp = new TransferPipe();
   15732                     try {
   15733                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
   15734                         tp.go(fd);
   15735                     } finally {
   15736                         tp.kill();
   15737                     }
   15738                 } catch (IOException e) {
   15739                     pw.println("Failure while dumping the app: " + r);
   15740                     pw.flush();
   15741                 } catch (RemoteException e) {
   15742                     pw.println("Got a RemoteException while dumping the app " + r);
   15743                     pw.flush();
   15744                 }
   15745             }
   15746         }
   15747     }
   15748 
   15749     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
   15750         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
   15751         if (procs == null) {
   15752             pw.println("No process found for: " + args[0]);
   15753             return;
   15754         }
   15755 
   15756         pw.println("Applications Database Info:");
   15757 
   15758         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   15759             ProcessRecord r = procs.get(i);
   15760             if (r.thread != null) {
   15761                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
   15762                 pw.flush();
   15763                 try {
   15764                     TransferPipe tp = new TransferPipe();
   15765                     try {
   15766                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
   15767                         tp.go(fd);
   15768                     } finally {
   15769                         tp.kill();
   15770                     }
   15771                 } catch (IOException e) {
   15772                     pw.println("Failure while dumping the app: " + r);
   15773                     pw.flush();
   15774                 } catch (RemoteException e) {
   15775                     pw.println("Got a RemoteException while dumping the app " + r);
   15776                     pw.flush();
   15777                 }
   15778             }
   15779         }
   15780     }
   15781 
   15782     final static class MemItem {
   15783         final boolean isProc;
   15784         final String label;
   15785         final String shortLabel;
   15786         final long pss;
   15787         final long swapPss;
   15788         final int id;
   15789         final boolean hasActivities;
   15790         ArrayList<MemItem> subitems;
   15791 
   15792         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
   15793                 boolean _hasActivities) {
   15794             isProc = true;
   15795             label = _label;
   15796             shortLabel = _shortLabel;
   15797             pss = _pss;
   15798             swapPss = _swapPss;
   15799             id = _id;
   15800             hasActivities = _hasActivities;
   15801         }
   15802 
   15803         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
   15804             isProc = false;
   15805             label = _label;
   15806             shortLabel = _shortLabel;
   15807             pss = _pss;
   15808             swapPss = _swapPss;
   15809             id = _id;
   15810             hasActivities = false;
   15811         }
   15812     }
   15813 
   15814     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
   15815             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
   15816         if (sort && !isCompact) {
   15817             Collections.sort(items, new Comparator<MemItem>() {
   15818                 @Override
   15819                 public int compare(MemItem lhs, MemItem rhs) {
   15820                     if (lhs.pss < rhs.pss) {
   15821                         return 1;
   15822                     } else if (lhs.pss > rhs.pss) {
   15823                         return -1;
   15824                     }
   15825                     return 0;
   15826                 }
   15827             });
   15828         }
   15829 
   15830         for (int i=0; i<items.size(); i++) {
   15831             MemItem mi = items.get(i);
   15832             if (!isCompact) {
   15833                 if (dumpSwapPss) {
   15834                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
   15835                             mi.label, stringifyKBSize(mi.swapPss));
   15836                 } else {
   15837                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
   15838                 }
   15839             } else if (mi.isProc) {
   15840                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
   15841                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
   15842                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
   15843                 pw.println(mi.hasActivities ? ",a" : ",e");
   15844             } else {
   15845                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
   15846                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
   15847             }
   15848             if (mi.subitems != null) {
   15849                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
   15850                         true, isCompact, dumpSwapPss);
   15851             }
   15852         }
   15853     }
   15854 
   15855     // These are in KB.
   15856     static final long[] DUMP_MEM_BUCKETS = new long[] {
   15857         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
   15858         120*1024, 160*1024, 200*1024,
   15859         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
   15860         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
   15861     };
   15862 
   15863     static final void appendMemBucket(StringBuilder out, long memKB, String label,
   15864             boolean stackLike) {
   15865         int start = label.lastIndexOf('.');
   15866         if (start >= 0) start++;
   15867         else start = 0;
   15868         int end = label.length();
   15869         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
   15870             if (DUMP_MEM_BUCKETS[i] >= memKB) {
   15871                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
   15872                 out.append(bucket);
   15873                 out.append(stackLike ? "MB." : "MB ");
   15874                 out.append(label, start, end);
   15875                 return;
   15876             }
   15877         }
   15878         out.append(memKB/1024);
   15879         out.append(stackLike ? "MB." : "MB ");
   15880         out.append(label, start, end);
   15881     }
   15882 
   15883     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
   15884             ProcessList.NATIVE_ADJ,
   15885             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
   15886             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
   15887             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
   15888             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
   15889             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
   15890             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
   15891     };
   15892     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
   15893             "Native",
   15894             "System", "Persistent", "Persistent Service", "Foreground",
   15895             "Visible", "Perceptible",
   15896             "Heavy Weight", "Backup",
   15897             "A Services", "Home",
   15898             "Previous", "B Services", "Cached"
   15899     };
   15900     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
   15901             "native",
   15902             "sys", "pers", "persvc", "fore",
   15903             "vis", "percept",
   15904             "heavy", "backup",
   15905             "servicea", "home",
   15906             "prev", "serviceb", "cached"
   15907     };
   15908 
   15909     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
   15910             long realtime, boolean isCheckinRequest, boolean isCompact) {
   15911         if (isCompact) {
   15912             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
   15913         }
   15914         if (isCheckinRequest || isCompact) {
   15915             // short checkin version
   15916             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
   15917         } else {
   15918             pw.println("Applications Memory Usage (in Kilobytes):");
   15919             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   15920         }
   15921     }
   15922 
   15923     private static final int KSM_SHARED = 0;
   15924     private static final int KSM_SHARING = 1;
   15925     private static final int KSM_UNSHARED = 2;
   15926     private static final int KSM_VOLATILE = 3;
   15927 
   15928     private final long[] getKsmInfo() {
   15929         long[] longOut = new long[4];
   15930         final int[] SINGLE_LONG_FORMAT = new int[] {
   15931             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
   15932         };
   15933         long[] longTmp = new long[1];
   15934         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
   15935                 SINGLE_LONG_FORMAT, null, longTmp, null);
   15936         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   15937         longTmp[0] = 0;
   15938         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
   15939                 SINGLE_LONG_FORMAT, null, longTmp, null);
   15940         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   15941         longTmp[0] = 0;
   15942         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
   15943                 SINGLE_LONG_FORMAT, null, longTmp, null);
   15944         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   15945         longTmp[0] = 0;
   15946         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
   15947                 SINGLE_LONG_FORMAT, null, longTmp, null);
   15948         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   15949         return longOut;
   15950     }
   15951 
   15952     private static String stringifySize(long size, int order) {
   15953         Locale locale = Locale.US;
   15954         switch (order) {
   15955             case 1:
   15956                 return String.format(locale, "%,13d", size);
   15957             case 1024:
   15958                 return String.format(locale, "%,9dK", size / 1024);
   15959             case 1024 * 1024:
   15960                 return String.format(locale, "%,5dM", size / 1024 / 1024);
   15961             case 1024 * 1024 * 1024:
   15962                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
   15963             default:
   15964                 throw new IllegalArgumentException("Invalid size order");
   15965         }
   15966     }
   15967 
   15968     private static String stringifyKBSize(long size) {
   15969         return stringifySize(size * 1024, 1024);
   15970     }
   15971 
   15972     // Update this version number in case you change the 'compact' format
   15973     private static final int MEMINFO_COMPACT_VERSION = 1;
   15974 
   15975     final void dumpApplicationMemoryUsage(FileDescriptor fd,
   15976             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
   15977         boolean dumpDetails = false;
   15978         boolean dumpFullDetails = false;
   15979         boolean dumpDalvik = false;
   15980         boolean dumpSummaryOnly = false;
   15981         boolean dumpUnreachable = false;
   15982         boolean oomOnly = false;
   15983         boolean isCompact = false;
   15984         boolean localOnly = false;
   15985         boolean packages = false;
   15986         boolean isCheckinRequest = false;
   15987         boolean dumpSwapPss = false;
   15988 
   15989         int opti = 0;
   15990         while (opti < args.length) {
   15991             String opt = args[opti];
   15992             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   15993                 break;
   15994             }
   15995             opti++;
   15996             if ("-a".equals(opt)) {
   15997                 dumpDetails = true;
   15998                 dumpFullDetails = true;
   15999                 dumpDalvik = true;
   16000                 dumpSwapPss = true;
   16001             } else if ("-d".equals(opt)) {
   16002                 dumpDalvik = true;
   16003             } else if ("-c".equals(opt)) {
   16004                 isCompact = true;
   16005             } else if ("-s".equals(opt)) {
   16006                 dumpDetails = true;
   16007                 dumpSummaryOnly = true;
   16008             } else if ("-S".equals(opt)) {
   16009                 dumpSwapPss = true;
   16010             } else if ("--unreachable".equals(opt)) {
   16011                 dumpUnreachable = true;
   16012             } else if ("--oom".equals(opt)) {
   16013                 oomOnly = true;
   16014             } else if ("--local".equals(opt)) {
   16015                 localOnly = true;
   16016             } else if ("--package".equals(opt)) {
   16017                 packages = true;
   16018             } else if ("--checkin".equals(opt)) {
   16019                 isCheckinRequest = true;
   16020 
   16021             } else if ("-h".equals(opt)) {
   16022                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
   16023                 pw.println("  -a: include all available information for each process.");
   16024                 pw.println("  -d: include dalvik details.");
   16025                 pw.println("  -c: dump in a compact machine-parseable representation.");
   16026                 pw.println("  -s: dump only summary of application memory usage.");
   16027                 pw.println("  -S: dump also SwapPss.");
   16028                 pw.println("  --oom: only show processes organized by oom adj.");
   16029                 pw.println("  --local: only collect details locally, don't call process.");
   16030                 pw.println("  --package: interpret process arg as package, dumping all");
   16031                 pw.println("             processes that have loaded that package.");
   16032                 pw.println("  --checkin: dump data for a checkin");
   16033                 pw.println("If [process] is specified it can be the name or ");
   16034                 pw.println("pid of a specific process to dump.");
   16035                 return;
   16036             } else {
   16037                 pw.println("Unknown argument: " + opt + "; use -h for help");
   16038             }
   16039         }
   16040 
   16041         long uptime = SystemClock.uptimeMillis();
   16042         long realtime = SystemClock.elapsedRealtime();
   16043         final long[] tmpLong = new long[1];
   16044 
   16045         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
   16046         if (procs == null) {
   16047             // No Java processes.  Maybe they want to print a native process.
   16048             if (args != null && args.length > opti
   16049                     && args[opti].charAt(0) != '-') {
   16050                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
   16051                         = new ArrayList<ProcessCpuTracker.Stats>();
   16052                 updateCpuStatsNow();
   16053                 int findPid = -1;
   16054                 try {
   16055                     findPid = Integer.parseInt(args[opti]);
   16056                 } catch (NumberFormatException e) {
   16057                 }
   16058                 synchronized (mProcessCpuTracker) {
   16059                     final int N = mProcessCpuTracker.countStats();
   16060                     for (int i=0; i<N; i++) {
   16061                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   16062                         if (st.pid == findPid || (st.baseName != null
   16063                                 && st.baseName.equals(args[opti]))) {
   16064                             nativeProcs.add(st);
   16065                         }
   16066                     }
   16067                 }
   16068                 if (nativeProcs.size() > 0) {
   16069                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
   16070                             isCompact);
   16071                     Debug.MemoryInfo mi = null;
   16072                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
   16073                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
   16074                         final int pid = r.pid;
   16075                         if (!isCheckinRequest && dumpDetails) {
   16076                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
   16077                         }
   16078                         if (mi == null) {
   16079                             mi = new Debug.MemoryInfo();
   16080                         }
   16081                         if (dumpDetails || (!brief && !oomOnly)) {
   16082                             Debug.getMemoryInfo(pid, mi);
   16083                         } else {
   16084                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
   16085                             mi.dalvikPrivateDirty = (int)tmpLong[0];
   16086                         }
   16087                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
   16088                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
   16089                         if (isCheckinRequest) {
   16090                             pw.println();
   16091                         }
   16092                     }
   16093                     return;
   16094                 }
   16095             }
   16096             pw.println("No process found for: " + args[opti]);
   16097             return;
   16098         }
   16099 
   16100         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
   16101             dumpDetails = true;
   16102         }
   16103 
   16104         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
   16105 
   16106         String[] innerArgs = new String[args.length-opti];
   16107         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
   16108 
   16109         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
   16110         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
   16111         long nativePss = 0;
   16112         long nativeSwapPss = 0;
   16113         long dalvikPss = 0;
   16114         long dalvikSwapPss = 0;
   16115         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
   16116                 EmptyArray.LONG;
   16117         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
   16118                 EmptyArray.LONG;
   16119         long otherPss = 0;
   16120         long otherSwapPss = 0;
   16121         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   16122         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   16123 
   16124         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   16125         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   16126         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
   16127                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
   16128 
   16129         long totalPss = 0;
   16130         long totalSwapPss = 0;
   16131         long cachedPss = 0;
   16132         long cachedSwapPss = 0;
   16133         boolean hasSwapPss = false;
   16134 
   16135         Debug.MemoryInfo mi = null;
   16136         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   16137             final ProcessRecord r = procs.get(i);
   16138             final IApplicationThread thread;
   16139             final int pid;
   16140             final int oomAdj;
   16141             final boolean hasActivities;
   16142             synchronized (this) {
   16143                 thread = r.thread;
   16144                 pid = r.pid;
   16145                 oomAdj = r.getSetAdjWithServices();
   16146                 hasActivities = r.activities.size() > 0;
   16147             }
   16148             if (thread != null) {
   16149                 if (!isCheckinRequest && dumpDetails) {
   16150                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
   16151                 }
   16152                 if (mi == null) {
   16153                     mi = new Debug.MemoryInfo();
   16154                 }
   16155                 if (dumpDetails || (!brief && !oomOnly)) {
   16156                     Debug.getMemoryInfo(pid, mi);
   16157                     hasSwapPss = mi.hasSwappedOutPss;
   16158                 } else {
   16159                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
   16160                     mi.dalvikPrivateDirty = (int)tmpLong[0];
   16161                 }
   16162                 if (dumpDetails) {
   16163                     if (localOnly) {
   16164                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
   16165                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
   16166                         if (isCheckinRequest) {
   16167                             pw.println();
   16168                         }
   16169                     } else {
   16170                         try {
   16171                             pw.flush();
   16172                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
   16173                                     dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
   16174                         } catch (RemoteException e) {
   16175                             if (!isCheckinRequest) {
   16176                                 pw.println("Got RemoteException!");
   16177                                 pw.flush();
   16178                             }
   16179                         }
   16180                     }
   16181                 }
   16182 
   16183                 final long myTotalPss = mi.getTotalPss();
   16184                 final long myTotalUss = mi.getTotalUss();
   16185                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
   16186 
   16187                 synchronized (this) {
   16188                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
   16189                         // Record this for posterity if the process has been stable.
   16190                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
   16191                     }
   16192                 }
   16193 
   16194                 if (!isCheckinRequest && mi != null) {
   16195                     totalPss += myTotalPss;
   16196                     totalSwapPss += myTotalSwapPss;
   16197                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
   16198                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
   16199                             myTotalSwapPss, pid, hasActivities);
   16200                     procMems.add(pssItem);
   16201                     procMemsMap.put(pid, pssItem);
   16202 
   16203                     nativePss += mi.nativePss;
   16204                     nativeSwapPss += mi.nativeSwappedOutPss;
   16205                     dalvikPss += mi.dalvikPss;
   16206                     dalvikSwapPss += mi.dalvikSwappedOutPss;
   16207                     for (int j=0; j<dalvikSubitemPss.length; j++) {
   16208                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   16209                         dalvikSubitemSwapPss[j] +=
   16210                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   16211                     }
   16212                     otherPss += mi.otherPss;
   16213                     otherSwapPss += mi.otherSwappedOutPss;
   16214                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   16215                         long mem = mi.getOtherPss(j);
   16216                         miscPss[j] += mem;
   16217                         otherPss -= mem;
   16218                         mem = mi.getOtherSwappedOutPss(j);
   16219                         miscSwapPss[j] += mem;
   16220                         otherSwapPss -= mem;
   16221                     }
   16222 
   16223                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   16224                         cachedPss += myTotalPss;
   16225                         cachedSwapPss += myTotalSwapPss;
   16226                     }
   16227 
   16228                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
   16229                         if (oomIndex == (oomPss.length - 1)
   16230                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
   16231                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
   16232                             oomPss[oomIndex] += myTotalPss;
   16233                             oomSwapPss[oomIndex] += myTotalSwapPss;
   16234                             if (oomProcs[oomIndex] == null) {
   16235                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
   16236                             }
   16237                             oomProcs[oomIndex].add(pssItem);
   16238                             break;
   16239                         }
   16240                     }
   16241                 }
   16242             }
   16243         }
   16244 
   16245         long nativeProcTotalPss = 0;
   16246 
   16247         if (!isCheckinRequest && procs.size() > 1 && !packages) {
   16248             // If we are showing aggregations, also look for native processes to
   16249             // include so that our aggregations are more accurate.
   16250             updateCpuStatsNow();
   16251             mi = null;
   16252             synchronized (mProcessCpuTracker) {
   16253                 final int N = mProcessCpuTracker.countStats();
   16254                 for (int i=0; i<N; i++) {
   16255                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   16256                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
   16257                         if (mi == null) {
   16258                             mi = new Debug.MemoryInfo();
   16259                         }
   16260                         if (!brief && !oomOnly) {
   16261                             Debug.getMemoryInfo(st.pid, mi);
   16262                         } else {
   16263                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
   16264                             mi.nativePrivateDirty = (int)tmpLong[0];
   16265                         }
   16266 
   16267                         final long myTotalPss = mi.getTotalPss();
   16268                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
   16269                         totalPss += myTotalPss;
   16270                         nativeProcTotalPss += myTotalPss;
   16271 
   16272                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
   16273                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
   16274                         procMems.add(pssItem);
   16275 
   16276                         nativePss += mi.nativePss;
   16277                         nativeSwapPss += mi.nativeSwappedOutPss;
   16278                         dalvikPss += mi.dalvikPss;
   16279                         dalvikSwapPss += mi.dalvikSwappedOutPss;
   16280                         for (int j=0; j<dalvikSubitemPss.length; j++) {
   16281                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   16282                             dalvikSubitemSwapPss[j] +=
   16283                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   16284                         }
   16285                         otherPss += mi.otherPss;
   16286                         otherSwapPss += mi.otherSwappedOutPss;
   16287                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   16288                             long mem = mi.getOtherPss(j);
   16289                             miscPss[j] += mem;
   16290                             otherPss -= mem;
   16291                             mem = mi.getOtherSwappedOutPss(j);
   16292                             miscSwapPss[j] += mem;
   16293                             otherSwapPss -= mem;
   16294                         }
   16295                         oomPss[0] += myTotalPss;
   16296                         oomSwapPss[0] += myTotalSwapPss;
   16297                         if (oomProcs[0] == null) {
   16298                             oomProcs[0] = new ArrayList<MemItem>();
   16299                         }
   16300                         oomProcs[0].add(pssItem);
   16301                     }
   16302                 }
   16303             }
   16304 
   16305             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
   16306 
   16307             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
   16308             final MemItem dalvikItem =
   16309                     new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
   16310             if (dalvikSubitemPss.length > 0) {
   16311                 dalvikItem.subitems = new ArrayList<MemItem>();
   16312                 for (int j=0; j<dalvikSubitemPss.length; j++) {
   16313                     final String name = Debug.MemoryInfo.getOtherLabel(
   16314                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
   16315                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
   16316                                     dalvikSubitemSwapPss[j], j));
   16317                 }
   16318             }
   16319             catMems.add(dalvikItem);
   16320             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
   16321             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   16322                 String label = Debug.MemoryInfo.getOtherLabel(j);
   16323                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
   16324             }
   16325 
   16326             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
   16327             for (int j=0; j<oomPss.length; j++) {
   16328                 if (oomPss[j] != 0) {
   16329                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
   16330                             : DUMP_MEM_OOM_LABEL[j];
   16331                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
   16332                             DUMP_MEM_OOM_ADJ[j]);
   16333                     item.subitems = oomProcs[j];
   16334                     oomMems.add(item);
   16335                 }
   16336             }
   16337 
   16338             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
   16339             if (!brief && !oomOnly && !isCompact) {
   16340                 pw.println();
   16341                 pw.println("Total PSS by process:");
   16342                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
   16343                 pw.println();
   16344             }
   16345             if (!isCompact) {
   16346                 pw.println("Total PSS by OOM adjustment:");
   16347             }
   16348             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
   16349             if (!brief && !oomOnly) {
   16350                 PrintWriter out = categoryPw != null ? categoryPw : pw;
   16351                 if (!isCompact) {
   16352                     out.println();
   16353                     out.println("Total PSS by category:");
   16354                 }
   16355                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
   16356             }
   16357             if (!isCompact) {
   16358                 pw.println();
   16359             }
   16360             MemInfoReader memInfo = new MemInfoReader();
   16361             memInfo.readMemInfo();
   16362             if (nativeProcTotalPss > 0) {
   16363                 synchronized (this) {
   16364                     final long cachedKb = memInfo.getCachedSizeKb();
   16365                     final long freeKb = memInfo.getFreeSizeKb();
   16366                     final long zramKb = memInfo.getZramTotalSizeKb();
   16367                     final long kernelKb = memInfo.getKernelUsedSizeKb();
   16368                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
   16369                             kernelKb*1024, nativeProcTotalPss*1024);
   16370                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
   16371                             nativeProcTotalPss);
   16372                 }
   16373             }
   16374             if (!brief) {
   16375                 if (!isCompact) {
   16376                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
   16377                     pw.print(" (status ");
   16378                     switch (mLastMemoryLevel) {
   16379                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
   16380                             pw.println("normal)");
   16381                             break;
   16382                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
   16383                             pw.println("moderate)");
   16384                             break;
   16385                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
   16386                             pw.println("low)");
   16387                             break;
   16388                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
   16389                             pw.println("critical)");
   16390                             break;
   16391                         default:
   16392                             pw.print(mLastMemoryLevel);
   16393                             pw.println(")");
   16394                             break;
   16395                     }
   16396                     pw.print(" Free RAM: ");
   16397                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
   16398                             + memInfo.getFreeSizeKb()));
   16399                     pw.print(" (");
   16400                     pw.print(stringifyKBSize(cachedPss));
   16401                     pw.print(" cached pss + ");
   16402                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
   16403                     pw.print(" cached kernel + ");
   16404                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
   16405                     pw.println(" free)");
   16406                 } else {
   16407                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
   16408                     pw.print(cachedPss + memInfo.getCachedSizeKb()
   16409                             + memInfo.getFreeSizeKb()); pw.print(",");
   16410                     pw.println(totalPss - cachedPss);
   16411                 }
   16412             }
   16413             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
   16414                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
   16415                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
   16416             if (!isCompact) {
   16417                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
   16418                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
   16419                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
   16420                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
   16421                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
   16422             } else {
   16423                 pw.print("lostram,"); pw.println(lostRAM);
   16424             }
   16425             if (!brief) {
   16426                 if (memInfo.getZramTotalSizeKb() != 0) {
   16427                     if (!isCompact) {
   16428                         pw.print("     ZRAM: ");
   16429                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
   16430                                 pw.print(" physical used for ");
   16431                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
   16432                                         - memInfo.getSwapFreeSizeKb()));
   16433                                 pw.print(" in swap (");
   16434                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
   16435                                 pw.println(" total swap)");
   16436                     } else {
   16437                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
   16438                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
   16439                                 pw.println(memInfo.getSwapFreeSizeKb());
   16440                     }
   16441                 }
   16442                 final long[] ksm = getKsmInfo();
   16443                 if (!isCompact) {
   16444                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
   16445                             || ksm[KSM_VOLATILE] != 0) {
   16446                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
   16447                                 pw.print(" saved from shared ");
   16448                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
   16449                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
   16450                                 pw.print(" unshared; ");
   16451                                 pw.print(stringifyKBSize(
   16452                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
   16453                     }
   16454                     pw.print("   Tuning: ");
   16455                     pw.print(ActivityManager.staticGetMemoryClass());
   16456                     pw.print(" (large ");
   16457                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   16458                     pw.print("), oom ");
   16459                     pw.print(stringifySize(
   16460                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
   16461                     pw.print(", restore limit ");
   16462                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
   16463                     if (ActivityManager.isLowRamDeviceStatic()) {
   16464                         pw.print(" (low-ram)");
   16465                     }
   16466                     if (ActivityManager.isHighEndGfx()) {
   16467                         pw.print(" (high-end-gfx)");
   16468                     }
   16469                     pw.println();
   16470                 } else {
   16471                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
   16472                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
   16473                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
   16474                     pw.print("tuning,");
   16475                     pw.print(ActivityManager.staticGetMemoryClass());
   16476                     pw.print(',');
   16477                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   16478                     pw.print(',');
   16479                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
   16480                     if (ActivityManager.isLowRamDeviceStatic()) {
   16481                         pw.print(",low-ram");
   16482                     }
   16483                     if (ActivityManager.isHighEndGfx()) {
   16484                         pw.print(",high-end-gfx");
   16485                     }
   16486                     pw.println();
   16487                 }
   16488             }
   16489         }
   16490     }
   16491 
   16492     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
   16493             long memtrack, String name) {
   16494         sb.append("  ");
   16495         sb.append(ProcessList.makeOomAdjString(oomAdj));
   16496         sb.append(' ');
   16497         sb.append(ProcessList.makeProcStateString(procState));
   16498         sb.append(' ');
   16499         ProcessList.appendRamKb(sb, pss);
   16500         sb.append(": ");
   16501         sb.append(name);
   16502         if (memtrack > 0) {
   16503             sb.append(" (");
   16504             sb.append(stringifyKBSize(memtrack));
   16505             sb.append(" memtrack)");
   16506         }
   16507     }
   16508 
   16509     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
   16510         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
   16511         sb.append(" (pid ");
   16512         sb.append(mi.pid);
   16513         sb.append(") ");
   16514         sb.append(mi.adjType);
   16515         sb.append('\n');
   16516         if (mi.adjReason != null) {
   16517             sb.append("                      ");
   16518             sb.append(mi.adjReason);
   16519             sb.append('\n');
   16520         }
   16521     }
   16522 
   16523     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
   16524         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
   16525         for (int i=0, N=memInfos.size(); i<N; i++) {
   16526             ProcessMemInfo mi = memInfos.get(i);
   16527             infoMap.put(mi.pid, mi);
   16528         }
   16529         updateCpuStatsNow();
   16530         long[] memtrackTmp = new long[1];
   16531         final List<ProcessCpuTracker.Stats> stats;
   16532         // Get a list of Stats that have vsize > 0
   16533         synchronized (mProcessCpuTracker) {
   16534             stats = mProcessCpuTracker.getStats((st) -> {
   16535                 return st.vsize > 0;
   16536             });
   16537         }
   16538         final int statsCount = stats.size();
   16539         for (int i = 0; i < statsCount; i++) {
   16540             ProcessCpuTracker.Stats st = stats.get(i);
   16541             long pss = Debug.getPss(st.pid, null, memtrackTmp);
   16542             if (pss > 0) {
   16543                 if (infoMap.indexOfKey(st.pid) < 0) {
   16544                     ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
   16545                             ProcessList.NATIVE_ADJ, -1, "native", null);
   16546                     mi.pss = pss;
   16547                     mi.memtrack = memtrackTmp[0];
   16548                     memInfos.add(mi);
   16549                 }
   16550             }
   16551         }
   16552 
   16553         long totalPss = 0;
   16554         long totalMemtrack = 0;
   16555         for (int i=0, N=memInfos.size(); i<N; i++) {
   16556             ProcessMemInfo mi = memInfos.get(i);
   16557             if (mi.pss == 0) {
   16558                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
   16559                 mi.memtrack = memtrackTmp[0];
   16560             }
   16561             totalPss += mi.pss;
   16562             totalMemtrack += mi.memtrack;
   16563         }
   16564         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
   16565             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
   16566                 if (lhs.oomAdj != rhs.oomAdj) {
   16567                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
   16568                 }
   16569                 if (lhs.pss != rhs.pss) {
   16570                     return lhs.pss < rhs.pss ? 1 : -1;
   16571                 }
   16572                 return 0;
   16573             }
   16574         });
   16575 
   16576         StringBuilder tag = new StringBuilder(128);
   16577         StringBuilder stack = new StringBuilder(128);
   16578         tag.append("Low on memory -- ");
   16579         appendMemBucket(tag, totalPss, "total", false);
   16580         appendMemBucket(stack, totalPss, "total", true);
   16581 
   16582         StringBuilder fullNativeBuilder = new StringBuilder(1024);
   16583         StringBuilder shortNativeBuilder = new StringBuilder(1024);
   16584         StringBuilder fullJavaBuilder = new StringBuilder(1024);
   16585 
   16586         boolean firstLine = true;
   16587         int lastOomAdj = Integer.MIN_VALUE;
   16588         long extraNativeRam = 0;
   16589         long extraNativeMemtrack = 0;
   16590         long cachedPss = 0;
   16591         for (int i=0, N=memInfos.size(); i<N; i++) {
   16592             ProcessMemInfo mi = memInfos.get(i);
   16593 
   16594             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   16595                 cachedPss += mi.pss;
   16596             }
   16597 
   16598             if (mi.oomAdj != ProcessList.NATIVE_ADJ
   16599                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
   16600                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
   16601                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
   16602                 if (lastOomAdj != mi.oomAdj) {
   16603                     lastOomAdj = mi.oomAdj;
   16604                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   16605                         tag.append(" / ");
   16606                     }
   16607                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
   16608                         if (firstLine) {
   16609                             stack.append(":");
   16610                             firstLine = false;
   16611                         }
   16612                         stack.append("\n\t at ");
   16613                     } else {
   16614                         stack.append("$");
   16615                     }
   16616                 } else {
   16617                     tag.append(" ");
   16618                     stack.append("$");
   16619                 }
   16620                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   16621                     appendMemBucket(tag, mi.pss, mi.name, false);
   16622                 }
   16623                 appendMemBucket(stack, mi.pss, mi.name, true);
   16624                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
   16625                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
   16626                     stack.append("(");
   16627                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
   16628                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
   16629                             stack.append(DUMP_MEM_OOM_LABEL[k]);
   16630                             stack.append(":");
   16631                             stack.append(DUMP_MEM_OOM_ADJ[k]);
   16632                         }
   16633                     }
   16634                     stack.append(")");
   16635                 }
   16636             }
   16637 
   16638             appendMemInfo(fullNativeBuilder, mi);
   16639             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
   16640                 // The short form only has native processes that are >= 512K.
   16641                 if (mi.pss >= 512) {
   16642                     appendMemInfo(shortNativeBuilder, mi);
   16643                 } else {
   16644                     extraNativeRam += mi.pss;
   16645                     extraNativeMemtrack += mi.memtrack;
   16646                 }
   16647             } else {
   16648                 // Short form has all other details, but if we have collected RAM
   16649                 // from smaller native processes let's dump a summary of that.
   16650                 if (extraNativeRam > 0) {
   16651                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
   16652                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
   16653                     shortNativeBuilder.append('\n');
   16654                     extraNativeRam = 0;
   16655                 }
   16656                 appendMemInfo(fullJavaBuilder, mi);
   16657             }
   16658         }
   16659 
   16660         fullJavaBuilder.append("           ");
   16661         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
   16662         fullJavaBuilder.append(": TOTAL");
   16663         if (totalMemtrack > 0) {
   16664             fullJavaBuilder.append(" (");
   16665             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
   16666             fullJavaBuilder.append(" memtrack)");
   16667         } else {
   16668         }
   16669         fullJavaBuilder.append("\n");
   16670 
   16671         MemInfoReader memInfo = new MemInfoReader();
   16672         memInfo.readMemInfo();
   16673         final long[] infos = memInfo.getRawInfo();
   16674 
   16675         StringBuilder memInfoBuilder = new StringBuilder(1024);
   16676         Debug.getMemInfo(infos);
   16677         memInfoBuilder.append("  MemInfo: ");
   16678         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
   16679         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
   16680         memInfoBuilder.append(stringifyKBSize(
   16681                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
   16682         memInfoBuilder.append(stringifyKBSize(
   16683                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
   16684         memInfoBuilder.append(stringifyKBSize(
   16685                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
   16686         memInfoBuilder.append("           ");
   16687         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
   16688         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
   16689         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
   16690         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
   16691         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
   16692             memInfoBuilder.append("  ZRAM: ");
   16693             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
   16694             memInfoBuilder.append(" RAM, ");
   16695             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
   16696             memInfoBuilder.append(" swap total, ");
   16697             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
   16698             memInfoBuilder.append(" swap free\n");
   16699         }
   16700         final long[] ksm = getKsmInfo();
   16701         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
   16702                 || ksm[KSM_VOLATILE] != 0) {
   16703             memInfoBuilder.append("  KSM: ");
   16704             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
   16705             memInfoBuilder.append(" saved from shared ");
   16706             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
   16707             memInfoBuilder.append("\n       ");
   16708             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
   16709             memInfoBuilder.append(" unshared; ");
   16710             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
   16711             memInfoBuilder.append(" volatile\n");
   16712         }
   16713         memInfoBuilder.append("  Free RAM: ");
   16714         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
   16715                 + memInfo.getFreeSizeKb()));
   16716         memInfoBuilder.append("\n");
   16717         memInfoBuilder.append("  Used RAM: ");
   16718         memInfoBuilder.append(stringifyKBSize(
   16719                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
   16720         memInfoBuilder.append("\n");
   16721         memInfoBuilder.append("  Lost RAM: ");
   16722         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
   16723                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
   16724                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
   16725         memInfoBuilder.append("\n");
   16726         Slog.i(TAG, "Low on memory:");
   16727         Slog.i(TAG, shortNativeBuilder.toString());
   16728         Slog.i(TAG, fullJavaBuilder.toString());
   16729         Slog.i(TAG, memInfoBuilder.toString());
   16730 
   16731         StringBuilder dropBuilder = new StringBuilder(1024);
   16732         /*
   16733         StringWriter oomSw = new StringWriter();
   16734         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
   16735         StringWriter catSw = new StringWriter();
   16736         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
   16737         String[] emptyArgs = new String[] { };
   16738         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
   16739         oomPw.flush();
   16740         String oomString = oomSw.toString();
   16741         */
   16742         dropBuilder.append("Low on memory:");
   16743         dropBuilder.append(stack);
   16744         dropBuilder.append('\n');
   16745         dropBuilder.append(fullNativeBuilder);
   16746         dropBuilder.append(fullJavaBuilder);
   16747         dropBuilder.append('\n');
   16748         dropBuilder.append(memInfoBuilder);
   16749         dropBuilder.append('\n');
   16750         /*
   16751         dropBuilder.append(oomString);
   16752         dropBuilder.append('\n');
   16753         */
   16754         StringWriter catSw = new StringWriter();
   16755         synchronized (ActivityManagerService.this) {
   16756             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
   16757             String[] emptyArgs = new String[] { };
   16758             catPw.println();
   16759             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
   16760             catPw.println();
   16761             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
   16762                     false, null).dumpLocked();
   16763             catPw.println();
   16764             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
   16765             catPw.flush();
   16766         }
   16767         dropBuilder.append(catSw.toString());
   16768         addErrorToDropBox("lowmem", null, "system_server", null,
   16769                 null, tag.toString(), dropBuilder.toString(), null, null);
   16770         //Slog.i(TAG, "Sent to dropbox:");
   16771         //Slog.i(TAG, dropBuilder.toString());
   16772         synchronized (ActivityManagerService.this) {
   16773             long now = SystemClock.uptimeMillis();
   16774             if (mLastMemUsageReportTime < now) {
   16775                 mLastMemUsageReportTime = now;
   16776             }
   16777         }
   16778     }
   16779 
   16780     /**
   16781      * Searches array of arguments for the specified string
   16782      * @param args array of argument strings
   16783      * @param value value to search for
   16784      * @return true if the value is contained in the array
   16785      */
   16786     private static boolean scanArgs(String[] args, String value) {
   16787         if (args != null) {
   16788             for (String arg : args) {
   16789                 if (value.equals(arg)) {
   16790                     return true;
   16791                 }
   16792             }
   16793         }
   16794         return false;
   16795     }
   16796 
   16797     private final boolean removeDyingProviderLocked(ProcessRecord proc,
   16798             ContentProviderRecord cpr, boolean always) {
   16799         final boolean inLaunching = mLaunchingProviders.contains(cpr);
   16800 
   16801         if (!inLaunching || always) {
   16802             synchronized (cpr) {
   16803                 cpr.launchingApp = null;
   16804                 cpr.notifyAll();
   16805             }
   16806             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
   16807             String names[] = cpr.info.authority.split(";");
   16808             for (int j = 0; j < names.length; j++) {
   16809                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
   16810             }
   16811         }
   16812 
   16813         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
   16814             ContentProviderConnection conn = cpr.connections.get(i);
   16815             if (conn.waiting) {
   16816                 // If this connection is waiting for the provider, then we don't
   16817                 // need to mess with its process unless we are always removing
   16818                 // or for some reason the provider is not currently launching.
   16819                 if (inLaunching && !always) {
   16820                     continue;
   16821                 }
   16822             }
   16823             ProcessRecord capp = conn.client;
   16824             conn.dead = true;
   16825             if (conn.stableCount > 0) {
   16826                 if (!capp.persistent && capp.thread != null
   16827                         && capp.pid != 0
   16828                         && capp.pid != MY_PID) {
   16829                     capp.kill("depends on provider "
   16830                             + cpr.name.flattenToShortString()
   16831                             + " in dying proc " + (proc != null ? proc.processName : "??")
   16832                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
   16833                 }
   16834             } else if (capp.thread != null && conn.provider.provider != null) {
   16835                 try {
   16836                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
   16837                 } catch (RemoteException e) {
   16838                 }
   16839                 // In the protocol here, we don't expect the client to correctly
   16840                 // clean up this connection, we'll just remove it.
   16841                 cpr.connections.remove(i);
   16842                 if (conn.client.conProviders.remove(conn)) {
   16843                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
   16844                 }
   16845             }
   16846         }
   16847 
   16848         if (inLaunching && always) {
   16849             mLaunchingProviders.remove(cpr);
   16850         }
   16851         return inLaunching;
   16852     }
   16853 
   16854     /**
   16855      * Main code for cleaning up a process when it has gone away.  This is
   16856      * called both as a result of the process dying, or directly when stopping
   16857      * a process when running in single process mode.
   16858      *
   16859      * @return Returns true if the given process has been restarted, so the
   16860      * app that was passed in must remain on the process lists.
   16861      */
   16862     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
   16863             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
   16864         Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
   16865         if (index >= 0) {
   16866             removeLruProcessLocked(app);
   16867             ProcessList.remove(app.pid);
   16868         }
   16869 
   16870         mProcessesToGc.remove(app);
   16871         mPendingPssProcesses.remove(app);
   16872 
   16873         // Dismiss any open dialogs.
   16874         if (app.crashDialog != null && !app.forceCrashReport) {
   16875             app.crashDialog.dismiss();
   16876             app.crashDialog = null;
   16877         }
   16878         if (app.anrDialog != null) {
   16879             app.anrDialog.dismiss();
   16880             app.anrDialog = null;
   16881         }
   16882         if (app.waitDialog != null) {
   16883             app.waitDialog.dismiss();
   16884             app.waitDialog = null;
   16885         }
   16886 
   16887         app.crashing = false;
   16888         app.notResponding = false;
   16889 
   16890         app.resetPackageList(mProcessStats);
   16891         app.unlinkDeathRecipient();
   16892         app.makeInactive(mProcessStats);
   16893         app.waitingToKill = null;
   16894         app.forcingToForeground = null;
   16895         updateProcessForegroundLocked(app, false, false);
   16896         app.foregroundActivities = false;
   16897         app.hasShownUi = false;
   16898         app.treatLikeActivity = false;
   16899         app.hasAboveClient = false;
   16900         app.hasClientActivities = false;
   16901 
   16902         mServices.killServicesLocked(app, allowRestart);
   16903 
   16904         boolean restart = false;
   16905 
   16906         // Remove published content providers.
   16907         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
   16908             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
   16909             final boolean always = app.bad || !allowRestart;
   16910             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
   16911             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
   16912                 // We left the provider in the launching list, need to
   16913                 // restart it.
   16914                 restart = true;
   16915             }
   16916 
   16917             cpr.provider = null;
   16918             cpr.proc = null;
   16919         }
   16920         app.pubProviders.clear();
   16921 
   16922         // Take care of any launching providers waiting for this process.
   16923         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
   16924             restart = true;
   16925         }
   16926 
   16927         // Unregister from connected content providers.
   16928         if (!app.conProviders.isEmpty()) {
   16929             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
   16930                 ContentProviderConnection conn = app.conProviders.get(i);
   16931                 conn.provider.connections.remove(conn);
   16932                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
   16933                         conn.provider.name);
   16934             }
   16935             app.conProviders.clear();
   16936         }
   16937 
   16938         // At this point there may be remaining entries in mLaunchingProviders
   16939         // where we were the only one waiting, so they are no longer of use.
   16940         // Look for these and clean up if found.
   16941         // XXX Commented out for now.  Trying to figure out a way to reproduce
   16942         // the actual situation to identify what is actually going on.
   16943         if (false) {
   16944             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
   16945                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
   16946                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
   16947                     synchronized (cpr) {
   16948                         cpr.launchingApp = null;
   16949                         cpr.notifyAll();
   16950                     }
   16951                 }
   16952             }
   16953         }
   16954 
   16955         skipCurrentReceiverLocked(app);
   16956 
   16957         // Unregister any receivers.
   16958         for (int i = app.receivers.size() - 1; i >= 0; i--) {
   16959             removeReceiverLocked(app.receivers.valueAt(i));
   16960         }
   16961         app.receivers.clear();
   16962 
   16963         // If the app is undergoing backup, tell the backup manager about it
   16964         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
   16965             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
   16966                     + mBackupTarget.appInfo + " died during backup");
   16967             try {
   16968                 IBackupManager bm = IBackupManager.Stub.asInterface(
   16969                         ServiceManager.getService(Context.BACKUP_SERVICE));
   16970                 bm.agentDisconnected(app.info.packageName);
   16971             } catch (RemoteException e) {
   16972                 // can't happen; backup manager is local
   16973             }
   16974         }
   16975 
   16976         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
   16977             ProcessChangeItem item = mPendingProcessChanges.get(i);
   16978             if (item.pid == app.pid) {
   16979                 mPendingProcessChanges.remove(i);
   16980                 mAvailProcessChanges.add(item);
   16981             }
   16982         }
   16983         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
   16984                 null).sendToTarget();
   16985 
   16986         // If the caller is restarting this app, then leave it in its
   16987         // current lists and let the caller take care of it.
   16988         if (restarting) {
   16989             return false;
   16990         }
   16991 
   16992         if (!app.persistent || app.isolated) {
   16993             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
   16994                     "Removing non-persistent process during cleanup: " + app);
   16995             if (!replacingPid) {
   16996                 removeProcessNameLocked(app.processName, app.uid);
   16997             }
   16998             if (mHeavyWeightProcess == app) {
   16999                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   17000                         mHeavyWeightProcess.userId, 0));
   17001                 mHeavyWeightProcess = null;
   17002             }
   17003         } else if (!app.removed) {
   17004             // This app is persistent, so we need to keep its record around.
   17005             // If it is not already on the pending app list, add it there
   17006             // and start a new process for it.
   17007             if (mPersistentStartingProcesses.indexOf(app) < 0) {
   17008                 mPersistentStartingProcesses.add(app);
   17009                 restart = true;
   17010             }
   17011         }
   17012         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
   17013                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
   17014         mProcessesOnHold.remove(app);
   17015 
   17016         if (app == mHomeProcess) {
   17017             mHomeProcess = null;
   17018         }
   17019         if (app == mPreviousProcess) {
   17020             mPreviousProcess = null;
   17021         }
   17022 
   17023         if (restart && !app.isolated) {
   17024             // We have components that still need to be running in the
   17025             // process, so re-launch it.
   17026             if (index < 0) {
   17027                 ProcessList.remove(app.pid);
   17028             }
   17029             addProcessNameLocked(app);
   17030             startProcessLocked(app, "restart", app.processName);
   17031             return true;
   17032         } else if (app.pid > 0 && app.pid != MY_PID) {
   17033             // Goodbye!
   17034             boolean removed;
   17035             synchronized (mPidsSelfLocked) {
   17036                 mPidsSelfLocked.remove(app.pid);
   17037                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   17038             }
   17039             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   17040             if (app.isolated) {
   17041                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   17042             }
   17043             app.setPid(0);
   17044         }
   17045         return false;
   17046     }
   17047 
   17048     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
   17049         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
   17050             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   17051             if (cpr.launchingApp == app) {
   17052                 return true;
   17053             }
   17054         }
   17055         return false;
   17056     }
   17057 
   17058     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
   17059         // Look through the content providers we are waiting to have launched,
   17060         // and if any run in this process then either schedule a restart of
   17061         // the process or kill the client waiting for it if this process has
   17062         // gone bad.
   17063         boolean restart = false;
   17064         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
   17065             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   17066             if (cpr.launchingApp == app) {
   17067                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
   17068                     restart = true;
   17069                 } else {
   17070                     removeDyingProviderLocked(app, cpr, true);
   17071                 }
   17072             }
   17073         }
   17074         return restart;
   17075     }
   17076 
   17077     // =========================================================
   17078     // SERVICES
   17079     // =========================================================
   17080 
   17081     @Override
   17082     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
   17083             int flags) {
   17084         enforceNotIsolatedCaller("getServices");
   17085         synchronized (this) {
   17086             return mServices.getRunningServiceInfoLocked(maxNum, flags);
   17087         }
   17088     }
   17089 
   17090     @Override
   17091     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
   17092         enforceNotIsolatedCaller("getRunningServiceControlPanel");
   17093         synchronized (this) {
   17094             return mServices.getRunningServiceControlPanelLocked(name);
   17095         }
   17096     }
   17097 
   17098     @Override
   17099     public ComponentName startService(IApplicationThread caller, Intent service,
   17100             String resolvedType, String callingPackage, int userId)
   17101             throws TransactionTooLargeException {
   17102         enforceNotIsolatedCaller("startService");
   17103         // Refuse possible leaked file descriptors
   17104         if (service != null && service.hasFileDescriptors() == true) {
   17105             throw new IllegalArgumentException("File descriptors passed in Intent");
   17106         }
   17107 
   17108         if (callingPackage == null) {
   17109             throw new IllegalArgumentException("callingPackage cannot be null");
   17110         }
   17111 
   17112         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
   17113                 "startService: " + service + " type=" + resolvedType);
   17114         synchronized(this) {
   17115             final int callingPid = Binder.getCallingPid();
   17116             final int callingUid = Binder.getCallingUid();
   17117             final long origId = Binder.clearCallingIdentity();
   17118             ComponentName res = mServices.startServiceLocked(caller, service,
   17119                     resolvedType, callingPid, callingUid, callingPackage, userId);
   17120             Binder.restoreCallingIdentity(origId);
   17121             return res;
   17122         }
   17123     }
   17124 
   17125     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
   17126             String callingPackage, int userId)
   17127             throws TransactionTooLargeException {
   17128         synchronized(this) {
   17129             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
   17130                     "startServiceInPackage: " + service + " type=" + resolvedType);
   17131             final long origId = Binder.clearCallingIdentity();
   17132             ComponentName res = mServices.startServiceLocked(null, service,
   17133                     resolvedType, -1, uid, callingPackage, userId);
   17134             Binder.restoreCallingIdentity(origId);
   17135             return res;
   17136         }
   17137     }
   17138 
   17139     @Override
   17140     public int stopService(IApplicationThread caller, Intent service,
   17141             String resolvedType, int userId) {
   17142         enforceNotIsolatedCaller("stopService");
   17143         // Refuse possible leaked file descriptors
   17144         if (service != null && service.hasFileDescriptors() == true) {
   17145             throw new IllegalArgumentException("File descriptors passed in Intent");
   17146         }
   17147 
   17148         synchronized(this) {
   17149             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
   17150         }
   17151     }
   17152 
   17153     @Override
   17154     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
   17155         enforceNotIsolatedCaller("peekService");
   17156         // Refuse possible leaked file descriptors
   17157         if (service != null && service.hasFileDescriptors() == true) {
   17158             throw new IllegalArgumentException("File descriptors passed in Intent");
   17159         }
   17160 
   17161         if (callingPackage == null) {
   17162             throw new IllegalArgumentException("callingPackage cannot be null");
   17163         }
   17164 
   17165         synchronized(this) {
   17166             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
   17167         }
   17168     }
   17169 
   17170     @Override
   17171     public boolean stopServiceToken(ComponentName className, IBinder token,
   17172             int startId) {
   17173         synchronized(this) {
   17174             return mServices.stopServiceTokenLocked(className, token, startId);
   17175         }
   17176     }
   17177 
   17178     @Override
   17179     public void setServiceForeground(ComponentName className, IBinder token,
   17180             int id, Notification notification, int flags) {
   17181         synchronized(this) {
   17182             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
   17183         }
   17184     }
   17185 
   17186     @Override
   17187     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
   17188             boolean requireFull, String name, String callerPackage) {
   17189         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
   17190                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
   17191     }
   17192 
   17193     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
   17194             String className, int flags) {
   17195         boolean result = false;
   17196         // For apps that don't have pre-defined UIDs, check for permission
   17197         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
   17198             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
   17199                 if (ActivityManager.checkUidPermission(
   17200                         INTERACT_ACROSS_USERS,
   17201                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
   17202                     ComponentName comp = new ComponentName(aInfo.packageName, className);
   17203                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
   17204                             + " requests FLAG_SINGLE_USER, but app does not hold "
   17205                             + INTERACT_ACROSS_USERS;
   17206                     Slog.w(TAG, msg);
   17207                     throw new SecurityException(msg);
   17208                 }
   17209                 // Permission passed
   17210                 result = true;
   17211             }
   17212         } else if ("system".equals(componentProcessName)) {
   17213             result = true;
   17214         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
   17215             // Phone app and persistent apps are allowed to export singleuser providers.
   17216             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
   17217                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
   17218         }
   17219         if (DEBUG_MU) Slog.v(TAG_MU,
   17220                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
   17221                 + Integer.toHexString(flags) + ") = " + result);
   17222         return result;
   17223     }
   17224 
   17225     /**
   17226      * Checks to see if the caller is in the same app as the singleton
   17227      * component, or the component is in a special app. It allows special apps
   17228      * to export singleton components but prevents exporting singleton
   17229      * components for regular apps.
   17230      */
   17231     boolean isValidSingletonCall(int callingUid, int componentUid) {
   17232         int componentAppId = UserHandle.getAppId(componentUid);
   17233         return UserHandle.isSameApp(callingUid, componentUid)
   17234                 || componentAppId == Process.SYSTEM_UID
   17235                 || componentAppId == Process.PHONE_UID
   17236                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
   17237                         == PackageManager.PERMISSION_GRANTED;
   17238     }
   17239 
   17240     public int bindService(IApplicationThread caller, IBinder token, Intent service,
   17241             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
   17242             int userId) throws TransactionTooLargeException {
   17243         enforceNotIsolatedCaller("bindService");
   17244 
   17245         // Refuse possible leaked file descriptors
   17246         if (service != null && service.hasFileDescriptors() == true) {
   17247             throw new IllegalArgumentException("File descriptors passed in Intent");
   17248         }
   17249 
   17250         if (callingPackage == null) {
   17251             throw new IllegalArgumentException("callingPackage cannot be null");
   17252         }
   17253 
   17254         synchronized(this) {
   17255             return mServices.bindServiceLocked(caller, token, service,
   17256                     resolvedType, connection, flags, callingPackage, userId);
   17257         }
   17258     }
   17259 
   17260     public boolean unbindService(IServiceConnection connection) {
   17261         synchronized (this) {
   17262             return mServices.unbindServiceLocked(connection);
   17263         }
   17264     }
   17265 
   17266     public void publishService(IBinder token, Intent intent, IBinder service) {
   17267         // Refuse possible leaked file descriptors
   17268         if (intent != null && intent.hasFileDescriptors() == true) {
   17269             throw new IllegalArgumentException("File descriptors passed in Intent");
   17270         }
   17271 
   17272         synchronized(this) {
   17273             if (!(token instanceof ServiceRecord)) {
   17274                 throw new IllegalArgumentException("Invalid service token");
   17275             }
   17276             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
   17277         }
   17278     }
   17279 
   17280     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
   17281         // Refuse possible leaked file descriptors
   17282         if (intent != null && intent.hasFileDescriptors() == true) {
   17283             throw new IllegalArgumentException("File descriptors passed in Intent");
   17284         }
   17285 
   17286         synchronized(this) {
   17287             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
   17288         }
   17289     }
   17290 
   17291     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
   17292         synchronized(this) {
   17293             if (!(token instanceof ServiceRecord)) {
   17294                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
   17295                 throw new IllegalArgumentException("Invalid service token");
   17296             }
   17297             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
   17298         }
   17299     }
   17300 
   17301     // =========================================================
   17302     // BACKUP AND RESTORE
   17303     // =========================================================
   17304 
   17305     // Cause the target app to be launched if necessary and its backup agent
   17306     // instantiated.  The backup agent will invoke backupAgentCreated() on the
   17307     // activity manager to announce its creation.
   17308     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
   17309         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
   17310         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
   17311 
   17312         IPackageManager pm = AppGlobals.getPackageManager();
   17313         ApplicationInfo app = null;
   17314         try {
   17315             app = pm.getApplicationInfo(packageName, 0, userId);
   17316         } catch (RemoteException e) {
   17317             // can't happen; package manager is process-local
   17318         }
   17319         if (app == null) {
   17320             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
   17321             return false;
   17322         }
   17323 
   17324         synchronized(this) {
   17325             // !!! TODO: currently no check here that we're already bound
   17326             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   17327             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   17328             synchronized (stats) {
   17329                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
   17330             }
   17331 
   17332             // Backup agent is now in use, its package can't be stopped.
   17333             try {
   17334                 AppGlobals.getPackageManager().setPackageStoppedState(
   17335                         app.packageName, false, UserHandle.getUserId(app.uid));
   17336             } catch (RemoteException e) {
   17337             } catch (IllegalArgumentException e) {
   17338                 Slog.w(TAG, "Failed trying to unstop package "
   17339                         + app.packageName + ": " + e);
   17340             }
   17341 
   17342             BackupRecord r = new BackupRecord(ss, app, backupMode);
   17343             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
   17344                     ? new ComponentName(app.packageName, app.backupAgentName)
   17345                     : new ComponentName("android", "FullBackupAgent");
   17346             // startProcessLocked() returns existing proc's record if it's already running
   17347             ProcessRecord proc = startProcessLocked(app.processName, app,
   17348                     false, 0, "backup", hostingName, false, false, false);
   17349             if (proc == null) {
   17350                 Slog.e(TAG, "Unable to start backup agent process " + r);
   17351                 return false;
   17352             }
   17353 
   17354             // If the app is a regular app (uid >= 10000) and not the system server or phone
   17355             // process, etc, then mark it as being in full backup so that certain calls to the
   17356             // process can be blocked. This is not reset to false anywhere because we kill the
   17357             // process after the full backup is done and the ProcessRecord will vaporize anyway.
   17358             if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
   17359                 proc.inFullBackup = true;
   17360             }
   17361             r.app = proc;
   17362             mBackupTarget = r;
   17363             mBackupAppName = app.packageName;
   17364 
   17365             // Try not to kill the process during backup
   17366             updateOomAdjLocked(proc);
   17367 
   17368             // If the process is already attached, schedule the creation of the backup agent now.
   17369             // If it is not yet live, this will be done when it attaches to the framework.
   17370             if (proc.thread != null) {
   17371                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
   17372                 try {
   17373                     proc.thread.scheduleCreateBackupAgent(app,
   17374                             compatibilityInfoForPackageLocked(app), backupMode);
   17375                 } catch (RemoteException e) {
   17376                     // Will time out on the backup manager side
   17377                 }
   17378             } else {
   17379                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
   17380             }
   17381             // Invariants: at this point, the target app process exists and the application
   17382             // is either already running or in the process of coming up.  mBackupTarget and
   17383             // mBackupAppName describe the app, so that when it binds back to the AM we
   17384             // know that it's scheduled for a backup-agent operation.
   17385         }
   17386 
   17387         return true;
   17388     }
   17389 
   17390     @Override
   17391     public void clearPendingBackup() {
   17392         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
   17393         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
   17394 
   17395         synchronized (this) {
   17396             mBackupTarget = null;
   17397             mBackupAppName = null;
   17398         }
   17399     }
   17400 
   17401     // A backup agent has just come up
   17402     public void backupAgentCreated(String agentPackageName, IBinder agent) {
   17403         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
   17404                 + " = " + agent);
   17405 
   17406         synchronized(this) {
   17407             if (!agentPackageName.equals(mBackupAppName)) {
   17408                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
   17409                 return;
   17410             }
   17411         }
   17412 
   17413         long oldIdent = Binder.clearCallingIdentity();
   17414         try {
   17415             IBackupManager bm = IBackupManager.Stub.asInterface(
   17416                     ServiceManager.getService(Context.BACKUP_SERVICE));
   17417             bm.agentConnected(agentPackageName, agent);
   17418         } catch (RemoteException e) {
   17419             // can't happen; the backup manager service is local
   17420         } catch (Exception e) {
   17421             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
   17422             e.printStackTrace();
   17423         } finally {
   17424             Binder.restoreCallingIdentity(oldIdent);
   17425         }
   17426     }
   17427 
   17428     // done with this agent
   17429     public void unbindBackupAgent(ApplicationInfo appInfo) {
   17430         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
   17431         if (appInfo == null) {
   17432             Slog.w(TAG, "unbind backup agent for null app");
   17433             return;
   17434         }
   17435 
   17436         synchronized(this) {
   17437             try {
   17438                 if (mBackupAppName == null) {
   17439                     Slog.w(TAG, "Unbinding backup agent with no active backup");
   17440                     return;
   17441                 }
   17442 
   17443                 if (!mBackupAppName.equals(appInfo.packageName)) {
   17444                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
   17445                     return;
   17446                 }
   17447 
   17448                 // Not backing this app up any more; reset its OOM adjustment
   17449                 final ProcessRecord proc = mBackupTarget.app;
   17450                 updateOomAdjLocked(proc);
   17451 
   17452                 // If the app crashed during backup, 'thread' will be null here
   17453                 if (proc.thread != null) {
   17454                     try {
   17455                         proc.thread.scheduleDestroyBackupAgent(appInfo,
   17456                                 compatibilityInfoForPackageLocked(appInfo));
   17457                     } catch (Exception e) {
   17458                         Slog.e(TAG, "Exception when unbinding backup agent:");
   17459                         e.printStackTrace();
   17460                     }
   17461                 }
   17462             } finally {
   17463                 mBackupTarget = null;
   17464                 mBackupAppName = null;
   17465             }
   17466         }
   17467     }
   17468     // =========================================================
   17469     // BROADCASTS
   17470     // =========================================================
   17471 
   17472     boolean isPendingBroadcastProcessLocked(int pid) {
   17473         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
   17474                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
   17475     }
   17476 
   17477     void skipPendingBroadcastLocked(int pid) {
   17478             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   17479             for (BroadcastQueue queue : mBroadcastQueues) {
   17480                 queue.skipPendingBroadcastLocked(pid);
   17481             }
   17482     }
   17483 
   17484     // The app just attached; send any pending broadcasts that it should receive
   17485     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
   17486         boolean didSomething = false;
   17487         for (BroadcastQueue queue : mBroadcastQueues) {
   17488             didSomething |= queue.sendPendingBroadcastsLocked(app);
   17489         }
   17490         return didSomething;
   17491     }
   17492 
   17493     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
   17494             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
   17495         enforceNotIsolatedCaller("registerReceiver");
   17496         ArrayList<Intent> stickyIntents = null;
   17497         ProcessRecord callerApp = null;
   17498         int callingUid;
   17499         int callingPid;
   17500         synchronized(this) {
   17501             if (caller != null) {
   17502                 callerApp = getRecordForAppLocked(caller);
   17503                 if (callerApp == null) {
   17504                     throw new SecurityException(
   17505                             "Unable to find app for caller " + caller
   17506                             + " (pid=" + Binder.getCallingPid()
   17507                             + ") when registering receiver " + receiver);
   17508                 }
   17509                 if (callerApp.info.uid != Process.SYSTEM_UID &&
   17510                         !callerApp.pkgList.containsKey(callerPackage) &&
   17511                         !"android".equals(callerPackage)) {
   17512                     throw new SecurityException("Given caller package " + callerPackage
   17513                             + " is not running in process " + callerApp);
   17514                 }
   17515                 callingUid = callerApp.info.uid;
   17516                 callingPid = callerApp.pid;
   17517             } else {
   17518                 callerPackage = null;
   17519                 callingUid = Binder.getCallingUid();
   17520                 callingPid = Binder.getCallingPid();
   17521             }
   17522 
   17523             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
   17524                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
   17525 
   17526             Iterator<String> actions = filter.actionsIterator();
   17527             if (actions == null) {
   17528                 ArrayList<String> noAction = new ArrayList<String>(1);
   17529                 noAction.add(null);
   17530                 actions = noAction.iterator();
   17531             }
   17532 
   17533             // Collect stickies of users
   17534             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
   17535             while (actions.hasNext()) {
   17536                 String action = actions.next();
   17537                 for (int id : userIds) {
   17538                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
   17539                     if (stickies != null) {
   17540                         ArrayList<Intent> intents = stickies.get(action);
   17541                         if (intents != null) {
   17542                             if (stickyIntents == null) {
   17543                                 stickyIntents = new ArrayList<Intent>();
   17544                             }
   17545                             stickyIntents.addAll(intents);
   17546                         }
   17547                     }
   17548                 }
   17549             }
   17550         }
   17551 
   17552         ArrayList<Intent> allSticky = null;
   17553         if (stickyIntents != null) {
   17554             final ContentResolver resolver = mContext.getContentResolver();
   17555             // Look for any matching sticky broadcasts...
   17556             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
   17557                 Intent intent = stickyIntents.get(i);
   17558                 // If intent has scheme "content", it will need to acccess
   17559                 // provider that needs to lock mProviderMap in ActivityThread
   17560                 // and also it may need to wait application response, so we
   17561                 // cannot lock ActivityManagerService here.
   17562                 if (filter.match(resolver, intent, true, TAG) >= 0) {
   17563                     if (allSticky == null) {
   17564                         allSticky = new ArrayList<Intent>();
   17565                     }
   17566                     allSticky.add(intent);
   17567                 }
   17568             }
   17569         }
   17570 
   17571         // The first sticky in the list is returned directly back to the client.
   17572         Intent sticky = allSticky != null ? allSticky.get(0) : null;
   17573         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
   17574         if (receiver == null) {
   17575             return sticky;
   17576         }
   17577 
   17578         synchronized (this) {
   17579             if (callerApp != null && (callerApp.thread == null
   17580                     || callerApp.thread.asBinder() != caller.asBinder())) {
   17581                 // Original caller already died
   17582                 return null;
   17583             }
   17584             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
   17585             if (rl == null) {
   17586                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
   17587                         userId, receiver);
   17588                 if (rl.app != null) {
   17589                     rl.app.receivers.add(rl);
   17590                 } else {
   17591                     try {
   17592                         receiver.asBinder().linkToDeath(rl, 0);
   17593                     } catch (RemoteException e) {
   17594                         return sticky;
   17595                     }
   17596                     rl.linkedToDeath = true;
   17597                 }
   17598                 mRegisteredReceivers.put(receiver.asBinder(), rl);
   17599             } else if (rl.uid != callingUid) {
   17600                 throw new IllegalArgumentException(
   17601                         "Receiver requested to register for uid " + callingUid
   17602                         + " was previously registered for uid " + rl.uid);
   17603             } else if (rl.pid != callingPid) {
   17604                 throw new IllegalArgumentException(
   17605                         "Receiver requested to register for pid " + callingPid
   17606                         + " was previously registered for pid " + rl.pid);
   17607             } else if (rl.userId != userId) {
   17608                 throw new IllegalArgumentException(
   17609                         "Receiver requested to register for user " + userId
   17610                         + " was previously registered for user " + rl.userId);
   17611             }
   17612             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
   17613                     permission, callingUid, userId);
   17614             rl.add(bf);
   17615             if (!bf.debugCheck()) {
   17616                 Slog.w(TAG, "==> For Dynamic broadcast");
   17617             }
   17618             mReceiverResolver.addFilter(bf);
   17619 
   17620             // Enqueue broadcasts for all existing stickies that match
   17621             // this filter.
   17622             if (allSticky != null) {
   17623                 ArrayList receivers = new ArrayList();
   17624                 receivers.add(bf);
   17625 
   17626                 final int stickyCount = allSticky.size();
   17627                 for (int i = 0; i < stickyCount; i++) {
   17628                     Intent intent = allSticky.get(i);
   17629                     BroadcastQueue queue = broadcastQueueForIntent(intent);
   17630                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
   17631                             null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
   17632                             null, 0, null, null, false, true, true, -1);
   17633                     queue.enqueueParallelBroadcastLocked(r);
   17634                     queue.scheduleBroadcastsLocked();
   17635                 }
   17636             }
   17637 
   17638             return sticky;
   17639         }
   17640     }
   17641 
   17642     public void unregisterReceiver(IIntentReceiver receiver) {
   17643         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
   17644 
   17645         final long origId = Binder.clearCallingIdentity();
   17646         try {
   17647             boolean doTrim = false;
   17648 
   17649             synchronized(this) {
   17650                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
   17651                 if (rl != null) {
   17652                     final BroadcastRecord r = rl.curBroadcast;
   17653                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
   17654                         final boolean doNext = r.queue.finishReceiverLocked(
   17655                                 r, r.resultCode, r.resultData, r.resultExtras,
   17656                                 r.resultAbort, false);
   17657                         if (doNext) {
   17658                             doTrim = true;
   17659                             r.queue.processNextBroadcast(false);
   17660                         }
   17661                     }
   17662 
   17663                     if (rl.app != null) {
   17664                         rl.app.receivers.remove(rl);
   17665                     }
   17666                     removeReceiverLocked(rl);
   17667                     if (rl.linkedToDeath) {
   17668                         rl.linkedToDeath = false;
   17669                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
   17670                     }
   17671                 }
   17672             }
   17673 
   17674             // If we actually concluded any broadcasts, we might now be able
   17675             // to trim the recipients' apps from our working set
   17676             if (doTrim) {
   17677                 trimApplications();
   17678                 return;
   17679             }
   17680 
   17681         } finally {
   17682             Binder.restoreCallingIdentity(origId);
   17683         }
   17684     }
   17685 
   17686     void removeReceiverLocked(ReceiverList rl) {
   17687         mRegisteredReceivers.remove(rl.receiver.asBinder());
   17688         for (int i = rl.size() - 1; i >= 0; i--) {
   17689             mReceiverResolver.removeFilter(rl.get(i));
   17690         }
   17691     }
   17692 
   17693     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
   17694         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   17695             ProcessRecord r = mLruProcesses.get(i);
   17696             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
   17697                 try {
   17698                     r.thread.dispatchPackageBroadcast(cmd, packages);
   17699                 } catch (RemoteException ex) {
   17700                 }
   17701             }
   17702         }
   17703     }
   17704 
   17705     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
   17706             int callingUid, int[] users) {
   17707         // TODO: come back and remove this assumption to triage all broadcasts
   17708         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
   17709 
   17710         List<ResolveInfo> receivers = null;
   17711         try {
   17712             HashSet<ComponentName> singleUserReceivers = null;
   17713             boolean scannedFirstReceivers = false;
   17714             for (int user : users) {
   17715                 // Skip users that have Shell restrictions, with exception of always permitted
   17716                 // Shell broadcasts
   17717                 if (callingUid == Process.SHELL_UID
   17718                         && mUserController.hasUserRestriction(
   17719                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
   17720                         && !isPermittedShellBroadcast(intent)) {
   17721                     continue;
   17722                 }
   17723                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
   17724                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
   17725                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
   17726                     // If this is not the system user, we need to check for
   17727                     // any receivers that should be filtered out.
   17728                     for (int i=0; i<newReceivers.size(); i++) {
   17729                         ResolveInfo ri = newReceivers.get(i);
   17730                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
   17731                             newReceivers.remove(i);
   17732                             i--;
   17733                         }
   17734                     }
   17735                 }
   17736                 if (newReceivers != null && newReceivers.size() == 0) {
   17737                     newReceivers = null;
   17738                 }
   17739                 if (receivers == null) {
   17740                     receivers = newReceivers;
   17741                 } else if (newReceivers != null) {
   17742                     // We need to concatenate the additional receivers
   17743                     // found with what we have do far.  This would be easy,
   17744                     // but we also need to de-dup any receivers that are
   17745                     // singleUser.
   17746                     if (!scannedFirstReceivers) {
   17747                         // Collect any single user receivers we had already retrieved.
   17748                         scannedFirstReceivers = true;
   17749                         for (int i=0; i<receivers.size(); i++) {
   17750                             ResolveInfo ri = receivers.get(i);
   17751                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   17752                                 ComponentName cn = new ComponentName(
   17753                                         ri.activityInfo.packageName, ri.activityInfo.name);
   17754                                 if (singleUserReceivers == null) {
   17755                                     singleUserReceivers = new HashSet<ComponentName>();
   17756                                 }
   17757                                 singleUserReceivers.add(cn);
   17758                             }
   17759                         }
   17760                     }
   17761                     // Add the new results to the existing results, tracking
   17762                     // and de-dupping single user receivers.
   17763                     for (int i=0; i<newReceivers.size(); i++) {
   17764                         ResolveInfo ri = newReceivers.get(i);
   17765                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   17766                             ComponentName cn = new ComponentName(
   17767                                     ri.activityInfo.packageName, ri.activityInfo.name);
   17768                             if (singleUserReceivers == null) {
   17769                                 singleUserReceivers = new HashSet<ComponentName>();
   17770                             }
   17771                             if (!singleUserReceivers.contains(cn)) {
   17772                                 singleUserReceivers.add(cn);
   17773                                 receivers.add(ri);
   17774                             }
   17775                         } else {
   17776                             receivers.add(ri);
   17777                         }
   17778                     }
   17779                 }
   17780             }
   17781         } catch (RemoteException ex) {
   17782             // pm is in same process, this will never happen.
   17783         }
   17784         return receivers;
   17785     }
   17786 
   17787     private boolean isPermittedShellBroadcast(Intent intent) {
   17788         // remote bugreport should always be allowed to be taken
   17789         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
   17790     }
   17791 
   17792     private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
   17793             String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
   17794         final String action = intent.getAction();
   17795         if (isProtectedBroadcast
   17796                 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
   17797                 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
   17798                 || Intent.ACTION_MEDIA_BUTTON.equals(action)
   17799                 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
   17800                 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
   17801                 || Intent.ACTION_MASTER_CLEAR.equals(action)
   17802                 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
   17803                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
   17804                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
   17805                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
   17806                 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
   17807             // Broadcast is either protected, or it's a public action that
   17808             // we've relaxed, so it's fine for system internals to send.
   17809             return;
   17810         }
   17811 
   17812         // This broadcast may be a problem...  but there are often system components that
   17813         // want to send an internal broadcast to themselves, which is annoying to have to
   17814         // explicitly list each action as a protected broadcast, so we will check for that
   17815         // one safe case and allow it: an explicit broadcast, only being received by something
   17816         // that has protected itself.
   17817         if (receivers != null && receivers.size() > 0
   17818                 && (intent.getPackage() != null || intent.getComponent() != null)) {
   17819             boolean allProtected = true;
   17820             for (int i = receivers.size()-1; i >= 0; i--) {
   17821                 Object target = receivers.get(i);
   17822                 if (target instanceof ResolveInfo) {
   17823                     ResolveInfo ri = (ResolveInfo)target;
   17824                     if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
   17825                         allProtected = false;
   17826                         break;
   17827                     }
   17828                 } else {
   17829                     BroadcastFilter bf = (BroadcastFilter)target;
   17830                     if (bf.requiredPermission == null) {
   17831                         allProtected = false;
   17832                         break;
   17833                     }
   17834                 }
   17835             }
   17836             if (allProtected) {
   17837                 // All safe!
   17838                 return;
   17839             }
   17840         }
   17841 
   17842         // The vast majority of broadcasts sent from system internals
   17843         // should be protected to avoid security holes, so yell loudly
   17844         // to ensure we examine these cases.
   17845         if (callerApp != null) {
   17846             Log.wtf(TAG, "Sending non-protected broadcast " + action
   17847                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
   17848                     new Throwable());
   17849         } else {
   17850             Log.wtf(TAG, "Sending non-protected broadcast " + action
   17851                             + " from system uid " + UserHandle.formatUid(callingUid)
   17852                             + " pkg " + callerPackage,
   17853                     new Throwable());
   17854         }
   17855     }
   17856 
   17857     final int broadcastIntentLocked(ProcessRecord callerApp,
   17858             String callerPackage, Intent intent, String resolvedType,
   17859             IIntentReceiver resultTo, int resultCode, String resultData,
   17860             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
   17861             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
   17862         intent = new Intent(intent);
   17863 
   17864         // By default broadcasts do not go to stopped apps.
   17865         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
   17866 
   17867         // If we have not finished booting, don't allow this to launch new processes.
   17868         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
   17869             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   17870         }
   17871 
   17872         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
   17873                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
   17874                 + " ordered=" + ordered + " userid=" + userId);
   17875         if ((resultTo != null) && !ordered) {
   17876             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
   17877         }
   17878 
   17879         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
   17880                 ALLOW_NON_FULL, "broadcast", callerPackage);
   17881 
   17882         // Make sure that the user who is receiving this broadcast is running.
   17883         // If not, we will just skip it. Make an exception for shutdown broadcasts
   17884         // and upgrade steps.
   17885 
   17886         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
   17887             if ((callingUid != Process.SYSTEM_UID
   17888                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
   17889                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
   17890                 Slog.w(TAG, "Skipping broadcast of " + intent
   17891                         + ": user " + userId + " is stopped");
   17892                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
   17893             }
   17894         }
   17895 
   17896         BroadcastOptions brOptions = null;
   17897         if (bOptions != null) {
   17898             brOptions = new BroadcastOptions(bOptions);
   17899             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
   17900                 // See if the caller is allowed to do this.  Note we are checking against
   17901                 // the actual real caller (not whoever provided the operation as say a
   17902                 // PendingIntent), because that who is actually supplied the arguments.
   17903                 if (checkComponentPermission(
   17904                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
   17905                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
   17906                         != PackageManager.PERMISSION_GRANTED) {
   17907                     String msg = "Permission Denial: " + intent.getAction()
   17908                             + " broadcast from " + callerPackage + " (pid=" + callingPid
   17909                             + ", uid=" + callingUid + ")"
   17910                             + " requires "
   17911                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
   17912                     Slog.w(TAG, msg);
   17913                     throw new SecurityException(msg);
   17914                 }
   17915             }
   17916         }
   17917 
   17918         // Verify that protected broadcasts are only being sent by system code,
   17919         // and that system code is only sending protected broadcasts.
   17920         final String action = intent.getAction();
   17921         final boolean isProtectedBroadcast;
   17922         try {
   17923             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
   17924         } catch (RemoteException e) {
   17925             Slog.w(TAG, "Remote exception", e);
   17926             return ActivityManager.BROADCAST_SUCCESS;
   17927         }
   17928 
   17929         final boolean isCallerSystem;
   17930         switch (UserHandle.getAppId(callingUid)) {
   17931             case Process.ROOT_UID:
   17932             case Process.SYSTEM_UID:
   17933             case Process.PHONE_UID:
   17934             case Process.BLUETOOTH_UID:
   17935             case Process.NFC_UID:
   17936                 isCallerSystem = true;
   17937                 break;
   17938             default:
   17939                 isCallerSystem = (callerApp != null) && callerApp.persistent;
   17940                 break;
   17941         }
   17942 
   17943         // First line security check before anything else: stop non-system apps from
   17944         // sending protected broadcasts.
   17945         if (!isCallerSystem) {
   17946             if (isProtectedBroadcast) {
   17947                 String msg = "Permission Denial: not allowed to send broadcast "
   17948                         + action + " from pid="
   17949                         + callingPid + ", uid=" + callingUid;
   17950                 Slog.w(TAG, msg);
   17951                 throw new SecurityException(msg);
   17952 
   17953             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
   17954                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
   17955                 // Special case for compatibility: we don't want apps to send this,
   17956                 // but historically it has not been protected and apps may be using it
   17957                 // to poke their own app widget.  So, instead of making it protected,
   17958                 // just limit it to the caller.
   17959                 if (callerPackage == null) {
   17960                     String msg = "Permission Denial: not allowed to send broadcast "
   17961                             + action + " from unknown caller.";
   17962                     Slog.w(TAG, msg);
   17963                     throw new SecurityException(msg);
   17964                 } else if (intent.getComponent() != null) {
   17965                     // They are good enough to send to an explicit component...  verify
   17966                     // it is being sent to the calling app.
   17967                     if (!intent.getComponent().getPackageName().equals(
   17968                             callerPackage)) {
   17969                         String msg = "Permission Denial: not allowed to send broadcast "
   17970                                 + action + " to "
   17971                                 + intent.getComponent().getPackageName() + " from "
   17972                                 + callerPackage;
   17973                         Slog.w(TAG, msg);
   17974                         throw new SecurityException(msg);
   17975                     }
   17976                 } else {
   17977                     // Limit broadcast to their own package.
   17978                     intent.setPackage(callerPackage);
   17979                 }
   17980             }
   17981         }
   17982 
   17983         if (action != null) {
   17984             switch (action) {
   17985                 case Intent.ACTION_UID_REMOVED:
   17986                 case Intent.ACTION_PACKAGE_REMOVED:
   17987                 case Intent.ACTION_PACKAGE_CHANGED:
   17988                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
   17989                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
   17990                 case Intent.ACTION_PACKAGES_SUSPENDED:
   17991                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
   17992                     // Handle special intents: if this broadcast is from the package
   17993                     // manager about a package being removed, we need to remove all of
   17994                     // its activities from the history stack.
   17995                     if (checkComponentPermission(
   17996                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
   17997                             callingPid, callingUid, -1, true)
   17998                             != PackageManager.PERMISSION_GRANTED) {
   17999                         String msg = "Permission Denial: " + intent.getAction()
   18000                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
   18001                                 + ", uid=" + callingUid + ")"
   18002                                 + " requires "
   18003                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
   18004                         Slog.w(TAG, msg);
   18005                         throw new SecurityException(msg);
   18006                     }
   18007                     switch (action) {
   18008                         case Intent.ACTION_UID_REMOVED:
   18009                             final Bundle intentExtras = intent.getExtras();
   18010                             final int uid = intentExtras != null
   18011                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
   18012                             if (uid >= 0) {
   18013                                 mBatteryStatsService.removeUid(uid);
   18014                                 mAppOpsService.uidRemoved(uid);
   18015                             }
   18016                             break;
   18017                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
   18018                             // If resources are unavailable just force stop all those packages
   18019                             // and flush the attribute cache as well.
   18020                             String list[] =
   18021                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   18022                             if (list != null && list.length > 0) {
   18023                                 for (int i = 0; i < list.length; i++) {
   18024                                     forceStopPackageLocked(list[i], -1, false, true, true,
   18025                                             false, false, userId, "storage unmount");
   18026                                 }
   18027                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
   18028                                 sendPackageBroadcastLocked(
   18029                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
   18030                                         userId);
   18031                             }
   18032                             break;
   18033                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
   18034                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
   18035                             break;
   18036                         case Intent.ACTION_PACKAGE_REMOVED:
   18037                         case Intent.ACTION_PACKAGE_CHANGED:
   18038                             Uri data = intent.getData();
   18039                             String ssp;
   18040                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   18041                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
   18042                                 final boolean replacing =
   18043                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
   18044                                 final boolean killProcess =
   18045                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
   18046                                 final boolean fullUninstall = removed && !replacing;
   18047                                 if (removed) {
   18048                                     if (killProcess) {
   18049                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
   18050                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
   18051                                                 false, true, true, false, fullUninstall, userId,
   18052                                                 removed ? "pkg removed" : "pkg changed");
   18053                                     }
   18054                                     final int cmd = killProcess
   18055                                             ? IApplicationThread.PACKAGE_REMOVED
   18056                                             : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
   18057                                     sendPackageBroadcastLocked(cmd,
   18058                                             new String[] {ssp}, userId);
   18059                                     if (fullUninstall) {
   18060                                         mAppOpsService.packageRemoved(
   18061                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
   18062 
   18063                                         // Remove all permissions granted from/to this package
   18064                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
   18065 
   18066                                         removeTasksByPackageNameLocked(ssp, userId);
   18067 
   18068                                         // Hide the "unsupported display" dialog if necessary.
   18069                                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
   18070                                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
   18071                                             mUnsupportedDisplaySizeDialog.dismiss();
   18072                                             mUnsupportedDisplaySizeDialog = null;
   18073                                         }
   18074                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
   18075                                         mBatteryStatsService.notePackageUninstalled(ssp);
   18076                                     }
   18077                                 } else {
   18078                                     if (killProcess) {
   18079                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
   18080                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
   18081                                                 userId, ProcessList.INVALID_ADJ,
   18082                                                 false, true, true, false, "change " + ssp);
   18083                                     }
   18084                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
   18085                                             intent.getStringArrayExtra(
   18086                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
   18087                                 }
   18088                             }
   18089                             break;
   18090                         case Intent.ACTION_PACKAGES_SUSPENDED:
   18091                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
   18092                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
   18093                                     intent.getAction());
   18094                             final String[] packageNames = intent.getStringArrayExtra(
   18095                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
   18096                             final int userHandle = intent.getIntExtra(
   18097                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
   18098 
   18099                             synchronized(ActivityManagerService.this) {
   18100                                 mRecentTasks.onPackagesSuspendedChanged(
   18101                                         packageNames, suspended, userHandle);
   18102                             }
   18103                             break;
   18104                     }
   18105                     break;
   18106                 case Intent.ACTION_PACKAGE_REPLACED:
   18107                 {
   18108                     final Uri data = intent.getData();
   18109                     final String ssp;
   18110                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
   18111                         final ApplicationInfo aInfo =
   18112                                 getPackageManagerInternalLocked().getApplicationInfo(
   18113                                         ssp,
   18114                                         userId);
   18115                         if (aInfo == null) {
   18116                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
   18117                                     + " ssp=" + ssp + " data=" + data);
   18118                             return ActivityManager.BROADCAST_SUCCESS;
   18119                         }
   18120                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
   18121                         sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
   18122                                 new String[] {ssp}, userId);
   18123                     }
   18124                     break;
   18125                 }
   18126                 case Intent.ACTION_PACKAGE_ADDED:
   18127                 {
   18128                     // Special case for adding a package: by default turn on compatibility mode.
   18129                     Uri data = intent.getData();
   18130                     String ssp;
   18131                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
   18132                         final boolean replacing =
   18133                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
   18134                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
   18135 
   18136                         try {
   18137                             ApplicationInfo ai = AppGlobals.getPackageManager().
   18138                                     getApplicationInfo(ssp, 0, 0);
   18139                             mBatteryStatsService.notePackageInstalled(ssp,
   18140                                     ai != null ? ai.versionCode : 0);
   18141                         } catch (RemoteException e) {
   18142                         }
   18143                     }
   18144                     break;
   18145                 }
   18146                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
   18147                 {
   18148                     Uri data = intent.getData();
   18149                     String ssp;
   18150                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
   18151                         // Hide the "unsupported display" dialog if necessary.
   18152                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
   18153                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
   18154                             mUnsupportedDisplaySizeDialog.dismiss();
   18155                             mUnsupportedDisplaySizeDialog = null;
   18156                         }
   18157                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
   18158                     }
   18159                     break;
   18160                 }
   18161                 case Intent.ACTION_TIMEZONE_CHANGED:
   18162                     // If this is the time zone changed action, queue up a message that will reset
   18163                     // the timezone of all currently running processes. This message will get
   18164                     // queued up before the broadcast happens.
   18165                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
   18166                     break;
   18167                 case Intent.ACTION_TIME_CHANGED:
   18168                     // If the user set the time, let all running processes know.
   18169                     final int is24Hour =
   18170                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
   18171                                     : 0;
   18172                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
   18173                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   18174                     synchronized (stats) {
   18175                         stats.noteCurrentTimeChangedLocked();
   18176                     }
   18177                     break;
   18178                 case Intent.ACTION_CLEAR_DNS_CACHE:
   18179                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
   18180                     break;
   18181                 case Proxy.PROXY_CHANGE_ACTION:
   18182                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
   18183                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
   18184                     break;
   18185                 case android.hardware.Camera.ACTION_NEW_PICTURE:
   18186                 case android.hardware.Camera.ACTION_NEW_VIDEO:
   18187                     // These broadcasts are no longer allowed by the system, since they can
   18188                     // cause significant thrashing at a crictical point (using the camera).
   18189                     // Apps should use JobScehduler to monitor for media provider changes.
   18190                     Slog.w(TAG, action + " no longer allowed; dropping from "
   18191                             + UserHandle.formatUid(callingUid));
   18192                     if (resultTo != null) {
   18193                         final BroadcastQueue queue = broadcastQueueForIntent(intent);
   18194                         try {
   18195                             queue.performReceiveLocked(callerApp, resultTo, intent,
   18196                                     Activity.RESULT_CANCELED, null, null,
   18197                                     false, false, userId);
   18198                         } catch (RemoteException e) {
   18199                             Slog.w(TAG, "Failure ["
   18200                                     + queue.mQueueName + "] sending broadcast result of "
   18201                                     + intent, e);
   18202 
   18203                         }
   18204                     }
   18205                     // Lie; we don't want to crash the app.
   18206                     return ActivityManager.BROADCAST_SUCCESS;
   18207             }
   18208         }
   18209 
   18210         // Add to the sticky list if requested.
   18211         if (sticky) {
   18212             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
   18213                     callingPid, callingUid)
   18214                     != PackageManager.PERMISSION_GRANTED) {
   18215                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
   18216                         + callingPid + ", uid=" + callingUid
   18217                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   18218                 Slog.w(TAG, msg);
   18219                 throw new SecurityException(msg);
   18220             }
   18221             if (requiredPermissions != null && requiredPermissions.length > 0) {
   18222                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
   18223                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
   18224                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
   18225             }
   18226             if (intent.getComponent() != null) {
   18227                 throw new SecurityException(
   18228                         "Sticky broadcasts can't target a specific component");
   18229             }
   18230             // We use userId directly here, since the "all" target is maintained
   18231             // as a separate set of sticky broadcasts.
   18232             if (userId != UserHandle.USER_ALL) {
   18233                 // But first, if this is not a broadcast to all users, then
   18234                 // make sure it doesn't conflict with an existing broadcast to
   18235                 // all users.
   18236                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
   18237                         UserHandle.USER_ALL);
   18238                 if (stickies != null) {
   18239                     ArrayList<Intent> list = stickies.get(intent.getAction());
   18240                     if (list != null) {
   18241                         int N = list.size();
   18242                         int i;
   18243                         for (i=0; i<N; i++) {
   18244                             if (intent.filterEquals(list.get(i))) {
   18245                                 throw new IllegalArgumentException(
   18246                                         "Sticky broadcast " + intent + " for user "
   18247                                         + userId + " conflicts with existing global broadcast");
   18248                             }
   18249                         }
   18250                     }
   18251                 }
   18252             }
   18253             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   18254             if (stickies == null) {
   18255                 stickies = new ArrayMap<>();
   18256                 mStickyBroadcasts.put(userId, stickies);
   18257             }
   18258             ArrayList<Intent> list = stickies.get(intent.getAction());
   18259             if (list == null) {
   18260                 list = new ArrayList<>();
   18261                 stickies.put(intent.getAction(), list);
   18262             }
   18263             final int stickiesCount = list.size();
   18264             int i;
   18265             for (i = 0; i < stickiesCount; i++) {
   18266                 if (intent.filterEquals(list.get(i))) {
   18267                     // This sticky already exists, replace it.
   18268                     list.set(i, new Intent(intent));
   18269                     break;
   18270                 }
   18271             }
   18272             if (i >= stickiesCount) {
   18273                 list.add(new Intent(intent));
   18274             }
   18275         }
   18276 
   18277         int[] users;
   18278         if (userId == UserHandle.USER_ALL) {
   18279             // Caller wants broadcast to go to all started users.
   18280             users = mUserController.getStartedUserArrayLocked();
   18281         } else {
   18282             // Caller wants broadcast to go to one specific user.
   18283             users = new int[] {userId};
   18284         }
   18285 
   18286         // Figure out who all will receive this broadcast.
   18287         List receivers = null;
   18288         List<BroadcastFilter> registeredReceivers = null;
   18289         // Need to resolve the intent to interested receivers...
   18290         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
   18291                  == 0) {
   18292             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
   18293         }
   18294         if (intent.getComponent() == null) {
   18295             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
   18296                 // Query one target user at a time, excluding shell-restricted users
   18297                 for (int i = 0; i < users.length; i++) {
   18298                     if (mUserController.hasUserRestriction(
   18299                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
   18300                         continue;
   18301                     }
   18302                     List<BroadcastFilter> registeredReceiversForUser =
   18303                             mReceiverResolver.queryIntent(intent,
   18304                                     resolvedType, false, users[i]);
   18305                     if (registeredReceivers == null) {
   18306                         registeredReceivers = registeredReceiversForUser;
   18307                     } else if (registeredReceiversForUser != null) {
   18308                         registeredReceivers.addAll(registeredReceiversForUser);
   18309                     }
   18310                 }
   18311             } else {
   18312                 registeredReceivers = mReceiverResolver.queryIntent(intent,
   18313                         resolvedType, false, userId);
   18314             }
   18315         }
   18316 
   18317         final boolean replacePending =
   18318                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
   18319 
   18320         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
   18321                 + " replacePending=" + replacePending);
   18322 
   18323         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
   18324         if (!ordered && NR > 0) {
   18325             // If we are not serializing this broadcast, then send the
   18326             // registered receivers separately so they don't wait for the
   18327             // components to be launched.
   18328             if (isCallerSystem) {
   18329                 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
   18330                         isProtectedBroadcast, registeredReceivers);
   18331             }
   18332             final BroadcastQueue queue = broadcastQueueForIntent(intent);
   18333             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   18334                     callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
   18335                     appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
   18336                     resultExtras, ordered, sticky, false, userId);
   18337             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
   18338             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
   18339             if (!replaced) {
   18340                 queue.enqueueParallelBroadcastLocked(r);
   18341                 queue.scheduleBroadcastsLocked();
   18342             }
   18343             registeredReceivers = null;
   18344             NR = 0;
   18345         }
   18346 
   18347         // Merge into one list.
   18348         int ir = 0;
   18349         if (receivers != null) {
   18350             // A special case for PACKAGE_ADDED: do not allow the package
   18351             // being added to see this broadcast.  This prevents them from
   18352             // using this as a back door to get run as soon as they are
   18353             // installed.  Maybe in the future we want to have a special install
   18354             // broadcast or such for apps, but we'd like to deliberately make
   18355             // this decision.
   18356             String skipPackages[] = null;
   18357             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
   18358                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
   18359                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
   18360                 Uri data = intent.getData();
   18361                 if (data != null) {
   18362                     String pkgName = data.getSchemeSpecificPart();
   18363                     if (pkgName != null) {
   18364                         skipPackages = new String[] { pkgName };
   18365                     }
   18366                 }
   18367             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
   18368                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   18369             }
   18370             if (skipPackages != null && (skipPackages.length > 0)) {
   18371                 for (String skipPackage : skipPackages) {
   18372                     if (skipPackage != null) {
   18373                         int NT = receivers.size();
   18374                         for (int it=0; it<NT; it++) {
   18375                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
   18376                             if (curt.activityInfo.packageName.equals(skipPackage)) {
   18377                                 receivers.remove(it);
   18378                                 it--;
   18379                                 NT--;
   18380                             }
   18381                         }
   18382                     }
   18383                 }
   18384             }
   18385 
   18386             int NT = receivers != null ? receivers.size() : 0;
   18387             int it = 0;
   18388             ResolveInfo curt = null;
   18389             BroadcastFilter curr = null;
   18390             while (it < NT && ir < NR) {
   18391                 if (curt == null) {
   18392                     curt = (ResolveInfo)receivers.get(it);
   18393                 }
   18394                 if (curr == null) {
   18395                     curr = registeredReceivers.get(ir);
   18396                 }
   18397                 if (curr.getPriority() >= curt.priority) {
   18398                     // Insert this broadcast record into the final list.
   18399                     receivers.add(it, curr);
   18400                     ir++;
   18401                     curr = null;
   18402                     it++;
   18403                     NT++;
   18404                 } else {
   18405                     // Skip to the next ResolveInfo in the final list.
   18406                     it++;
   18407                     curt = null;
   18408                 }
   18409             }
   18410         }
   18411         while (ir < NR) {
   18412             if (receivers == null) {
   18413                 receivers = new ArrayList();
   18414             }
   18415             receivers.add(registeredReceivers.get(ir));
   18416             ir++;
   18417         }
   18418 
   18419         if (isCallerSystem) {
   18420             checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
   18421                     isProtectedBroadcast, receivers);
   18422         }
   18423 
   18424         if ((receivers != null && receivers.size() > 0)
   18425                 || resultTo != null) {
   18426             BroadcastQueue queue = broadcastQueueForIntent(intent);
   18427             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   18428                     callerPackage, callingPid, callingUid, resolvedType,
   18429                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
   18430                     resultData, resultExtras, ordered, sticky, false, userId);
   18431 
   18432             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
   18433                     + ": prev had " + queue.mOrderedBroadcasts.size());
   18434             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
   18435                     "Enqueueing broadcast " + r.intent.getAction());
   18436 
   18437             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
   18438             if (!replaced) {
   18439                 queue.enqueueOrderedBroadcastLocked(r);
   18440                 queue.scheduleBroadcastsLocked();
   18441             }
   18442         } else {
   18443             // There was nobody interested in the broadcast, but we still want to record
   18444             // that it happened.
   18445             if (intent.getComponent() == null && intent.getPackage() == null
   18446                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   18447                 // This was an implicit broadcast... let's record it for posterity.
   18448                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
   18449             }
   18450         }
   18451 
   18452         return ActivityManager.BROADCAST_SUCCESS;
   18453     }
   18454 
   18455     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
   18456             int skipCount, long dispatchTime) {
   18457         final long now = SystemClock.elapsedRealtime();
   18458         if (mCurBroadcastStats == null ||
   18459                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
   18460             mLastBroadcastStats = mCurBroadcastStats;
   18461             if (mLastBroadcastStats != null) {
   18462                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
   18463                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
   18464             }
   18465             mCurBroadcastStats = new BroadcastStats();
   18466         }
   18467         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
   18468     }
   18469 
   18470     final Intent verifyBroadcastLocked(Intent intent) {
   18471         // Refuse possible leaked file descriptors
   18472         if (intent != null && intent.hasFileDescriptors() == true) {
   18473             throw new IllegalArgumentException("File descriptors passed in Intent");
   18474         }
   18475 
   18476         int flags = intent.getFlags();
   18477 
   18478         if (!mProcessesReady) {
   18479             // if the caller really truly claims to know what they're doing, go
   18480             // ahead and allow the broadcast without launching any receivers
   18481             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
   18482                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
   18483             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   18484                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
   18485                         + " before boot completion");
   18486                 throw new IllegalStateException("Cannot broadcast before boot completed");
   18487             }
   18488         }
   18489 
   18490         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   18491             throw new IllegalArgumentException(
   18492                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   18493         }
   18494 
   18495         return intent;
   18496     }
   18497 
   18498     public final int broadcastIntent(IApplicationThread caller,
   18499             Intent intent, String resolvedType, IIntentReceiver resultTo,
   18500             int resultCode, String resultData, Bundle resultExtras,
   18501             String[] requiredPermissions, int appOp, Bundle bOptions,
   18502             boolean serialized, boolean sticky, int userId) {
   18503         enforceNotIsolatedCaller("broadcastIntent");
   18504         synchronized(this) {
   18505             intent = verifyBroadcastLocked(intent);
   18506 
   18507             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   18508             final int callingPid = Binder.getCallingPid();
   18509             final int callingUid = Binder.getCallingUid();
   18510             final long origId = Binder.clearCallingIdentity();
   18511             int res = broadcastIntentLocked(callerApp,
   18512                     callerApp != null ? callerApp.info.packageName : null,
   18513                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
   18514                     requiredPermissions, appOp, bOptions, serialized, sticky,
   18515                     callingPid, callingUid, userId);
   18516             Binder.restoreCallingIdentity(origId);
   18517             return res;
   18518         }
   18519     }
   18520 
   18521 
   18522     int broadcastIntentInPackage(String packageName, int uid,
   18523             Intent intent, String resolvedType, IIntentReceiver resultTo,
   18524             int resultCode, String resultData, Bundle resultExtras,
   18525             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
   18526             int userId) {
   18527         synchronized(this) {
   18528             intent = verifyBroadcastLocked(intent);
   18529 
   18530             final long origId = Binder.clearCallingIdentity();
   18531             String[] requiredPermissions = requiredPermission == null ? null
   18532                     : new String[] {requiredPermission};
   18533             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
   18534                     resultTo, resultCode, resultData, resultExtras,
   18535                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
   18536                     sticky, -1, uid, userId);
   18537             Binder.restoreCallingIdentity(origId);
   18538             return res;
   18539         }
   18540     }
   18541 
   18542     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
   18543         // Refuse possible leaked file descriptors
   18544         if (intent != null && intent.hasFileDescriptors() == true) {
   18545             throw new IllegalArgumentException("File descriptors passed in Intent");
   18546         }
   18547 
   18548         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   18549                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
   18550 
   18551         synchronized(this) {
   18552             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
   18553                     != PackageManager.PERMISSION_GRANTED) {
   18554                 String msg = "Permission Denial: unbroadcastIntent() from pid="
   18555                         + Binder.getCallingPid()
   18556                         + ", uid=" + Binder.getCallingUid()
   18557                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   18558                 Slog.w(TAG, msg);
   18559                 throw new SecurityException(msg);
   18560             }
   18561             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   18562             if (stickies != null) {
   18563                 ArrayList<Intent> list = stickies.get(intent.getAction());
   18564                 if (list != null) {
   18565                     int N = list.size();
   18566                     int i;
   18567                     for (i=0; i<N; i++) {
   18568                         if (intent.filterEquals(list.get(i))) {
   18569                             list.remove(i);
   18570                             break;
   18571                         }
   18572                     }
   18573                     if (list.size() <= 0) {
   18574                         stickies.remove(intent.getAction());
   18575                     }
   18576                 }
   18577                 if (stickies.size() <= 0) {
   18578                     mStickyBroadcasts.remove(userId);
   18579                 }
   18580             }
   18581         }
   18582     }
   18583 
   18584     void backgroundServicesFinishedLocked(int userId) {
   18585         for (BroadcastQueue queue : mBroadcastQueues) {
   18586             queue.backgroundServicesFinishedLocked(userId);
   18587         }
   18588     }
   18589 
   18590     public void finishReceiver(IBinder who, int resultCode, String resultData,
   18591             Bundle resultExtras, boolean resultAbort, int flags) {
   18592         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
   18593 
   18594         // Refuse possible leaked file descriptors
   18595         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
   18596             throw new IllegalArgumentException("File descriptors passed in Bundle");
   18597         }
   18598 
   18599         final long origId = Binder.clearCallingIdentity();
   18600         try {
   18601             boolean doNext = false;
   18602             BroadcastRecord r;
   18603 
   18604             synchronized(this) {
   18605                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
   18606                         ? mFgBroadcastQueue : mBgBroadcastQueue;
   18607                 r = queue.getMatchingOrderedReceiver(who);
   18608                 if (r != null) {
   18609                     doNext = r.queue.finishReceiverLocked(r, resultCode,
   18610                         resultData, resultExtras, resultAbort, true);
   18611                 }
   18612             }
   18613 
   18614             if (doNext) {
   18615                 r.queue.processNextBroadcast(false);
   18616             }
   18617             trimApplications();
   18618         } finally {
   18619             Binder.restoreCallingIdentity(origId);
   18620         }
   18621     }
   18622 
   18623     // =========================================================
   18624     // INSTRUMENTATION
   18625     // =========================================================
   18626 
   18627     public boolean startInstrumentation(ComponentName className,
   18628             String profileFile, int flags, Bundle arguments,
   18629             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
   18630             int userId, String abiOverride) {
   18631         enforceNotIsolatedCaller("startInstrumentation");
   18632         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   18633                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
   18634         // Refuse possible leaked file descriptors
   18635         if (arguments != null && arguments.hasFileDescriptors()) {
   18636             throw new IllegalArgumentException("File descriptors passed in Bundle");
   18637         }
   18638 
   18639         synchronized(this) {
   18640             InstrumentationInfo ii = null;
   18641             ApplicationInfo ai = null;
   18642             try {
   18643                 ii = mContext.getPackageManager().getInstrumentationInfo(
   18644                     className, STOCK_PM_FLAGS);
   18645                 ai = AppGlobals.getPackageManager().getApplicationInfo(
   18646                         ii.targetPackage, STOCK_PM_FLAGS, userId);
   18647             } catch (PackageManager.NameNotFoundException e) {
   18648             } catch (RemoteException e) {
   18649             }
   18650             if (ii == null) {
   18651                 reportStartInstrumentationFailureLocked(watcher, className,
   18652                         "Unable to find instrumentation info for: " + className);
   18653                 return false;
   18654             }
   18655             if (ai == null) {
   18656                 reportStartInstrumentationFailureLocked(watcher, className,
   18657                         "Unable to find instrumentation target package: " + ii.targetPackage);
   18658                 return false;
   18659             }
   18660             if (!ai.hasCode()) {
   18661                 reportStartInstrumentationFailureLocked(watcher, className,
   18662                         "Instrumentation target has no code: " + ii.targetPackage);
   18663                 return false;
   18664             }
   18665 
   18666             int match = mContext.getPackageManager().checkSignatures(
   18667                     ii.targetPackage, ii.packageName);
   18668             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
   18669                 String msg = "Permission Denial: starting instrumentation "
   18670                         + className + " from pid="
   18671                         + Binder.getCallingPid()
   18672                         + ", uid=" + Binder.getCallingPid()
   18673                         + " not allowed because package " + ii.packageName
   18674                         + " does not have a signature matching the target "
   18675                         + ii.targetPackage;
   18676                 reportStartInstrumentationFailureLocked(watcher, className, msg);
   18677                 throw new SecurityException(msg);
   18678             }
   18679 
   18680             final long origId = Binder.clearCallingIdentity();
   18681             // Instrumentation can kill and relaunch even persistent processes
   18682             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
   18683                     "start instr");
   18684             ProcessRecord app = addAppLocked(ai, false, abiOverride);
   18685             app.instrumentationClass = className;
   18686             app.instrumentationInfo = ai;
   18687             app.instrumentationProfileFile = profileFile;
   18688             app.instrumentationArguments = arguments;
   18689             app.instrumentationWatcher = watcher;
   18690             app.instrumentationUiAutomationConnection = uiAutomationConnection;
   18691             app.instrumentationResultClass = className;
   18692             Binder.restoreCallingIdentity(origId);
   18693         }
   18694 
   18695         return true;
   18696     }
   18697 
   18698     /**
   18699      * Report errors that occur while attempting to start Instrumentation.  Always writes the
   18700      * error to the logs, but if somebody is watching, send the report there too.  This enables
   18701      * the "am" command to report errors with more information.
   18702      *
   18703      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
   18704      * @param cn The component name of the instrumentation.
   18705      * @param report The error report.
   18706      */
   18707     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
   18708             ComponentName cn, String report) {
   18709         Slog.w(TAG, report);
   18710         if (watcher != null) {
   18711             Bundle results = new Bundle();
   18712             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
   18713             results.putString("Error", report);
   18714             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
   18715         }
   18716     }
   18717 
   18718     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
   18719         if (app.instrumentationWatcher != null) {
   18720             mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
   18721                     app.instrumentationClass, resultCode, results);
   18722         }
   18723 
   18724         // Can't call out of the system process with a lock held, so post a message.
   18725         if (app.instrumentationUiAutomationConnection != null) {
   18726             mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
   18727                     app.instrumentationUiAutomationConnection).sendToTarget();
   18728         }
   18729 
   18730         app.instrumentationWatcher = null;
   18731         app.instrumentationUiAutomationConnection = null;
   18732         app.instrumentationClass = null;
   18733         app.instrumentationInfo = null;
   18734         app.instrumentationProfileFile = null;
   18735         app.instrumentationArguments = null;
   18736 
   18737         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
   18738                 "finished inst");
   18739     }
   18740 
   18741     public void finishInstrumentation(IApplicationThread target,
   18742             int resultCode, Bundle results) {
   18743         int userId = UserHandle.getCallingUserId();
   18744         // Refuse possible leaked file descriptors
   18745         if (results != null && results.hasFileDescriptors()) {
   18746             throw new IllegalArgumentException("File descriptors passed in Intent");
   18747         }
   18748 
   18749         synchronized(this) {
   18750             ProcessRecord app = getRecordForAppLocked(target);
   18751             if (app == null) {
   18752                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
   18753                 return;
   18754             }
   18755             final long origId = Binder.clearCallingIdentity();
   18756             finishInstrumentationLocked(app, resultCode, results);
   18757             Binder.restoreCallingIdentity(origId);
   18758         }
   18759     }
   18760 
   18761     // =========================================================
   18762     // CONFIGURATION
   18763     // =========================================================
   18764 
   18765     public ConfigurationInfo getDeviceConfigurationInfo() {
   18766         ConfigurationInfo config = new ConfigurationInfo();
   18767         synchronized (this) {
   18768             config.reqTouchScreen = mConfiguration.touchscreen;
   18769             config.reqKeyboardType = mConfiguration.keyboard;
   18770             config.reqNavigation = mConfiguration.navigation;
   18771             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
   18772                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
   18773                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
   18774             }
   18775             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
   18776                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
   18777                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
   18778             }
   18779             config.reqGlEsVersion = GL_ES_VERSION;
   18780         }
   18781         return config;
   18782     }
   18783 
   18784     ActivityStack getFocusedStack() {
   18785         return mStackSupervisor.getFocusedStack();
   18786     }
   18787 
   18788     @Override
   18789     public int getFocusedStackId() throws RemoteException {
   18790         ActivityStack focusedStack = getFocusedStack();
   18791         if (focusedStack != null) {
   18792             return focusedStack.getStackId();
   18793         }
   18794         return -1;
   18795     }
   18796 
   18797     public Configuration getConfiguration() {
   18798         Configuration ci;
   18799         synchronized(this) {
   18800             ci = new Configuration(mConfiguration);
   18801             ci.userSetLocale = false;
   18802         }
   18803         return ci;
   18804     }
   18805 
   18806     @Override
   18807     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
   18808         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
   18809         synchronized (this) {
   18810             mSuppressResizeConfigChanges = suppress;
   18811         }
   18812     }
   18813 
   18814     @Override
   18815     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
   18816         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
   18817         if (fromStackId == HOME_STACK_ID) {
   18818             throw new IllegalArgumentException("You can't move tasks from the home stack.");
   18819         }
   18820         synchronized (this) {
   18821             final long origId = Binder.clearCallingIdentity();
   18822             try {
   18823                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
   18824             } finally {
   18825                 Binder.restoreCallingIdentity(origId);
   18826             }
   18827         }
   18828     }
   18829 
   18830     @Override
   18831     public void updatePersistentConfiguration(Configuration values) {
   18832         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   18833                 "updateConfiguration()");
   18834         enforceWriteSettingsPermission("updateConfiguration()");
   18835         if (values == null) {
   18836             throw new NullPointerException("Configuration must not be null");
   18837         }
   18838 
   18839         int userId = UserHandle.getCallingUserId();
   18840 
   18841         synchronized(this) {
   18842             updatePersistentConfigurationLocked(values, userId);
   18843         }
   18844     }
   18845 
   18846     private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
   18847         final long origId = Binder.clearCallingIdentity();
   18848         try {
   18849             updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
   18850         } finally {
   18851             Binder.restoreCallingIdentity(origId);
   18852         }
   18853     }
   18854 
   18855     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
   18856         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
   18857                 FONT_SCALE, 1.0f, userId);
   18858         if (mConfiguration.fontScale != scaleFactor) {
   18859             final Configuration configuration = mWindowManager.computeNewConfiguration();
   18860             configuration.fontScale = scaleFactor;
   18861             synchronized (this) {
   18862                 updatePersistentConfigurationLocked(configuration, userId);
   18863             }
   18864         }
   18865     }
   18866 
   18867     private void enforceWriteSettingsPermission(String func) {
   18868         int uid = Binder.getCallingUid();
   18869         if (uid == Process.ROOT_UID) {
   18870             return;
   18871         }
   18872 
   18873         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
   18874                 Settings.getPackageNameForUid(mContext, uid), false)) {
   18875             return;
   18876         }
   18877 
   18878         String msg = "Permission Denial: " + func + " from pid="
   18879                 + Binder.getCallingPid()
   18880                 + ", uid=" + uid
   18881                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
   18882         Slog.w(TAG, msg);
   18883         throw new SecurityException(msg);
   18884     }
   18885 
   18886     public void updateConfiguration(Configuration values) {
   18887         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   18888                 "updateConfiguration()");
   18889 
   18890         synchronized(this) {
   18891             if (values == null && mWindowManager != null) {
   18892                 // sentinel: fetch the current configuration from the window manager
   18893                 values = mWindowManager.computeNewConfiguration();
   18894             }
   18895 
   18896             if (mWindowManager != null) {
   18897                 mProcessList.applyDisplaySize(mWindowManager);
   18898             }
   18899 
   18900             final long origId = Binder.clearCallingIdentity();
   18901             if (values != null) {
   18902                 Settings.System.clearConfiguration(values);
   18903             }
   18904             updateConfigurationLocked(values, null, false);
   18905             Binder.restoreCallingIdentity(origId);
   18906         }
   18907     }
   18908 
   18909     void updateUserConfigurationLocked() {
   18910         Configuration configuration = new Configuration(mConfiguration);
   18911         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
   18912                 mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
   18913         updateConfigurationLocked(configuration, null, false);
   18914     }
   18915 
   18916     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
   18917             boolean initLocale) {
   18918         return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
   18919     }
   18920 
   18921     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
   18922             boolean initLocale, boolean deferResume) {
   18923         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
   18924         return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
   18925                 UserHandle.USER_NULL, deferResume);
   18926     }
   18927 
   18928     // To cache the list of supported system locales
   18929     private String[] mSupportedSystemLocales = null;
   18930 
   18931     /**
   18932      * Do either or both things: (1) change the current configuration, and (2)
   18933      * make sure the given activity is running with the (now) current
   18934      * configuration.  Returns true if the activity has been left running, or
   18935      * false if <var>starting</var> is being destroyed to match the new
   18936      * configuration.
   18937      *
   18938      * @param userId is only used when persistent parameter is set to true to persist configuration
   18939      *               for that particular user
   18940      */
   18941     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
   18942             boolean initLocale, boolean persistent, int userId, boolean deferResume) {
   18943         int changes = 0;
   18944 
   18945         if (mWindowManager != null) {
   18946             mWindowManager.deferSurfaceLayout();
   18947         }
   18948         if (values != null) {
   18949             Configuration newConfig = new Configuration(mConfiguration);
   18950             changes = newConfig.updateFrom(values);
   18951             if (changes != 0) {
   18952                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
   18953                         "Updating configuration to: " + values);
   18954 
   18955                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
   18956 
   18957                 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
   18958                     final LocaleList locales = values.getLocales();
   18959                     int bestLocaleIndex = 0;
   18960                     if (locales.size() > 1) {
   18961                         if (mSupportedSystemLocales == null) {
   18962                             mSupportedSystemLocales =
   18963                                     Resources.getSystem().getAssets().getLocales();
   18964                         }
   18965                         bestLocaleIndex = Math.max(0,
   18966                                 locales.getFirstMatchIndex(mSupportedSystemLocales));
   18967                     }
   18968                     SystemProperties.set("persist.sys.locale",
   18969                             locales.get(bestLocaleIndex).toLanguageTag());
   18970                     LocaleList.setDefault(locales, bestLocaleIndex);
   18971                     mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
   18972                             locales.get(bestLocaleIndex)));
   18973                 }
   18974 
   18975                 mConfigurationSeq++;
   18976                 if (mConfigurationSeq <= 0) {
   18977                     mConfigurationSeq = 1;
   18978                 }
   18979                 newConfig.seq = mConfigurationSeq;
   18980                 mConfiguration = newConfig;
   18981                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
   18982                 mUsageStatsService.reportConfigurationChange(newConfig,
   18983                         mUserController.getCurrentUserIdLocked());
   18984                 //mUsageStatsService.noteStartConfig(newConfig);
   18985 
   18986                 final Configuration configCopy = new Configuration(mConfiguration);
   18987 
   18988                 // TODO: If our config changes, should we auto dismiss any currently
   18989                 // showing dialogs?
   18990                 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
   18991 
   18992                 AttributeCache ac = AttributeCache.instance();
   18993                 if (ac != null) {
   18994                     ac.updateConfiguration(configCopy);
   18995                 }
   18996 
   18997                 // Make sure all resources in our process are updated
   18998                 // right now, so that anyone who is going to retrieve
   18999                 // resource values after we return will be sure to get
   19000                 // the new ones.  This is especially important during
   19001                 // boot, where the first config change needs to guarantee
   19002                 // all resources have that config before following boot
   19003                 // code is executed.
   19004                 mSystemThread.applyConfigurationToResources(configCopy);
   19005 
   19006                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
   19007                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
   19008                     msg.obj = new Configuration(configCopy);
   19009                     msg.arg1 = userId;
   19010                     mHandler.sendMessage(msg);
   19011                 }
   19012 
   19013                 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
   19014                 if (isDensityChange) {
   19015                     // Reset the unsupported display size dialog.
   19016                     mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
   19017 
   19018                     killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
   19019                             ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
   19020                 }
   19021 
   19022                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   19023                     ProcessRecord app = mLruProcesses.get(i);
   19024                     try {
   19025                         if (app.thread != null) {
   19026                             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
   19027                                     + app.processName + " new config " + mConfiguration);
   19028                             app.thread.scheduleConfigurationChanged(configCopy);
   19029                         }
   19030                     } catch (Exception e) {
   19031                     }
   19032                 }
   19033                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
   19034                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   19035                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
   19036                         | Intent.FLAG_RECEIVER_FOREGROUND);
   19037                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
   19038                         null, AppOpsManager.OP_NONE, null, false, false,
   19039                         MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   19040                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
   19041                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
   19042                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   19043 	            if (initLocale || !mProcessesReady) {
   19044                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   19045                     }
   19046                     broadcastIntentLocked(null, null, intent,
   19047                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   19048                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   19049                 }
   19050             }
   19051             // Update the configuration with WM first and check if any of the stacks need to be
   19052             // resized due to the configuration change. If so, resize the stacks now and do any
   19053             // relaunches if necessary. This way we don't need to relaunch again below in
   19054             // ensureActivityConfigurationLocked().
   19055             if (mWindowManager != null) {
   19056                 final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
   19057                 if (resizedStacks != null) {
   19058                     for (int stackId : resizedStacks) {
   19059                         final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
   19060                         mStackSupervisor.resizeStackLocked(
   19061                                 stackId, newBounds, null, null, false, false, deferResume);
   19062                     }
   19063                 }
   19064             }
   19065         }
   19066 
   19067         boolean kept = true;
   19068         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
   19069         // mainStack is null during startup.
   19070         if (mainStack != null) {
   19071             if (changes != 0 && starting == null) {
   19072                 // If the configuration changed, and the caller is not already
   19073                 // in the process of starting an activity, then find the top
   19074                 // activity to check if its configuration needs to change.
   19075                 starting = mainStack.topRunningActivityLocked();
   19076             }
   19077 
   19078             if (starting != null) {
   19079                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
   19080                 // And we need to make sure at this point that all other activities
   19081                 // are made visible with the correct configuration.
   19082                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
   19083                         !PRESERVE_WINDOWS);
   19084             }
   19085         }
   19086         if (mWindowManager != null) {
   19087             mWindowManager.continueSurfaceLayout();
   19088         }
   19089         return kept;
   19090     }
   19091 
   19092     /**
   19093      * Decide based on the configuration whether we should shouw the ANR,
   19094      * crash, etc dialogs.  The idea is that if there is no affordence to
   19095      * press the on-screen buttons, or the user experience would be more
   19096      * greatly impacted than the crash itself, we shouldn't show the dialog.
   19097      *
   19098      * A thought: SystemUI might also want to get told about this, the Power
   19099      * dialog / global actions also might want different behaviors.
   19100      */
   19101     private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
   19102         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
   19103                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
   19104                                    && config.navigation == Configuration.NAVIGATION_NONAV);
   19105         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
   19106         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
   19107                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
   19108         return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
   19109     }
   19110 
   19111     @Override
   19112     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
   19113         synchronized (this) {
   19114             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
   19115             if (srec != null) {
   19116                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
   19117             }
   19118         }
   19119         return false;
   19120     }
   19121 
   19122     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
   19123             Intent resultData) {
   19124 
   19125         synchronized (this) {
   19126             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   19127             if (r != null) {
   19128                 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
   19129             }
   19130             return false;
   19131         }
   19132     }
   19133 
   19134     public int getLaunchedFromUid(IBinder activityToken) {
   19135         ActivityRecord srec;
   19136         synchronized (this) {
   19137             srec = ActivityRecord.forTokenLocked(activityToken);
   19138         }
   19139         if (srec == null) {
   19140             return -1;
   19141         }
   19142         return srec.launchedFromUid;
   19143     }
   19144 
   19145     public String getLaunchedFromPackage(IBinder activityToken) {
   19146         ActivityRecord srec;
   19147         synchronized (this) {
   19148             srec = ActivityRecord.forTokenLocked(activityToken);
   19149         }
   19150         if (srec == null) {
   19151             return null;
   19152         }
   19153         return srec.launchedFromPackage;
   19154     }
   19155 
   19156     // =========================================================
   19157     // LIFETIME MANAGEMENT
   19158     // =========================================================
   19159 
   19160     // Returns which broadcast queue the app is the current [or imminent] receiver
   19161     // on, or 'null' if the app is not an active broadcast recipient.
   19162     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
   19163         BroadcastRecord r = app.curReceiver;
   19164         if (r != null) {
   19165             return r.queue;
   19166         }
   19167 
   19168         // It's not the current receiver, but it might be starting up to become one
   19169         synchronized (this) {
   19170             for (BroadcastQueue queue : mBroadcastQueues) {
   19171                 r = queue.mPendingBroadcast;
   19172                 if (r != null && r.curApp == app) {
   19173                     // found it; report which queue it's in
   19174                     return queue;
   19175                 }
   19176             }
   19177         }
   19178 
   19179         return null;
   19180     }
   19181 
   19182     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
   19183             int targetUid, ComponentName targetComponent, String targetProcess) {
   19184         if (!mTrackingAssociations) {
   19185             return null;
   19186         }
   19187         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
   19188                 = mAssociations.get(targetUid);
   19189         if (components == null) {
   19190             components = new ArrayMap<>();
   19191             mAssociations.put(targetUid, components);
   19192         }
   19193         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
   19194         if (sourceUids == null) {
   19195             sourceUids = new SparseArray<>();
   19196             components.put(targetComponent, sourceUids);
   19197         }
   19198         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
   19199         if (sourceProcesses == null) {
   19200             sourceProcesses = new ArrayMap<>();
   19201             sourceUids.put(sourceUid, sourceProcesses);
   19202         }
   19203         Association ass = sourceProcesses.get(sourceProcess);
   19204         if (ass == null) {
   19205             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
   19206                     targetProcess);
   19207             sourceProcesses.put(sourceProcess, ass);
   19208         }
   19209         ass.mCount++;
   19210         ass.mNesting++;
   19211         if (ass.mNesting == 1) {
   19212             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
   19213             ass.mLastState = sourceState;
   19214         }
   19215         return ass;
   19216     }
   19217 
   19218     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
   19219             ComponentName targetComponent) {
   19220         if (!mTrackingAssociations) {
   19221             return;
   19222         }
   19223         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
   19224                 = mAssociations.get(targetUid);
   19225         if (components == null) {
   19226             return;
   19227         }
   19228         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
   19229         if (sourceUids == null) {
   19230             return;
   19231         }
   19232         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
   19233         if (sourceProcesses == null) {
   19234             return;
   19235         }
   19236         Association ass = sourceProcesses.get(sourceProcess);
   19237         if (ass == null || ass.mNesting <= 0) {
   19238             return;
   19239         }
   19240         ass.mNesting--;
   19241         if (ass.mNesting == 0) {
   19242             long uptime = SystemClock.uptimeMillis();
   19243             ass.mTime += uptime - ass.mStartTime;
   19244             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
   19245                     += uptime - ass.mLastStateUptime;
   19246             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
   19247         }
   19248     }
   19249 
   19250     private void noteUidProcessState(final int uid, final int state) {
   19251         mBatteryStatsService.noteUidProcessState(uid, state);
   19252         if (mTrackingAssociations) {
   19253             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
   19254                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
   19255                         = mAssociations.valueAt(i1);
   19256                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
   19257                     SparseArray<ArrayMap<String, Association>> sourceUids
   19258                             = targetComponents.valueAt(i2);
   19259                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
   19260                     if (sourceProcesses != null) {
   19261                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
   19262                             Association ass = sourceProcesses.valueAt(i4);
   19263                             if (ass.mNesting >= 1) {
   19264                                 // currently associated
   19265                                 long uptime = SystemClock.uptimeMillis();
   19266                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
   19267                                         += uptime - ass.mLastStateUptime;
   19268                                 ass.mLastState = state;
   19269                                 ass.mLastStateUptime = uptime;
   19270                             }
   19271                         }
   19272                     }
   19273                 }
   19274             }
   19275         }
   19276     }
   19277 
   19278     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
   19279             boolean doingAll, long now) {
   19280         if (mAdjSeq == app.adjSeq) {
   19281             // This adjustment has already been computed.
   19282             return app.curRawAdj;
   19283         }
   19284 
   19285         if (app.thread == null) {
   19286             app.adjSeq = mAdjSeq;
   19287             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   19288             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   19289             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
   19290         }
   19291 
   19292         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
   19293         app.adjSource = null;
   19294         app.adjTarget = null;
   19295         app.empty = false;
   19296         app.cached = false;
   19297 
   19298         final int activitiesSize = app.activities.size();
   19299 
   19300         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   19301             // The max adjustment doesn't allow this app to be anything
   19302             // below foreground, so it is not worth doing work for it.
   19303             app.adjType = "fixed";
   19304             app.adjSeq = mAdjSeq;
   19305             app.curRawAdj = app.maxAdj;
   19306             app.foregroundActivities = false;
   19307             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19308             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
   19309             // System processes can do UI, and when they do we want to have
   19310             // them trim their memory after the user leaves the UI.  To
   19311             // facilitate this, here we need to determine whether or not it
   19312             // is currently showing UI.
   19313             app.systemNoUi = true;
   19314             if (app == TOP_APP) {
   19315                 app.systemNoUi = false;
   19316                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
   19317                 app.adjType = "pers-top-activity";
   19318             } else if (app.hasTopUi) {
   19319                 app.systemNoUi = false;
   19320                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
   19321                 app.adjType = "pers-top-ui";
   19322             } else if (activitiesSize > 0) {
   19323                 for (int j = 0; j < activitiesSize; j++) {
   19324                     final ActivityRecord r = app.activities.get(j);
   19325                     if (r.visible) {
   19326                         app.systemNoUi = false;
   19327                     }
   19328                 }
   19329             }
   19330             if (!app.systemNoUi) {
   19331                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
   19332             }
   19333             return (app.curAdj=app.maxAdj);
   19334         }
   19335 
   19336         app.systemNoUi = false;
   19337 
   19338         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
   19339 
   19340         // Determine the importance of the process, starting with most
   19341         // important to least, and assign an appropriate OOM adjustment.
   19342         int adj;
   19343         int schedGroup;
   19344         int procState;
   19345         boolean foregroundActivities = false;
   19346         BroadcastQueue queue;
   19347         if (app == TOP_APP) {
   19348             // The last app on the list is the foreground app.
   19349             adj = ProcessList.FOREGROUND_APP_ADJ;
   19350             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
   19351             app.adjType = "top-activity";
   19352             foregroundActivities = true;
   19353             procState = PROCESS_STATE_CUR_TOP;
   19354         } else if (app.instrumentationClass != null) {
   19355             // Don't want to kill running instrumentation.
   19356             adj = ProcessList.FOREGROUND_APP_ADJ;
   19357             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19358             app.adjType = "instrumentation";
   19359             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
   19360         } else if ((queue = isReceivingBroadcast(app)) != null) {
   19361             // An app that is currently receiving a broadcast also
   19362             // counts as being in the foreground for OOM killer purposes.
   19363             // It's placed in a sched group based on the nature of the
   19364             // broadcast as reflected by which queue it's active in.
   19365             adj = ProcessList.FOREGROUND_APP_ADJ;
   19366             schedGroup = (queue == mFgBroadcastQueue)
   19367                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
   19368             app.adjType = "broadcast";
   19369             procState = ActivityManager.PROCESS_STATE_RECEIVER;
   19370         } else if (app.executingServices.size() > 0) {
   19371             // An app that is currently executing a service callback also
   19372             // counts as being in the foreground.
   19373             adj = ProcessList.FOREGROUND_APP_ADJ;
   19374             schedGroup = app.execServicesFg ?
   19375                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
   19376             app.adjType = "exec-service";
   19377             procState = ActivityManager.PROCESS_STATE_SERVICE;
   19378             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
   19379         } else {
   19380             // As far as we know the process is empty.  We may change our mind later.
   19381             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   19382             // At this point we don't actually know the adjustment.  Use the cached adj
   19383             // value that the caller wants us to.
   19384             adj = cachedAdj;
   19385             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   19386             app.cached = true;
   19387             app.empty = true;
   19388             app.adjType = "cch-empty";
   19389         }
   19390 
   19391         // Examine all activities if not already foreground.
   19392         if (!foregroundActivities && activitiesSize > 0) {
   19393             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
   19394             for (int j = 0; j < activitiesSize; j++) {
   19395                 final ActivityRecord r = app.activities.get(j);
   19396                 if (r.app != app) {
   19397                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
   19398                             + " instead of expected " + app);
   19399                     if (r.app == null || (r.app.uid == app.uid)) {
   19400                         // Only fix things up when they look sane
   19401                         r.app = app;
   19402                     } else {
   19403                         continue;
   19404                     }
   19405                 }
   19406                 if (r.visible) {
   19407                     // App has a visible activity; only upgrade adjustment.
   19408                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   19409                         adj = ProcessList.VISIBLE_APP_ADJ;
   19410                         app.adjType = "visible";
   19411                     }
   19412                     if (procState > PROCESS_STATE_CUR_TOP) {
   19413                         procState = PROCESS_STATE_CUR_TOP;
   19414                     }
   19415                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19416                     app.cached = false;
   19417                     app.empty = false;
   19418                     foregroundActivities = true;
   19419                     if (r.task != null && minLayer > 0) {
   19420                         final int layer = r.task.mLayerRank;
   19421                         if (layer >= 0 && minLayer > layer) {
   19422                             minLayer = layer;
   19423                         }
   19424                     }
   19425                     break;
   19426                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
   19427                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   19428                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   19429                         app.adjType = "pausing";
   19430                     }
   19431                     if (procState > PROCESS_STATE_CUR_TOP) {
   19432                         procState = PROCESS_STATE_CUR_TOP;
   19433                     }
   19434                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19435                     app.cached = false;
   19436                     app.empty = false;
   19437                     foregroundActivities = true;
   19438                 } else if (r.state == ActivityState.STOPPING) {
   19439                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   19440                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   19441                         app.adjType = "stopping";
   19442                     }
   19443                     // For the process state, we will at this point consider the
   19444                     // process to be cached.  It will be cached either as an activity
   19445                     // or empty depending on whether the activity is finishing.  We do
   19446                     // this so that we can treat the process as cached for purposes of
   19447                     // memory trimming (determing current memory level, trim command to
   19448                     // send to process) since there can be an arbitrary number of stopping
   19449                     // processes and they should soon all go into the cached state.
   19450                     if (!r.finishing) {
   19451                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   19452                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   19453                         }
   19454                     }
   19455                     app.cached = false;
   19456                     app.empty = false;
   19457                     foregroundActivities = true;
   19458                 } else {
   19459                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   19460                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   19461                         app.adjType = "cch-act";
   19462                     }
   19463                 }
   19464             }
   19465             if (adj == ProcessList.VISIBLE_APP_ADJ) {
   19466                 adj += minLayer;
   19467             }
   19468         }
   19469 
   19470         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
   19471                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
   19472             if (app.foregroundServices) {
   19473                 // The user is aware of this app, so make it visible.
   19474                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   19475                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
   19476                 app.cached = false;
   19477                 app.adjType = "fg-service";
   19478                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19479             } else if (app.forcingToForeground != null) {
   19480                 // The user is aware of this app, so make it visible.
   19481                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   19482                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   19483                 app.cached = false;
   19484                 app.adjType = "force-fg";
   19485                 app.adjSource = app.forcingToForeground;
   19486                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19487             }
   19488         }
   19489 
   19490         if (app == mHeavyWeightProcess) {
   19491             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   19492                 // We don't want to kill the current heavy-weight process.
   19493                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
   19494                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   19495                 app.cached = false;
   19496                 app.adjType = "heavy";
   19497             }
   19498             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
   19499                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
   19500             }
   19501         }
   19502 
   19503         if (app == mHomeProcess) {
   19504             if (adj > ProcessList.HOME_APP_ADJ) {
   19505                 // This process is hosting what we currently consider to be the
   19506                 // home app, so we don't want to let it go into the background.
   19507                 adj = ProcessList.HOME_APP_ADJ;
   19508                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   19509                 app.cached = false;
   19510                 app.adjType = "home";
   19511             }
   19512             if (procState > ActivityManager.PROCESS_STATE_HOME) {
   19513                 procState = ActivityManager.PROCESS_STATE_HOME;
   19514             }
   19515         }
   19516 
   19517         if (app == mPreviousProcess && app.activities.size() > 0) {
   19518             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
   19519                 // This was the previous process that showed UI to the user.
   19520                 // We want to try to keep it around more aggressively, to give
   19521                 // a good experience around switching between two apps.
   19522                 adj = ProcessList.PREVIOUS_APP_ADJ;
   19523                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   19524                 app.cached = false;
   19525                 app.adjType = "previous";
   19526             }
   19527             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   19528                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   19529             }
   19530         }
   19531 
   19532         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
   19533                 + " reason=" + app.adjType);
   19534 
   19535         // By default, we use the computed adjustment.  It may be changed if
   19536         // there are applications dependent on our services or providers, but
   19537         // this gives us a baseline and makes sure we don't get into an
   19538         // infinite recursion.
   19539         app.adjSeq = mAdjSeq;
   19540         app.curRawAdj = adj;
   19541         app.hasStartedServices = false;
   19542 
   19543         if (mBackupTarget != null && app == mBackupTarget.app) {
   19544             // If possible we want to avoid killing apps while they're being backed up
   19545             if (adj > ProcessList.BACKUP_APP_ADJ) {
   19546                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
   19547                 adj = ProcessList.BACKUP_APP_ADJ;
   19548                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   19549                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
   19550                 }
   19551                 app.adjType = "backup";
   19552                 app.cached = false;
   19553             }
   19554             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
   19555                 procState = ActivityManager.PROCESS_STATE_BACKUP;
   19556             }
   19557         }
   19558 
   19559         boolean mayBeTop = false;
   19560 
   19561         for (int is = app.services.size()-1;
   19562                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   19563                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   19564                         || procState > ActivityManager.PROCESS_STATE_TOP);
   19565                 is--) {
   19566             ServiceRecord s = app.services.valueAt(is);
   19567             if (s.startRequested) {
   19568                 app.hasStartedServices = true;
   19569                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
   19570                     procState = ActivityManager.PROCESS_STATE_SERVICE;
   19571                 }
   19572                 if (app.hasShownUi && app != mHomeProcess) {
   19573                     // If this process has shown some UI, let it immediately
   19574                     // go to the LRU list because it may be pretty heavy with
   19575                     // UI stuff.  We'll tag it with a label just to help
   19576                     // debug and understand what is going on.
   19577                     if (adj > ProcessList.SERVICE_ADJ) {
   19578                         app.adjType = "cch-started-ui-services";
   19579                     }
   19580                 } else {
   19581                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   19582                         // This service has seen some activity within
   19583                         // recent memory, so we will keep its process ahead
   19584                         // of the background processes.
   19585                         if (adj > ProcessList.SERVICE_ADJ) {
   19586                             adj = ProcessList.SERVICE_ADJ;
   19587                             app.adjType = "started-services";
   19588                             app.cached = false;
   19589                         }
   19590                     }
   19591                     // If we have let the service slide into the background
   19592                     // state, still have some text describing what it is doing
   19593                     // even though the service no longer has an impact.
   19594                     if (adj > ProcessList.SERVICE_ADJ) {
   19595                         app.adjType = "cch-started-services";
   19596                     }
   19597                 }
   19598             }
   19599 
   19600             for (int conni = s.connections.size()-1;
   19601                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   19602                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   19603                             || procState > ActivityManager.PROCESS_STATE_TOP);
   19604                     conni--) {
   19605                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
   19606                 for (int i = 0;
   19607                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
   19608                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   19609                                 || procState > ActivityManager.PROCESS_STATE_TOP);
   19610                         i++) {
   19611                     // XXX should compute this based on the max of
   19612                     // all connected clients.
   19613                     ConnectionRecord cr = clist.get(i);
   19614                     if (cr.binding.client == app) {
   19615                         // Binding to ourself is not interesting.
   19616                         continue;
   19617                     }
   19618 
   19619                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
   19620                         ProcessRecord client = cr.binding.client;
   19621                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
   19622                                 TOP_APP, doingAll, now);
   19623                         int clientProcState = client.curProcState;
   19624                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   19625                             // If the other app is cached for any reason, for purposes here
   19626                             // we are going to consider it empty.  The specific cached state
   19627                             // doesn't propagate except under certain conditions.
   19628                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   19629                         }
   19630                         String adjType = null;
   19631                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
   19632                             // Not doing bind OOM management, so treat
   19633                             // this guy more like a started service.
   19634                             if (app.hasShownUi && app != mHomeProcess) {
   19635                                 // If this process has shown some UI, let it immediately
   19636                                 // go to the LRU list because it may be pretty heavy with
   19637                                 // UI stuff.  We'll tag it with a label just to help
   19638                                 // debug and understand what is going on.
   19639                                 if (adj > clientAdj) {
   19640                                     adjType = "cch-bound-ui-services";
   19641                                 }
   19642                                 app.cached = false;
   19643                                 clientAdj = adj;
   19644                                 clientProcState = procState;
   19645                             } else {
   19646                                 if (now >= (s.lastActivity
   19647                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   19648                                     // This service has not seen activity within
   19649                                     // recent memory, so allow it to drop to the
   19650                                     // LRU list if there is no other reason to keep
   19651                                     // it around.  We'll also tag it with a label just
   19652                                     // to help debug and undertand what is going on.
   19653                                     if (adj > clientAdj) {
   19654                                         adjType = "cch-bound-services";
   19655                                     }
   19656                                     clientAdj = adj;
   19657                                 }
   19658                             }
   19659                         }
   19660                         if (adj > clientAdj) {
   19661                             // If this process has recently shown UI, and
   19662                             // the process that is binding to it is less
   19663                             // important than being visible, then we don't
   19664                             // care about the binding as much as we care
   19665                             // about letting this process get into the LRU
   19666                             // list to be killed and restarted if needed for
   19667                             // memory.
   19668                             if (app.hasShownUi && app != mHomeProcess
   19669                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   19670                                 adjType = "cch-bound-ui-services";
   19671                             } else {
   19672                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
   19673                                         |Context.BIND_IMPORTANT)) != 0) {
   19674                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
   19675                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
   19676                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
   19677                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
   19678                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   19679                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   19680                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   19681                                     adj = clientAdj;
   19682                                 } else {
   19683                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   19684                                         adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
   19685                                     }
   19686                                 }
   19687                                 if (!client.cached) {
   19688                                     app.cached = false;
   19689                                 }
   19690                                 adjType = "service";
   19691                             }
   19692                         }
   19693                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   19694                             // This will treat important bound services identically to
   19695                             // the top app, which may behave differently than generic
   19696                             // foreground work.
   19697                             if (client.curSchedGroup > schedGroup) {
   19698                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
   19699                                     schedGroup = client.curSchedGroup;
   19700                                 } else {
   19701                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19702                                 }
   19703                             }
   19704                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   19705                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   19706                                     // Special handling of clients who are in the top state.
   19707                                     // We *may* want to consider this process to be in the
   19708                                     // top state as well, but only if there is not another
   19709                                     // reason for it to be running.  Being on the top is a
   19710                                     // special state, meaning you are specifically running
   19711                                     // for the current top app.  If the process is already
   19712                                     // running in the background for some other reason, it
   19713                                     // is more important to continue considering it to be
   19714                                     // in the background state.
   19715                                     mayBeTop = true;
   19716                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   19717                                 } else {
   19718                                     // Special handling for above-top states (persistent
   19719                                     // processes).  These should not bring the current process
   19720                                     // into the top state, since they are not on top.  Instead
   19721                                     // give them the best state after that.
   19722                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
   19723                                         clientProcState =
   19724                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
   19725                                     } else if (mWakefulness
   19726                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
   19727                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
   19728                                                     != 0) {
   19729                                         clientProcState =
   19730                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
   19731                                     } else {
   19732                                         clientProcState =
   19733                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   19734                                     }
   19735                                 }
   19736                             }
   19737                         } else {
   19738                             if (clientProcState <
   19739                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   19740                                 clientProcState =
   19741                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
   19742                             }
   19743                         }
   19744                         if (procState > clientProcState) {
   19745                             procState = clientProcState;
   19746                         }
   19747                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   19748                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
   19749                             app.pendingUiClean = true;
   19750                         }
   19751                         if (adjType != null) {
   19752                             app.adjType = adjType;
   19753                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   19754                                     .REASON_SERVICE_IN_USE;
   19755                             app.adjSource = cr.binding.client;
   19756                             app.adjSourceProcState = clientProcState;
   19757                             app.adjTarget = s.name;
   19758                         }
   19759                     }
   19760                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
   19761                         app.treatLikeActivity = true;
   19762                     }
   19763                     final ActivityRecord a = cr.activity;
   19764                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
   19765                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
   19766                             (a.visible || a.state == ActivityState.RESUMED ||
   19767                              a.state == ActivityState.PAUSING)) {
   19768                             adj = ProcessList.FOREGROUND_APP_ADJ;
   19769                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   19770                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
   19771                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
   19772                                 } else {
   19773                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19774                                 }
   19775                             }
   19776                             app.cached = false;
   19777                             app.adjType = "service";
   19778                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   19779                                     .REASON_SERVICE_IN_USE;
   19780                             app.adjSource = a;
   19781                             app.adjSourceProcState = procState;
   19782                             app.adjTarget = s.name;
   19783                         }
   19784                     }
   19785                 }
   19786             }
   19787         }
   19788 
   19789         for (int provi = app.pubProviders.size()-1;
   19790                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   19791                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   19792                         || procState > ActivityManager.PROCESS_STATE_TOP);
   19793                 provi--) {
   19794             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
   19795             for (int i = cpr.connections.size()-1;
   19796                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   19797                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   19798                             || procState > ActivityManager.PROCESS_STATE_TOP);
   19799                     i--) {
   19800                 ContentProviderConnection conn = cpr.connections.get(i);
   19801                 ProcessRecord client = conn.client;
   19802                 if (client == app) {
   19803                     // Being our own client is not interesting.
   19804                     continue;
   19805                 }
   19806                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
   19807                 int clientProcState = client.curProcState;
   19808                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   19809                     // If the other app is cached for any reason, for purposes here
   19810                     // we are going to consider it empty.
   19811                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   19812                 }
   19813                 if (adj > clientAdj) {
   19814                     if (app.hasShownUi && app != mHomeProcess
   19815                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   19816                         app.adjType = "cch-ui-provider";
   19817                     } else {
   19818                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
   19819                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
   19820                         app.adjType = "provider";
   19821                     }
   19822                     app.cached &= client.cached;
   19823                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   19824                             .REASON_PROVIDER_IN_USE;
   19825                     app.adjSource = client;
   19826                     app.adjSourceProcState = clientProcState;
   19827                     app.adjTarget = cpr.name;
   19828                 }
   19829                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   19830                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   19831                         // Special handling of clients who are in the top state.
   19832                         // We *may* want to consider this process to be in the
   19833                         // top state as well, but only if there is not another
   19834                         // reason for it to be running.  Being on the top is a
   19835                         // special state, meaning you are specifically running
   19836                         // for the current top app.  If the process is already
   19837                         // running in the background for some other reason, it
   19838                         // is more important to continue considering it to be
   19839                         // in the background state.
   19840                         mayBeTop = true;
   19841                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   19842                     } else {
   19843                         // Special handling for above-top states (persistent
   19844                         // processes).  These should not bring the current process
   19845                         // into the top state, since they are not on top.  Instead
   19846                         // give them the best state after that.
   19847                         clientProcState =
   19848                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
   19849                     }
   19850                 }
   19851                 if (procState > clientProcState) {
   19852                     procState = clientProcState;
   19853                 }
   19854                 if (client.curSchedGroup > schedGroup) {
   19855                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19856                 }
   19857             }
   19858             // If the provider has external (non-framework) process
   19859             // dependencies, ensure that its adjustment is at least
   19860             // FOREGROUND_APP_ADJ.
   19861             if (cpr.hasExternalProcessHandles()) {
   19862                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
   19863                     adj = ProcessList.FOREGROUND_APP_ADJ;
   19864                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19865                     app.cached = false;
   19866                     app.adjType = "provider";
   19867                     app.adjTarget = cpr.name;
   19868                 }
   19869                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
   19870                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   19871                 }
   19872             }
   19873         }
   19874 
   19875         if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
   19876             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
   19877                 adj = ProcessList.PREVIOUS_APP_ADJ;
   19878                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   19879                 app.cached = false;
   19880                 app.adjType = "provider";
   19881             }
   19882             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   19883                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   19884             }
   19885         }
   19886 
   19887         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
   19888             // A client of one of our services or providers is in the top state.  We
   19889             // *may* want to be in the top state, but not if we are already running in
   19890             // the background for some other reason.  For the decision here, we are going
   19891             // to pick out a few specific states that we want to remain in when a client
   19892             // is top (states that tend to be longer-term) and otherwise allow it to go
   19893             // to the top state.
   19894             switch (procState) {
   19895                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
   19896                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
   19897                 case ActivityManager.PROCESS_STATE_SERVICE:
   19898                     // These all are longer-term states, so pull them up to the top
   19899                     // of the background states, but not all the way to the top state.
   19900                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
   19901                     break;
   19902                 default:
   19903                     // Otherwise, top is a better choice, so take it.
   19904                     procState = ActivityManager.PROCESS_STATE_TOP;
   19905                     break;
   19906             }
   19907         }
   19908 
   19909         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
   19910             if (app.hasClientActivities) {
   19911                 // This is a cached process, but with client activities.  Mark it so.
   19912                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
   19913                 app.adjType = "cch-client-act";
   19914             } else if (app.treatLikeActivity) {
   19915                 // This is a cached process, but somebody wants us to treat it like it has
   19916                 // an activity, okay!
   19917                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   19918                 app.adjType = "cch-as-act";
   19919             }
   19920         }
   19921 
   19922         if (adj == ProcessList.SERVICE_ADJ) {
   19923             if (doingAll) {
   19924                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
   19925                 mNewNumServiceProcs++;
   19926                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
   19927                 if (!app.serviceb) {
   19928                     // This service isn't far enough down on the LRU list to
   19929                     // normally be a B service, but if we are low on RAM and it
   19930                     // is large we want to force it down since we would prefer to
   19931                     // keep launcher over it.
   19932                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
   19933                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
   19934                         app.serviceHighRam = true;
   19935                         app.serviceb = true;
   19936                         //Slog.i(TAG, "ADJ " + app + " high ram!");
   19937                     } else {
   19938                         mNewNumAServiceProcs++;
   19939                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
   19940                     }
   19941                 } else {
   19942                     app.serviceHighRam = false;
   19943                 }
   19944             }
   19945             if (app.serviceb) {
   19946                 adj = ProcessList.SERVICE_B_ADJ;
   19947             }
   19948         }
   19949 
   19950         app.curRawAdj = adj;
   19951 
   19952         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
   19953         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
   19954         if (adj > app.maxAdj) {
   19955             adj = app.maxAdj;
   19956             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   19957                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   19958             }
   19959         }
   19960 
   19961         // Do final modification to adj.  Everything we do between here and applying
   19962         // the final setAdj must be done in this function, because we will also use
   19963         // it when computing the final cached adj later.  Note that we don't need to
   19964         // worry about this for max adj above, since max adj will always be used to
   19965         // keep it out of the cached vaues.
   19966         app.curAdj = app.modifyRawOomAdj(adj);
   19967         app.curSchedGroup = schedGroup;
   19968         app.curProcState = procState;
   19969         app.foregroundActivities = foregroundActivities;
   19970 
   19971         return app.curRawAdj;
   19972     }
   19973 
   19974     /**
   19975      * Record new PSS sample for a process.
   19976      */
   19977     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
   19978             long now) {
   19979         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
   19980                 swapPss * 1024);
   19981         proc.lastPssTime = now;
   19982         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
   19983         if (DEBUG_PSS) Slog.d(TAG_PSS,
   19984                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
   19985                 + " state=" + ProcessList.makeProcStateString(procState));
   19986         if (proc.initialIdlePss == 0) {
   19987             proc.initialIdlePss = pss;
   19988         }
   19989         proc.lastPss = pss;
   19990         proc.lastSwapPss = swapPss;
   19991         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
   19992             proc.lastCachedPss = pss;
   19993             proc.lastCachedSwapPss = swapPss;
   19994         }
   19995 
   19996         final SparseArray<Pair<Long, String>> watchUids
   19997                 = mMemWatchProcesses.getMap().get(proc.processName);
   19998         Long check = null;
   19999         if (watchUids != null) {
   20000             Pair<Long, String> val = watchUids.get(proc.uid);
   20001             if (val == null) {
   20002                 val = watchUids.get(0);
   20003             }
   20004             if (val != null) {
   20005                 check = val.first;
   20006             }
   20007         }
   20008         if (check != null) {
   20009             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
   20010                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   20011                 if (!isDebuggable) {
   20012                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   20013                         isDebuggable = true;
   20014                     }
   20015                 }
   20016                 if (isDebuggable) {
   20017                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
   20018                     final ProcessRecord myProc = proc;
   20019                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
   20020                     mMemWatchDumpProcName = proc.processName;
   20021                     mMemWatchDumpFile = heapdumpFile.toString();
   20022                     mMemWatchDumpPid = proc.pid;
   20023                     mMemWatchDumpUid = proc.uid;
   20024                     BackgroundThread.getHandler().post(new Runnable() {
   20025                         @Override
   20026                         public void run() {
   20027                             revokeUriPermission(ActivityThread.currentActivityThread()
   20028                                             .getApplicationThread(),
   20029                                     DumpHeapActivity.JAVA_URI,
   20030                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
   20031                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
   20032                                     UserHandle.myUserId());
   20033                             ParcelFileDescriptor fd = null;
   20034                             try {
   20035                                 heapdumpFile.delete();
   20036                                 fd = ParcelFileDescriptor.open(heapdumpFile,
   20037                                         ParcelFileDescriptor.MODE_CREATE |
   20038                                                 ParcelFileDescriptor.MODE_TRUNCATE |
   20039                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
   20040                                                 ParcelFileDescriptor.MODE_APPEND);
   20041                                 IApplicationThread thread = myProc.thread;
   20042                                 if (thread != null) {
   20043                                     try {
   20044                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
   20045                                                 "Requesting dump heap from "
   20046                                                 + myProc + " to " + heapdumpFile);
   20047                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
   20048                                     } catch (RemoteException e) {
   20049                                     }
   20050                                 }
   20051                             } catch (FileNotFoundException e) {
   20052                                 e.printStackTrace();
   20053                             } finally {
   20054                                 if (fd != null) {
   20055                                     try {
   20056                                         fd.close();
   20057                                     } catch (IOException e) {
   20058                                     }
   20059                                 }
   20060                             }
   20061                         }
   20062                     });
   20063                 } else {
   20064                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
   20065                             + ", but debugging not enabled");
   20066                 }
   20067             }
   20068         }
   20069     }
   20070 
   20071     /**
   20072      * Schedule PSS collection of a process.
   20073      */
   20074     void requestPssLocked(ProcessRecord proc, int procState) {
   20075         if (mPendingPssProcesses.contains(proc)) {
   20076             return;
   20077         }
   20078         if (mPendingPssProcesses.size() == 0) {
   20079             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   20080         }
   20081         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
   20082         proc.pssProcState = procState;
   20083         mPendingPssProcesses.add(proc);
   20084     }
   20085 
   20086     /**
   20087      * Schedule PSS collection of all processes.
   20088      */
   20089     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
   20090         if (!always) {
   20091             if (now < (mLastFullPssTime +
   20092                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
   20093                 return;
   20094             }
   20095         }
   20096         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
   20097         mLastFullPssTime = now;
   20098         mFullPssPending = true;
   20099         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
   20100         mPendingPssProcesses.clear();
   20101         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   20102             ProcessRecord app = mLruProcesses.get(i);
   20103             if (app.thread == null
   20104                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
   20105                 continue;
   20106             }
   20107             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
   20108                 app.pssProcState = app.setProcState;
   20109                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
   20110                         mTestPssMode, isSleepingLocked(), now);
   20111                 mPendingPssProcesses.add(app);
   20112             }
   20113         }
   20114         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   20115     }
   20116 
   20117     public void setTestPssMode(boolean enabled) {
   20118         synchronized (this) {
   20119             mTestPssMode = enabled;
   20120             if (enabled) {
   20121                 // Whenever we enable the mode, we want to take a snapshot all of current
   20122                 // process mem use.
   20123                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
   20124             }
   20125         }
   20126     }
   20127 
   20128     /**
   20129      * Ask a given process to GC right now.
   20130      */
   20131     final void performAppGcLocked(ProcessRecord app) {
   20132         try {
   20133             app.lastRequestedGc = SystemClock.uptimeMillis();
   20134             if (app.thread != null) {
   20135                 if (app.reportLowMemory) {
   20136                     app.reportLowMemory = false;
   20137                     app.thread.scheduleLowMemory();
   20138                 } else {
   20139                     app.thread.processInBackground();
   20140                 }
   20141             }
   20142         } catch (Exception e) {
   20143             // whatever.
   20144         }
   20145     }
   20146 
   20147     /**
   20148      * Returns true if things are idle enough to perform GCs.
   20149      */
   20150     private final boolean canGcNowLocked() {
   20151         boolean processingBroadcasts = false;
   20152         for (BroadcastQueue q : mBroadcastQueues) {
   20153             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
   20154                 processingBroadcasts = true;
   20155             }
   20156         }
   20157         return !processingBroadcasts
   20158                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
   20159     }
   20160 
   20161     /**
   20162      * Perform GCs on all processes that are waiting for it, but only
   20163      * if things are idle.
   20164      */
   20165     final void performAppGcsLocked() {
   20166         final int N = mProcessesToGc.size();
   20167         if (N <= 0) {
   20168             return;
   20169         }
   20170         if (canGcNowLocked()) {
   20171             while (mProcessesToGc.size() > 0) {
   20172                 ProcessRecord proc = mProcessesToGc.remove(0);
   20173                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
   20174                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
   20175                             <= SystemClock.uptimeMillis()) {
   20176                         // To avoid spamming the system, we will GC processes one
   20177                         // at a time, waiting a few seconds between each.
   20178                         performAppGcLocked(proc);
   20179                         scheduleAppGcsLocked();
   20180                         return;
   20181                     } else {
   20182                         // It hasn't been long enough since we last GCed this
   20183                         // process...  put it in the list to wait for its time.
   20184                         addProcessToGcListLocked(proc);
   20185                         break;
   20186                     }
   20187                 }
   20188             }
   20189 
   20190             scheduleAppGcsLocked();
   20191         }
   20192     }
   20193 
   20194     /**
   20195      * If all looks good, perform GCs on all processes waiting for them.
   20196      */
   20197     final void performAppGcsIfAppropriateLocked() {
   20198         if (canGcNowLocked()) {
   20199             performAppGcsLocked();
   20200             return;
   20201         }
   20202         // Still not idle, wait some more.
   20203         scheduleAppGcsLocked();
   20204     }
   20205 
   20206     /**
   20207      * Schedule the execution of all pending app GCs.
   20208      */
   20209     final void scheduleAppGcsLocked() {
   20210         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
   20211 
   20212         if (mProcessesToGc.size() > 0) {
   20213             // Schedule a GC for the time to the next process.
   20214             ProcessRecord proc = mProcessesToGc.get(0);
   20215             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
   20216 
   20217             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
   20218             long now = SystemClock.uptimeMillis();
   20219             if (when < (now+GC_TIMEOUT)) {
   20220                 when = now + GC_TIMEOUT;
   20221             }
   20222             mHandler.sendMessageAtTime(msg, when);
   20223         }
   20224     }
   20225 
   20226     /**
   20227      * Add a process to the array of processes waiting to be GCed.  Keeps the
   20228      * list in sorted order by the last GC time.  The process can't already be
   20229      * on the list.
   20230      */
   20231     final void addProcessToGcListLocked(ProcessRecord proc) {
   20232         boolean added = false;
   20233         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
   20234             if (mProcessesToGc.get(i).lastRequestedGc <
   20235                     proc.lastRequestedGc) {
   20236                 added = true;
   20237                 mProcessesToGc.add(i+1, proc);
   20238                 break;
   20239             }
   20240         }
   20241         if (!added) {
   20242             mProcessesToGc.add(0, proc);
   20243         }
   20244     }
   20245 
   20246     /**
   20247      * Set up to ask a process to GC itself.  This will either do it
   20248      * immediately, or put it on the list of processes to gc the next
   20249      * time things are idle.
   20250      */
   20251     final void scheduleAppGcLocked(ProcessRecord app) {
   20252         long now = SystemClock.uptimeMillis();
   20253         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
   20254             return;
   20255         }
   20256         if (!mProcessesToGc.contains(app)) {
   20257             addProcessToGcListLocked(app);
   20258             scheduleAppGcsLocked();
   20259         }
   20260     }
   20261 
   20262     final void checkExcessivePowerUsageLocked(boolean doKills) {
   20263         updateCpuStatsNow();
   20264 
   20265         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   20266         boolean doWakeKills = doKills;
   20267         boolean doCpuKills = doKills;
   20268         if (mLastPowerCheckRealtime == 0) {
   20269             doWakeKills = false;
   20270         }
   20271         if (mLastPowerCheckUptime == 0) {
   20272             doCpuKills = false;
   20273         }
   20274         if (stats.isScreenOn()) {
   20275             doWakeKills = false;
   20276         }
   20277         final long curRealtime = SystemClock.elapsedRealtime();
   20278         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
   20279         final long curUptime = SystemClock.uptimeMillis();
   20280         final long uptimeSince = curUptime - mLastPowerCheckUptime;
   20281         mLastPowerCheckRealtime = curRealtime;
   20282         mLastPowerCheckUptime = curUptime;
   20283         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
   20284             doWakeKills = false;
   20285         }
   20286         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
   20287             doCpuKills = false;
   20288         }
   20289         int i = mLruProcesses.size();
   20290         while (i > 0) {
   20291             i--;
   20292             ProcessRecord app = mLruProcesses.get(i);
   20293             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
   20294                 long wtime;
   20295                 synchronized (stats) {
   20296                     wtime = stats.getProcessWakeTime(app.info.uid,
   20297                             app.pid, curRealtime);
   20298                 }
   20299                 long wtimeUsed = wtime - app.lastWakeTime;
   20300                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
   20301                 if (DEBUG_POWER) {
   20302                     StringBuilder sb = new StringBuilder(128);
   20303                     sb.append("Wake for ");
   20304                     app.toShortString(sb);
   20305                     sb.append(": over ");
   20306                     TimeUtils.formatDuration(realtimeSince, sb);
   20307                     sb.append(" used ");
   20308                     TimeUtils.formatDuration(wtimeUsed, sb);
   20309                     sb.append(" (");
   20310                     sb.append((wtimeUsed*100)/realtimeSince);
   20311                     sb.append("%)");
   20312                     Slog.i(TAG_POWER, sb.toString());
   20313                     sb.setLength(0);
   20314                     sb.append("CPU for ");
   20315                     app.toShortString(sb);
   20316                     sb.append(": over ");
   20317                     TimeUtils.formatDuration(uptimeSince, sb);
   20318                     sb.append(" used ");
   20319                     TimeUtils.formatDuration(cputimeUsed, sb);
   20320                     sb.append(" (");
   20321                     sb.append((cputimeUsed*100)/uptimeSince);
   20322                     sb.append("%)");
   20323                     Slog.i(TAG_POWER, sb.toString());
   20324                 }
   20325                 // If a process has held a wake lock for more
   20326                 // than 50% of the time during this period,
   20327                 // that sounds bad.  Kill!
   20328                 if (doWakeKills && realtimeSince > 0
   20329                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
   20330                     synchronized (stats) {
   20331                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
   20332                                 realtimeSince, wtimeUsed);
   20333                     }
   20334                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
   20335                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
   20336                 } else if (doCpuKills && uptimeSince > 0
   20337                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
   20338                     synchronized (stats) {
   20339                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
   20340                                 uptimeSince, cputimeUsed);
   20341                     }
   20342                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
   20343                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
   20344                 } else {
   20345                     app.lastWakeTime = wtime;
   20346                     app.lastCpuTime = app.curCpuTime;
   20347                 }
   20348             }
   20349         }
   20350     }
   20351 
   20352     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
   20353             long nowElapsed) {
   20354         boolean success = true;
   20355 
   20356         if (app.curRawAdj != app.setRawAdj) {
   20357             app.setRawAdj = app.curRawAdj;
   20358         }
   20359 
   20360         int changes = 0;
   20361 
   20362         if (app.curAdj != app.setAdj) {
   20363             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
   20364             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   20365                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
   20366                     + app.adjType);
   20367             app.setAdj = app.curAdj;
   20368             app.verifiedAdj = ProcessList.INVALID_ADJ;
   20369         }
   20370 
   20371         if (app.setSchedGroup != app.curSchedGroup) {
   20372             int oldSchedGroup = app.setSchedGroup;
   20373             app.setSchedGroup = app.curSchedGroup;
   20374             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   20375                     "Setting sched group of " + app.processName
   20376                     + " to " + app.curSchedGroup);
   20377             if (app.waitingToKill != null && app.curReceiver == null
   20378                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
   20379                 app.kill(app.waitingToKill, true);
   20380                 success = false;
   20381             } else {
   20382                 int processGroup;
   20383                 switch (app.curSchedGroup) {
   20384                     case ProcessList.SCHED_GROUP_BACKGROUND:
   20385                         processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   20386                         break;
   20387                     case ProcessList.SCHED_GROUP_TOP_APP:
   20388                     case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
   20389                         processGroup = Process.THREAD_GROUP_TOP_APP;
   20390                         break;
   20391                     default:
   20392                         processGroup = Process.THREAD_GROUP_DEFAULT;
   20393                         break;
   20394                 }
   20395                 long oldId = Binder.clearCallingIdentity();
   20396                 try {
   20397                     Process.setProcessGroup(app.pid, processGroup);
   20398                     if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
   20399                         // do nothing if we already switched to RT
   20400                         if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
   20401                             // Switch VR thread for app to SCHED_FIFO
   20402                             if (mInVrMode && app.vrThreadTid != 0) {
   20403                                 try {
   20404                                     Process.setThreadScheduler(app.vrThreadTid,
   20405                                         Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
   20406                                 } catch (IllegalArgumentException e) {
   20407                                     // thread died, ignore
   20408                                 }
   20409                             }
   20410                             if (mUseFifoUiScheduling) {
   20411                                 // Switch UI pipeline for app to SCHED_FIFO
   20412                                 app.savedPriority = Process.getThreadPriority(app.pid);
   20413                                 try {
   20414                                     Process.setThreadScheduler(app.pid,
   20415                                         Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
   20416                                 } catch (IllegalArgumentException e) {
   20417                                     // thread died, ignore
   20418                                 }
   20419                                 if (app.renderThreadTid != 0) {
   20420                                     try {
   20421                                         Process.setThreadScheduler(app.renderThreadTid,
   20422                                             Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
   20423                                     } catch (IllegalArgumentException e) {
   20424                                         // thread died, ignore
   20425                                     }
   20426                                     if (DEBUG_OOM_ADJ) {
   20427                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
   20428                                             app.renderThreadTid + ") to FIFO");
   20429                                     }
   20430                                 } else {
   20431                                     if (DEBUG_OOM_ADJ) {
   20432                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
   20433                                     }
   20434                                 }
   20435                             } else {
   20436                                 // Boost priority for top app UI and render threads
   20437                                 Process.setThreadPriority(app.pid, -10);
   20438                                 if (app.renderThreadTid != 0) {
   20439                                     try {
   20440                                         Process.setThreadPriority(app.renderThreadTid, -10);
   20441                                     } catch (IllegalArgumentException e) {
   20442                                         // thread died, ignore
   20443                                     }
   20444                                 }
   20445                             }
   20446                         }
   20447                     } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
   20448                                app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
   20449                         // Reset VR thread to SCHED_OTHER
   20450                         // Safe to do even if we're not in VR mode
   20451                         if (app.vrThreadTid != 0) {
   20452                             Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
   20453                         }
   20454                         if (mUseFifoUiScheduling) {
   20455                             // Reset UI pipeline to SCHED_OTHER
   20456                             Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
   20457                             Process.setThreadPriority(app.pid, app.savedPriority);
   20458                             if (app.renderThreadTid != 0) {
   20459                                 Process.setThreadScheduler(app.renderThreadTid,
   20460                                     Process.SCHED_OTHER, 0);
   20461                                 Process.setThreadPriority(app.renderThreadTid, -4);
   20462                             }
   20463                         } else {
   20464                             // Reset priority for top app UI and render threads
   20465                             Process.setThreadPriority(app.pid, 0);
   20466                             if (app.renderThreadTid != 0) {
   20467                                 Process.setThreadPriority(app.renderThreadTid, 0);
   20468                             }
   20469                         }
   20470                     }
   20471                 } catch (Exception e) {
   20472                     Slog.w(TAG, "Failed setting process group of " + app.pid
   20473                             + " to " + app.curSchedGroup);
   20474                     e.printStackTrace();
   20475                 } finally {
   20476                     Binder.restoreCallingIdentity(oldId);
   20477                 }
   20478             }
   20479         }
   20480         if (app.repForegroundActivities != app.foregroundActivities) {
   20481             app.repForegroundActivities = app.foregroundActivities;
   20482             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
   20483         }
   20484         if (app.repProcState != app.curProcState) {
   20485             app.repProcState = app.curProcState;
   20486             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
   20487             if (app.thread != null) {
   20488                 try {
   20489                     if (false) {
   20490                         //RuntimeException h = new RuntimeException("here");
   20491                         Slog.i(TAG, "Sending new process state " + app.repProcState
   20492                                 + " to " + app /*, h*/);
   20493                     }
   20494                     app.thread.setProcessState(app.repProcState);
   20495                 } catch (RemoteException e) {
   20496                 }
   20497             }
   20498         }
   20499         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
   20500                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
   20501             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
   20502                 // Experimental code to more aggressively collect pss while
   20503                 // running test...  the problem is that this tends to collect
   20504                 // the data right when a process is transitioning between process
   20505                 // states, which well tend to give noisy data.
   20506                 long start = SystemClock.uptimeMillis();
   20507                 long pss = Debug.getPss(app.pid, mTmpLong, null);
   20508                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
   20509                 mPendingPssProcesses.remove(app);
   20510                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
   20511                         + " to " + app.curProcState + ": "
   20512                         + (SystemClock.uptimeMillis()-start) + "ms");
   20513             }
   20514             app.lastStateTime = now;
   20515             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
   20516                     mTestPssMode, isSleepingLocked(), now);
   20517             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
   20518                     + ProcessList.makeProcStateString(app.setProcState) + " to "
   20519                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
   20520                     + (app.nextPssTime-now) + ": " + app);
   20521         } else {
   20522             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
   20523                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
   20524                     mTestPssMode)))) {
   20525                 requestPssLocked(app, app.setProcState);
   20526                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
   20527                         mTestPssMode, isSleepingLocked(), now);
   20528             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
   20529                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
   20530         }
   20531         if (app.setProcState != app.curProcState) {
   20532             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   20533                     "Proc state change of " + app.processName
   20534                             + " to " + app.curProcState);
   20535             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
   20536             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
   20537             if (setImportant && !curImportant) {
   20538                 // This app is no longer something we consider important enough to allow to
   20539                 // use arbitrary amounts of battery power.  Note
   20540                 // its current wake lock time to later know to kill it if
   20541                 // it is not behaving well.
   20542                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   20543                 synchronized (stats) {
   20544                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
   20545                             app.pid, nowElapsed);
   20546                 }
   20547                 app.lastCpuTime = app.curCpuTime;
   20548 
   20549             }
   20550             // Inform UsageStats of important process state change
   20551             // Must be called before updating setProcState
   20552             maybeUpdateUsageStatsLocked(app, nowElapsed);
   20553 
   20554             app.setProcState = app.curProcState;
   20555             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
   20556                 app.notCachedSinceIdle = false;
   20557             }
   20558             if (!doingAll) {
   20559                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
   20560             } else {
   20561                 app.procStateChanged = true;
   20562             }
   20563         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
   20564                 > USAGE_STATS_INTERACTION_INTERVAL) {
   20565             // For apps that sit around for a long time in the interactive state, we need
   20566             // to report this at least once a day so they don't go idle.
   20567             maybeUpdateUsageStatsLocked(app, nowElapsed);
   20568         }
   20569 
   20570         if (changes != 0) {
   20571             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   20572                     "Changes in " + app + ": " + changes);
   20573             int i = mPendingProcessChanges.size()-1;
   20574             ProcessChangeItem item = null;
   20575             while (i >= 0) {
   20576                 item = mPendingProcessChanges.get(i);
   20577                 if (item.pid == app.pid) {
   20578                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   20579                             "Re-using existing item: " + item);
   20580                     break;
   20581                 }
   20582                 i--;
   20583             }
   20584             if (i < 0) {
   20585                 // No existing item in pending changes; need a new one.
   20586                 final int NA = mAvailProcessChanges.size();
   20587                 if (NA > 0) {
   20588                     item = mAvailProcessChanges.remove(NA-1);
   20589                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   20590                             "Retrieving available item: " + item);
   20591                 } else {
   20592                     item = new ProcessChangeItem();
   20593                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   20594                             "Allocating new item: " + item);
   20595                 }
   20596                 item.changes = 0;
   20597                 item.pid = app.pid;
   20598                 item.uid = app.info.uid;
   20599                 if (mPendingProcessChanges.size() == 0) {
   20600                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   20601                             "*** Enqueueing dispatch processes changed!");
   20602                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
   20603                 }
   20604                 mPendingProcessChanges.add(item);
   20605             }
   20606             item.changes |= changes;
   20607             item.processState = app.repProcState;
   20608             item.foregroundActivities = app.repForegroundActivities;
   20609             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   20610                     "Item " + Integer.toHexString(System.identityHashCode(item))
   20611                     + " " + app.toShortString() + ": changes=" + item.changes
   20612                     + " procState=" + item.processState
   20613                     + " foreground=" + item.foregroundActivities
   20614                     + " type=" + app.adjType + " source=" + app.adjSource
   20615                     + " target=" + app.adjTarget);
   20616         }
   20617 
   20618         return success;
   20619     }
   20620 
   20621     private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
   20622         final UidRecord.ChangeItem pendingChange;
   20623         if (uidRec == null || uidRec.pendingChange == null) {
   20624             if (mPendingUidChanges.size() == 0) {
   20625                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   20626                         "*** Enqueueing dispatch uid changed!");
   20627                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
   20628             }
   20629             final int NA = mAvailUidChanges.size();
   20630             if (NA > 0) {
   20631                 pendingChange = mAvailUidChanges.remove(NA-1);
   20632                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   20633                         "Retrieving available item: " + pendingChange);
   20634             } else {
   20635                 pendingChange = new UidRecord.ChangeItem();
   20636                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   20637                         "Allocating new item: " + pendingChange);
   20638             }
   20639             if (uidRec != null) {
   20640                 uidRec.pendingChange = pendingChange;
   20641                 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
   20642                     // If this uid is going away, and we haven't yet reported it is gone,
   20643                     // then do so now.
   20644                     change = UidRecord.CHANGE_GONE_IDLE;
   20645                 }
   20646             } else if (uid < 0) {
   20647                 throw new IllegalArgumentException("No UidRecord or uid");
   20648             }
   20649             pendingChange.uidRecord = uidRec;
   20650             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
   20651             mPendingUidChanges.add(pendingChange);
   20652         } else {
   20653             pendingChange = uidRec.pendingChange;
   20654             if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
   20655                 change = UidRecord.CHANGE_GONE_IDLE;
   20656             }
   20657         }
   20658         pendingChange.change = change;
   20659         pendingChange.processState = uidRec != null
   20660                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
   20661     }
   20662 
   20663     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
   20664             String authority) {
   20665         if (app == null) return;
   20666         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
   20667             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
   20668             if (userState == null) return;
   20669             final long now = SystemClock.elapsedRealtime();
   20670             Long lastReported = userState.mProviderLastReportedFg.get(authority);
   20671             if (lastReported == null || lastReported < now - 60 * 1000L) {
   20672                 if (mSystemReady) {
   20673                     // Cannot touch the user stats if not system ready
   20674                     mUsageStatsService.reportContentProviderUsage(
   20675                             authority, providerPkgName, app.userId);
   20676                 }
   20677                 userState.mProviderLastReportedFg.put(authority, now);
   20678             }
   20679         }
   20680     }
   20681 
   20682     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
   20683         if (DEBUG_USAGE_STATS) {
   20684             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
   20685                     + "] state changes: old = " + app.setProcState + ", new = "
   20686                     + app.curProcState);
   20687         }
   20688         if (mUsageStatsService == null) {
   20689             return;
   20690         }
   20691         boolean isInteraction;
   20692         // To avoid some abuse patterns, we are going to be careful about what we consider
   20693         // to be an app interaction.  Being the top activity doesn't count while the display
   20694         // is sleeping, nor do short foreground services.
   20695         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
   20696             isInteraction = true;
   20697             app.fgInteractionTime = 0;
   20698         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
   20699             if (app.fgInteractionTime == 0) {
   20700                 app.fgInteractionTime = nowElapsed;
   20701                 isInteraction = false;
   20702             } else {
   20703                 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
   20704             }
   20705         } else {
   20706             // If the app was being forced to the foreground, by say a Toast, then
   20707             // no need to treat it as an interaction
   20708             isInteraction = app.forcingToForeground == null
   20709                     && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   20710             app.fgInteractionTime = 0;
   20711         }
   20712         if (isInteraction && (!app.reportedInteraction
   20713                 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
   20714             app.interactionEventTime = nowElapsed;
   20715             String[] packages = app.getPackageList();
   20716             if (packages != null) {
   20717                 for (int i = 0; i < packages.length; i++) {
   20718                     mUsageStatsService.reportEvent(packages[i], app.userId,
   20719                             UsageEvents.Event.SYSTEM_INTERACTION);
   20720                 }
   20721             }
   20722         }
   20723         app.reportedInteraction = isInteraction;
   20724         if (!isInteraction) {
   20725             app.interactionEventTime = 0;
   20726         }
   20727     }
   20728 
   20729     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
   20730         if (proc.thread != null) {
   20731             if (proc.baseProcessTracker != null) {
   20732                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
   20733             }
   20734         }
   20735     }
   20736 
   20737     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
   20738             ProcessRecord TOP_APP, boolean doingAll, long now) {
   20739         if (app.thread == null) {
   20740             return false;
   20741         }
   20742 
   20743         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
   20744 
   20745         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
   20746     }
   20747 
   20748     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
   20749             boolean oomAdj) {
   20750         if (isForeground != proc.foregroundServices) {
   20751             proc.foregroundServices = isForeground;
   20752             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
   20753                     proc.info.uid);
   20754             if (isForeground) {
   20755                 if (curProcs == null) {
   20756                     curProcs = new ArrayList<ProcessRecord>();
   20757                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
   20758                 }
   20759                 if (!curProcs.contains(proc)) {
   20760                     curProcs.add(proc);
   20761                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
   20762                             proc.info.packageName, proc.info.uid);
   20763                 }
   20764             } else {
   20765                 if (curProcs != null) {
   20766                     if (curProcs.remove(proc)) {
   20767                         mBatteryStatsService.noteEvent(
   20768                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
   20769                                 proc.info.packageName, proc.info.uid);
   20770                         if (curProcs.size() <= 0) {
   20771                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
   20772                         }
   20773                     }
   20774                 }
   20775             }
   20776             if (oomAdj) {
   20777                 updateOomAdjLocked();
   20778             }
   20779         }
   20780     }
   20781 
   20782     private final ActivityRecord resumedAppLocked() {
   20783         ActivityRecord act = mStackSupervisor.resumedAppLocked();
   20784         String pkg;
   20785         int uid;
   20786         if (act != null) {
   20787             pkg = act.packageName;
   20788             uid = act.info.applicationInfo.uid;
   20789         } else {
   20790             pkg = null;
   20791             uid = -1;
   20792         }
   20793         // Has the UID or resumed package name changed?
   20794         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
   20795                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
   20796             if (mCurResumedPackage != null) {
   20797                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
   20798                         mCurResumedPackage, mCurResumedUid);
   20799             }
   20800             mCurResumedPackage = pkg;
   20801             mCurResumedUid = uid;
   20802             if (mCurResumedPackage != null) {
   20803                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
   20804                         mCurResumedPackage, mCurResumedUid);
   20805             }
   20806         }
   20807         return act;
   20808     }
   20809 
   20810     final boolean updateOomAdjLocked(ProcessRecord app) {
   20811         final ActivityRecord TOP_ACT = resumedAppLocked();
   20812         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   20813         final boolean wasCached = app.cached;
   20814 
   20815         mAdjSeq++;
   20816 
   20817         // This is the desired cached adjusment we want to tell it to use.
   20818         // If our app is currently cached, we know it, and that is it.  Otherwise,
   20819         // we don't know it yet, and it needs to now be cached we will then
   20820         // need to do a complete oom adj.
   20821         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
   20822                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
   20823         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
   20824                 SystemClock.uptimeMillis());
   20825         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
   20826             // Changed to/from cached state, so apps after it in the LRU
   20827             // list may also be changed.
   20828             updateOomAdjLocked();
   20829         }
   20830         return success;
   20831     }
   20832 
   20833     final void updateOomAdjLocked() {
   20834         final ActivityRecord TOP_ACT = resumedAppLocked();
   20835         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   20836         final long now = SystemClock.uptimeMillis();
   20837         final long nowElapsed = SystemClock.elapsedRealtime();
   20838         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
   20839         final int N = mLruProcesses.size();
   20840 
   20841         if (false) {
   20842             RuntimeException e = new RuntimeException();
   20843             e.fillInStackTrace();
   20844             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
   20845         }
   20846 
   20847         // Reset state in all uid records.
   20848         for (int i=mActiveUids.size()-1; i>=0; i--) {
   20849             final UidRecord uidRec = mActiveUids.valueAt(i);
   20850             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   20851                     "Starting update of " + uidRec);
   20852             uidRec.reset();
   20853         }
   20854 
   20855         mStackSupervisor.rankTaskLayersIfNeeded();
   20856 
   20857         mAdjSeq++;
   20858         mNewNumServiceProcs = 0;
   20859         mNewNumAServiceProcs = 0;
   20860 
   20861         final int emptyProcessLimit;
   20862         final int cachedProcessLimit;
   20863         if (mProcessLimit <= 0) {
   20864             emptyProcessLimit = cachedProcessLimit = 0;
   20865         } else if (mProcessLimit == 1) {
   20866             emptyProcessLimit = 1;
   20867             cachedProcessLimit = 0;
   20868         } else {
   20869             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
   20870             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
   20871         }
   20872 
   20873         // Let's determine how many processes we have running vs.
   20874         // how many slots we have for background processes; we may want
   20875         // to put multiple processes in a slot of there are enough of
   20876         // them.
   20877         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
   20878                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
   20879         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
   20880         if (numEmptyProcs > cachedProcessLimit) {
   20881             // If there are more empty processes than our limit on cached
   20882             // processes, then use the cached process limit for the factor.
   20883             // This ensures that the really old empty processes get pushed
   20884             // down to the bottom, so if we are running low on memory we will
   20885             // have a better chance at keeping around more cached processes
   20886             // instead of a gazillion empty processes.
   20887             numEmptyProcs = cachedProcessLimit;
   20888         }
   20889         int emptyFactor = numEmptyProcs/numSlots;
   20890         if (emptyFactor < 1) emptyFactor = 1;
   20891         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
   20892         if (cachedFactor < 1) cachedFactor = 1;
   20893         int stepCached = 0;
   20894         int stepEmpty = 0;
   20895         int numCached = 0;
   20896         int numEmpty = 0;
   20897         int numTrimming = 0;
   20898 
   20899         mNumNonCachedProcs = 0;
   20900         mNumCachedHiddenProcs = 0;
   20901 
   20902         // First update the OOM adjustment for each of the
   20903         // application processes based on their current state.
   20904         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
   20905         int nextCachedAdj = curCachedAdj+1;
   20906         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
   20907         int nextEmptyAdj = curEmptyAdj+2;
   20908         for (int i=N-1; i>=0; i--) {
   20909             ProcessRecord app = mLruProcesses.get(i);
   20910             if (!app.killedByAm && app.thread != null) {
   20911                 app.procStateChanged = false;
   20912                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
   20913 
   20914                 // If we haven't yet assigned the final cached adj
   20915                 // to the process, do that now.
   20916                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
   20917                     switch (app.curProcState) {
   20918                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   20919                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   20920                             // This process is a cached process holding activities...
   20921                             // assign it the next cached value for that type, and then
   20922                             // step that cached level.
   20923                             app.curRawAdj = curCachedAdj;
   20924                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
   20925                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
   20926                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
   20927                                     + ")");
   20928                             if (curCachedAdj != nextCachedAdj) {
   20929                                 stepCached++;
   20930                                 if (stepCached >= cachedFactor) {
   20931                                     stepCached = 0;
   20932                                     curCachedAdj = nextCachedAdj;
   20933                                     nextCachedAdj += 2;
   20934                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   20935                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
   20936                                     }
   20937                                 }
   20938                             }
   20939                             break;
   20940                         default:
   20941                             // For everything else, assign next empty cached process
   20942                             // level and bump that up.  Note that this means that
   20943                             // long-running services that have dropped down to the
   20944                             // cached level will be treated as empty (since their process
   20945                             // state is still as a service), which is what we want.
   20946                             app.curRawAdj = curEmptyAdj;
   20947                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
   20948                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
   20949                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
   20950                                     + ")");
   20951                             if (curEmptyAdj != nextEmptyAdj) {
   20952                                 stepEmpty++;
   20953                                 if (stepEmpty >= emptyFactor) {
   20954                                     stepEmpty = 0;
   20955                                     curEmptyAdj = nextEmptyAdj;
   20956                                     nextEmptyAdj += 2;
   20957                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   20958                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
   20959                                     }
   20960                                 }
   20961                             }
   20962                             break;
   20963                     }
   20964                 }
   20965 
   20966                 applyOomAdjLocked(app, true, now, nowElapsed);
   20967 
   20968                 // Count the number of process types.
   20969                 switch (app.curProcState) {
   20970                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   20971                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   20972                         mNumCachedHiddenProcs++;
   20973                         numCached++;
   20974                         if (numCached > cachedProcessLimit) {
   20975                             app.kill("cached #" + numCached, true);
   20976                         }
   20977                         break;
   20978                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
   20979                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
   20980                                 && app.lastActivityTime < oldTime) {
   20981                             app.kill("empty for "
   20982                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
   20983                                     / 1000) + "s", true);
   20984                         } else {
   20985                             numEmpty++;
   20986                             if (numEmpty > emptyProcessLimit) {
   20987                                 app.kill("empty #" + numEmpty, true);
   20988                             }
   20989                         }
   20990                         break;
   20991                     default:
   20992                         mNumNonCachedProcs++;
   20993                         break;
   20994                 }
   20995 
   20996                 if (app.isolated && app.services.size() <= 0) {
   20997                     // If this is an isolated process, and there are no
   20998                     // services running in it, then the process is no longer
   20999                     // needed.  We agressively kill these because we can by
   21000                     // definition not re-use the same process again, and it is
   21001                     // good to avoid having whatever code was running in them
   21002                     // left sitting around after no longer needed.
   21003                     app.kill("isolated not needed", true);
   21004                 } else {
   21005                     // Keeping this process, update its uid.
   21006                     final UidRecord uidRec = app.uidRecord;
   21007                     if (uidRec != null && uidRec.curProcState > app.curProcState) {
   21008                         uidRec.curProcState = app.curProcState;
   21009                     }
   21010                 }
   21011 
   21012                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   21013                         && !app.killedByAm) {
   21014                     numTrimming++;
   21015                 }
   21016             }
   21017         }
   21018 
   21019         mNumServiceProcs = mNewNumServiceProcs;
   21020 
   21021         // Now determine the memory trimming level of background processes.
   21022         // Unfortunately we need to start at the back of the list to do this
   21023         // properly.  We only do this if the number of background apps we
   21024         // are managing to keep around is less than half the maximum we desire;
   21025         // if we are keeping a good number around, we'll let them use whatever
   21026         // memory they want.
   21027         final int numCachedAndEmpty = numCached + numEmpty;
   21028         int memFactor;
   21029         if (numCached <= ProcessList.TRIM_CACHED_APPS
   21030                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
   21031             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
   21032                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
   21033             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
   21034                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
   21035             } else {
   21036                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
   21037             }
   21038         } else {
   21039             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
   21040         }
   21041         // We always allow the memory level to go up (better).  We only allow it to go
   21042         // down if we are in a state where that is allowed, *and* the total number of processes
   21043         // has gone down since last time.
   21044         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
   21045                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
   21046                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
   21047         if (memFactor > mLastMemoryLevel) {
   21048             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
   21049                 memFactor = mLastMemoryLevel;
   21050                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
   21051             }
   21052         }
   21053         if (memFactor != mLastMemoryLevel) {
   21054             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
   21055         }
   21056         mLastMemoryLevel = memFactor;
   21057         mLastNumProcesses = mLruProcesses.size();
   21058         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
   21059         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
   21060         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
   21061             if (mLowRamStartTime == 0) {
   21062                 mLowRamStartTime = now;
   21063             }
   21064             int step = 0;
   21065             int fgTrimLevel;
   21066             switch (memFactor) {
   21067                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
   21068                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
   21069                     break;
   21070                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
   21071                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
   21072                     break;
   21073                 default:
   21074                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
   21075                     break;
   21076             }
   21077             int factor = numTrimming/3;
   21078             int minFactor = 2;
   21079             if (mHomeProcess != null) minFactor++;
   21080             if (mPreviousProcess != null) minFactor++;
   21081             if (factor < minFactor) factor = minFactor;
   21082             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
   21083             for (int i=N-1; i>=0; i--) {
   21084                 ProcessRecord app = mLruProcesses.get(i);
   21085                 if (allChanged || app.procStateChanged) {
   21086                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
   21087                     app.procStateChanged = false;
   21088                 }
   21089                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   21090                         && !app.killedByAm) {
   21091                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
   21092                         try {
   21093                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   21094                                     "Trimming memory of " + app.processName + " to " + curLevel);
   21095                             app.thread.scheduleTrimMemory(curLevel);
   21096                         } catch (RemoteException e) {
   21097                         }
   21098                         if (false) {
   21099                             // For now we won't do this; our memory trimming seems
   21100                             // to be good enough at this point that destroying
   21101                             // activities causes more harm than good.
   21102                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
   21103                                     && app != mHomeProcess && app != mPreviousProcess) {
   21104                                 // Need to do this on its own message because the stack may not
   21105                                 // be in a consistent state at this point.
   21106                                 // For these apps we will also finish their activities
   21107                                 // to help them free memory.
   21108                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
   21109                             }
   21110                         }
   21111                     }
   21112                     app.trimMemoryLevel = curLevel;
   21113                     step++;
   21114                     if (step >= factor) {
   21115                         step = 0;
   21116                         switch (curLevel) {
   21117                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
   21118                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
   21119                                 break;
   21120                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
   21121                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   21122                                 break;
   21123                         }
   21124                     }
   21125                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
   21126                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
   21127                             && app.thread != null) {
   21128                         try {
   21129                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   21130                                     "Trimming memory of heavy-weight " + app.processName
   21131                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   21132                             app.thread.scheduleTrimMemory(
   21133                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   21134                         } catch (RemoteException e) {
   21135                         }
   21136                     }
   21137                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   21138                 } else {
   21139                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   21140                             || app.systemNoUi) && app.pendingUiClean) {
   21141                         // If this application is now in the background and it
   21142                         // had done UI, then give it the special trim level to
   21143                         // have it free UI resources.
   21144                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
   21145                         if (app.trimMemoryLevel < level && app.thread != null) {
   21146                             try {
   21147                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   21148                                         "Trimming memory of bg-ui " + app.processName
   21149                                         + " to " + level);
   21150                                 app.thread.scheduleTrimMemory(level);
   21151                             } catch (RemoteException e) {
   21152                             }
   21153                         }
   21154                         app.pendingUiClean = false;
   21155                     }
   21156                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
   21157                         try {
   21158                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   21159                                     "Trimming memory of fg " + app.processName
   21160                                     + " to " + fgTrimLevel);
   21161                             app.thread.scheduleTrimMemory(fgTrimLevel);
   21162                         } catch (RemoteException e) {
   21163                         }
   21164                     }
   21165                     app.trimMemoryLevel = fgTrimLevel;
   21166                 }
   21167             }
   21168         } else {
   21169             if (mLowRamStartTime != 0) {
   21170                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
   21171                 mLowRamStartTime = 0;
   21172             }
   21173             for (int i=N-1; i>=0; i--) {
   21174                 ProcessRecord app = mLruProcesses.get(i);
   21175                 if (allChanged || app.procStateChanged) {
   21176                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
   21177                     app.procStateChanged = false;
   21178                 }
   21179                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   21180                         || app.systemNoUi) && app.pendingUiClean) {
   21181                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
   21182                             && app.thread != null) {
   21183                         try {
   21184                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   21185                                     "Trimming memory of ui hidden " + app.processName
   21186                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   21187                             app.thread.scheduleTrimMemory(
   21188                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   21189                         } catch (RemoteException e) {
   21190                         }
   21191                     }
   21192                     app.pendingUiClean = false;
   21193                 }
   21194                 app.trimMemoryLevel = 0;
   21195             }
   21196         }
   21197 
   21198         if (mAlwaysFinishActivities) {
   21199             // Need to do this on its own message because the stack may not
   21200             // be in a consistent state at this point.
   21201             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
   21202         }
   21203 
   21204         if (allChanged) {
   21205             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
   21206         }
   21207 
   21208         // Update from any uid changes.
   21209         for (int i=mActiveUids.size()-1; i>=0; i--) {
   21210             final UidRecord uidRec = mActiveUids.valueAt(i);
   21211             int uidChange = UidRecord.CHANGE_PROCSTATE;
   21212             if (uidRec.setProcState != uidRec.curProcState) {
   21213                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   21214                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
   21215                         + " to " + uidRec.curProcState);
   21216                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
   21217                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
   21218                         uidRec.lastBackgroundTime = nowElapsed;
   21219                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
   21220                             // Note: the background settle time is in elapsed realtime, while
   21221                             // the handler time base is uptime.  All this means is that we may
   21222                             // stop background uids later than we had intended, but that only
   21223                             // happens because the device was sleeping so we are okay anyway.
   21224                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
   21225                         }
   21226                     }
   21227                 } else {
   21228                     if (uidRec.idle) {
   21229                         uidChange = UidRecord.CHANGE_ACTIVE;
   21230                         uidRec.idle = false;
   21231                     }
   21232                     uidRec.lastBackgroundTime = 0;
   21233                 }
   21234                 uidRec.setProcState = uidRec.curProcState;
   21235                 enqueueUidChangeLocked(uidRec, -1, uidChange);
   21236                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
   21237             }
   21238         }
   21239 
   21240         if (mProcessStats.shouldWriteNowLocked(now)) {
   21241             mHandler.post(new Runnable() {
   21242                 @Override public void run() {
   21243                     synchronized (ActivityManagerService.this) {
   21244                         mProcessStats.writeStateAsyncLocked();
   21245                     }
   21246                 }
   21247             });
   21248         }
   21249 
   21250         if (DEBUG_OOM_ADJ) {
   21251             final long duration = SystemClock.uptimeMillis() - now;
   21252             if (false) {
   21253                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
   21254                         new RuntimeException("here").fillInStackTrace());
   21255             } else {
   21256                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
   21257             }
   21258         }
   21259     }
   21260 
   21261     final void idleUids() {
   21262         synchronized (this) {
   21263             final long nowElapsed = SystemClock.elapsedRealtime();
   21264             final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
   21265             long nextTime = 0;
   21266             for (int i=mActiveUids.size()-1; i>=0; i--) {
   21267                 final UidRecord uidRec = mActiveUids.valueAt(i);
   21268                 final long bgTime = uidRec.lastBackgroundTime;
   21269                 if (bgTime > 0 && !uidRec.idle) {
   21270                     if (bgTime <= maxBgTime) {
   21271                         uidRec.idle = true;
   21272                         doStopUidLocked(uidRec.uid, uidRec);
   21273                     } else {
   21274                         if (nextTime == 0 || nextTime > bgTime) {
   21275                             nextTime = bgTime;
   21276                         }
   21277                     }
   21278                 }
   21279             }
   21280             if (nextTime > 0) {
   21281                 mHandler.removeMessages(IDLE_UIDS_MSG);
   21282                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
   21283                         nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
   21284             }
   21285         }
   21286     }
   21287 
   21288     final void runInBackgroundDisabled(int uid) {
   21289         synchronized (this) {
   21290             UidRecord uidRec = mActiveUids.get(uid);
   21291             if (uidRec != null) {
   21292                 // This uid is actually running...  should it be considered background now?
   21293                 if (uidRec.idle) {
   21294                     doStopUidLocked(uidRec.uid, uidRec);
   21295                 }
   21296             } else {
   21297                 // This uid isn't actually running...  still send a report about it being "stopped".
   21298                 doStopUidLocked(uid, null);
   21299             }
   21300         }
   21301     }
   21302 
   21303     final void doStopUidLocked(int uid, final UidRecord uidRec) {
   21304         mServices.stopInBackgroundLocked(uid);
   21305         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
   21306     }
   21307 
   21308     final void trimApplications() {
   21309         synchronized (this) {
   21310             int i;
   21311 
   21312             // First remove any unused application processes whose package
   21313             // has been removed.
   21314             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
   21315                 final ProcessRecord app = mRemovedProcesses.get(i);
   21316                 if (app.activities.size() == 0
   21317                         && app.curReceiver == null && app.services.size() == 0) {
   21318                     Slog.i(
   21319                         TAG, "Exiting empty application process "
   21320                         + app.toShortString() + " ("
   21321                         + (app.thread != null ? app.thread.asBinder() : null)
   21322                         + ")\n");
   21323                     if (app.pid > 0 && app.pid != MY_PID) {
   21324                         app.kill("empty", false);
   21325                     } else {
   21326                         try {
   21327                             app.thread.scheduleExit();
   21328                         } catch (Exception e) {
   21329                             // Ignore exceptions.
   21330                         }
   21331                     }
   21332                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
   21333                     mRemovedProcesses.remove(i);
   21334 
   21335                     if (app.persistent) {
   21336                         addAppLocked(app.info, false, null /* ABI override */);
   21337                     }
   21338                 }
   21339             }
   21340 
   21341             // Now update the oom adj for all processes.
   21342             updateOomAdjLocked();
   21343         }
   21344     }
   21345 
   21346     /** This method sends the specified signal to each of the persistent apps */
   21347     public void signalPersistentProcesses(int sig) throws RemoteException {
   21348         if (sig != Process.SIGNAL_USR1) {
   21349             throw new SecurityException("Only SIGNAL_USR1 is allowed");
   21350         }
   21351 
   21352         synchronized (this) {
   21353             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
   21354                     != PackageManager.PERMISSION_GRANTED) {
   21355                 throw new SecurityException("Requires permission "
   21356                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
   21357             }
   21358 
   21359             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   21360                 ProcessRecord r = mLruProcesses.get(i);
   21361                 if (r.thread != null && r.persistent) {
   21362                     Process.sendSignal(r.pid, sig);
   21363                 }
   21364             }
   21365         }
   21366     }
   21367 
   21368     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
   21369         if (proc == null || proc == mProfileProc) {
   21370             proc = mProfileProc;
   21371             profileType = mProfileType;
   21372             clearProfilerLocked();
   21373         }
   21374         if (proc == null) {
   21375             return;
   21376         }
   21377         try {
   21378             proc.thread.profilerControl(false, null, profileType);
   21379         } catch (RemoteException e) {
   21380             throw new IllegalStateException("Process disappeared");
   21381         }
   21382     }
   21383 
   21384     private void clearProfilerLocked() {
   21385         if (mProfileFd != null) {
   21386             try {
   21387                 mProfileFd.close();
   21388             } catch (IOException e) {
   21389             }
   21390         }
   21391         mProfileApp = null;
   21392         mProfileProc = null;
   21393         mProfileFile = null;
   21394         mProfileType = 0;
   21395         mAutoStopProfiler = false;
   21396         mSamplingInterval = 0;
   21397     }
   21398 
   21399     public boolean profileControl(String process, int userId, boolean start,
   21400             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
   21401 
   21402         try {
   21403             synchronized (this) {
   21404                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   21405                 // its own permission.
   21406                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   21407                         != PackageManager.PERMISSION_GRANTED) {
   21408                     throw new SecurityException("Requires permission "
   21409                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   21410                 }
   21411 
   21412                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
   21413                     throw new IllegalArgumentException("null profile info or fd");
   21414                 }
   21415 
   21416                 ProcessRecord proc = null;
   21417                 if (process != null) {
   21418                     proc = findProcessLocked(process, userId, "profileControl");
   21419                 }
   21420 
   21421                 if (start && (proc == null || proc.thread == null)) {
   21422                     throw new IllegalArgumentException("Unknown process: " + process);
   21423                 }
   21424 
   21425                 if (start) {
   21426                     stopProfilerLocked(null, 0);
   21427                     setProfileApp(proc.info, proc.processName, profilerInfo);
   21428                     mProfileProc = proc;
   21429                     mProfileType = profileType;
   21430                     ParcelFileDescriptor fd = profilerInfo.profileFd;
   21431                     try {
   21432                         fd = fd.dup();
   21433                     } catch (IOException e) {
   21434                         fd = null;
   21435                     }
   21436                     profilerInfo.profileFd = fd;
   21437                     proc.thread.profilerControl(start, profilerInfo, profileType);
   21438                     fd = null;
   21439                     mProfileFd = null;
   21440                 } else {
   21441                     stopProfilerLocked(proc, profileType);
   21442                     if (profilerInfo != null && profilerInfo.profileFd != null) {
   21443                         try {
   21444                             profilerInfo.profileFd.close();
   21445                         } catch (IOException e) {
   21446                         }
   21447                     }
   21448                 }
   21449 
   21450                 return true;
   21451             }
   21452         } catch (RemoteException e) {
   21453             throw new IllegalStateException("Process disappeared");
   21454         } finally {
   21455             if (profilerInfo != null && profilerInfo.profileFd != null) {
   21456                 try {
   21457                     profilerInfo.profileFd.close();
   21458                 } catch (IOException e) {
   21459                 }
   21460             }
   21461         }
   21462     }
   21463 
   21464     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
   21465         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   21466                 userId, true, ALLOW_FULL_ONLY, callName, null);
   21467         ProcessRecord proc = null;
   21468         try {
   21469             int pid = Integer.parseInt(process);
   21470             synchronized (mPidsSelfLocked) {
   21471                 proc = mPidsSelfLocked.get(pid);
   21472             }
   21473         } catch (NumberFormatException e) {
   21474         }
   21475 
   21476         if (proc == null) {
   21477             ArrayMap<String, SparseArray<ProcessRecord>> all
   21478                     = mProcessNames.getMap();
   21479             SparseArray<ProcessRecord> procs = all.get(process);
   21480             if (procs != null && procs.size() > 0) {
   21481                 proc = procs.valueAt(0);
   21482                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
   21483                     for (int i=1; i<procs.size(); i++) {
   21484                         ProcessRecord thisProc = procs.valueAt(i);
   21485                         if (thisProc.userId == userId) {
   21486                             proc = thisProc;
   21487                             break;
   21488                         }
   21489                     }
   21490                 }
   21491             }
   21492         }
   21493 
   21494         return proc;
   21495     }
   21496 
   21497     public boolean dumpHeap(String process, int userId, boolean managed,
   21498             String path, ParcelFileDescriptor fd) throws RemoteException {
   21499 
   21500         try {
   21501             synchronized (this) {
   21502                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   21503                 // its own permission (same as profileControl).
   21504                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   21505                         != PackageManager.PERMISSION_GRANTED) {
   21506                     throw new SecurityException("Requires permission "
   21507                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   21508                 }
   21509 
   21510                 if (fd == null) {
   21511                     throw new IllegalArgumentException("null fd");
   21512                 }
   21513 
   21514                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
   21515                 if (proc == null || proc.thread == null) {
   21516                     throw new IllegalArgumentException("Unknown process: " + process);
   21517                 }
   21518 
   21519                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   21520                 if (!isDebuggable) {
   21521                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   21522                         throw new SecurityException("Process not debuggable: " + proc);
   21523                     }
   21524                 }
   21525 
   21526                 proc.thread.dumpHeap(managed, path, fd);
   21527                 fd = null;
   21528                 return true;
   21529             }
   21530         } catch (RemoteException e) {
   21531             throw new IllegalStateException("Process disappeared");
   21532         } finally {
   21533             if (fd != null) {
   21534                 try {
   21535                     fd.close();
   21536                 } catch (IOException e) {
   21537                 }
   21538             }
   21539         }
   21540     }
   21541 
   21542     @Override
   21543     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
   21544             String reportPackage) {
   21545         if (processName != null) {
   21546             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   21547                     "setDumpHeapDebugLimit()");
   21548         } else {
   21549             synchronized (mPidsSelfLocked) {
   21550                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
   21551                 if (proc == null) {
   21552                     throw new SecurityException("No process found for calling pid "
   21553                             + Binder.getCallingPid());
   21554                 }
   21555                 if (!Build.IS_DEBUGGABLE
   21556                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   21557                     throw new SecurityException("Not running a debuggable build");
   21558                 }
   21559                 processName = proc.processName;
   21560                 uid = proc.uid;
   21561                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
   21562                     throw new SecurityException("Package " + reportPackage + " is not running in "
   21563                             + proc);
   21564                 }
   21565             }
   21566         }
   21567         synchronized (this) {
   21568             if (maxMemSize > 0) {
   21569                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
   21570             } else {
   21571                 if (uid != 0) {
   21572                     mMemWatchProcesses.remove(processName, uid);
   21573                 } else {
   21574                     mMemWatchProcesses.getMap().remove(processName);
   21575                 }
   21576             }
   21577         }
   21578     }
   21579 
   21580     @Override
   21581     public void dumpHeapFinished(String path) {
   21582         synchronized (this) {
   21583             if (Binder.getCallingPid() != mMemWatchDumpPid) {
   21584                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
   21585                         + " does not match last pid " + mMemWatchDumpPid);
   21586                 return;
   21587             }
   21588             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
   21589                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
   21590                         + " does not match last path " + mMemWatchDumpFile);
   21591                 return;
   21592             }
   21593             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
   21594             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
   21595         }
   21596     }
   21597 
   21598     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
   21599     public void monitor() {
   21600         synchronized (this) { }
   21601     }
   21602 
   21603     void onCoreSettingsChange(Bundle settings) {
   21604         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   21605             ProcessRecord processRecord = mLruProcesses.get(i);
   21606             try {
   21607                 if (processRecord.thread != null) {
   21608                     processRecord.thread.setCoreSettings(settings);
   21609                 }
   21610             } catch (RemoteException re) {
   21611                 /* ignore */
   21612             }
   21613         }
   21614     }
   21615 
   21616     // Multi-user methods
   21617 
   21618     /**
   21619      * Start user, if its not already running, but don't bring it to foreground.
   21620      */
   21621     @Override
   21622     public boolean startUserInBackground(final int userId) {
   21623         return mUserController.startUser(userId, /* foreground */ false);
   21624     }
   21625 
   21626     @Override
   21627     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
   21628         return mUserController.unlockUser(userId, token, secret, listener);
   21629     }
   21630 
   21631     @Override
   21632     public boolean switchUser(final int targetUserId) {
   21633         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
   21634         UserInfo currentUserInfo;
   21635         UserInfo targetUserInfo;
   21636         synchronized (this) {
   21637             int currentUserId = mUserController.getCurrentUserIdLocked();
   21638             currentUserInfo = mUserController.getUserInfo(currentUserId);
   21639             targetUserInfo = mUserController.getUserInfo(targetUserId);
   21640             if (targetUserInfo == null) {
   21641                 Slog.w(TAG, "No user info for user #" + targetUserId);
   21642                 return false;
   21643             }
   21644             if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
   21645                 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
   21646                         + " when device is in demo mode");
   21647                 return false;
   21648             }
   21649             if (!targetUserInfo.supportsSwitchTo()) {
   21650                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
   21651                 return false;
   21652             }
   21653             if (targetUserInfo.isManagedProfile()) {
   21654                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
   21655                 return false;
   21656             }
   21657             mUserController.setTargetUserIdLocked(targetUserId);
   21658         }
   21659         Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
   21660         mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
   21661         mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
   21662         return true;
   21663     }
   21664 
   21665     void scheduleStartProfilesLocked() {
   21666         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
   21667             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
   21668                     DateUtils.SECOND_IN_MILLIS);
   21669         }
   21670     }
   21671 
   21672     @Override
   21673     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
   21674         return mUserController.stopUser(userId, force, callback);
   21675     }
   21676 
   21677     @Override
   21678     public UserInfo getCurrentUser() {
   21679         return mUserController.getCurrentUser();
   21680     }
   21681 
   21682     @Override
   21683     public boolean isUserRunning(int userId, int flags) {
   21684         if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
   21685                 && checkCallingPermission(INTERACT_ACROSS_USERS)
   21686                     != PackageManager.PERMISSION_GRANTED) {
   21687             String msg = "Permission Denial: isUserRunning() from pid="
   21688                     + Binder.getCallingPid()
   21689                     + ", uid=" + Binder.getCallingUid()
   21690                     + " requires " + INTERACT_ACROSS_USERS;
   21691             Slog.w(TAG, msg);
   21692             throw new SecurityException(msg);
   21693         }
   21694         synchronized (this) {
   21695             return mUserController.isUserRunningLocked(userId, flags);
   21696         }
   21697     }
   21698 
   21699     @Override
   21700     public int[] getRunningUserIds() {
   21701         if (checkCallingPermission(INTERACT_ACROSS_USERS)
   21702                 != PackageManager.PERMISSION_GRANTED) {
   21703             String msg = "Permission Denial: isUserRunning() from pid="
   21704                     + Binder.getCallingPid()
   21705                     + ", uid=" + Binder.getCallingUid()
   21706                     + " requires " + INTERACT_ACROSS_USERS;
   21707             Slog.w(TAG, msg);
   21708             throw new SecurityException(msg);
   21709         }
   21710         synchronized (this) {
   21711             return mUserController.getStartedUserArrayLocked();
   21712         }
   21713     }
   21714 
   21715     @Override
   21716     public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
   21717         mUserController.registerUserSwitchObserver(observer, name);
   21718     }
   21719 
   21720     @Override
   21721     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
   21722         mUserController.unregisterUserSwitchObserver(observer);
   21723     }
   21724 
   21725     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
   21726         if (info == null) return null;
   21727         ApplicationInfo newInfo = new ApplicationInfo(info);
   21728         newInfo.initForUser(userId);
   21729         return newInfo;
   21730     }
   21731 
   21732     public boolean isUserStopped(int userId) {
   21733         synchronized (this) {
   21734             return mUserController.getStartedUserStateLocked(userId) == null;
   21735         }
   21736     }
   21737 
   21738     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
   21739         if (aInfo == null
   21740                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
   21741             return aInfo;
   21742         }
   21743 
   21744         ActivityInfo info = new ActivityInfo(aInfo);
   21745         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
   21746         return info;
   21747     }
   21748 
   21749     private boolean processSanityChecksLocked(ProcessRecord process) {
   21750         if (process == null || process.thread == null) {
   21751             return false;
   21752         }
   21753 
   21754         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   21755         if (!isDebuggable) {
   21756             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   21757                 return false;
   21758             }
   21759         }
   21760 
   21761         return true;
   21762     }
   21763 
   21764     public boolean startBinderTracking() throws RemoteException {
   21765         synchronized (this) {
   21766             mBinderTransactionTrackingEnabled = true;
   21767             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
   21768             // permission (same as profileControl).
   21769             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   21770                     != PackageManager.PERMISSION_GRANTED) {
   21771                 throw new SecurityException("Requires permission "
   21772                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   21773             }
   21774 
   21775             for (int i = 0; i < mLruProcesses.size(); i++) {
   21776                 ProcessRecord process = mLruProcesses.get(i);
   21777                 if (!processSanityChecksLocked(process)) {
   21778                     continue;
   21779                 }
   21780                 try {
   21781                     process.thread.startBinderTracking();
   21782                 } catch (RemoteException e) {
   21783                     Log.v(TAG, "Process disappared");
   21784                 }
   21785             }
   21786             return true;
   21787         }
   21788     }
   21789 
   21790     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
   21791         try {
   21792             synchronized (this) {
   21793                 mBinderTransactionTrackingEnabled = false;
   21794                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
   21795                 // permission (same as profileControl).
   21796                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   21797                         != PackageManager.PERMISSION_GRANTED) {
   21798                     throw new SecurityException("Requires permission "
   21799                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   21800                 }
   21801 
   21802                 if (fd == null) {
   21803                     throw new IllegalArgumentException("null fd");
   21804                 }
   21805 
   21806                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
   21807                 pw.println("Binder transaction traces for all processes.\n");
   21808                 for (ProcessRecord process : mLruProcesses) {
   21809                     if (!processSanityChecksLocked(process)) {
   21810                         continue;
   21811                     }
   21812 
   21813                     pw.println("Traces for process: " + process.processName);
   21814                     pw.flush();
   21815                     try {
   21816                         TransferPipe tp = new TransferPipe();
   21817                         try {
   21818                             process.thread.stopBinderTrackingAndDump(
   21819                                     tp.getWriteFd().getFileDescriptor());
   21820                             tp.go(fd.getFileDescriptor());
   21821                         } finally {
   21822                             tp.kill();
   21823                         }
   21824                     } catch (IOException e) {
   21825                         pw.println("Failure while dumping IPC traces from " + process +
   21826                                 ".  Exception: " + e);
   21827                         pw.flush();
   21828                     } catch (RemoteException e) {
   21829                         pw.println("Got a RemoteException while dumping IPC traces from " +
   21830                                 process + ".  Exception: " + e);
   21831                         pw.flush();
   21832                     }
   21833                 }
   21834                 fd = null;
   21835                 return true;
   21836             }
   21837         } finally {
   21838             if (fd != null) {
   21839                 try {
   21840                     fd.close();
   21841                 } catch (IOException e) {
   21842                 }
   21843             }
   21844         }
   21845     }
   21846 
   21847     private final class LocalService extends ActivityManagerInternal {
   21848         @Override
   21849         public void onWakefulnessChanged(int wakefulness) {
   21850             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
   21851         }
   21852 
   21853         @Override
   21854         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
   21855                 String processName, String abiOverride, int uid, Runnable crashHandler) {
   21856             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
   21857                     processName, abiOverride, uid, crashHandler);
   21858         }
   21859 
   21860         @Override
   21861         public SleepToken acquireSleepToken(String tag) {
   21862             Preconditions.checkNotNull(tag);
   21863 
   21864             ComponentName requestedVrService = null;
   21865             ComponentName callingVrActivity = null;
   21866             int userId = -1;
   21867             synchronized (ActivityManagerService.this) {
   21868                 if (mFocusedActivity != null) {
   21869                     requestedVrService = mFocusedActivity.requestedVrComponent;
   21870                     callingVrActivity = mFocusedActivity.info.getComponentName();
   21871                     userId = mFocusedActivity.userId;
   21872                 }
   21873             }
   21874 
   21875             if (requestedVrService != null) {
   21876                 applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
   21877             }
   21878 
   21879             synchronized (ActivityManagerService.this) {
   21880                 SleepTokenImpl token = new SleepTokenImpl(tag);
   21881                 mSleepTokens.add(token);
   21882                 updateSleepIfNeededLocked();
   21883                 return token;
   21884             }
   21885         }
   21886 
   21887         @Override
   21888         public ComponentName getHomeActivityForUser(int userId) {
   21889             synchronized (ActivityManagerService.this) {
   21890                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
   21891                 return homeActivity == null ? null : homeActivity.realActivity;
   21892             }
   21893         }
   21894 
   21895         @Override
   21896         public void onUserRemoved(int userId) {
   21897             synchronized (ActivityManagerService.this) {
   21898                 ActivityManagerService.this.onUserStoppedLocked(userId);
   21899             }
   21900         }
   21901 
   21902         @Override
   21903         public void onLocalVoiceInteractionStarted(IBinder activity,
   21904                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
   21905             synchronized (ActivityManagerService.this) {
   21906                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
   21907                         voiceSession, voiceInteractor);
   21908             }
   21909         }
   21910 
   21911         @Override
   21912         public void notifyStartingWindowDrawn() {
   21913             synchronized (ActivityManagerService.this) {
   21914                 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
   21915             }
   21916         }
   21917 
   21918         @Override
   21919         public void notifyAppTransitionStarting(int reason) {
   21920             synchronized (ActivityManagerService.this) {
   21921                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
   21922             }
   21923         }
   21924 
   21925         @Override
   21926         public void notifyAppTransitionFinished() {
   21927             synchronized (ActivityManagerService.this) {
   21928                 mStackSupervisor.notifyAppTransitionDone();
   21929             }
   21930         }
   21931 
   21932         @Override
   21933         public void notifyAppTransitionCancelled() {
   21934             synchronized (ActivityManagerService.this) {
   21935                 mStackSupervisor.notifyAppTransitionDone();
   21936             }
   21937         }
   21938 
   21939         @Override
   21940         public List<IBinder> getTopVisibleActivities() {
   21941             synchronized (ActivityManagerService.this) {
   21942                 return mStackSupervisor.getTopVisibleActivities();
   21943             }
   21944         }
   21945 
   21946         @Override
   21947         public void notifyDockedStackMinimizedChanged(boolean minimized) {
   21948             synchronized (ActivityManagerService.this) {
   21949                 mStackSupervisor.setDockedStackMinimized(minimized);
   21950             }
   21951         }
   21952 
   21953         @Override
   21954         public void killForegroundAppsForUser(int userHandle) {
   21955             synchronized (ActivityManagerService.this) {
   21956                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
   21957                 final int NP = mProcessNames.getMap().size();
   21958                 for (int ip = 0; ip < NP; ip++) {
   21959                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   21960                     final int NA = apps.size();
   21961                     for (int ia = 0; ia < NA; ia++) {
   21962                         final ProcessRecord app = apps.valueAt(ia);
   21963                         if (app.persistent) {
   21964                             // We don't kill persistent processes.
   21965                             continue;
   21966                         }
   21967                         if (app.removed) {
   21968                             procs.add(app);
   21969                         } else if (app.userId == userHandle && app.foregroundActivities) {
   21970                             app.removed = true;
   21971                             procs.add(app);
   21972                         }
   21973                     }
   21974                 }
   21975 
   21976                 final int N = procs.size();
   21977                 for (int i = 0; i < N; i++) {
   21978                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
   21979                 }
   21980             }
   21981         }
   21982 
   21983         @Override
   21984         public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
   21985             if (!(target instanceof PendingIntentRecord)) {
   21986                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
   21987                 return;
   21988             }
   21989             ((PendingIntentRecord) target).setWhitelistDuration(duration);
   21990         }
   21991 
   21992         @Override
   21993         public void updatePersistentConfigurationForUser(@NonNull Configuration values,
   21994                 int userId) {
   21995             Preconditions.checkNotNull(values, "Configuration must not be null");
   21996             Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
   21997             synchronized (ActivityManagerService.this) {
   21998                 updateConfigurationLocked(values, null, false, true, userId,
   21999                         false /* deferResume */);
   22000             }
   22001         }
   22002 
   22003         @Override
   22004         public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
   22005                 Bundle bOptions) {
   22006             Preconditions.checkNotNull(intents, "intents");
   22007             final String[] resolvedTypes = new String[intents.length];
   22008             for (int i = 0; i < intents.length; i++) {
   22009                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
   22010             }
   22011 
   22012             // UID of the package on user userId.
   22013             // "= 0" is needed because otherwise catch(RemoteException) would make it look like
   22014             // packageUid may not be initialized.
   22015             int packageUid = 0;
   22016             try {
   22017                 packageUid = AppGlobals.getPackageManager().getPackageUid(
   22018                         packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
   22019             } catch (RemoteException e) {
   22020                 // Shouldn't happen.
   22021             }
   22022 
   22023             synchronized (ActivityManagerService.this) {
   22024                 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
   22025                         /*resultTo*/ null, bOptions, userId);
   22026             }
   22027         }
   22028 
   22029         @Override
   22030         public int getUidProcessState(int uid) {
   22031             return getUidState(uid);
   22032         }
   22033     }
   22034 
   22035     private final class SleepTokenImpl extends SleepToken {
   22036         private final String mTag;
   22037         private final long mAcquireTime;
   22038 
   22039         public SleepTokenImpl(String tag) {
   22040             mTag = tag;
   22041             mAcquireTime = SystemClock.uptimeMillis();
   22042         }
   22043 
   22044         @Override
   22045         public void release() {
   22046             synchronized (ActivityManagerService.this) {
   22047                 if (mSleepTokens.remove(this)) {
   22048                     updateSleepIfNeededLocked();
   22049                 }
   22050             }
   22051         }
   22052 
   22053         @Override
   22054         public String toString() {
   22055             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
   22056         }
   22057     }
   22058 
   22059     /**
   22060      * An implementation of IAppTask, that allows an app to manage its own tasks via
   22061      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
   22062      * only the process that calls getAppTasks() can call the AppTask methods.
   22063      */
   22064     class AppTaskImpl extends IAppTask.Stub {
   22065         private int mTaskId;
   22066         private int mCallingUid;
   22067 
   22068         public AppTaskImpl(int taskId, int callingUid) {
   22069             mTaskId = taskId;
   22070             mCallingUid = callingUid;
   22071         }
   22072 
   22073         private void checkCaller() {
   22074             if (mCallingUid != Binder.getCallingUid()) {
   22075                 throw new SecurityException("Caller " + mCallingUid
   22076                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
   22077             }
   22078         }
   22079 
   22080         @Override
   22081         public void finishAndRemoveTask() {
   22082             checkCaller();
   22083 
   22084             synchronized (ActivityManagerService.this) {
   22085                 long origId = Binder.clearCallingIdentity();
   22086                 try {
   22087                     // We remove the task from recents to preserve backwards
   22088                     if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
   22089                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   22090                     }
   22091                 } finally {
   22092                     Binder.restoreCallingIdentity(origId);
   22093                 }
   22094             }
   22095         }
   22096 
   22097         @Override
   22098         public ActivityManager.RecentTaskInfo getTaskInfo() {
   22099             checkCaller();
   22100 
   22101             synchronized (ActivityManagerService.this) {
   22102                 long origId = Binder.clearCallingIdentity();
   22103                 try {
   22104                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
   22105                     if (tr == null) {
   22106                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   22107                     }
   22108                     return createRecentTaskInfoFromTaskRecord(tr);
   22109                 } finally {
   22110                     Binder.restoreCallingIdentity(origId);
   22111                 }
   22112             }
   22113         }
   22114 
   22115         @Override
   22116         public void moveToFront() {
   22117             checkCaller();
   22118             // Will bring task to front if it already has a root activity.
   22119             final long origId = Binder.clearCallingIdentity();
   22120             try {
   22121                 synchronized (this) {
   22122                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
   22123                 }
   22124             } finally {
   22125                 Binder.restoreCallingIdentity(origId);
   22126             }
   22127         }
   22128 
   22129         @Override
   22130         public int startActivity(IBinder whoThread, String callingPackage,
   22131                 Intent intent, String resolvedType, Bundle bOptions) {
   22132             checkCaller();
   22133 
   22134             int callingUser = UserHandle.getCallingUserId();
   22135             TaskRecord tr;
   22136             IApplicationThread appThread;
   22137             synchronized (ActivityManagerService.this) {
   22138                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
   22139                 if (tr == null) {
   22140                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   22141                 }
   22142                 appThread = ApplicationThreadNative.asInterface(whoThread);
   22143                 if (appThread == null) {
   22144                     throw new IllegalArgumentException("Bad app thread " + appThread);
   22145                 }
   22146             }
   22147             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
   22148                     resolvedType, null, null, null, null, 0, 0, null, null,
   22149                     null, bOptions, false, callingUser, null, tr);
   22150         }
   22151 
   22152         @Override
   22153         public void setExcludeFromRecents(boolean exclude) {
   22154             checkCaller();
   22155 
   22156             synchronized (ActivityManagerService.this) {
   22157                 long origId = Binder.clearCallingIdentity();
   22158                 try {
   22159                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
   22160                     if (tr == null) {
   22161                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   22162                     }
   22163                     Intent intent = tr.getBaseIntent();
   22164                     if (exclude) {
   22165                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
   22166                     } else {
   22167                         intent.setFlags(intent.getFlags()
   22168                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
   22169                     }
   22170                 } finally {
   22171                     Binder.restoreCallingIdentity(origId);
   22172                 }
   22173             }
   22174         }
   22175     }
   22176 
   22177     /**
   22178      * Kill processes for the user with id userId and that depend on the package named packageName
   22179      */
   22180     @Override
   22181     public void killPackageDependents(String packageName, int userId) {
   22182         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
   22183         if (packageName == null) {
   22184             throw new NullPointerException(
   22185                     "Cannot kill the dependents of a package without its name.");
   22186         }
   22187 
   22188         long callingId = Binder.clearCallingIdentity();
   22189         IPackageManager pm = AppGlobals.getPackageManager();
   22190         int pkgUid = -1;
   22191         try {
   22192             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
   22193         } catch (RemoteException e) {
   22194         }
   22195         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
   22196             throw new IllegalArgumentException(
   22197                     "Cannot kill dependents of non-existing package " + packageName);
   22198         }
   22199         try {
   22200             synchronized(this) {
   22201                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
   22202                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
   22203                         "dep: " + packageName);
   22204             }
   22205         } finally {
   22206             Binder.restoreCallingIdentity(callingId);
   22207         }
   22208     }
   22209 
   22210     @Override
   22211     public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
   22212         final int userId = intent.getCreatorUserHandle().getIdentifier();
   22213         if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
   22214             return false;
   22215         }
   22216         IIntentSender target = intent.getTarget();
   22217         if (!(target instanceof PendingIntentRecord)) {
   22218             return false;
   22219         }
   22220         final PendingIntentRecord record = (PendingIntentRecord) target;
   22221         final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
   22222                 record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
   22223         // For direct boot aware activities, they can be shown without triggering a work challenge
   22224         // before the profile user is unlocked.
   22225         return rInfo != null && rInfo.activityInfo != null;
   22226     }
   22227 }
   22228