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 static android.Manifest.permission.CHANGE_CONFIGURATION;
     20 import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
     21 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
     22 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
     23 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
     24 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
     25 import static android.Manifest.permission.READ_FRAME_BUFFER;
     26 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
     27 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
     28 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
     29 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
     30 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
     31 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
     32 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
     33 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
     34 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
     35 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
     36 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
     37 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
     38 import static android.content.pm.PackageManager.GET_PROVIDERS;
     39 import static android.content.pm.PackageManager.MATCH_ANY_USER;
     40 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
     41 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
     42 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
     43 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
     44 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
     45 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
     46 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
     47 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
     48 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
     49 import static android.os.Build.VERSION_CODES.N;
     50 import static android.os.Process.BLUETOOTH_UID;
     51 import static android.os.Process.FIRST_APPLICATION_UID;
     52 import static android.os.Process.FIRST_ISOLATED_UID;
     53 import static android.os.Process.LAST_ISOLATED_UID;
     54 import static android.os.Process.NFC_UID;
     55 import static android.os.Process.PHONE_UID;
     56 import static android.os.Process.PROC_CHAR;
     57 import static android.os.Process.PROC_OUT_LONG;
     58 import static android.os.Process.PROC_PARENS;
     59 import static android.os.Process.PROC_SPACE_TERM;
     60 import static android.os.Process.ProcessStartResult;
     61 import static android.os.Process.ROOT_UID;
     62 import static android.os.Process.SCHED_FIFO;
     63 import static android.os.Process.SCHED_OTHER;
     64 import static android.os.Process.SCHED_RESET_ON_FORK;
     65 import static android.os.Process.SHELL_UID;
     66 import static android.os.Process.SIGNAL_QUIT;
     67 import static android.os.Process.SIGNAL_USR1;
     68 import static android.os.Process.SYSTEM_UID;
     69 import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
     70 import static android.os.Process.THREAD_GROUP_DEFAULT;
     71 import static android.os.Process.THREAD_GROUP_TOP_APP;
     72 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
     73 import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
     74 import static android.os.Process.getFreeMemory;
     75 import static android.os.Process.getTotalMemory;
     76 import static android.os.Process.isThreadInProcess;
     77 import static android.os.Process.killProcess;
     78 import static android.os.Process.killProcessQuiet;
     79 import static android.os.Process.myPid;
     80 import static android.os.Process.myUid;
     81 import static android.os.Process.readProcFile;
     82 import static android.os.Process.removeAllProcessGroups;
     83 import static android.os.Process.sendSignal;
     84 import static android.os.Process.setProcessGroup;
     85 import static android.os.Process.setThreadPriority;
     86 import static android.os.Process.setThreadScheduler;
     87 import static android.os.Process.startWebView;
     88 import static android.os.Process.zygoteProcess;
     89 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
     90 import static android.provider.Settings.Global.DEBUG_APP;
     91 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
     92 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
     93 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
     94 import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
     95 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
     96 import static android.provider.Settings.System.FONT_SCALE;
     97 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
     98 import static android.view.Display.DEFAULT_DISPLAY;
     99 import static android.view.Display.INVALID_DISPLAY;
    100 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
    101 import static com.android.internal.util.XmlUtils.readIntAttribute;
    102 import static com.android.internal.util.XmlUtils.readLongAttribute;
    103 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
    104 import static com.android.internal.util.XmlUtils.writeIntAttribute;
    105 import static com.android.internal.util.XmlUtils.writeLongAttribute;
    106 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
    107 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
    108 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
    109 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
    110 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
    111 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
    112 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
    113 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
    114 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
    115 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
    116 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
    117 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
    118 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
    119 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
    120 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
    121 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
    122 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
    123 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
    124 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
    125 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
    126 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
    127 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
    128 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
    129 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
    130 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
    131 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
    132 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
    133 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
    134 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
    135 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
    136 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
    137 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
    138 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
    139 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
    140 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
    141 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
    142 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
    143 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
    144 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
    145 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
    146 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
    147 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
    148 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
    149 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
    150 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
    151 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
    152 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
    153 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
    154 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
    155 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
    156 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
    157 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
    158 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
    159 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
    160 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
    161 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
    162 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
    163 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
    164 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
    165 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
    166 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
    167 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
    168 import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
    169 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
    170 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
    171 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
    172 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
    173 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
    174 import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
    175 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
    176 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
    177 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
    178 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
    179 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
    180 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
    181 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
    182 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
    183 import static com.android.server.wm.AppTransition.TRANSIT_NONE;
    184 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
    185 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
    186 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
    187 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
    188 import static org.xmlpull.v1.XmlPullParser.START_TAG;
    189 
    190 import android.Manifest;
    191 import android.Manifest.permission;
    192 import android.annotation.NonNull;
    193 import android.annotation.Nullable;
    194 import android.annotation.UserIdInt;
    195 import android.app.Activity;
    196 import android.app.ActivityManager;
    197 import android.app.ActivityManager.RunningTaskInfo;
    198 import android.app.ActivityManager.StackId;
    199 import android.app.ActivityManager.StackInfo;
    200 import android.app.ActivityManager.TaskSnapshot;
    201 import android.app.ActivityManager.TaskThumbnailInfo;
    202 import android.app.ActivityManagerInternal;
    203 import android.app.ActivityManagerInternal.SleepToken;
    204 import android.app.ActivityOptions;
    205 import android.app.ActivityThread;
    206 import android.app.AlertDialog;
    207 import android.app.AppGlobals;
    208 import android.app.AppOpsManager;
    209 import android.app.ApplicationErrorReport;
    210 import android.app.ApplicationThreadConstants;
    211 import android.app.BroadcastOptions;
    212 import android.app.ContentProviderHolder;
    213 import android.app.Dialog;
    214 import android.app.IActivityContainer;
    215 import android.app.IActivityContainerCallback;
    216 import android.app.IActivityController;
    217 import android.app.IActivityManager;
    218 import android.app.IAppTask;
    219 import android.app.IApplicationThread;
    220 import android.app.IInstrumentationWatcher;
    221 import android.app.INotificationManager;
    222 import android.app.IProcessObserver;
    223 import android.app.IServiceConnection;
    224 import android.app.IStopUserCallback;
    225 import android.app.ITaskStackListener;
    226 import android.app.IUiAutomationConnection;
    227 import android.app.IUidObserver;
    228 import android.app.IUserSwitchObserver;
    229 import android.app.Instrumentation;
    230 import android.app.Notification;
    231 import android.app.NotificationManager;
    232 import android.app.PendingIntent;
    233 import android.app.PictureInPictureParams;
    234 import android.app.ProfilerInfo;
    235 import android.app.RemoteAction;
    236 import android.app.WaitResult;
    237 import android.app.admin.DevicePolicyManager;
    238 import android.app.assist.AssistContent;
    239 import android.app.assist.AssistStructure;
    240 import android.app.backup.IBackupManager;
    241 import android.app.usage.UsageEvents;
    242 import android.app.usage.UsageStatsManagerInternal;
    243 import android.appwidget.AppWidgetManager;
    244 import android.content.ActivityNotFoundException;
    245 import android.content.BroadcastReceiver;
    246 import android.content.ClipData;
    247 import android.content.ComponentCallbacks2;
    248 import android.content.ComponentName;
    249 import android.content.ContentProvider;
    250 import android.content.ContentResolver;
    251 import android.content.Context;
    252 import android.content.DialogInterface;
    253 import android.content.IContentProvider;
    254 import android.content.IIntentReceiver;
    255 import android.content.IIntentSender;
    256 import android.content.Intent;
    257 import android.content.IntentFilter;
    258 import android.content.IntentSender;
    259 import android.content.pm.ActivityInfo;
    260 import android.content.pm.ApplicationInfo;
    261 import android.content.pm.ConfigurationInfo;
    262 import android.content.pm.IPackageDataObserver;
    263 import android.content.pm.IPackageManager;
    264 import android.content.pm.InstrumentationInfo;
    265 import android.content.pm.PackageInfo;
    266 import android.content.pm.PackageManager;
    267 import android.content.pm.PackageManager.NameNotFoundException;
    268 import android.content.pm.PackageManagerInternal;
    269 import android.content.pm.ParceledListSlice;
    270 import android.content.pm.PathPermission;
    271 import android.content.pm.PermissionInfo;
    272 import android.content.pm.ProviderInfo;
    273 import android.content.pm.ResolveInfo;
    274 import android.content.pm.SELinuxUtil;
    275 import android.content.pm.ServiceInfo;
    276 import android.content.pm.UserInfo;
    277 import android.content.res.CompatibilityInfo;
    278 import android.content.res.Configuration;
    279 import android.content.res.Resources;
    280 import android.database.ContentObserver;
    281 import android.graphics.Bitmap;
    282 import android.graphics.Point;
    283 import android.graphics.Rect;
    284 import android.location.LocationManager;
    285 import android.media.audiofx.AudioEffect;
    286 import android.metrics.LogMaker;
    287 import android.net.Proxy;
    288 import android.net.ProxyInfo;
    289 import android.net.Uri;
    290 import android.os.BatteryStats;
    291 import android.os.Binder;
    292 import android.os.Build;
    293 import android.os.Bundle;
    294 import android.os.Debug;
    295 import android.os.DropBoxManager;
    296 import android.os.Environment;
    297 import android.os.FactoryTest;
    298 import android.os.FileObserver;
    299 import android.os.FileUtils;
    300 import android.os.Handler;
    301 import android.os.IBinder;
    302 import android.os.IDeviceIdentifiersPolicyService;
    303 import android.os.IPermissionController;
    304 import android.os.IProcessInfoService;
    305 import android.os.IProgressListener;
    306 import android.os.LocaleList;
    307 import android.os.Looper;
    308 import android.os.Message;
    309 import android.os.Parcel;
    310 import android.os.ParcelFileDescriptor;
    311 import android.os.PersistableBundle;
    312 import android.os.PowerManager;
    313 import android.os.PowerManagerInternal;
    314 import android.os.Process;
    315 import android.os.RemoteCallbackList;
    316 import android.os.RemoteException;
    317 import android.os.ResultReceiver;
    318 import android.os.ServiceManager;
    319 import android.os.ShellCallback;
    320 import android.os.StrictMode;
    321 import android.os.SystemClock;
    322 import android.os.SystemProperties;
    323 import android.os.Trace;
    324 import android.os.TransactionTooLargeException;
    325 import android.os.UpdateLock;
    326 import android.os.UserHandle;
    327 import android.os.UserManager;
    328 import android.os.WorkSource;
    329 import android.os.storage.IStorageManager;
    330 import android.os.storage.StorageManager;
    331 import android.os.storage.StorageManagerInternal;
    332 import android.provider.Downloads;
    333 import android.provider.Settings;
    334 import android.service.voice.IVoiceInteractionSession;
    335 import android.service.voice.VoiceInteractionManagerInternal;
    336 import android.service.voice.VoiceInteractionSession;
    337 import android.telecom.TelecomManager;
    338 import android.text.TextUtils;
    339 import android.text.format.DateUtils;
    340 import android.text.format.Time;
    341 import android.text.style.SuggestionSpan;
    342 import android.util.ArrayMap;
    343 import android.util.ArraySet;
    344 import android.util.AtomicFile;
    345 import android.util.BootTimingsTraceLog;
    346 import android.util.DebugUtils;
    347 import android.util.DisplayMetrics;
    348 import android.util.EventLog;
    349 import android.util.Log;
    350 import android.util.Pair;
    351 import android.util.PrintWriterPrinter;
    352 import android.util.Slog;
    353 import android.util.SparseArray;
    354 import android.util.SparseIntArray;
    355 import android.util.TimeUtils;
    356 import android.util.Xml;
    357 import android.view.Gravity;
    358 import android.view.LayoutInflater;
    359 import android.view.View;
    360 import android.view.WindowManager;
    361 
    362 import com.android.server.job.JobSchedulerInternal;
    363 import com.google.android.collect.Lists;
    364 import com.google.android.collect.Maps;
    365 
    366 import com.android.internal.R;
    367 import com.android.internal.annotations.GuardedBy;
    368 import com.android.internal.annotations.VisibleForTesting;
    369 import com.android.internal.app.AssistUtils;
    370 import com.android.internal.app.DumpHeapActivity;
    371 import com.android.internal.app.IAppOpsCallback;
    372 import com.android.internal.app.IAppOpsService;
    373 import com.android.internal.app.IVoiceInteractor;
    374 import com.android.internal.app.ProcessMap;
    375 import com.android.internal.app.SystemUserHomeActivity;
    376 import com.android.internal.app.procstats.ProcessStats;
    377 import com.android.internal.logging.MetricsLogger;
    378 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
    379 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
    380 import com.android.internal.notification.SystemNotificationChannels;
    381 import com.android.internal.os.BackgroundThread;
    382 import com.android.internal.os.BatteryStatsImpl;
    383 import com.android.internal.os.IResultReceiver;
    384 import com.android.internal.os.ProcessCpuTracker;
    385 import com.android.internal.os.TransferPipe;
    386 import com.android.internal.os.Zygote;
    387 import com.android.internal.policy.IKeyguardDismissCallback;
    388 import com.android.internal.telephony.TelephonyIntents;
    389 import com.android.internal.util.ArrayUtils;
    390 import com.android.internal.util.DumpUtils;
    391 import com.android.internal.util.FastPrintWriter;
    392 import com.android.internal.util.FastXmlSerializer;
    393 import com.android.internal.util.MemInfoReader;
    394 import com.android.internal.util.Preconditions;
    395 import com.android.server.AppOpsService;
    396 import com.android.server.AttributeCache;
    397 import com.android.server.DeviceIdleController;
    398 import com.android.server.IntentResolver;
    399 import com.android.server.LocalServices;
    400 import com.android.server.LockGuard;
    401 import com.android.server.NetworkManagementInternal;
    402 import com.android.server.RescueParty;
    403 import com.android.server.ServiceThread;
    404 import com.android.server.SystemConfig;
    405 import com.android.server.SystemService;
    406 import com.android.server.SystemServiceManager;
    407 import com.android.server.ThreadPriorityBooster;
    408 import com.android.server.Watchdog;
    409 import com.android.server.am.ActivityStack.ActivityState;
    410 import com.android.server.firewall.IntentFirewall;
    411 import com.android.server.pm.Installer;
    412 import com.android.server.pm.Installer.InstallerException;
    413 import com.android.server.statusbar.StatusBarManagerInternal;
    414 import com.android.server.vr.VrManagerInternal;
    415 import com.android.server.wm.PinnedStackWindowController;
    416 import com.android.server.wm.WindowManagerService;
    417 
    418 import org.xmlpull.v1.XmlPullParser;
    419 import org.xmlpull.v1.XmlPullParserException;
    420 import org.xmlpull.v1.XmlSerializer;
    421 
    422 import java.io.File;
    423 import java.io.FileDescriptor;
    424 import java.io.FileInputStream;
    425 import java.io.FileNotFoundException;
    426 import java.io.FileOutputStream;
    427 import java.io.IOException;
    428 import java.io.InputStreamReader;
    429 import java.io.PrintWriter;
    430 import java.io.StringWriter;
    431 import java.io.UnsupportedEncodingException;
    432 import java.lang.ref.WeakReference;
    433 import java.nio.charset.StandardCharsets;
    434 import java.text.DateFormat;
    435 import java.util.ArrayList;
    436 import java.util.Arrays;
    437 import java.util.Collections;
    438 import java.util.Comparator;
    439 import java.util.Date;
    440 import java.util.HashMap;
    441 import java.util.HashSet;
    442 import java.util.Iterator;
    443 import java.util.List;
    444 import java.util.Locale;
    445 import java.util.Map;
    446 import java.util.Objects;
    447 import java.util.Set;
    448 import java.util.concurrent.CountDownLatch;
    449 import java.util.concurrent.atomic.AtomicBoolean;
    450 import java.util.concurrent.atomic.AtomicLong;
    451 
    452 import dalvik.system.VMRuntime;
    453 import libcore.io.IoUtils;
    454 import libcore.util.EmptyArray;
    455 
    456 public class ActivityManagerService extends IActivityManager.Stub
    457         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    458 
    459     /**
    460      * Priority we boost main thread and RT of top app to.
    461      */
    462     public static final int TOP_APP_PRIORITY_BOOST = -10;
    463 
    464     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
    465     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
    466     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
    467     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
    468     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
    469     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
    470     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
    471     private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
    472     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
    473     private static final String TAG_LRU = TAG + POSTFIX_LRU;
    474     private static final String TAG_MU = TAG + POSTFIX_MU;
    475     private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
    476     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
    477     private static final String TAG_POWER = TAG + POSTFIX_POWER;
    478     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
    479     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
    480     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
    481     private static final String TAG_PSS = TAG + POSTFIX_PSS;
    482     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
    483     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
    484     private static final String TAG_STACK = TAG + POSTFIX_STACK;
    485     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
    486     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
    487     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
    488     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
    489     private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
    490 
    491     // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
    492     // here so that while the job scheduler can depend on AMS, the other way around
    493     // need not be the case.
    494     public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
    495 
    496     /** Control over CPU and battery monitoring */
    497     // write battery stats every 30 minutes.
    498     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
    499     static final boolean MONITOR_CPU_USAGE = true;
    500     // don't sample cpu less than every 5 seconds.
    501     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
    502     // wait possibly forever for next cpu sample.
    503     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
    504     static final boolean MONITOR_THREAD_CPU_USAGE = false;
    505 
    506     // The flags that are set for all calls we make to the package manager.
    507     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
    508 
    509     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
    510 
    511     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
    512 
    513     // Amount of time after a call to stopAppSwitches() during which we will
    514     // prevent further untrusted switches from happening.
    515     static final long APP_SWITCH_DELAY_TIME = 5*1000;
    516 
    517     // How long we wait for a launched process to attach to the activity manager
    518     // before we decide it's never going to come up for real.
    519     static final int PROC_START_TIMEOUT = 10*1000;
    520     // How long we wait for an attached process to publish its content providers
    521     // before we decide it must be hung.
    522     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
    523 
    524     // How long we wait for a launched process to attach to the activity manager
    525     // before we decide it's never going to come up for real, when the process was
    526     // started with a wrapper for instrumentation (such as Valgrind) because it
    527     // could take much longer than usual.
    528     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
    529 
    530     // How long we allow a receiver to run before giving up on it.
    531     static final int BROADCAST_FG_TIMEOUT = 10*1000;
    532     static final int BROADCAST_BG_TIMEOUT = 60*1000;
    533 
    534     // How long we wait until we timeout on key dispatching.
    535     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
    536 
    537     // How long we wait until we timeout on key dispatching during instrumentation.
    538     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
    539 
    540     // How long to wait in getAssistContextExtras for the activity and foreground services
    541     // to respond with the result.
    542     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
    543 
    544     // How long top wait when going through the modern assist (which doesn't need to block
    545     // on getting this result before starting to launch its UI).
    546     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
    547 
    548     // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
    549     static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
    550 
    551     // Maximum number of persisted Uri grants a package is allowed
    552     static final int MAX_PERSISTED_URI_GRANTS = 128;
    553 
    554     static final int MY_PID = myPid();
    555 
    556     static final String[] EMPTY_STRING_ARRAY = new String[0];
    557 
    558     // How many bytes to write into the dropbox log before truncating
    559     static final int DROPBOX_MAX_SIZE = 192 * 1024;
    560     // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
    561     // as one line, but close enough for now.
    562     static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
    563 
    564     // Access modes for handleIncomingUser.
    565     static final int ALLOW_NON_FULL = 0;
    566     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
    567     static final int ALLOW_FULL_ONLY = 2;
    568 
    569     // Necessary ApplicationInfo flags to mark an app as persistent
    570     private static final int PERSISTENT_MASK =
    571             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
    572 
    573     // Intent sent when remote bugreport collection has been completed
    574     private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
    575             "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
    576 
    577     // Used to indicate that an app transition should be animated.
    578     static final boolean ANIMATE = true;
    579 
    580     // Determines whether to take full screen screenshots
    581     static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
    582 
    583     /**
    584      * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
    585      */
    586     private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
    587 
    588     /**
    589      * State indicating that there is no need for any blocking for network.
    590      */
    591     @VisibleForTesting
    592     static final int NETWORK_STATE_NO_CHANGE = 0;
    593 
    594     /**
    595      * State indicating that the main thread needs to be informed about the network wait.
    596      */
    597     @VisibleForTesting
    598     static final int NETWORK_STATE_BLOCK = 1;
    599 
    600     /**
    601      * State indicating that any threads waiting for network state to get updated can be unblocked.
    602      */
    603     @VisibleForTesting
    604     static final int NETWORK_STATE_UNBLOCK = 2;
    605 
    606     // Max character limit for a notification title. If the notification title is larger than this
    607     // the notification will not be legible to the user.
    608     private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
    609 
    610     /** All system services */
    611     SystemServiceManager mSystemServiceManager;
    612     AssistUtils mAssistUtils;
    613 
    614     private Installer mInstaller;
    615 
    616     /** Run all ActivityStacks through this */
    617     final ActivityStackSupervisor mStackSupervisor;
    618     private final KeyguardController mKeyguardController;
    619 
    620     final ActivityStarter mActivityStarter;
    621 
    622     final TaskChangeNotificationController mTaskChangeNotificationController;
    623 
    624     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
    625 
    626     final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
    627 
    628     public final IntentFirewall mIntentFirewall;
    629 
    630     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
    631     // default action automatically.  Important for devices without direct input
    632     // devices.
    633     private boolean mShowDialogs = true;
    634 
    635     private final VrController mVrController;
    636 
    637     // VR Vr2d Display Id.
    638     int mVr2dDisplayId = INVALID_DISPLAY;
    639 
    640     // Whether we should use SCHED_FIFO for UI and RenderThreads.
    641     private boolean mUseFifoUiScheduling = false;
    642 
    643     BroadcastQueue mFgBroadcastQueue;
    644     BroadcastQueue mBgBroadcastQueue;
    645     // Convenient for easy iteration over the queues. Foreground is first
    646     // so that dispatch of foreground broadcasts gets precedence.
    647     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
    648 
    649     BroadcastStats mLastBroadcastStats;
    650     BroadcastStats mCurBroadcastStats;
    651 
    652     BroadcastQueue broadcastQueueForIntent(Intent intent) {
    653         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
    654         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
    655                 "Broadcast intent " + intent + " on "
    656                 + (isFg ? "foreground" : "background") + " queue");
    657         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
    658     }
    659 
    660     /**
    661      * The last resumed activity. This is identical to the current resumed activity most
    662      * of the time but could be different when we're pausing one activity before we resume
    663      * another activity.
    664      */
    665     private ActivityRecord mLastResumedActivity;
    666 
    667     /**
    668      * If non-null, we are tracking the time the user spends in the currently focused app.
    669      */
    670     private AppTimeTracker mCurAppTimeTracker;
    671 
    672     /**
    673      * List of intents that were used to start the most recent tasks.
    674      */
    675     final RecentTasks mRecentTasks;
    676 
    677     /**
    678      * For addAppTask: cached of the last activity component that was added.
    679      */
    680     ComponentName mLastAddedTaskComponent;
    681 
    682     /**
    683      * For addAppTask: cached of the last activity uid that was added.
    684      */
    685     int mLastAddedTaskUid;
    686 
    687     /**
    688      * For addAppTask: cached of the last ActivityInfo that was added.
    689      */
    690     ActivityInfo mLastAddedTaskActivity;
    691 
    692     /**
    693      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
    694      */
    695     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
    696 
    697     /**
    698      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
    699      */
    700     String mDeviceOwnerName;
    701 
    702     final UserController mUserController;
    703 
    704     final AppErrors mAppErrors;
    705 
    706     /**
    707      * Dump of the activity state at the time of the last ANR. Cleared after
    708      * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
    709      */
    710     String mLastANRState;
    711 
    712     /**
    713      * Indicates the maximum time spent waiting for the network rules to get updated.
    714      */
    715     @VisibleForTesting
    716     long mWaitForNetworkTimeoutMs;
    717 
    718     public boolean canShowErrorDialogs() {
    719         return mShowDialogs && !mSleeping && !mShuttingDown
    720                 && !mKeyguardController.isKeyguardShowing();
    721     }
    722 
    723     private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
    724             THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
    725 
    726     static void boostPriorityForLockedSection() {
    727         sThreadPriorityBooster.boost();
    728     }
    729 
    730     static void resetPriorityAfterLockedSection() {
    731         sThreadPriorityBooster.reset();
    732     }
    733 
    734     public class PendingAssistExtras extends Binder implements Runnable {
    735         public final ActivityRecord activity;
    736         public boolean isHome;
    737         public final Bundle extras;
    738         public final Intent intent;
    739         public final String hint;
    740         public final IResultReceiver receiver;
    741         public final int userHandle;
    742         public boolean haveResult = false;
    743         public Bundle result = null;
    744         public AssistStructure structure = null;
    745         public AssistContent content = null;
    746         public Bundle receiverExtras;
    747 
    748         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
    749                 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
    750             activity = _activity;
    751             extras = _extras;
    752             intent = _intent;
    753             hint = _hint;
    754             receiver = _receiver;
    755             receiverExtras = _receiverExtras;
    756             userHandle = _userHandle;
    757         }
    758 
    759         @Override
    760         public void run() {
    761             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
    762             synchronized (this) {
    763                 haveResult = true;
    764                 notifyAll();
    765             }
    766             pendingAssistExtrasTimedOut(this);
    767         }
    768     }
    769 
    770     final ArrayList<PendingAssistExtras> mPendingAssistExtras
    771             = new ArrayList<PendingAssistExtras>();
    772 
    773     /**
    774      * Process management.
    775      */
    776     final ProcessList mProcessList = new ProcessList();
    777 
    778     /**
    779      * All of the applications we currently have running organized by name.
    780      * The keys are strings of the application package name (as
    781      * returned by the package manager), and the keys are ApplicationRecord
    782      * objects.
    783      */
    784     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
    785 
    786     /**
    787      * Tracking long-term execution of processes to look for abuse and other
    788      * bad app behavior.
    789      */
    790     final ProcessStatsService mProcessStats;
    791 
    792     /**
    793      * The currently running isolated processes.
    794      */
    795     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
    796 
    797     /**
    798      * Counter for assigning isolated process uids, to avoid frequently reusing the
    799      * same ones.
    800      */
    801     int mNextIsolatedProcessUid = 0;
    802 
    803     /**
    804      * The currently running heavy-weight process, if any.
    805      */
    806     ProcessRecord mHeavyWeightProcess = null;
    807 
    808     /**
    809      * Non-persistent appId whitelist for background restrictions
    810      */
    811     int[] mBackgroundAppIdWhitelist = new int[] {
    812             BLUETOOTH_UID
    813     };
    814 
    815     /**
    816      * Broadcast actions that will always be deliverable to unlaunched/background apps
    817      */
    818     ArraySet<String> mBackgroundLaunchBroadcasts;
    819 
    820     /**
    821      * All of the processes we currently have running organized by pid.
    822      * The keys are the pid running the application.
    823      *
    824      * <p>NOTE: This object is protected by its own lock, NOT the global
    825      * activity manager lock!
    826      */
    827     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
    828 
    829     /**
    830      * All of the processes that have been forced to be important.  The key
    831      * is the pid of the caller who requested it (we hold a death
    832      * link on it).
    833      */
    834     abstract class ImportanceToken implements IBinder.DeathRecipient {
    835         final int pid;
    836         final IBinder token;
    837         final String reason;
    838 
    839         ImportanceToken(int _pid, IBinder _token, String _reason) {
    840             pid = _pid;
    841             token = _token;
    842             reason = _reason;
    843         }
    844 
    845         @Override
    846         public String toString() {
    847             return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
    848                     + " " + reason + " " + pid + " " + token + " }";
    849         }
    850     }
    851     final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
    852 
    853     /**
    854      * List of records for processes that someone had tried to start before the
    855      * system was ready.  We don't start them at that point, but ensure they
    856      * are started by the time booting is complete.
    857      */
    858     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
    859 
    860     /**
    861      * List of persistent applications that are in the process
    862      * of being started.
    863      */
    864     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
    865 
    866     /**
    867      * Processes that are being forcibly torn down.
    868      */
    869     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
    870 
    871     /**
    872      * List of running applications, sorted by recent usage.
    873      * The first entry in the list is the least recently used.
    874      */
    875     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
    876 
    877     /**
    878      * Where in mLruProcesses that the processes hosting activities start.
    879      */
    880     int mLruProcessActivityStart = 0;
    881 
    882     /**
    883      * Where in mLruProcesses that the processes hosting services start.
    884      * This is after (lower index) than mLruProcessesActivityStart.
    885      */
    886     int mLruProcessServiceStart = 0;
    887 
    888     /**
    889      * List of processes that should gc as soon as things are idle.
    890      */
    891     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
    892 
    893     /**
    894      * Processes we want to collect PSS data from.
    895      */
    896     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
    897 
    898     private boolean mBinderTransactionTrackingEnabled = false;
    899 
    900     /**
    901      * Last time we requested PSS data of all processes.
    902      */
    903     long mLastFullPssTime = SystemClock.uptimeMillis();
    904 
    905     /**
    906      * If set, the next time we collect PSS data we should do a full collection
    907      * with data from native processes and the kernel.
    908      */
    909     boolean mFullPssPending = false;
    910 
    911     /**
    912      * This is the process holding what we currently consider to be
    913      * the "home" activity.
    914      */
    915     ProcessRecord mHomeProcess;
    916 
    917     /**
    918      * This is the process holding the activity the user last visited that
    919      * is in a different process from the one they are currently in.
    920      */
    921     ProcessRecord mPreviousProcess;
    922 
    923     /**
    924      * The time at which the previous process was last visible.
    925      */
    926     long mPreviousProcessVisibleTime;
    927 
    928     /**
    929      * Track all uids that have actively running processes.
    930      */
    931     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
    932 
    933     /**
    934      * This is for verifying the UID report flow.
    935      */
    936     static final boolean VALIDATE_UID_STATES = true;
    937     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
    938 
    939     /**
    940      * Packages that the user has asked to have run in screen size
    941      * compatibility mode instead of filling the screen.
    942      */
    943     final CompatModePackages mCompatModePackages;
    944 
    945     /**
    946      * Set of IntentSenderRecord objects that are currently active.
    947      */
    948     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
    949             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
    950 
    951     /**
    952      * Fingerprints (hashCode()) of stack traces that we've
    953      * already logged DropBox entries for.  Guarded by itself.  If
    954      * something (rogue user app) forces this over
    955      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
    956      */
    957     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
    958     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
    959 
    960     /**
    961      * Strict Mode background batched logging state.
    962      *
    963      * The string buffer is guarded by itself, and its lock is also
    964      * used to determine if another batched write is already
    965      * in-flight.
    966      */
    967     private final StringBuilder mStrictModeBuffer = new StringBuilder();
    968 
    969     /**
    970      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
    971      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
    972      */
    973     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
    974 
    975     /**
    976      * Resolver for broadcast intents to registered receivers.
    977      * Holds BroadcastFilter (subclass of IntentFilter).
    978      */
    979     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
    980             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
    981         @Override
    982         protected boolean allowFilterResult(
    983                 BroadcastFilter filter, List<BroadcastFilter> dest) {
    984             IBinder target = filter.receiverList.receiver.asBinder();
    985             for (int i = dest.size() - 1; i >= 0; i--) {
    986                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
    987                     return false;
    988                 }
    989             }
    990             return true;
    991         }
    992 
    993         @Override
    994         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
    995             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
    996                     || userId == filter.owningUserId) {
    997                 return super.newResult(filter, match, userId);
    998             }
    999             return null;
   1000         }
   1001 
   1002         @Override
   1003         protected BroadcastFilter[] newArray(int size) {
   1004             return new BroadcastFilter[size];
   1005         }
   1006 
   1007         @Override
   1008         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
   1009             return packageName.equals(filter.packageName);
   1010         }
   1011     };
   1012 
   1013     /**
   1014      * State of all active sticky broadcasts per user.  Keys are the action of the
   1015      * sticky Intent, values are an ArrayList of all broadcasted intents with
   1016      * that action (which should usually be one).  The SparseArray is keyed
   1017      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
   1018      * for stickies that are sent to all users.
   1019      */
   1020     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
   1021             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
   1022 
   1023     final ActiveServices mServices;
   1024 
   1025     final static class Association {
   1026         final int mSourceUid;
   1027         final String mSourceProcess;
   1028         final int mTargetUid;
   1029         final ComponentName mTargetComponent;
   1030         final String mTargetProcess;
   1031 
   1032         int mCount;
   1033         long mTime;
   1034 
   1035         int mNesting;
   1036         long mStartTime;
   1037 
   1038         // states of the source process when the bind occurred.
   1039         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
   1040         long mLastStateUptime;
   1041         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
   1042                 - ActivityManager.MIN_PROCESS_STATE+1];
   1043 
   1044         Association(int sourceUid, String sourceProcess, int targetUid,
   1045                 ComponentName targetComponent, String targetProcess) {
   1046             mSourceUid = sourceUid;
   1047             mSourceProcess = sourceProcess;
   1048             mTargetUid = targetUid;
   1049             mTargetComponent = targetComponent;
   1050             mTargetProcess = targetProcess;
   1051         }
   1052     }
   1053 
   1054     /**
   1055      * When service association tracking is enabled, this is all of the associations we
   1056      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
   1057      * -> association data.
   1058      */
   1059     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
   1060             mAssociations = new SparseArray<>();
   1061     boolean mTrackingAssociations;
   1062 
   1063     /**
   1064      * Backup/restore process management
   1065      */
   1066     String mBackupAppName = null;
   1067     BackupRecord mBackupTarget = null;
   1068 
   1069     final ProviderMap mProviderMap;
   1070 
   1071     /**
   1072      * List of content providers who have clients waiting for them.  The
   1073      * application is currently being launched and the provider will be
   1074      * removed from this list once it is published.
   1075      */
   1076     final ArrayList<ContentProviderRecord> mLaunchingProviders
   1077             = new ArrayList<ContentProviderRecord>();
   1078 
   1079     /**
   1080      * File storing persisted {@link #mGrantedUriPermissions}.
   1081      */
   1082     private final AtomicFile mGrantFile;
   1083 
   1084     /** XML constants used in {@link #mGrantFile} */
   1085     private static final String TAG_URI_GRANTS = "uri-grants";
   1086     private static final String TAG_URI_GRANT = "uri-grant";
   1087     private static final String ATTR_USER_HANDLE = "userHandle";
   1088     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
   1089     private static final String ATTR_TARGET_USER_ID = "targetUserId";
   1090     private static final String ATTR_SOURCE_PKG = "sourcePkg";
   1091     private static final String ATTR_TARGET_PKG = "targetPkg";
   1092     private static final String ATTR_URI = "uri";
   1093     private static final String ATTR_MODE_FLAGS = "modeFlags";
   1094     private static final String ATTR_CREATED_TIME = "createdTime";
   1095     private static final String ATTR_PREFIX = "prefix";
   1096 
   1097     /**
   1098      * Global set of specific {@link Uri} permissions that have been granted.
   1099      * This optimized lookup structure maps from {@link UriPermission#targetUid}
   1100      * to {@link UriPermission#uri} to {@link UriPermission}.
   1101      */
   1102     @GuardedBy("this")
   1103     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
   1104             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
   1105 
   1106     public static class GrantUri {
   1107         public final int sourceUserId;
   1108         public final Uri uri;
   1109         public boolean prefix;
   1110 
   1111         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
   1112             this.sourceUserId = sourceUserId;
   1113             this.uri = uri;
   1114             this.prefix = prefix;
   1115         }
   1116 
   1117         @Override
   1118         public int hashCode() {
   1119             int hashCode = 1;
   1120             hashCode = 31 * hashCode + sourceUserId;
   1121             hashCode = 31 * hashCode + uri.hashCode();
   1122             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
   1123             return hashCode;
   1124         }
   1125 
   1126         @Override
   1127         public boolean equals(Object o) {
   1128             if (o instanceof GrantUri) {
   1129                 GrantUri other = (GrantUri) o;
   1130                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
   1131                         && prefix == other.prefix;
   1132             }
   1133             return false;
   1134         }
   1135 
   1136         @Override
   1137         public String toString() {
   1138             String result = uri.toString() + " [user " + sourceUserId + "]";
   1139             if (prefix) result += " [prefix]";
   1140             return result;
   1141         }
   1142 
   1143         public String toSafeString() {
   1144             String result = uri.toSafeString() + " [user " + sourceUserId + "]";
   1145             if (prefix) result += " [prefix]";
   1146             return result;
   1147         }
   1148 
   1149         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
   1150             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
   1151                     ContentProvider.getUriWithoutUserId(uri), false);
   1152         }
   1153     }
   1154 
   1155     CoreSettingsObserver mCoreSettingsObserver;
   1156 
   1157     FontScaleSettingObserver mFontScaleSettingObserver;
   1158 
   1159     private final class FontScaleSettingObserver extends ContentObserver {
   1160         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
   1161 
   1162         public FontScaleSettingObserver() {
   1163             super(mHandler);
   1164             ContentResolver resolver = mContext.getContentResolver();
   1165             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
   1166         }
   1167 
   1168         @Override
   1169         public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
   1170             if (mFontScaleUri.equals(uri)) {
   1171                 updateFontScaleIfNeeded(userId);
   1172             }
   1173         }
   1174     }
   1175 
   1176     /**
   1177      * Thread-local storage used to carry caller permissions over through
   1178      * indirect content-provider access.
   1179      */
   1180     private class Identity {
   1181         public final IBinder token;
   1182         public final int pid;
   1183         public final int uid;
   1184 
   1185         Identity(IBinder _token, int _pid, int _uid) {
   1186             token = _token;
   1187             pid = _pid;
   1188             uid = _uid;
   1189         }
   1190     }
   1191 
   1192     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
   1193 
   1194     /**
   1195      * All information we have collected about the runtime performance of
   1196      * any user id that can impact battery performance.
   1197      */
   1198     final BatteryStatsService mBatteryStatsService;
   1199 
   1200     /**
   1201      * Information about component usage
   1202      */
   1203     UsageStatsManagerInternal mUsageStatsService;
   1204 
   1205     /**
   1206      * Access to DeviceIdleController service.
   1207      */
   1208     DeviceIdleController.LocalService mLocalDeviceIdleController;
   1209 
   1210     /**
   1211      * Set of app ids that are whitelisted for device idle and thus background check.
   1212      */
   1213     int[] mDeviceIdleWhitelist = new int[0];
   1214 
   1215     /**
   1216      * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
   1217      */
   1218     int[] mDeviceIdleTempWhitelist = new int[0];
   1219 
   1220     static final class PendingTempWhitelist {
   1221         final int targetUid;
   1222         final long duration;
   1223         final String tag;
   1224 
   1225         PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
   1226             targetUid = _targetUid;
   1227             duration = _duration;
   1228             tag = _tag;
   1229         }
   1230     }
   1231 
   1232     final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
   1233 
   1234     /**
   1235      * Information about and control over application operations
   1236      */
   1237     final AppOpsService mAppOpsService;
   1238 
   1239     /** Current sequencing integer of the configuration, for skipping old configurations. */
   1240     private int mConfigurationSeq;
   1241 
   1242     /**
   1243      * Temp object used when global and/or display override configuration is updated. It is also
   1244      * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
   1245      * anyone...
   1246      */
   1247     private Configuration mTempConfig = new Configuration();
   1248 
   1249     private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
   1250             new UpdateConfigurationResult();
   1251     private static final class UpdateConfigurationResult {
   1252         // Configuration changes that were updated.
   1253         int changes;
   1254         // If the activity was relaunched to match the new configuration.
   1255         boolean activityRelaunched;
   1256 
   1257         void reset() {
   1258             changes = 0;
   1259             activityRelaunched = false;
   1260         }
   1261     }
   1262 
   1263     boolean mSuppressResizeConfigChanges;
   1264 
   1265     /**
   1266      * Hardware-reported OpenGLES version.
   1267      */
   1268     final int GL_ES_VERSION;
   1269 
   1270     /**
   1271      * List of initialization arguments to pass to all processes when binding applications to them.
   1272      * For example, references to the commonly used services.
   1273      */
   1274     HashMap<String, IBinder> mAppBindArgs;
   1275     HashMap<String, IBinder> mIsolatedAppBindArgs;
   1276 
   1277     /**
   1278      * Temporary to avoid allocations.  Protected by main lock.
   1279      */
   1280     final StringBuilder mStringBuilder = new StringBuilder(256);
   1281 
   1282     /**
   1283      * Used to control how we initialize the service.
   1284      */
   1285     ComponentName mTopComponent;
   1286     String mTopAction = Intent.ACTION_MAIN;
   1287     String mTopData;
   1288 
   1289     volatile boolean mProcessesReady = false;
   1290     volatile boolean mSystemReady = false;
   1291     volatile boolean mOnBattery = false;
   1292     volatile int mFactoryTest;
   1293 
   1294     @GuardedBy("this") boolean mBooting = false;
   1295     @GuardedBy("this") boolean mCallFinishBooting = false;
   1296     @GuardedBy("this") boolean mBootAnimationComplete = false;
   1297     @GuardedBy("this") boolean mLaunchWarningShown = false;
   1298     @GuardedBy("this") boolean mCheckedForSetup = false;
   1299 
   1300     final Context mContext;
   1301 
   1302     /**
   1303      * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
   1304      * change at runtime. Use mContext for non-UI purposes.
   1305      */
   1306     final Context mUiContext;
   1307 
   1308     /**
   1309      * The time at which we will allow normal application switches again,
   1310      * after a call to {@link #stopAppSwitches()}.
   1311      */
   1312     long mAppSwitchesAllowedTime;
   1313 
   1314     /**
   1315      * This is set to true after the first switch after mAppSwitchesAllowedTime
   1316      * is set; any switches after that will clear the time.
   1317      */
   1318     boolean mDidAppSwitch;
   1319 
   1320     /**
   1321      * Last time (in realtime) at which we checked for power usage.
   1322      */
   1323     long mLastPowerCheckRealtime;
   1324 
   1325     /**
   1326      * Last time (in uptime) at which we checked for power usage.
   1327      */
   1328     long mLastPowerCheckUptime;
   1329 
   1330     /**
   1331      * Set while we are wanting to sleep, to prevent any
   1332      * activities from being started/resumed.
   1333      *
   1334      * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
   1335      *
   1336      * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
   1337      * while in the sleep state until there is a pending transition out of sleep, in which case
   1338      * mSleeping is set to false, and remains false while awake.
   1339      *
   1340      * Whether mSleeping can quickly toggled between true/false without the device actually
   1341      * display changing states is undefined.
   1342      */
   1343     private boolean mSleeping = false;
   1344 
   1345     /**
   1346      * The process state used for processes that are running the top activities.
   1347      * This changes between TOP and TOP_SLEEPING to following mSleeping.
   1348      */
   1349     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
   1350 
   1351     /**
   1352      * Set while we are running a voice interaction.  This overrides
   1353      * sleeping while it is active.
   1354      */
   1355     private IVoiceInteractionSession mRunningVoice;
   1356 
   1357     /**
   1358      * For some direct access we need to power manager.
   1359      */
   1360     PowerManagerInternal mLocalPowerManager;
   1361 
   1362     /**
   1363      * We want to hold a wake lock while running a voice interaction session, since
   1364      * this may happen with the screen off and we need to keep the CPU running to
   1365      * be able to continue to interact with the user.
   1366      */
   1367     PowerManager.WakeLock mVoiceWakeLock;
   1368 
   1369     /**
   1370      * State of external calls telling us if the device is awake or asleep.
   1371      */
   1372     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
   1373 
   1374     /**
   1375      * A list of tokens that cause the top activity to be put to sleep.
   1376      * They are used by components that may hide and block interaction with underlying
   1377      * activities.
   1378      */
   1379     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
   1380 
   1381     /**
   1382      * Set if we are shutting down the system, similar to sleeping.
   1383      */
   1384     boolean mShuttingDown = false;
   1385 
   1386     /**
   1387      * Current sequence id for oom_adj computation traversal.
   1388      */
   1389     int mAdjSeq = 0;
   1390 
   1391     /**
   1392      * Current sequence id for process LRU updating.
   1393      */
   1394     int mLruSeq = 0;
   1395 
   1396     /**
   1397      * Keep track of the non-cached/empty process we last found, to help
   1398      * determine how to distribute cached/empty processes next time.
   1399      */
   1400     int mNumNonCachedProcs = 0;
   1401 
   1402     /**
   1403      * Keep track of the number of cached hidden procs, to balance oom adj
   1404      * distribution between those and empty procs.
   1405      */
   1406     int mNumCachedHiddenProcs = 0;
   1407 
   1408     /**
   1409      * Keep track of the number of service processes we last found, to
   1410      * determine on the next iteration which should be B services.
   1411      */
   1412     int mNumServiceProcs = 0;
   1413     int mNewNumAServiceProcs = 0;
   1414     int mNewNumServiceProcs = 0;
   1415 
   1416     /**
   1417      * Allow the current computed overall memory level of the system to go down?
   1418      * This is set to false when we are killing processes for reasons other than
   1419      * memory management, so that the now smaller process list will not be taken as
   1420      * an indication that memory is tighter.
   1421      */
   1422     boolean mAllowLowerMemLevel = false;
   1423 
   1424     /**
   1425      * The last computed memory level, for holding when we are in a state that
   1426      * processes are going away for other reasons.
   1427      */
   1428     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
   1429 
   1430     /**
   1431      * The last total number of process we have, to determine if changes actually look
   1432      * like a shrinking number of process due to lower RAM.
   1433      */
   1434     int mLastNumProcesses;
   1435 
   1436     /**
   1437      * The uptime of the last time we performed idle maintenance.
   1438      */
   1439     long mLastIdleTime = SystemClock.uptimeMillis();
   1440 
   1441     /**
   1442      * Total time spent with RAM that has been added in the past since the last idle time.
   1443      */
   1444     long mLowRamTimeSinceLastIdle = 0;
   1445 
   1446     /**
   1447      * If RAM is currently low, when that horrible situation started.
   1448      */
   1449     long mLowRamStartTime = 0;
   1450 
   1451     /**
   1452      * For reporting to battery stats the current top application.
   1453      */
   1454     private String mCurResumedPackage = null;
   1455     private int mCurResumedUid = -1;
   1456 
   1457     /**
   1458      * For reporting to battery stats the apps currently running foreground
   1459      * service.  The ProcessMap is package/uid tuples; each of these contain
   1460      * an array of the currently foreground processes.
   1461      */
   1462     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
   1463             = new ProcessMap<ArrayList<ProcessRecord>>();
   1464 
   1465     /**
   1466      * This is set if we had to do a delayed dexopt of an app before launching
   1467      * it, to increase the ANR timeouts in that case.
   1468      */
   1469     boolean mDidDexOpt;
   1470 
   1471     /**
   1472      * Set if the systemServer made a call to enterSafeMode.
   1473      */
   1474     boolean mSafeMode;
   1475 
   1476     /**
   1477      * If true, we are running under a test environment so will sample PSS from processes
   1478      * much more rapidly to try to collect better data when the tests are rapidly
   1479      * running through apps.
   1480      */
   1481     boolean mTestPssMode = false;
   1482 
   1483     String mDebugApp = null;
   1484     boolean mWaitForDebugger = false;
   1485     boolean mDebugTransient = false;
   1486     String mOrigDebugApp = null;
   1487     boolean mOrigWaitForDebugger = false;
   1488     boolean mAlwaysFinishActivities = false;
   1489     boolean mForceResizableActivities;
   1490     /**
   1491      * Flag that indicates if multi-window is enabled.
   1492      *
   1493      * For any particular form of multi-window to be enabled, generic multi-window must be enabled
   1494      * in {@link com.android.internal.R.bool.config_supportsMultiWindow} config or
   1495      * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
   1496      * At least one of the forms of multi-window must be enabled in order for this flag to be
   1497      * initialized to 'true'.
   1498      *
   1499      * @see #mSupportsSplitScreenMultiWindow
   1500      * @see #mSupportsFreeformWindowManagement
   1501      * @see #mSupportsPictureInPicture
   1502      * @see #mSupportsMultiDisplay
   1503      */
   1504     boolean mSupportsMultiWindow;
   1505     boolean mSupportsSplitScreenMultiWindow;
   1506     boolean mSupportsFreeformWindowManagement;
   1507     boolean mSupportsPictureInPicture;
   1508     boolean mSupportsMultiDisplay;
   1509     boolean mSupportsLeanbackOnly;
   1510     IActivityController mController = null;
   1511     boolean mControllerIsAMonkey = false;
   1512     String mProfileApp = null;
   1513     ProcessRecord mProfileProc = null;
   1514     String mProfileFile;
   1515     ParcelFileDescriptor mProfileFd;
   1516     int mSamplingInterval = 0;
   1517     boolean mAutoStopProfiler = false;
   1518     boolean mStreamingOutput = false;
   1519     int mProfileType = 0;
   1520     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
   1521     String mMemWatchDumpProcName;
   1522     String mMemWatchDumpFile;
   1523     int mMemWatchDumpPid;
   1524     int mMemWatchDumpUid;
   1525     String mTrackAllocationApp = null;
   1526     String mNativeDebuggingApp = null;
   1527 
   1528     final long[] mTmpLong = new long[2];
   1529 
   1530     private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
   1531 
   1532     /**
   1533      * A global counter for generating sequence numbers.
   1534      * This value will be used when incrementing sequence numbers in individual uidRecords.
   1535      *
   1536      * Having a global counter ensures that seq numbers are monotonically increasing for a
   1537      * particular uid even when the uidRecord is re-created.
   1538      */
   1539     @GuardedBy("this")
   1540     @VisibleForTesting
   1541     long mProcStateSeqCounter = 0;
   1542 
   1543     private final Injector mInjector;
   1544 
   1545     static final class ProcessChangeItem {
   1546         static final int CHANGE_ACTIVITIES = 1<<0;
   1547         int changes;
   1548         int uid;
   1549         int pid;
   1550         int processState;
   1551         boolean foregroundActivities;
   1552     }
   1553 
   1554     static final class UidObserverRegistration {
   1555         final int uid;
   1556         final String pkg;
   1557         final int which;
   1558         final int cutpoint;
   1559 
   1560         final SparseIntArray lastProcStates;
   1561 
   1562         UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
   1563             uid = _uid;
   1564             pkg = _pkg;
   1565             which = _which;
   1566             cutpoint = _cutpoint;
   1567             if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
   1568                 lastProcStates = new SparseIntArray();
   1569             } else {
   1570                 lastProcStates = null;
   1571             }
   1572         }
   1573     }
   1574 
   1575     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
   1576     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
   1577 
   1578     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
   1579     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
   1580 
   1581     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
   1582     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
   1583 
   1584     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
   1585     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
   1586 
   1587     /**
   1588      * Runtime CPU use collection thread.  This object's lock is used to
   1589      * perform synchronization with the thread (notifying it to run).
   1590      */
   1591     final Thread mProcessCpuThread;
   1592 
   1593     /**
   1594      * Used to collect per-process CPU use for ANRs, battery stats, etc.
   1595      * Must acquire this object's lock when accessing it.
   1596      * NOTE: this lock will be held while doing long operations (trawling
   1597      * through all processes in /proc), so it should never be acquired by
   1598      * any critical paths such as when holding the main activity manager lock.
   1599      */
   1600     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
   1601             MONITOR_THREAD_CPU_USAGE);
   1602     final AtomicLong mLastCpuTime = new AtomicLong(0);
   1603     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
   1604     final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
   1605 
   1606     long mLastWriteTime = 0;
   1607 
   1608     /**
   1609      * Used to retain an update lock when the foreground activity is in
   1610      * immersive mode.
   1611      */
   1612     final UpdateLock mUpdateLock = new UpdateLock("immersive");
   1613 
   1614     /**
   1615      * Set to true after the system has finished booting.
   1616      */
   1617     boolean mBooted = false;
   1618 
   1619     WindowManagerService mWindowManager;
   1620     final ActivityThread mSystemThread;
   1621 
   1622     private final class AppDeathRecipient implements IBinder.DeathRecipient {
   1623         final ProcessRecord mApp;
   1624         final int mPid;
   1625         final IApplicationThread mAppThread;
   1626 
   1627         AppDeathRecipient(ProcessRecord app, int pid,
   1628                 IApplicationThread thread) {
   1629             if (DEBUG_ALL) Slog.v(
   1630                 TAG, "New death recipient " + this
   1631                 + " for thread " + thread.asBinder());
   1632             mApp = app;
   1633             mPid = pid;
   1634             mAppThread = thread;
   1635         }
   1636 
   1637         @Override
   1638         public void binderDied() {
   1639             if (DEBUG_ALL) Slog.v(
   1640                 TAG, "Death received in " + this
   1641                 + " for thread " + mAppThread.asBinder());
   1642             synchronized(ActivityManagerService.this) {
   1643                 appDiedLocked(mApp, mPid, mAppThread, true);
   1644             }
   1645         }
   1646     }
   1647 
   1648     static final int SHOW_ERROR_UI_MSG = 1;
   1649     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
   1650     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
   1651     static final int UPDATE_CONFIGURATION_MSG = 4;
   1652     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
   1653     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
   1654     static final int SERVICE_TIMEOUT_MSG = 12;
   1655     static final int UPDATE_TIME_ZONE = 13;
   1656     static final int SHOW_UID_ERROR_UI_MSG = 14;
   1657     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
   1658     static final int PROC_START_TIMEOUT_MSG = 20;
   1659     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
   1660     static final int KILL_APPLICATION_MSG = 22;
   1661     static final int FINALIZE_PENDING_INTENT_MSG = 23;
   1662     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
   1663     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
   1664     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
   1665     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
   1666     static final int CLEAR_DNS_CACHE_MSG = 28;
   1667     static final int UPDATE_HTTP_PROXY_MSG = 29;
   1668     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
   1669     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
   1670     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
   1671     static final int REPORT_MEM_USAGE_MSG = 33;
   1672     static final int REPORT_USER_SWITCH_MSG = 34;
   1673     static final int CONTINUE_USER_SWITCH_MSG = 35;
   1674     static final int USER_SWITCH_TIMEOUT_MSG = 36;
   1675     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
   1676     static final int PERSIST_URI_GRANTS_MSG = 38;
   1677     static final int REQUEST_ALL_PSS_MSG = 39;
   1678     static final int START_PROFILES_MSG = 40;
   1679     static final int UPDATE_TIME_PREFERENCE_MSG = 41;
   1680     static final int SYSTEM_USER_START_MSG = 42;
   1681     static final int SYSTEM_USER_CURRENT_MSG = 43;
   1682     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
   1683     static final int FINISH_BOOTING_MSG = 45;
   1684     static final int START_USER_SWITCH_UI_MSG = 46;
   1685     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
   1686     static final int DISMISS_DIALOG_UI_MSG = 48;
   1687     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
   1688     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
   1689     static final int DELETE_DUMPHEAP_MSG = 51;
   1690     static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
   1691     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
   1692     static final int REPORT_TIME_TRACKER_MSG = 54;
   1693     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
   1694     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
   1695     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
   1696     static final int IDLE_UIDS_MSG = 58;
   1697     static final int SYSTEM_USER_UNLOCK_MSG = 59;
   1698     static final int LOG_STACK_STATE = 60;
   1699     static final int VR_MODE_CHANGE_MSG = 61;
   1700     static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
   1701     static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
   1702     static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
   1703     static final int NOTIFY_VR_SLEEPING_MSG = 65;
   1704     static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
   1705     static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
   1706     static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
   1707     static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
   1708     static final int START_USER_SWITCH_FG_MSG = 712;
   1709 
   1710     static final int FIRST_ACTIVITY_STACK_MSG = 100;
   1711     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
   1712     static final int FIRST_COMPAT_MODE_MSG = 300;
   1713     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
   1714 
   1715     static ServiceThread sKillThread = null;
   1716     static KillHandler sKillHandler = null;
   1717 
   1718     CompatModeDialog mCompatModeDialog;
   1719     UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
   1720     long mLastMemUsageReportTime = 0;
   1721 
   1722     /**
   1723      * Flag whether the current user is a "monkey", i.e. whether
   1724      * the UI is driven by a UI automation tool.
   1725      */
   1726     private boolean mUserIsMonkey;
   1727 
   1728     /** Flag whether the device has a Recents UI */
   1729     boolean mHasRecents;
   1730 
   1731     /** The dimensions of the thumbnails in the Recents UI. */
   1732     int mThumbnailWidth;
   1733     int mThumbnailHeight;
   1734     float mFullscreenThumbnailScale;
   1735 
   1736     final ServiceThread mHandlerThread;
   1737     final MainHandler mHandler;
   1738     final Handler mUiHandler;
   1739 
   1740     final ActivityManagerConstants mConstants;
   1741 
   1742     PackageManagerInternal mPackageManagerInt;
   1743 
   1744     // VoiceInteraction session ID that changes for each new request except when
   1745     // being called for multiwindow assist in a single session.
   1746     private int mViSessionId = 1000;
   1747 
   1748     final boolean mPermissionReviewRequired;
   1749 
   1750     /**
   1751      * Current global configuration information. Contains general settings for the entire system,
   1752      * also corresponds to the merged configuration of the default display.
   1753      */
   1754     Configuration getGlobalConfiguration() {
   1755         return mStackSupervisor.getConfiguration();
   1756     }
   1757 
   1758     final class KillHandler extends Handler {
   1759         static final int KILL_PROCESS_GROUP_MSG = 4000;
   1760 
   1761         public KillHandler(Looper looper) {
   1762             super(looper, null, true);
   1763         }
   1764 
   1765         @Override
   1766         public void handleMessage(Message msg) {
   1767             switch (msg.what) {
   1768                 case KILL_PROCESS_GROUP_MSG:
   1769                 {
   1770                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
   1771                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
   1772                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   1773                 }
   1774                 break;
   1775 
   1776                 default:
   1777                     super.handleMessage(msg);
   1778             }
   1779         }
   1780     }
   1781 
   1782     final class UiHandler extends Handler {
   1783         public UiHandler() {
   1784             super(com.android.server.UiThread.get().getLooper(), null, true);
   1785         }
   1786 
   1787         @Override
   1788         public void handleMessage(Message msg) {
   1789             switch (msg.what) {
   1790             case SHOW_ERROR_UI_MSG: {
   1791                 mAppErrors.handleShowAppErrorUi(msg);
   1792                 ensureBootCompleted();
   1793             } break;
   1794             case SHOW_NOT_RESPONDING_UI_MSG: {
   1795                 mAppErrors.handleShowAnrUi(msg);
   1796                 ensureBootCompleted();
   1797             } break;
   1798             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
   1799                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
   1800                 synchronized (ActivityManagerService.this) {
   1801                     ProcessRecord proc = (ProcessRecord) data.get("app");
   1802                     if (proc == null) {
   1803                         Slog.e(TAG, "App not found when showing strict mode dialog.");
   1804                         break;
   1805                     }
   1806                     if (proc.crashDialog != null) {
   1807                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
   1808                         return;
   1809                     }
   1810                     AppErrorResult res = (AppErrorResult) data.get("result");
   1811                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
   1812                         Dialog d = new StrictModeViolationDialog(mUiContext,
   1813                                 ActivityManagerService.this, res, proc);
   1814                         d.show();
   1815                         proc.crashDialog = d;
   1816                     } else {
   1817                         // The device is asleep, so just pretend that the user
   1818                         // saw a crash dialog and hit "force quit".
   1819                         res.set(0);
   1820                     }
   1821                 }
   1822                 ensureBootCompleted();
   1823             } break;
   1824             case SHOW_FACTORY_ERROR_UI_MSG: {
   1825                 Dialog d = new FactoryErrorDialog(
   1826                         mUiContext, msg.getData().getCharSequence("msg"));
   1827                 d.show();
   1828                 ensureBootCompleted();
   1829             } break;
   1830             case WAIT_FOR_DEBUGGER_UI_MSG: {
   1831                 synchronized (ActivityManagerService.this) {
   1832                     ProcessRecord app = (ProcessRecord)msg.obj;
   1833                     if (msg.arg1 != 0) {
   1834                         if (!app.waitedForDebugger) {
   1835                             Dialog d = new AppWaitingForDebuggerDialog(
   1836                                     ActivityManagerService.this,
   1837                                     mUiContext, app);
   1838                             app.waitDialog = d;
   1839                             app.waitedForDebugger = true;
   1840                             d.show();
   1841                         }
   1842                     } else {
   1843                         if (app.waitDialog != null) {
   1844                             app.waitDialog.dismiss();
   1845                             app.waitDialog = null;
   1846                         }
   1847                     }
   1848                 }
   1849             } break;
   1850             case SHOW_UID_ERROR_UI_MSG: {
   1851                 if (mShowDialogs) {
   1852                     AlertDialog d = new BaseErrorDialog(mUiContext);
   1853                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   1854                     d.setCancelable(false);
   1855                     d.setTitle(mUiContext.getText(R.string.android_system_label));
   1856                     d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
   1857                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
   1858                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
   1859                     d.show();
   1860                 }
   1861             } break;
   1862             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
   1863                 if (mShowDialogs) {
   1864                     AlertDialog d = new BaseErrorDialog(mUiContext);
   1865                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   1866                     d.setCancelable(false);
   1867                     d.setTitle(mUiContext.getText(R.string.android_system_label));
   1868                     d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
   1869                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
   1870                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
   1871                     d.show();
   1872                 }
   1873             } break;
   1874             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
   1875                 synchronized (ActivityManagerService.this) {
   1876                     ActivityRecord ar = (ActivityRecord) msg.obj;
   1877                     if (mCompatModeDialog != null) {
   1878                         if (mCompatModeDialog.mAppInfo.packageName.equals(
   1879                                 ar.info.applicationInfo.packageName)) {
   1880                             return;
   1881                         }
   1882                         mCompatModeDialog.dismiss();
   1883                         mCompatModeDialog = null;
   1884                     }
   1885                     if (ar != null && false) {
   1886                         if (mCompatModePackages.getPackageAskCompatModeLocked(
   1887                                 ar.packageName)) {
   1888                             int mode = mCompatModePackages.computeCompatModeLocked(
   1889                                     ar.info.applicationInfo);
   1890                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
   1891                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
   1892                                 mCompatModeDialog = new CompatModeDialog(
   1893                                         ActivityManagerService.this, mUiContext,
   1894                                         ar.info.applicationInfo);
   1895                                 mCompatModeDialog.show();
   1896                             }
   1897                         }
   1898                     }
   1899                 }
   1900                 break;
   1901             }
   1902             case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
   1903                 synchronized (ActivityManagerService.this) {
   1904                     final ActivityRecord ar = (ActivityRecord) msg.obj;
   1905                     if (mUnsupportedDisplaySizeDialog != null) {
   1906                         mUnsupportedDisplaySizeDialog.dismiss();
   1907                         mUnsupportedDisplaySizeDialog = null;
   1908                     }
   1909                     if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
   1910                             ar.packageName)) {
   1911                         // TODO(multi-display): Show dialog on appropriate display.
   1912                         mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
   1913                                 ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
   1914                         mUnsupportedDisplaySizeDialog.show();
   1915                     }
   1916                 }
   1917                 break;
   1918             }
   1919             case START_USER_SWITCH_UI_MSG: {
   1920                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
   1921                 break;
   1922             }
   1923             case DISMISS_DIALOG_UI_MSG: {
   1924                 final Dialog d = (Dialog) msg.obj;
   1925                 d.dismiss();
   1926                 break;
   1927             }
   1928             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
   1929                 dispatchProcessesChanged();
   1930                 break;
   1931             }
   1932             case DISPATCH_PROCESS_DIED_UI_MSG: {
   1933                 final int pid = msg.arg1;
   1934                 final int uid = msg.arg2;
   1935                 dispatchProcessDied(pid, uid);
   1936                 break;
   1937             }
   1938             case DISPATCH_UIDS_CHANGED_UI_MSG: {
   1939                 dispatchUidsChanged();
   1940             } break;
   1941             case PUSH_TEMP_WHITELIST_UI_MSG: {
   1942                 pushTempWhitelist();
   1943             } break;
   1944             }
   1945         }
   1946     }
   1947 
   1948     final class MainHandler extends Handler {
   1949         public MainHandler(Looper looper) {
   1950             super(looper, null, true);
   1951         }
   1952 
   1953         @Override
   1954         public void handleMessage(Message msg) {
   1955             switch (msg.what) {
   1956             case UPDATE_CONFIGURATION_MSG: {
   1957                 final ContentResolver resolver = mContext.getContentResolver();
   1958                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
   1959                         msg.arg1);
   1960             } break;
   1961             case GC_BACKGROUND_PROCESSES_MSG: {
   1962                 synchronized (ActivityManagerService.this) {
   1963                     performAppGcsIfAppropriateLocked();
   1964                 }
   1965             } break;
   1966             case SERVICE_TIMEOUT_MSG: {
   1967                 if (mDidDexOpt) {
   1968                     mDidDexOpt = false;
   1969                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   1970                     nmsg.obj = msg.obj;
   1971                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
   1972                     return;
   1973                 }
   1974                 mServices.serviceTimeout((ProcessRecord)msg.obj);
   1975             } break;
   1976             case SERVICE_FOREGROUND_TIMEOUT_MSG: {
   1977                 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
   1978             } break;
   1979             case SERVICE_FOREGROUND_CRASH_MSG: {
   1980                 mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
   1981             } break;
   1982             case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
   1983                 RemoteCallbackList<IResultReceiver> callbacks
   1984                         = (RemoteCallbackList<IResultReceiver>)msg.obj;
   1985                 int N = callbacks.beginBroadcast();
   1986                 for (int i = 0; i < N; i++) {
   1987                     try {
   1988                         callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
   1989                     } catch (RemoteException e) {
   1990                     }
   1991                 }
   1992                 callbacks.finishBroadcast();
   1993             } break;
   1994             case UPDATE_TIME_ZONE: {
   1995                 synchronized (ActivityManagerService.this) {
   1996                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1997                         ProcessRecord r = mLruProcesses.get(i);
   1998                         if (r.thread != null) {
   1999                             try {
   2000                                 r.thread.updateTimeZone();
   2001                             } catch (RemoteException ex) {
   2002                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
   2003                             }
   2004                         }
   2005                     }
   2006                 }
   2007             } break;
   2008             case CLEAR_DNS_CACHE_MSG: {
   2009                 synchronized (ActivityManagerService.this) {
   2010                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   2011                         ProcessRecord r = mLruProcesses.get(i);
   2012                         if (r.thread != null) {
   2013                             try {
   2014                                 r.thread.clearDnsCache();
   2015                             } catch (RemoteException ex) {
   2016                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
   2017                             }
   2018                         }
   2019                     }
   2020                 }
   2021             } break;
   2022             case UPDATE_HTTP_PROXY_MSG: {
   2023                 ProxyInfo proxy = (ProxyInfo)msg.obj;
   2024                 String host = "";
   2025                 String port = "";
   2026                 String exclList = "";
   2027                 Uri pacFileUrl = Uri.EMPTY;
   2028                 if (proxy != null) {
   2029                     host = proxy.getHost();
   2030                     port = Integer.toString(proxy.getPort());
   2031                     exclList = proxy.getExclusionListAsString();
   2032                     pacFileUrl = proxy.getPacFileUrl();
   2033                 }
   2034                 synchronized (ActivityManagerService.this) {
   2035                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   2036                         ProcessRecord r = mLruProcesses.get(i);
   2037                         if (r.thread != null) {
   2038                             try {
   2039                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
   2040                             } catch (RemoteException ex) {
   2041                                 Slog.w(TAG, "Failed to update http proxy for: " +
   2042                                         r.info.processName);
   2043                             }
   2044                         }
   2045                     }
   2046                 }
   2047             } break;
   2048             case PROC_START_TIMEOUT_MSG: {
   2049                 if (mDidDexOpt) {
   2050                     mDidDexOpt = false;
   2051                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   2052                     nmsg.obj = msg.obj;
   2053                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
   2054                     return;
   2055                 }
   2056                 ProcessRecord app = (ProcessRecord)msg.obj;
   2057                 synchronized (ActivityManagerService.this) {
   2058                     processStartTimedOutLocked(app);
   2059                 }
   2060             } break;
   2061             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
   2062                 ProcessRecord app = (ProcessRecord)msg.obj;
   2063                 synchronized (ActivityManagerService.this) {
   2064                     processContentProviderPublishTimedOutLocked(app);
   2065                 }
   2066             } break;
   2067             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
   2068                 synchronized (ActivityManagerService.this) {
   2069                     mActivityStarter.doPendingActivityLaunchesLocked(true);
   2070                 }
   2071             } break;
   2072             case KILL_APPLICATION_MSG: {
   2073                 synchronized (ActivityManagerService.this) {
   2074                     final int appId = msg.arg1;
   2075                     final int userId = msg.arg2;
   2076                     Bundle bundle = (Bundle)msg.obj;
   2077                     String pkg = bundle.getString("pkg");
   2078                     String reason = bundle.getString("reason");
   2079                     forceStopPackageLocked(pkg, appId, false, false, true, false,
   2080                             false, userId, reason);
   2081                 }
   2082             } break;
   2083             case FINALIZE_PENDING_INTENT_MSG: {
   2084                 ((PendingIntentRecord)msg.obj).completeFinalize();
   2085             } break;
   2086             case POST_HEAVY_NOTIFICATION_MSG: {
   2087                 INotificationManager inm = NotificationManager.getService();
   2088                 if (inm == null) {
   2089                     return;
   2090                 }
   2091 
   2092                 ActivityRecord root = (ActivityRecord)msg.obj;
   2093                 ProcessRecord process = root.app;
   2094                 if (process == null) {
   2095                     return;
   2096                 }
   2097 
   2098                 try {
   2099                     Context context = mContext.createPackageContext(process.info.packageName, 0);
   2100                     String text = mContext.getString(R.string.heavy_weight_notification,
   2101                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
   2102                     Notification notification =
   2103                             new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
   2104                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
   2105                             .setWhen(0)
   2106                             .setOngoing(true)
   2107                             .setTicker(text)
   2108                             .setColor(mContext.getColor(
   2109                                     com.android.internal.R.color.system_notification_accent_color))
   2110                             .setContentTitle(text)
   2111                             .setContentText(
   2112                                     mContext.getText(R.string.heavy_weight_notification_detail))
   2113                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
   2114                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
   2115                                     new UserHandle(root.userId)))
   2116                             .build();
   2117                     try {
   2118                         inm.enqueueNotificationWithTag("android", "android", null,
   2119                                 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
   2120                                 notification, root.userId);
   2121                     } catch (RuntimeException e) {
   2122                         Slog.w(ActivityManagerService.TAG,
   2123                                 "Error showing notification for heavy-weight app", e);
   2124                     } catch (RemoteException e) {
   2125                     }
   2126                 } catch (NameNotFoundException e) {
   2127                     Slog.w(TAG, "Unable to create context for heavy notification", e);
   2128                 }
   2129             } break;
   2130             case CANCEL_HEAVY_NOTIFICATION_MSG: {
   2131                 INotificationManager inm = NotificationManager.getService();
   2132                 if (inm == null) {
   2133                     return;
   2134                 }
   2135                 try {
   2136                     inm.cancelNotificationWithTag("android", null,
   2137                             SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,  msg.arg1);
   2138                 } catch (RuntimeException e) {
   2139                     Slog.w(ActivityManagerService.TAG,
   2140                             "Error canceling notification for service", e);
   2141                 } catch (RemoteException e) {
   2142                 }
   2143             } break;
   2144             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
   2145                 synchronized (ActivityManagerService.this) {
   2146                     checkExcessivePowerUsageLocked(true);
   2147                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   2148                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   2149                     sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
   2150                 }
   2151             } break;
   2152             case REPORT_MEM_USAGE_MSG: {
   2153                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
   2154                 Thread thread = new Thread() {
   2155                     @Override public void run() {
   2156                         reportMemUsage(memInfos);
   2157                     }
   2158                 };
   2159                 thread.start();
   2160                 break;
   2161             }
   2162             case START_USER_SWITCH_FG_MSG: {
   2163                 mUserController.startUserInForeground(msg.arg1);
   2164                 break;
   2165             }
   2166             case REPORT_USER_SWITCH_MSG: {
   2167                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
   2168                 break;
   2169             }
   2170             case CONTINUE_USER_SWITCH_MSG: {
   2171                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
   2172                 break;
   2173             }
   2174             case USER_SWITCH_TIMEOUT_MSG: {
   2175                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
   2176                 break;
   2177             }
   2178             case IMMERSIVE_MODE_LOCK_MSG: {
   2179                 final boolean nextState = (msg.arg1 != 0);
   2180                 if (mUpdateLock.isHeld() != nextState) {
   2181                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
   2182                             "Applying new update lock state '" + nextState
   2183                             + "' for " + (ActivityRecord)msg.obj);
   2184                     if (nextState) {
   2185                         mUpdateLock.acquire();
   2186                     } else {
   2187                         mUpdateLock.release();
   2188                     }
   2189                 }
   2190                 break;
   2191             }
   2192             case PERSIST_URI_GRANTS_MSG: {
   2193                 writeGrantedUriPermissions();
   2194                 break;
   2195             }
   2196             case REQUEST_ALL_PSS_MSG: {
   2197                 synchronized (ActivityManagerService.this) {
   2198                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
   2199                 }
   2200                 break;
   2201             }
   2202             case START_PROFILES_MSG: {
   2203                 synchronized (ActivityManagerService.this) {
   2204                     mUserController.startProfilesLocked();
   2205                 }
   2206                 break;
   2207             }
   2208             case UPDATE_TIME_PREFERENCE_MSG: {
   2209                 // The user's time format preference might have changed.
   2210                 // For convenience we re-use the Intent extra values.
   2211                 synchronized (ActivityManagerService.this) {
   2212                     for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   2213                         ProcessRecord r = mLruProcesses.get(i);
   2214                         if (r.thread != null) {
   2215                             try {
   2216                                 r.thread.updateTimePrefs(msg.arg1);
   2217                             } catch (RemoteException ex) {
   2218                                 Slog.w(TAG, "Failed to update preferences for: "
   2219                                         + r.info.processName);
   2220                             }
   2221                         }
   2222                     }
   2223                 }
   2224                 break;
   2225             }
   2226             case SYSTEM_USER_START_MSG: {
   2227                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
   2228                         Integer.toString(msg.arg1), msg.arg1);
   2229                 mSystemServiceManager.startUser(msg.arg1);
   2230                 break;
   2231             }
   2232             case SYSTEM_USER_UNLOCK_MSG: {
   2233                 final int userId = msg.arg1;
   2234                 mSystemServiceManager.unlockUser(userId);
   2235                 synchronized (ActivityManagerService.this) {
   2236                     mRecentTasks.loadUserRecentsLocked(userId);
   2237                 }
   2238                 if (userId == UserHandle.USER_SYSTEM) {
   2239                     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
   2240                 }
   2241                 installEncryptionUnawareProviders(userId);
   2242                 mUserController.finishUserUnlocked((UserState) msg.obj);
   2243                 break;
   2244             }
   2245             case SYSTEM_USER_CURRENT_MSG: {
   2246                 mBatteryStatsService.noteEvent(
   2247                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
   2248                         Integer.toString(msg.arg2), msg.arg2);
   2249                 mBatteryStatsService.noteEvent(
   2250                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
   2251                         Integer.toString(msg.arg1), msg.arg1);
   2252                 mSystemServiceManager.switchUser(msg.arg1);
   2253                 break;
   2254             }
   2255             case ENTER_ANIMATION_COMPLETE_MSG: {
   2256                 synchronized (ActivityManagerService.this) {
   2257                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
   2258                     if (r != null && r.app != null && r.app.thread != null) {
   2259                         try {
   2260                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
   2261                         } catch (RemoteException e) {
   2262                         }
   2263                     }
   2264                 }
   2265                 break;
   2266             }
   2267             case FINISH_BOOTING_MSG: {
   2268                 if (msg.arg1 != 0) {
   2269                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
   2270                     finishBooting();
   2271                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   2272                 }
   2273                 if (msg.arg2 != 0) {
   2274                     enableScreenAfterBoot();
   2275                 }
   2276                 break;
   2277             }
   2278             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
   2279                 try {
   2280                     Locale l = (Locale) msg.obj;
   2281                     IBinder service = ServiceManager.getService("mount");
   2282                     IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
   2283                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
   2284                     storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
   2285                 } catch (RemoteException e) {
   2286                     Log.e(TAG, "Error storing locale for decryption UI", e);
   2287                 }
   2288                 break;
   2289             }
   2290             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
   2291                 final int uid = msg.arg1;
   2292                 final byte[] firstPacket = (byte[]) msg.obj;
   2293 
   2294                 synchronized (mPidsSelfLocked) {
   2295                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
   2296                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
   2297                         if (p.uid == uid) {
   2298                             try {
   2299                                 p.thread.notifyCleartextNetwork(firstPacket);
   2300                             } catch (RemoteException ignored) {
   2301                             }
   2302                         }
   2303                     }
   2304                 }
   2305                 break;
   2306             }
   2307             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
   2308                 final String procName;
   2309                 final int uid;
   2310                 final long memLimit;
   2311                 final String reportPackage;
   2312                 synchronized (ActivityManagerService.this) {
   2313                     procName = mMemWatchDumpProcName;
   2314                     uid = mMemWatchDumpUid;
   2315                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
   2316                     if (val == null) {
   2317                         val = mMemWatchProcesses.get(procName, 0);
   2318                     }
   2319                     if (val != null) {
   2320                         memLimit = val.first;
   2321                         reportPackage = val.second;
   2322                     } else {
   2323                         memLimit = 0;
   2324                         reportPackage = null;
   2325                     }
   2326                 }
   2327                 if (procName == null) {
   2328                     return;
   2329                 }
   2330 
   2331                 if (DEBUG_PSS) Slog.d(TAG_PSS,
   2332                         "Showing dump heap notification from " + procName + "/" + uid);
   2333 
   2334                 INotificationManager inm = NotificationManager.getService();
   2335                 if (inm == null) {
   2336                     return;
   2337                 }
   2338 
   2339                 String text = mContext.getString(R.string.dump_heap_notification, procName);
   2340 
   2341 
   2342                 Intent deleteIntent = new Intent();
   2343                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
   2344                 Intent intent = new Intent();
   2345                 intent.setClassName("android", DumpHeapActivity.class.getName());
   2346                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
   2347                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
   2348                 if (reportPackage != null) {
   2349                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
   2350                 }
   2351                 int userId = UserHandle.getUserId(uid);
   2352                 Notification notification =
   2353                         new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
   2354                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
   2355                         .setWhen(0)
   2356                         .setOngoing(true)
   2357                         .setAutoCancel(true)
   2358                         .setTicker(text)
   2359                         .setColor(mContext.getColor(
   2360                                 com.android.internal.R.color.system_notification_accent_color))
   2361                         .setContentTitle(text)
   2362                         .setContentText(
   2363                                 mContext.getText(R.string.dump_heap_notification_detail))
   2364                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
   2365                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
   2366                                 new UserHandle(userId)))
   2367                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
   2368                                 deleteIntent, 0, UserHandle.SYSTEM))
   2369                         .build();
   2370 
   2371                 try {
   2372                     inm.enqueueNotificationWithTag("android", "android", null,
   2373                             SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
   2374                             notification, userId);
   2375                 } catch (RuntimeException e) {
   2376                     Slog.w(ActivityManagerService.TAG,
   2377                             "Error showing notification for dump heap", e);
   2378                 } catch (RemoteException e) {
   2379                 }
   2380             } break;
   2381             case DELETE_DUMPHEAP_MSG: {
   2382                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
   2383                         null, DumpHeapActivity.JAVA_URI,
   2384                         Intent.FLAG_GRANT_READ_URI_PERMISSION
   2385                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
   2386                         UserHandle.myUserId());
   2387                 synchronized (ActivityManagerService.this) {
   2388                     mMemWatchDumpFile = null;
   2389                     mMemWatchDumpProcName = null;
   2390                     mMemWatchDumpPid = -1;
   2391                     mMemWatchDumpUid = -1;
   2392                 }
   2393             } break;
   2394             case FOREGROUND_PROFILE_CHANGED_MSG: {
   2395                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
   2396             } break;
   2397             case REPORT_TIME_TRACKER_MSG: {
   2398                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
   2399                 tracker.deliverResult(mContext);
   2400             } break;
   2401             case REPORT_USER_SWITCH_COMPLETE_MSG: {
   2402                 mUserController.dispatchUserSwitchComplete(msg.arg1);
   2403             } break;
   2404             case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
   2405                 mUserController.dispatchLockedBootComplete(msg.arg1);
   2406             } break;
   2407             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
   2408                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
   2409                 try {
   2410                     connection.shutdown();
   2411                 } catch (RemoteException e) {
   2412                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
   2413                 }
   2414                 // Only a UiAutomation can set this flag and now that
   2415                 // it is finished we make sure it is reset to its default.
   2416                 mUserIsMonkey = false;
   2417             } break;
   2418             case IDLE_UIDS_MSG: {
   2419                 idleUids();
   2420             } break;
   2421             case VR_MODE_CHANGE_MSG: {
   2422                 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
   2423                     return;
   2424                 }
   2425                 synchronized (ActivityManagerService.this) {
   2426                     final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
   2427                     mWindowManager.disableNonVrUi(disableNonVrUi);
   2428                     if (disableNonVrUi) {
   2429                         // If we are in a VR mode where Picture-in-Picture mode is unsupported,
   2430                         // then remove the pinned stack.
   2431                         final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
   2432                                 PINNED_STACK_ID);
   2433                         if (pinnedStack != null) {
   2434                             mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
   2435                         }
   2436                     }
   2437                 }
   2438             } break;
   2439             case NOTIFY_VR_SLEEPING_MSG: {
   2440                 notifyVrManagerOfSleepState(msg.arg1 != 0);
   2441             } break;
   2442             case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
   2443                 synchronized (ActivityManagerService.this) {
   2444                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   2445                         ProcessRecord r = mLruProcesses.get(i);
   2446                         if (r.thread != null) {
   2447                             try {
   2448                                 r.thread.handleTrustStorageUpdate();
   2449                             } catch (RemoteException ex) {
   2450                                 Slog.w(TAG, "Failed to handle trust storage update for: " +
   2451                                         r.info.processName);
   2452                             }
   2453                         }
   2454                     }
   2455                 }
   2456             } break;
   2457             }
   2458         }
   2459     };
   2460 
   2461     static final int COLLECT_PSS_BG_MSG = 1;
   2462 
   2463     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
   2464         @Override
   2465         public void handleMessage(Message msg) {
   2466             switch (msg.what) {
   2467             case COLLECT_PSS_BG_MSG: {
   2468                 long start = SystemClock.uptimeMillis();
   2469                 MemInfoReader memInfo = null;
   2470                 synchronized (ActivityManagerService.this) {
   2471                     if (mFullPssPending) {
   2472                         mFullPssPending = false;
   2473                         memInfo = new MemInfoReader();
   2474                     }
   2475                 }
   2476                 if (memInfo != null) {
   2477                     updateCpuStatsNow();
   2478                     long nativeTotalPss = 0;
   2479                     final List<ProcessCpuTracker.Stats> stats;
   2480                     synchronized (mProcessCpuTracker) {
   2481                         stats = mProcessCpuTracker.getStats( (st)-> {
   2482                             return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
   2483                         });
   2484                     }
   2485                     final int N = stats.size();
   2486                     for (int j = 0; j < N; j++) {
   2487                         synchronized (mPidsSelfLocked) {
   2488                             if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
   2489                                 // This is one of our own processes; skip it.
   2490                                 continue;
   2491                             }
   2492                         }
   2493                         nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
   2494                     }
   2495                     memInfo.readMemInfo();
   2496                     synchronized (ActivityManagerService.this) {
   2497                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
   2498                                 + (SystemClock.uptimeMillis()-start) + "ms");
   2499                         final long cachedKb = memInfo.getCachedSizeKb();
   2500                         final long freeKb = memInfo.getFreeSizeKb();
   2501                         final long zramKb = memInfo.getZramTotalSizeKb();
   2502                         final long kernelKb = memInfo.getKernelUsedSizeKb();
   2503                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
   2504                                 kernelKb*1024, nativeTotalPss*1024);
   2505                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
   2506                                 nativeTotalPss);
   2507                     }
   2508                 }
   2509 
   2510                 int num = 0;
   2511                 long[] tmp = new long[2];
   2512                 do {
   2513                     ProcessRecord proc;
   2514                     int procState;
   2515                     int pid;
   2516                     long lastPssTime;
   2517                     synchronized (ActivityManagerService.this) {
   2518                         if (mPendingPssProcesses.size() <= 0) {
   2519                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
   2520                                     "Collected PSS of " + num + " processes in "
   2521                                     + (SystemClock.uptimeMillis() - start) + "ms");
   2522                             mPendingPssProcesses.clear();
   2523                             return;
   2524                         }
   2525                         proc = mPendingPssProcesses.remove(0);
   2526                         procState = proc.pssProcState;
   2527                         lastPssTime = proc.lastPssTime;
   2528                         if (proc.thread != null && procState == proc.setProcState
   2529                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
   2530                                         < SystemClock.uptimeMillis()) {
   2531                             pid = proc.pid;
   2532                         } else {
   2533                             proc = null;
   2534                             pid = 0;
   2535                         }
   2536                     }
   2537                     if (proc != null) {
   2538                         long pss = Debug.getPss(pid, tmp, null);
   2539                         synchronized (ActivityManagerService.this) {
   2540                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
   2541                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
   2542                                 num++;
   2543                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
   2544                                         SystemClock.uptimeMillis());
   2545                             }
   2546                         }
   2547                     }
   2548                 } while (true);
   2549             }
   2550             }
   2551         }
   2552     };
   2553 
   2554     public void setSystemProcess() {
   2555         try {
   2556             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
   2557             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
   2558             ServiceManager.addService("meminfo", new MemBinder(this));
   2559             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
   2560             ServiceManager.addService("dbinfo", new DbBinder(this));
   2561             if (MONITOR_CPU_USAGE) {
   2562                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
   2563             }
   2564             ServiceManager.addService("permission", new PermissionController(this));
   2565             ServiceManager.addService("processinfo", new ProcessInfoService(this));
   2566 
   2567             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
   2568                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
   2569             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
   2570 
   2571             synchronized (this) {
   2572                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
   2573                 app.persistent = true;
   2574                 app.pid = MY_PID;
   2575                 app.maxAdj = ProcessList.SYSTEM_ADJ;
   2576                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
   2577                 synchronized (mPidsSelfLocked) {
   2578                     mPidsSelfLocked.put(app.pid, app);
   2579                 }
   2580                 updateLruProcessLocked(app, false, null);
   2581                 updateOomAdjLocked();
   2582             }
   2583         } catch (PackageManager.NameNotFoundException e) {
   2584             throw new RuntimeException(
   2585                     "Unable to find android system package", e);
   2586         }
   2587     }
   2588 
   2589     public void setWindowManager(WindowManagerService wm) {
   2590         mWindowManager = wm;
   2591         mStackSupervisor.setWindowManager(wm);
   2592         mActivityStarter.setWindowManager(wm);
   2593     }
   2594 
   2595     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
   2596         mUsageStatsService = usageStatsManager;
   2597     }
   2598 
   2599     public void startObservingNativeCrashes() {
   2600         final NativeCrashListener ncl = new NativeCrashListener(this);
   2601         ncl.start();
   2602     }
   2603 
   2604     public IAppOpsService getAppOpsService() {
   2605         return mAppOpsService;
   2606     }
   2607 
   2608     static class MemBinder extends Binder {
   2609         ActivityManagerService mActivityManagerService;
   2610         MemBinder(ActivityManagerService activityManagerService) {
   2611             mActivityManagerService = activityManagerService;
   2612         }
   2613 
   2614         @Override
   2615         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2616             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
   2617                     "meminfo", pw)) return;
   2618             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
   2619         }
   2620     }
   2621 
   2622     static class GraphicsBinder extends Binder {
   2623         ActivityManagerService mActivityManagerService;
   2624         GraphicsBinder(ActivityManagerService activityManagerService) {
   2625             mActivityManagerService = activityManagerService;
   2626         }
   2627 
   2628         @Override
   2629         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2630             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
   2631                     "gfxinfo", pw)) return;
   2632             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
   2633         }
   2634     }
   2635 
   2636     static class DbBinder extends Binder {
   2637         ActivityManagerService mActivityManagerService;
   2638         DbBinder(ActivityManagerService activityManagerService) {
   2639             mActivityManagerService = activityManagerService;
   2640         }
   2641 
   2642         @Override
   2643         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2644             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
   2645                     "dbinfo", pw)) return;
   2646             mActivityManagerService.dumpDbInfo(fd, pw, args);
   2647         }
   2648     }
   2649 
   2650     static class CpuBinder extends Binder {
   2651         ActivityManagerService mActivityManagerService;
   2652         CpuBinder(ActivityManagerService activityManagerService) {
   2653             mActivityManagerService = activityManagerService;
   2654         }
   2655 
   2656         @Override
   2657         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2658             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
   2659                     "cpuinfo", pw)) return;
   2660             synchronized (mActivityManagerService.mProcessCpuTracker) {
   2661                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
   2662                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
   2663                         SystemClock.uptimeMillis()));
   2664             }
   2665         }
   2666     }
   2667 
   2668     public static final class Lifecycle extends SystemService {
   2669         private final ActivityManagerService mService;
   2670 
   2671         public Lifecycle(Context context) {
   2672             super(context);
   2673             mService = new ActivityManagerService(context);
   2674         }
   2675 
   2676         @Override
   2677         public void onStart() {
   2678             mService.start();
   2679         }
   2680 
   2681         public ActivityManagerService getService() {
   2682             return mService;
   2683         }
   2684     }
   2685 
   2686     @VisibleForTesting
   2687     public ActivityManagerService(Injector injector) {
   2688         mInjector = injector;
   2689         mContext = mInjector.getContext();
   2690         mUiContext = null;
   2691         GL_ES_VERSION = 0;
   2692         mActivityStarter = null;
   2693         mAppErrors = null;
   2694         mAppOpsService = mInjector.getAppOpsService(null, null);
   2695         mBatteryStatsService = null;
   2696         mCompatModePackages = null;
   2697         mConstants = null;
   2698         mGrantFile = null;
   2699         mHandler = null;
   2700         mHandlerThread = null;
   2701         mIntentFirewall = null;
   2702         mKeyguardController = null;
   2703         mPermissionReviewRequired = false;
   2704         mProcessCpuThread = null;
   2705         mProcessStats = null;
   2706         mProviderMap = null;
   2707         mRecentTasks = null;
   2708         mServices = null;
   2709         mStackSupervisor = null;
   2710         mSystemThread = null;
   2711         mTaskChangeNotificationController = null;
   2712         mUiHandler = injector.getUiHandler(null);
   2713         mUserController = null;
   2714         mVrController = null;
   2715     }
   2716 
   2717     // Note: This method is invoked on the main thread but may need to attach various
   2718     // handlers to other threads.  So take care to be explicit about the looper.
   2719     public ActivityManagerService(Context systemContext) {
   2720         LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
   2721         mInjector = new Injector();
   2722         mContext = systemContext;
   2723 
   2724         mFactoryTest = FactoryTest.getMode();
   2725         mSystemThread = ActivityThread.currentActivityThread();
   2726         mUiContext = mSystemThread.getSystemUiContext();
   2727 
   2728         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
   2729 
   2730         mPermissionReviewRequired = mContext.getResources().getBoolean(
   2731                 com.android.internal.R.bool.config_permissionReviewRequired);
   2732 
   2733         mHandlerThread = new ServiceThread(TAG,
   2734                 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
   2735         mHandlerThread.start();
   2736         mHandler = new MainHandler(mHandlerThread.getLooper());
   2737         mUiHandler = mInjector.getUiHandler(this);
   2738 
   2739         mConstants = new ActivityManagerConstants(this, mHandler);
   2740 
   2741         /* static; one-time init here */
   2742         if (sKillHandler == null) {
   2743             sKillThread = new ServiceThread(TAG + ":kill",
   2744                     THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
   2745             sKillThread.start();
   2746             sKillHandler = new KillHandler(sKillThread.getLooper());
   2747         }
   2748 
   2749         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
   2750                 "foreground", BROADCAST_FG_TIMEOUT, false);
   2751         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
   2752                 "background", BROADCAST_BG_TIMEOUT, true);
   2753         mBroadcastQueues[0] = mFgBroadcastQueue;
   2754         mBroadcastQueues[1] = mBgBroadcastQueue;
   2755 
   2756         mServices = new ActiveServices(this);
   2757         mProviderMap = new ProviderMap(this);
   2758         mAppErrors = new AppErrors(mUiContext, this);
   2759 
   2760         // TODO: Move creation of battery stats service outside of activity manager service.
   2761         File dataDir = Environment.getDataDirectory();
   2762         File systemDir = new File(dataDir, "system");
   2763         systemDir.mkdirs();
   2764         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
   2765         mBatteryStatsService.getActiveStatistics().readLocked();
   2766         mBatteryStatsService.scheduleWriteToDisk();
   2767         mOnBattery = DEBUG_POWER ? true
   2768                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
   2769         mBatteryStatsService.getActiveStatistics().setCallback(this);
   2770 
   2771         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
   2772 
   2773         mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
   2774         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
   2775                 new IAppOpsCallback.Stub() {
   2776                     @Override public void opChanged(int op, int uid, String packageName) {
   2777                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
   2778                             if (mAppOpsService.checkOperation(op, uid, packageName)
   2779                                     != AppOpsManager.MODE_ALLOWED) {
   2780                                 runInBackgroundDisabled(uid);
   2781                             }
   2782                         }
   2783                     }
   2784                 });
   2785 
   2786         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
   2787 
   2788         mUserController = new UserController(this);
   2789 
   2790         mVrController = new VrController(this);
   2791 
   2792         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
   2793             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
   2794 
   2795         if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
   2796             mUseFifoUiScheduling = true;
   2797         }
   2798 
   2799         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
   2800         mTempConfig.setToDefaults();
   2801         mTempConfig.setLocales(LocaleList.getDefault());
   2802         mConfigurationSeq = mTempConfig.seq = 1;
   2803         mStackSupervisor = createStackSupervisor();
   2804         mStackSupervisor.onConfigurationChanged(mTempConfig);
   2805         mKeyguardController = mStackSupervisor.mKeyguardController;
   2806         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
   2807         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
   2808         mTaskChangeNotificationController =
   2809                 new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
   2810         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
   2811         mRecentTasks = new RecentTasks(this, mStackSupervisor);
   2812 
   2813         mProcessCpuThread = new Thread("CpuTracker") {
   2814             @Override
   2815             public void run() {
   2816                 synchronized (mProcessCpuTracker) {
   2817                     mProcessCpuInitLatch.countDown();
   2818                     mProcessCpuTracker.init();
   2819                 }
   2820                 while (true) {
   2821                     try {
   2822                         try {
   2823                             synchronized(this) {
   2824                                 final long now = SystemClock.uptimeMillis();
   2825                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
   2826                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
   2827                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
   2828                                 //        + ", write delay=" + nextWriteDelay);
   2829                                 if (nextWriteDelay < nextCpuDelay) {
   2830                                     nextCpuDelay = nextWriteDelay;
   2831                                 }
   2832                                 if (nextCpuDelay > 0) {
   2833                                     mProcessCpuMutexFree.set(true);
   2834                                     this.wait(nextCpuDelay);
   2835                                 }
   2836                             }
   2837                         } catch (InterruptedException e) {
   2838                         }
   2839                         updateCpuStatsNow();
   2840                     } catch (Exception e) {
   2841                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
   2842                     }
   2843                 }
   2844             }
   2845         };
   2846 
   2847         Watchdog.getInstance().addMonitor(this);
   2848         Watchdog.getInstance().addThread(mHandler);
   2849     }
   2850 
   2851     protected ActivityStackSupervisor createStackSupervisor() {
   2852         return new ActivityStackSupervisor(this, mHandler.getLooper());
   2853     }
   2854 
   2855     public void setSystemServiceManager(SystemServiceManager mgr) {
   2856         mSystemServiceManager = mgr;
   2857     }
   2858 
   2859     public void setInstaller(Installer installer) {
   2860         mInstaller = installer;
   2861     }
   2862 
   2863     private void start() {
   2864         removeAllProcessGroups();
   2865         mProcessCpuThread.start();
   2866 
   2867         mBatteryStatsService.publish(mContext);
   2868         mAppOpsService.publish(mContext);
   2869         Slog.d("AppOps", "AppOpsService published");
   2870         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
   2871         // Wait for the synchronized block started in mProcessCpuThread,
   2872         // so that any other acccess to mProcessCpuTracker from main thread
   2873         // will be blocked during mProcessCpuTracker initialization.
   2874         try {
   2875             mProcessCpuInitLatch.await();
   2876         } catch (InterruptedException e) {
   2877             Slog.wtf(TAG, "Interrupted wait during start", e);
   2878             Thread.currentThread().interrupt();
   2879             throw new IllegalStateException("Interrupted wait during start");
   2880         }
   2881     }
   2882 
   2883     void onUserStoppedLocked(int userId) {
   2884         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
   2885     }
   2886 
   2887     public void initPowerManagement() {
   2888         mStackSupervisor.initPowerManagement();
   2889         mBatteryStatsService.initPowerManagement();
   2890         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
   2891         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
   2892         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
   2893         mVoiceWakeLock.setReferenceCounted(false);
   2894     }
   2895 
   2896     private ArraySet<String> getBackgroundLaunchBroadcasts() {
   2897         if (mBackgroundLaunchBroadcasts == null) {
   2898             mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
   2899         }
   2900         return mBackgroundLaunchBroadcasts;
   2901     }
   2902 
   2903     @Override
   2904     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   2905             throws RemoteException {
   2906         if (code == SYSPROPS_TRANSACTION) {
   2907             // We need to tell all apps about the system property change.
   2908             ArrayList<IBinder> procs = new ArrayList<IBinder>();
   2909             synchronized(this) {
   2910                 final int NP = mProcessNames.getMap().size();
   2911                 for (int ip=0; ip<NP; ip++) {
   2912                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   2913                     final int NA = apps.size();
   2914                     for (int ia=0; ia<NA; ia++) {
   2915                         ProcessRecord app = apps.valueAt(ia);
   2916                         if (app.thread != null) {
   2917                             procs.add(app.thread.asBinder());
   2918                         }
   2919                     }
   2920                 }
   2921             }
   2922 
   2923             int N = procs.size();
   2924             for (int i=0; i<N; i++) {
   2925                 Parcel data2 = Parcel.obtain();
   2926                 try {
   2927                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
   2928                             Binder.FLAG_ONEWAY);
   2929                 } catch (RemoteException e) {
   2930                 }
   2931                 data2.recycle();
   2932             }
   2933         }
   2934         try {
   2935             return super.onTransact(code, data, reply, flags);
   2936         } catch (RuntimeException e) {
   2937             // The activity manager only throws security exceptions, so let's
   2938             // log all others.
   2939             if (!(e instanceof SecurityException)) {
   2940                 Slog.wtf(TAG, "Activity Manager Crash."
   2941                         + " UID:" + Binder.getCallingUid()
   2942                         + " PID:" + Binder.getCallingPid()
   2943                         + " TRANS:" + code, e);
   2944             }
   2945             throw e;
   2946         }
   2947     }
   2948 
   2949     void updateCpuStats() {
   2950         final long now = SystemClock.uptimeMillis();
   2951         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
   2952             return;
   2953         }
   2954         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
   2955             synchronized (mProcessCpuThread) {
   2956                 mProcessCpuThread.notify();
   2957             }
   2958         }
   2959     }
   2960 
   2961     void updateCpuStatsNow() {
   2962         synchronized (mProcessCpuTracker) {
   2963             mProcessCpuMutexFree.set(false);
   2964             final long now = SystemClock.uptimeMillis();
   2965             boolean haveNewCpuStats = false;
   2966 
   2967             if (MONITOR_CPU_USAGE &&
   2968                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
   2969                 mLastCpuTime.set(now);
   2970                 mProcessCpuTracker.update();
   2971                 if (mProcessCpuTracker.hasGoodLastStats()) {
   2972                     haveNewCpuStats = true;
   2973                     //Slog.i(TAG, mProcessCpu.printCurrentState());
   2974                     //Slog.i(TAG, "Total CPU usage: "
   2975                     //        + mProcessCpu.getTotalCpuPercent() + "%");
   2976 
   2977                     // Slog the cpu usage if the property is set.
   2978                     if ("true".equals(SystemProperties.get("events.cpu"))) {
   2979                         int user = mProcessCpuTracker.getLastUserTime();
   2980                         int system = mProcessCpuTracker.getLastSystemTime();
   2981                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
   2982                         int irq = mProcessCpuTracker.getLastIrqTime();
   2983                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
   2984                         int idle = mProcessCpuTracker.getLastIdleTime();
   2985 
   2986                         int total = user + system + iowait + irq + softIrq + idle;
   2987                         if (total == 0) total = 1;
   2988 
   2989                         EventLog.writeEvent(EventLogTags.CPU,
   2990                                 ((user+system+iowait+irq+softIrq) * 100) / total,
   2991                                 (user * 100) / total,
   2992                                 (system * 100) / total,
   2993                                 (iowait * 100) / total,
   2994                                 (irq * 100) / total,
   2995                                 (softIrq * 100) / total);
   2996                     }
   2997                 }
   2998             }
   2999 
   3000             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
   3001             synchronized(bstats) {
   3002                 synchronized(mPidsSelfLocked) {
   3003                     if (haveNewCpuStats) {
   3004                         if (bstats.startAddingCpuLocked()) {
   3005                             int totalUTime = 0;
   3006                             int totalSTime = 0;
   3007                             final int N = mProcessCpuTracker.countStats();
   3008                             for (int i=0; i<N; i++) {
   3009                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   3010                                 if (!st.working) {
   3011                                     continue;
   3012                                 }
   3013                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
   3014                                 totalUTime += st.rel_utime;
   3015                                 totalSTime += st.rel_stime;
   3016                                 if (pr != null) {
   3017                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
   3018                                     if (ps == null || !ps.isActive()) {
   3019                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
   3020                                                 pr.info.uid, pr.processName);
   3021                                     }
   3022                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
   3023                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
   3024                                 } else {
   3025                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
   3026                                     if (ps == null || !ps.isActive()) {
   3027                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
   3028                                                 bstats.mapUid(st.uid), st.name);
   3029                                     }
   3030                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
   3031                                 }
   3032                             }
   3033                             final int userTime = mProcessCpuTracker.getLastUserTime();
   3034                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
   3035                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
   3036                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
   3037                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
   3038                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
   3039                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
   3040                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
   3041                         }
   3042                     }
   3043                 }
   3044 
   3045                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
   3046                     mLastWriteTime = now;
   3047                     mBatteryStatsService.scheduleWriteToDisk();
   3048                 }
   3049             }
   3050         }
   3051     }
   3052 
   3053     @Override
   3054     public void batteryNeedsCpuUpdate() {
   3055         updateCpuStatsNow();
   3056     }
   3057 
   3058     @Override
   3059     public void batteryPowerChanged(boolean onBattery) {
   3060         // When plugging in, update the CPU stats first before changing
   3061         // the plug state.
   3062         updateCpuStatsNow();
   3063         synchronized (this) {
   3064             synchronized(mPidsSelfLocked) {
   3065                 mOnBattery = DEBUG_POWER ? true : onBattery;
   3066             }
   3067         }
   3068     }
   3069 
   3070     @Override
   3071     public void batterySendBroadcast(Intent intent) {
   3072         synchronized (this) {
   3073             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
   3074                     AppOpsManager.OP_NONE, null, false, false,
   3075                     -1, SYSTEM_UID, UserHandle.USER_ALL);
   3076         }
   3077     }
   3078 
   3079     /**
   3080      * Initialize the application bind args. These are passed to each
   3081      * process when the bindApplication() IPC is sent to the process. They're
   3082      * lazily setup to make sure the services are running when they're asked for.
   3083      */
   3084     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
   3085         // Isolated processes won't get this optimization, so that we don't
   3086         // violate the rules about which services they have access to.
   3087         if (isolated) {
   3088             if (mIsolatedAppBindArgs == null) {
   3089                 mIsolatedAppBindArgs = new HashMap<>();
   3090                 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
   3091             }
   3092             return mIsolatedAppBindArgs;
   3093         }
   3094 
   3095         if (mAppBindArgs == null) {
   3096             mAppBindArgs = new HashMap<>();
   3097 
   3098             // Setup the application init args
   3099             mAppBindArgs.put("package", ServiceManager.getService("package"));
   3100             mAppBindArgs.put("window", ServiceManager.getService("window"));
   3101             mAppBindArgs.put(Context.ALARM_SERVICE,
   3102                     ServiceManager.getService(Context.ALARM_SERVICE));
   3103         }
   3104         return mAppBindArgs;
   3105     }
   3106 
   3107     /**
   3108      * Update AMS states when an activity is resumed. This should only be called by
   3109      * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
   3110      */
   3111     void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
   3112         final TaskRecord task = r.getTask();
   3113         if (task.isApplicationTask()) {
   3114             if (mCurAppTimeTracker != r.appTimeTracker) {
   3115                 // We are switching app tracking.  Complete the current one.
   3116                 if (mCurAppTimeTracker != null) {
   3117                     mCurAppTimeTracker.stop();
   3118                     mHandler.obtainMessage(
   3119                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
   3120                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
   3121                     mCurAppTimeTracker = null;
   3122                 }
   3123                 if (r.appTimeTracker != null) {
   3124                     mCurAppTimeTracker = r.appTimeTracker;
   3125                     startTimeTrackingFocusedActivityLocked();
   3126                 }
   3127             } else {
   3128                 startTimeTrackingFocusedActivityLocked();
   3129             }
   3130         } else {
   3131             r.appTimeTracker = null;
   3132         }
   3133         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
   3134         // TODO: Probably not, because we don't want to resume voice on switching
   3135         // back to this activity
   3136         if (task.voiceInteractor != null) {
   3137             startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
   3138         } else {
   3139             finishRunningVoiceLocked();
   3140 
   3141             if (mLastResumedActivity != null) {
   3142                 final IVoiceInteractionSession session;
   3143 
   3144                 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
   3145                 if (lastResumedActivityTask != null
   3146                         && lastResumedActivityTask.voiceSession != null) {
   3147                     session = lastResumedActivityTask.voiceSession;
   3148                 } else {
   3149                     session = mLastResumedActivity.voiceSession;
   3150                 }
   3151 
   3152                 if (session != null) {
   3153                     // We had been in a voice interaction session, but now focused has
   3154                     // move to something different.  Just finish the session, we can't
   3155                     // return to it and retain the proper state and synchronization with
   3156                     // the voice interaction service.
   3157                     finishVoiceTask(session);
   3158                 }
   3159             }
   3160         }
   3161 
   3162         if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
   3163             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
   3164             mHandler.obtainMessage(
   3165                     FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
   3166         }
   3167         mLastResumedActivity = r;
   3168 
   3169         mWindowManager.setFocusedApp(r.appToken, true);
   3170 
   3171         applyUpdateLockStateLocked(r);
   3172         applyUpdateVrModeLocked(r);
   3173 
   3174         EventLogTags.writeAmSetResumedActivity(
   3175                 r == null ? -1 : r.userId,
   3176                 r == null ? "NULL" : r.shortComponentName,
   3177                 reason);
   3178     }
   3179 
   3180     @Override
   3181     public void setFocusedStack(int stackId) {
   3182         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
   3183         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
   3184         final long callingId = Binder.clearCallingIdentity();
   3185         try {
   3186             synchronized (this) {
   3187                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
   3188                 if (stack == null) {
   3189                     return;
   3190                 }
   3191                 final ActivityRecord r = stack.topRunningActivityLocked();
   3192                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
   3193                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
   3194                 }
   3195             }
   3196         } finally {
   3197             Binder.restoreCallingIdentity(callingId);
   3198         }
   3199     }
   3200 
   3201     @Override
   3202     public void setFocusedTask(int taskId) {
   3203         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
   3204         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
   3205         final long callingId = Binder.clearCallingIdentity();
   3206         try {
   3207             synchronized (this) {
   3208                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   3209                 if (task == null) {
   3210                     return;
   3211                 }
   3212                 final ActivityRecord r = task.topRunningActivityLocked();
   3213                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
   3214                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
   3215                 }
   3216             }
   3217         } finally {
   3218             Binder.restoreCallingIdentity(callingId);
   3219         }
   3220     }
   3221 
   3222     /** Sets the task stack listener that gets callbacks when a task stack changes. */
   3223     @Override
   3224     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
   3225         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
   3226         mTaskChangeNotificationController.registerTaskStackListener(listener);
   3227     }
   3228 
   3229     /**
   3230      * Unregister a task stack listener so that it stops receiving callbacks.
   3231      */
   3232     @Override
   3233     public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
   3234          enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
   3235          mTaskChangeNotificationController.unregisterTaskStackListener(listener);
   3236      }
   3237 
   3238     @Override
   3239     public void notifyActivityDrawn(IBinder token) {
   3240         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
   3241         synchronized (this) {
   3242             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
   3243             if (r != null) {
   3244                 r.getStack().notifyActivityDrawnLocked(r);
   3245             }
   3246         }
   3247     }
   3248 
   3249     final void applyUpdateLockStateLocked(ActivityRecord r) {
   3250         // Modifications to the UpdateLock state are done on our handler, outside
   3251         // the activity manager's locks.  The new state is determined based on the
   3252         // state *now* of the relevant activity record.  The object is passed to
   3253         // the handler solely for logging detail, not to be consulted/modified.
   3254         final boolean nextState = r != null && r.immersive;
   3255         mHandler.sendMessage(
   3256                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
   3257     }
   3258 
   3259     final void applyUpdateVrModeLocked(ActivityRecord r) {
   3260         mHandler.sendMessage(
   3261                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
   3262     }
   3263 
   3264     private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
   3265         mHandler.sendMessage(
   3266                 mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
   3267     }
   3268 
   3269     private void notifyVrManagerOfSleepState(boolean isSleeping) {
   3270         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
   3271         if (vrService == null) {
   3272             return;
   3273         }
   3274         vrService.onSleepStateChanged(isSleeping);
   3275     }
   3276 
   3277     final void showAskCompatModeDialogLocked(ActivityRecord r) {
   3278         Message msg = Message.obtain();
   3279         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
   3280         msg.obj = r.getTask().askedCompatMode ? null : r;
   3281         mUiHandler.sendMessage(msg);
   3282     }
   3283 
   3284     final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
   3285         final Configuration globalConfig = getGlobalConfiguration();
   3286         if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
   3287                 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
   3288             final Message msg = Message.obtain();
   3289             msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
   3290             msg.obj = r;
   3291             mUiHandler.sendMessage(msg);
   3292         }
   3293     }
   3294 
   3295     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
   3296             String what, Object obj, ProcessRecord srcApp) {
   3297         app.lastActivityTime = now;
   3298 
   3299         if (app.activities.size() > 0) {
   3300             // Don't want to touch dependent processes that are hosting activities.
   3301             return index;
   3302         }
   3303 
   3304         int lrui = mLruProcesses.lastIndexOf(app);
   3305         if (lrui < 0) {
   3306             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
   3307                     + what + " " + obj + " from " + srcApp);
   3308             return index;
   3309         }
   3310 
   3311         if (lrui >= index) {
   3312             // Don't want to cause this to move dependent processes *back* in the
   3313             // list as if they were less frequently used.
   3314             return index;
   3315         }
   3316 
   3317         if (lrui >= mLruProcessActivityStart) {
   3318             // Don't want to touch dependent processes that are hosting activities.
   3319             return index;
   3320         }
   3321 
   3322         mLruProcesses.remove(lrui);
   3323         if (index > 0) {
   3324             index--;
   3325         }
   3326         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
   3327                 + " in LRU list: " + app);
   3328         mLruProcesses.add(index, app);
   3329         return index;
   3330     }
   3331 
   3332     static void killProcessGroup(int uid, int pid) {
   3333         if (sKillHandler != null) {
   3334             sKillHandler.sendMessage(
   3335                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
   3336         } else {
   3337             Slog.w(TAG, "Asked to kill process group before system bringup!");
   3338             Process.killProcessGroup(uid, pid);
   3339         }
   3340     }
   3341 
   3342     final void removeLruProcessLocked(ProcessRecord app) {
   3343         int lrui = mLruProcesses.lastIndexOf(app);
   3344         if (lrui >= 0) {
   3345             if (!app.killed) {
   3346                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
   3347                 killProcessQuiet(app.pid);
   3348                 killProcessGroup(app.uid, app.pid);
   3349             }
   3350             if (lrui <= mLruProcessActivityStart) {
   3351                 mLruProcessActivityStart--;
   3352             }
   3353             if (lrui <= mLruProcessServiceStart) {
   3354                 mLruProcessServiceStart--;
   3355             }
   3356             mLruProcesses.remove(lrui);
   3357         }
   3358     }
   3359 
   3360     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
   3361             ProcessRecord client) {
   3362         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
   3363                 || app.treatLikeActivity;
   3364         final boolean hasService = false; // not impl yet. app.services.size() > 0;
   3365         if (!activityChange && hasActivity) {
   3366             // The process has activities, so we are only allowing activity-based adjustments
   3367             // to move it.  It should be kept in the front of the list with other
   3368             // processes that have activities, and we don't want those to change their
   3369             // order except due to activity operations.
   3370             return;
   3371         }
   3372 
   3373         mLruSeq++;
   3374         final long now = SystemClock.uptimeMillis();
   3375         app.lastActivityTime = now;
   3376 
   3377         // First a quick reject: if the app is already at the position we will
   3378         // put it, then there is nothing to do.
   3379         if (hasActivity) {
   3380             final int N = mLruProcesses.size();
   3381             if (N > 0 && mLruProcesses.get(N-1) == app) {
   3382                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
   3383                 return;
   3384             }
   3385         } else {
   3386             if (mLruProcessServiceStart > 0
   3387                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
   3388                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
   3389                 return;
   3390             }
   3391         }
   3392 
   3393         int lrui = mLruProcesses.lastIndexOf(app);
   3394 
   3395         if (app.persistent && lrui >= 0) {
   3396             // We don't care about the position of persistent processes, as long as
   3397             // they are in the list.
   3398             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
   3399             return;
   3400         }
   3401 
   3402         /* In progress: compute new position first, so we can avoid doing work
   3403            if the process is not actually going to move.  Not yet working.
   3404         int addIndex;
   3405         int nextIndex;
   3406         boolean inActivity = false, inService = false;
   3407         if (hasActivity) {
   3408             // Process has activities, put it at the very tipsy-top.
   3409             addIndex = mLruProcesses.size();
   3410             nextIndex = mLruProcessServiceStart;
   3411             inActivity = true;
   3412         } else if (hasService) {
   3413             // Process has services, put it at the top of the service list.
   3414             addIndex = mLruProcessActivityStart;
   3415             nextIndex = mLruProcessServiceStart;
   3416             inActivity = true;
   3417             inService = true;
   3418         } else  {
   3419             // Process not otherwise of interest, it goes to the top of the non-service area.
   3420             addIndex = mLruProcessServiceStart;
   3421             if (client != null) {
   3422                 int clientIndex = mLruProcesses.lastIndexOf(client);
   3423                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
   3424                         + app);
   3425                 if (clientIndex >= 0 && addIndex > clientIndex) {
   3426                     addIndex = clientIndex;
   3427                 }
   3428             }
   3429             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
   3430         }
   3431 
   3432         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
   3433                 + mLruProcessActivityStart + "): " + app);
   3434         */
   3435 
   3436         if (lrui >= 0) {
   3437             if (lrui < mLruProcessActivityStart) {
   3438                 mLruProcessActivityStart--;
   3439             }
   3440             if (lrui < mLruProcessServiceStart) {
   3441                 mLruProcessServiceStart--;
   3442             }
   3443             /*
   3444             if (addIndex > lrui) {
   3445                 addIndex--;
   3446             }
   3447             if (nextIndex > lrui) {
   3448                 nextIndex--;
   3449             }
   3450             */
   3451             mLruProcesses.remove(lrui);
   3452         }
   3453 
   3454         /*
   3455         mLruProcesses.add(addIndex, app);
   3456         if (inActivity) {
   3457             mLruProcessActivityStart++;
   3458         }
   3459         if (inService) {
   3460             mLruProcessActivityStart++;
   3461         }
   3462         */
   3463 
   3464         int nextIndex;
   3465         if (hasActivity) {
   3466             final int N = mLruProcesses.size();
   3467             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
   3468                 // Process doesn't have activities, but has clients with
   3469                 // activities...  move it up, but one below the top (the top
   3470                 // should always have a real activity).
   3471                 if (DEBUG_LRU) Slog.d(TAG_LRU,
   3472                         "Adding to second-top of LRU activity list: " + app);
   3473                 mLruProcesses.add(N - 1, app);
   3474                 // To keep it from spamming the LRU list (by making a bunch of clients),
   3475                 // we will push down any other entries owned by the app.
   3476                 final int uid = app.info.uid;
   3477                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
   3478                     ProcessRecord subProc = mLruProcesses.get(i);
   3479                     if (subProc.info.uid == uid) {
   3480                         // We want to push this one down the list.  If the process after
   3481                         // it is for the same uid, however, don't do so, because we don't
   3482                         // want them internally to be re-ordered.
   3483                         if (mLruProcesses.get(i - 1).info.uid != uid) {
   3484                             if (DEBUG_LRU) Slog.d(TAG_LRU,
   3485                                     "Pushing uid " + uid + " swapping at " + i + ": "
   3486                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
   3487                             ProcessRecord tmp = mLruProcesses.get(i);
   3488                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
   3489                             mLruProcesses.set(i - 1, tmp);
   3490                             i--;
   3491                         }
   3492                     } else {
   3493                         // A gap, we can stop here.
   3494                         break;
   3495                     }
   3496                 }
   3497             } else {
   3498                 // Process has activities, put it at the very tipsy-top.
   3499                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
   3500                 mLruProcesses.add(app);
   3501             }
   3502             nextIndex = mLruProcessServiceStart;
   3503         } else if (hasService) {
   3504             // Process has services, put it at the top of the service list.
   3505             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
   3506             mLruProcesses.add(mLruProcessActivityStart, app);
   3507             nextIndex = mLruProcessServiceStart;
   3508             mLruProcessActivityStart++;
   3509         } else  {
   3510             // Process not otherwise of interest, it goes to the top of the non-service area.
   3511             int index = mLruProcessServiceStart;
   3512             if (client != null) {
   3513                 // If there is a client, don't allow the process to be moved up higher
   3514                 // in the list than that client.
   3515                 int clientIndex = mLruProcesses.lastIndexOf(client);
   3516                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
   3517                         + " when updating " + app);
   3518                 if (clientIndex <= lrui) {
   3519                     // Don't allow the client index restriction to push it down farther in the
   3520                     // list than it already is.
   3521                     clientIndex = lrui;
   3522                 }
   3523                 if (clientIndex >= 0 && index > clientIndex) {
   3524                     index = clientIndex;
   3525                 }
   3526             }
   3527             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
   3528             mLruProcesses.add(index, app);
   3529             nextIndex = index-1;
   3530             mLruProcessActivityStart++;
   3531             mLruProcessServiceStart++;
   3532         }
   3533 
   3534         // If the app is currently using a content provider or service,
   3535         // bump those processes as well.
   3536         for (int j=app.connections.size()-1; j>=0; j--) {
   3537             ConnectionRecord cr = app.connections.valueAt(j);
   3538             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
   3539                     && cr.binding.service.app != null
   3540                     && cr.binding.service.app.lruSeq != mLruSeq
   3541                     && !cr.binding.service.app.persistent) {
   3542                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
   3543                         "service connection", cr, app);
   3544             }
   3545         }
   3546         for (int j=app.conProviders.size()-1; j>=0; j--) {
   3547             ContentProviderRecord cpr = app.conProviders.get(j).provider;
   3548             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
   3549                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
   3550                         "provider reference", cpr, app);
   3551             }
   3552         }
   3553     }
   3554 
   3555     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
   3556         if (uid == SYSTEM_UID) {
   3557             // The system gets to run in any process.  If there are multiple
   3558             // processes with the same uid, just pick the first (this
   3559             // should never happen).
   3560             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
   3561             if (procs == null) return null;
   3562             final int procCount = procs.size();
   3563             for (int i = 0; i < procCount; i++) {
   3564                 final int procUid = procs.keyAt(i);
   3565                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
   3566                     // Don't use an app process or different user process for system component.
   3567                     continue;
   3568                 }
   3569                 return procs.valueAt(i);
   3570             }
   3571         }
   3572         ProcessRecord proc = mProcessNames.get(processName, uid);
   3573         if (false && proc != null && !keepIfLarge
   3574                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
   3575                 && proc.lastCachedPss >= 4000) {
   3576             // Turn this condition on to cause killing to happen regularly, for testing.
   3577             if (proc.baseProcessTracker != null) {
   3578                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
   3579             }
   3580             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
   3581         } else if (proc != null && !keepIfLarge
   3582                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
   3583                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
   3584             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
   3585             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
   3586                 if (proc.baseProcessTracker != null) {
   3587                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
   3588                 }
   3589                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
   3590             }
   3591         }
   3592         return proc;
   3593     }
   3594 
   3595     void notifyPackageUse(String packageName, int reason) {
   3596         IPackageManager pm = AppGlobals.getPackageManager();
   3597         try {
   3598             pm.notifyPackageUse(packageName, reason);
   3599         } catch (RemoteException e) {
   3600         }
   3601     }
   3602 
   3603     boolean isNextTransitionForward() {
   3604         int transit = mWindowManager.getPendingAppTransition();
   3605         return transit == TRANSIT_ACTIVITY_OPEN
   3606                 || transit == TRANSIT_TASK_OPEN
   3607                 || transit == TRANSIT_TASK_TO_FRONT;
   3608     }
   3609 
   3610     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
   3611             String processName, String abiOverride, int uid, Runnable crashHandler) {
   3612         synchronized(this) {
   3613             ApplicationInfo info = new ApplicationInfo();
   3614             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
   3615             // For isolated processes, the former contains the parent's uid and the latter the
   3616             // actual uid of the isolated process.
   3617             // In the special case introduced by this method (which is, starting an isolated
   3618             // process directly from the SystemServer without an actual parent app process) the
   3619             // closest thing to a parent's uid is SYSTEM_UID.
   3620             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
   3621             // the |isolated| logic in the ProcessRecord constructor.
   3622             info.uid = SYSTEM_UID;
   3623             info.processName = processName;
   3624             info.className = entryPoint;
   3625             info.packageName = "android";
   3626             info.seInfoUser = SELinuxUtil.COMPLETE_STR;
   3627             ProcessRecord proc = startProcessLocked(processName, info /* info */,
   3628                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
   3629                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
   3630                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
   3631                     crashHandler);
   3632             return proc != null ? proc.pid : 0;
   3633         }
   3634     }
   3635 
   3636     final ProcessRecord startProcessLocked(String processName,
   3637             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
   3638             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
   3639             boolean isolated, boolean keepIfLarge) {
   3640         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
   3641                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
   3642                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
   3643                 null /* crashHandler */);
   3644     }
   3645 
   3646     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
   3647             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
   3648             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
   3649             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
   3650         long startTime = SystemClock.elapsedRealtime();
   3651         ProcessRecord app;
   3652         if (!isolated) {
   3653             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
   3654             checkTime(startTime, "startProcess: after getProcessRecord");
   3655 
   3656             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
   3657                 // If we are in the background, then check to see if this process
   3658                 // is bad.  If so, we will just silently fail.
   3659                 if (mAppErrors.isBadProcessLocked(info)) {
   3660                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
   3661                             + "/" + info.processName);
   3662                     return null;
   3663                 }
   3664             } else {
   3665                 // When the user is explicitly starting a process, then clear its
   3666                 // crash count so that we won't make it bad until they see at
   3667                 // least one crash dialog again, and make the process good again
   3668                 // if it had been bad.
   3669                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
   3670                         + "/" + info.processName);
   3671                 mAppErrors.resetProcessCrashTimeLocked(info);
   3672                 if (mAppErrors.isBadProcessLocked(info)) {
   3673                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
   3674                             UserHandle.getUserId(info.uid), info.uid,
   3675                             info.processName);
   3676                     mAppErrors.clearBadProcessLocked(info);
   3677                     if (app != null) {
   3678                         app.bad = false;
   3679                     }
   3680                 }
   3681             }
   3682         } else {
   3683             // If this is an isolated process, it can't re-use an existing process.
   3684             app = null;
   3685         }
   3686 
   3687         // We don't have to do anything more if:
   3688         // (1) There is an existing application record; and
   3689         // (2) The caller doesn't think it is dead, OR there is no thread
   3690         //     object attached to it so we know it couldn't have crashed; and
   3691         // (3) There is a pid assigned to it, so it is either starting or
   3692         //     already running.
   3693         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
   3694                 + " app=" + app + " knownToBeDead=" + knownToBeDead
   3695                 + " thread=" + (app != null ? app.thread : null)
   3696                 + " pid=" + (app != null ? app.pid : -1));
   3697         if (app != null && app.pid > 0) {
   3698             if ((!knownToBeDead && !app.killed) || app.thread == null) {
   3699                 // We already have the app running, or are waiting for it to
   3700                 // come up (we have a pid but not yet its thread), so keep it.
   3701                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
   3702                 // If this is a new package in the process, add the package to the list
   3703                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
   3704                 checkTime(startTime, "startProcess: done, added package to proc");
   3705                 return app;
   3706             }
   3707 
   3708             // An application record is attached to a previous process,
   3709             // clean it up now.
   3710             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
   3711             checkTime(startTime, "startProcess: bad proc running, killing");
   3712             killProcessGroup(app.uid, app.pid);
   3713             handleAppDiedLocked(app, true, true);
   3714             checkTime(startTime, "startProcess: done killing old proc");
   3715         }
   3716 
   3717         String hostingNameStr = hostingName != null
   3718                 ? hostingName.flattenToShortString() : null;
   3719 
   3720         if (app == null) {
   3721             checkTime(startTime, "startProcess: creating new process record");
   3722             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
   3723             if (app == null) {
   3724                 Slog.w(TAG, "Failed making new process record for "
   3725                         + processName + "/" + info.uid + " isolated=" + isolated);
   3726                 return null;
   3727             }
   3728             app.crashHandler = crashHandler;
   3729             checkTime(startTime, "startProcess: done creating new process record");
   3730         } else {
   3731             // If this is a new package in the process, add the package to the list
   3732             app.addPackage(info.packageName, info.versionCode, mProcessStats);
   3733             checkTime(startTime, "startProcess: added package to existing proc");
   3734         }
   3735 
   3736         // If the system is not ready yet, then hold off on starting this
   3737         // process until it is.
   3738         if (!mProcessesReady
   3739                 && !isAllowedWhileBooting(info)
   3740                 && !allowWhileBooting) {
   3741             if (!mProcessesOnHold.contains(app)) {
   3742                 mProcessesOnHold.add(app);
   3743             }
   3744             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
   3745                     "System not ready, putting on hold: " + app);
   3746             checkTime(startTime, "startProcess: returning with proc on hold");
   3747             return app;
   3748         }
   3749 
   3750         checkTime(startTime, "startProcess: stepping in to startProcess");
   3751         startProcessLocked(
   3752                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
   3753         checkTime(startTime, "startProcess: done starting proc!");
   3754         return (app.pid != 0) ? app : null;
   3755     }
   3756 
   3757     boolean isAllowedWhileBooting(ApplicationInfo ai) {
   3758         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
   3759     }
   3760 
   3761     private final void startProcessLocked(ProcessRecord app,
   3762             String hostingType, String hostingNameStr) {
   3763         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
   3764                 null /* entryPoint */, null /* entryPointArgs */);
   3765     }
   3766 
   3767     private final void startProcessLocked(ProcessRecord app, String hostingType,
   3768             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
   3769         long startTime = SystemClock.elapsedRealtime();
   3770         if (app.pid > 0 && app.pid != MY_PID) {
   3771             checkTime(startTime, "startProcess: removing from pids map");
   3772             synchronized (mPidsSelfLocked) {
   3773                 mPidsSelfLocked.remove(app.pid);
   3774                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   3775             }
   3776             checkTime(startTime, "startProcess: done removing from pids map");
   3777             app.setPid(0);
   3778         }
   3779 
   3780         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
   3781                 "startProcessLocked removing on hold: " + app);
   3782         mProcessesOnHold.remove(app);
   3783 
   3784         checkTime(startTime, "startProcess: starting to update cpu stats");
   3785         updateCpuStats();
   3786         checkTime(startTime, "startProcess: done updating cpu stats");
   3787 
   3788         try {
   3789             try {
   3790                 final int userId = UserHandle.getUserId(app.uid);
   3791                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
   3792             } catch (RemoteException e) {
   3793                 throw e.rethrowAsRuntimeException();
   3794             }
   3795 
   3796             int uid = app.uid;
   3797             int[] gids = null;
   3798             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
   3799             if (!app.isolated) {
   3800                 int[] permGids = null;
   3801                 try {
   3802                     checkTime(startTime, "startProcess: getting gids from package manager");
   3803                     final IPackageManager pm = AppGlobals.getPackageManager();
   3804                     permGids = pm.getPackageGids(app.info.packageName,
   3805                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
   3806                     StorageManagerInternal storageManagerInternal = LocalServices.getService(
   3807                             StorageManagerInternal.class);
   3808                     mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
   3809                             app.info.packageName);
   3810                 } catch (RemoteException e) {
   3811                     throw e.rethrowAsRuntimeException();
   3812                 }
   3813 
   3814                 /*
   3815                  * Add shared application and profile GIDs so applications can share some
   3816                  * resources like shared libraries and access user-wide resources
   3817                  */
   3818                 if (ArrayUtils.isEmpty(permGids)) {
   3819                     gids = new int[3];
   3820                 } else {
   3821                     gids = new int[permGids.length + 3];
   3822                     System.arraycopy(permGids, 0, gids, 3, permGids.length);
   3823                 }
   3824                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
   3825                 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
   3826                 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
   3827             }
   3828             checkTime(startTime, "startProcess: building args");
   3829             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
   3830                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
   3831                         && mTopComponent != null
   3832                         && app.processName.equals(mTopComponent.getPackageName())) {
   3833                     uid = 0;
   3834                 }
   3835                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
   3836                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
   3837                     uid = 0;
   3838                 }
   3839             }
   3840             int debugFlags = 0;
   3841             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   3842                 debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
   3843                 debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
   3844                 // Also turn on CheckJNI for debuggable apps. It's quite
   3845                 // awkward to turn on otherwise.
   3846                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   3847             }
   3848             // Run the app in safe mode if its manifest requests so or the
   3849             // system is booted in safe mode.
   3850             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
   3851                 mSafeMode == true) {
   3852                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
   3853             }
   3854             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
   3855                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   3856             }
   3857             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
   3858             if ("true".equals(genDebugInfoProperty)) {
   3859                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
   3860             }
   3861             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
   3862                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
   3863             }
   3864             if ("1".equals(SystemProperties.get("debug.assert"))) {
   3865                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
   3866             }
   3867             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
   3868                 // Enable all debug flags required by the native debugger.
   3869                 debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
   3870                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
   3871                 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
   3872                 mNativeDebuggingApp = null;
   3873             }
   3874 
   3875             String invokeWith = null;
   3876             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   3877                 // Debuggable apps may include a wrapper script with their library directory.
   3878                 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
   3879                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
   3880                 try {
   3881                     if (new File(wrapperFileName).exists()) {
   3882                         invokeWith = "/system/bin/logwrapper " + wrapperFileName;
   3883                     }
   3884                 } finally {
   3885                     StrictMode.setThreadPolicy(oldPolicy);
   3886                 }
   3887             }
   3888 
   3889             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
   3890             if (requiredAbi == null) {
   3891                 requiredAbi = Build.SUPPORTED_ABIS[0];
   3892             }
   3893 
   3894             String instructionSet = null;
   3895             if (app.info.primaryCpuAbi != null) {
   3896                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
   3897             }
   3898 
   3899             app.gids = gids;
   3900             app.requiredAbi = requiredAbi;
   3901             app.instructionSet = instructionSet;
   3902 
   3903             // the per-user SELinux context must be set
   3904             if (TextUtils.isEmpty(app.info.seInfoUser)) {
   3905                 Slog.wtf(TAG, "SELinux tag not defined",
   3906                         new IllegalStateException("SELinux tag not defined for "
   3907                         + app.info.packageName + " (uid " + app.uid + ")"));
   3908             }
   3909             final String seInfo = app.info.seInfo
   3910                     + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
   3911             // Start the process.  It will either succeed and return a result containing
   3912             // the PID of the new process, or else throw a RuntimeException.
   3913             boolean isActivityProcess = (entryPoint == null);
   3914             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
   3915             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
   3916                     app.processName);
   3917             checkTime(startTime, "startProcess: asking zygote to start proc");
   3918             ProcessStartResult startResult;
   3919             if (hostingType.equals("webview_service")) {
   3920                 startResult = startWebView(entryPoint,
   3921                         app.processName, uid, uid, gids, debugFlags, mountExternal,
   3922                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
   3923                         app.info.dataDir, null, entryPointArgs);
   3924             } else {
   3925                 startResult = Process.start(entryPoint,
   3926                         app.processName, uid, uid, gids, debugFlags, mountExternal,
   3927                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
   3928                         app.info.dataDir, invokeWith, entryPointArgs);
   3929             }
   3930             checkTime(startTime, "startProcess: returned from zygote!");
   3931             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   3932 
   3933             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
   3934             checkTime(startTime, "startProcess: done updating battery stats");
   3935 
   3936             EventLog.writeEvent(EventLogTags.AM_PROC_START,
   3937                     UserHandle.getUserId(uid), startResult.pid, uid,
   3938                     app.processName, hostingType,
   3939                     hostingNameStr != null ? hostingNameStr : "");
   3940 
   3941             try {
   3942                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
   3943                         seInfo, app.info.sourceDir, startResult.pid);
   3944             } catch (RemoteException ex) {
   3945                 // Ignore
   3946             }
   3947 
   3948             if (app.persistent) {
   3949                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
   3950             }
   3951 
   3952             checkTime(startTime, "startProcess: building log message");
   3953             StringBuilder buf = mStringBuilder;
   3954             buf.setLength(0);
   3955             buf.append("Start proc ");
   3956             buf.append(startResult.pid);
   3957             buf.append(':');
   3958             buf.append(app.processName);
   3959             buf.append('/');
   3960             UserHandle.formatUid(buf, uid);
   3961             if (!isActivityProcess) {
   3962                 buf.append(" [");
   3963                 buf.append(entryPoint);
   3964                 buf.append("]");
   3965             }
   3966             buf.append(" for ");
   3967             buf.append(hostingType);
   3968             if (hostingNameStr != null) {
   3969                 buf.append(" ");
   3970                 buf.append(hostingNameStr);
   3971             }
   3972             Slog.i(TAG, buf.toString());
   3973             app.setPid(startResult.pid);
   3974             app.usingWrapper = startResult.usingWrapper;
   3975             app.removed = false;
   3976             app.killed = false;
   3977             app.killedByAm = false;
   3978             checkTime(startTime, "startProcess: starting to update pids map");
   3979             ProcessRecord oldApp;
   3980             synchronized (mPidsSelfLocked) {
   3981                 oldApp = mPidsSelfLocked.get(startResult.pid);
   3982             }
   3983             // If there is already an app occupying that pid that hasn't been cleaned up
   3984             if (oldApp != null && !app.isolated) {
   3985                 // Clean up anything relating to this pid first
   3986                 Slog.w(TAG, "Reusing pid " + startResult.pid
   3987                         + " while app is still mapped to it");
   3988                 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
   3989                         true /*replacingPid*/);
   3990             }
   3991             synchronized (mPidsSelfLocked) {
   3992                 this.mPidsSelfLocked.put(startResult.pid, app);
   3993                 if (isActivityProcess) {
   3994                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   3995                     msg.obj = app;
   3996                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
   3997                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
   3998                 }
   3999             }
   4000             checkTime(startTime, "startProcess: done updating pids map");
   4001         } catch (RuntimeException e) {
   4002             Slog.e(TAG, "Failure starting process " + app.processName, e);
   4003 
   4004             // Something went very wrong while trying to start this process; one
   4005             // common case is when the package is frozen due to an active
   4006             // upgrade. To recover, clean up any active bookkeeping related to
   4007             // starting this process. (We already invoked this method once when
   4008             // the package was initially frozen through KILL_APPLICATION_MSG, so
   4009             // it doesn't hurt to use it again.)
   4010             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
   4011                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
   4012         }
   4013     }
   4014 
   4015     void updateUsageStats(ActivityRecord component, boolean resumed) {
   4016         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
   4017                 "updateUsageStats: comp=" + component + "res=" + resumed);
   4018         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   4019         if (resumed) {
   4020             if (mUsageStatsService != null) {
   4021                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
   4022                         UsageEvents.Event.MOVE_TO_FOREGROUND);
   4023             }
   4024             synchronized (stats) {
   4025                 stats.noteActivityResumedLocked(component.app.uid);
   4026             }
   4027         } else {
   4028             if (mUsageStatsService != null) {
   4029                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
   4030                         UsageEvents.Event.MOVE_TO_BACKGROUND);
   4031             }
   4032             synchronized (stats) {
   4033                 stats.noteActivityPausedLocked(component.app.uid);
   4034             }
   4035         }
   4036     }
   4037 
   4038     Intent getHomeIntent() {
   4039         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
   4040         intent.setComponent(mTopComponent);
   4041         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
   4042         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   4043             intent.addCategory(Intent.CATEGORY_HOME);
   4044         }
   4045         return intent;
   4046     }
   4047 
   4048     boolean startHomeActivityLocked(int userId, String reason) {
   4049         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
   4050                 && mTopAction == null) {
   4051             // We are running in factory test mode, but unable to find
   4052             // the factory test app, so just sit around displaying the
   4053             // error message and don't try to start anything.
   4054             return false;
   4055         }
   4056         Intent intent = getHomeIntent();
   4057         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
   4058         if (aInfo != null) {
   4059             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
   4060             // Don't do this if the home app is currently being
   4061             // instrumented.
   4062             aInfo = new ActivityInfo(aInfo);
   4063             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
   4064             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
   4065                     aInfo.applicationInfo.uid, true);
   4066             if (app == null || app.instr == null) {
   4067                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
   4068                 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
   4069                 // For ANR debugging to verify if the user activity is the one that actually
   4070                 // launched.
   4071                 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
   4072                 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
   4073             }
   4074         } else {
   4075             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
   4076         }
   4077 
   4078         return true;
   4079     }
   4080 
   4081     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
   4082         ActivityInfo ai = null;
   4083         ComponentName comp = intent.getComponent();
   4084         try {
   4085             if (comp != null) {
   4086                 // Factory test.
   4087                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
   4088             } else {
   4089                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
   4090                         intent,
   4091                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
   4092                         flags, userId);
   4093 
   4094                 if (info != null) {
   4095                     ai = info.activityInfo;
   4096                 }
   4097             }
   4098         } catch (RemoteException e) {
   4099             // ignore
   4100         }
   4101 
   4102         return ai;
   4103     }
   4104 
   4105     /**
   4106      * Starts the "new version setup screen" if appropriate.
   4107      */
   4108     void startSetupActivityLocked() {
   4109         // Only do this once per boot.
   4110         if (mCheckedForSetup) {
   4111             return;
   4112         }
   4113 
   4114         // We will show this screen if the current one is a different
   4115         // version than the last one shown, and we are not running in
   4116         // low-level factory test mode.
   4117         final ContentResolver resolver = mContext.getContentResolver();
   4118         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
   4119                 Settings.Global.getInt(resolver,
   4120                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
   4121             mCheckedForSetup = true;
   4122 
   4123             // See if we should be showing the platform update setup UI.
   4124             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
   4125             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
   4126                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
   4127             if (!ris.isEmpty()) {
   4128                 final ResolveInfo ri = ris.get(0);
   4129                 String vers = ri.activityInfo.metaData != null
   4130                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
   4131                         : null;
   4132                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
   4133                     vers = ri.activityInfo.applicationInfo.metaData.getString(
   4134                             Intent.METADATA_SETUP_VERSION);
   4135                 }
   4136                 String lastVers = Settings.Secure.getString(
   4137                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
   4138                 if (vers != null && !vers.equals(lastVers)) {
   4139                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   4140                     intent.setComponent(new ComponentName(
   4141                             ri.activityInfo.packageName, ri.activityInfo.name));
   4142                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
   4143                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
   4144                             null, 0, 0, 0, null, false, false, null, null, null,
   4145                             "startSetupActivity");
   4146                 }
   4147             }
   4148         }
   4149     }
   4150 
   4151     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
   4152         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
   4153     }
   4154 
   4155     void enforceNotIsolatedCaller(String caller) {
   4156         if (UserHandle.isIsolated(Binder.getCallingUid())) {
   4157             throw new SecurityException("Isolated process not allowed to call " + caller);
   4158         }
   4159     }
   4160 
   4161     void enforceShellRestriction(String restriction, int userHandle) {
   4162         if (Binder.getCallingUid() == SHELL_UID) {
   4163             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
   4164                 throw new SecurityException("Shell does not have permission to access user "
   4165                         + userHandle);
   4166             }
   4167         }
   4168     }
   4169 
   4170     @Override
   4171     public int getFrontActivityScreenCompatMode() {
   4172         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
   4173         synchronized (this) {
   4174             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
   4175         }
   4176     }
   4177 
   4178     @Override
   4179     public void setFrontActivityScreenCompatMode(int mode) {
   4180         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   4181                 "setFrontActivityScreenCompatMode");
   4182         synchronized (this) {
   4183             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
   4184         }
   4185     }
   4186 
   4187     @Override
   4188     public int getPackageScreenCompatMode(String packageName) {
   4189         enforceNotIsolatedCaller("getPackageScreenCompatMode");
   4190         synchronized (this) {
   4191             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
   4192         }
   4193     }
   4194 
   4195     @Override
   4196     public void setPackageScreenCompatMode(String packageName, int mode) {
   4197         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   4198                 "setPackageScreenCompatMode");
   4199         synchronized (this) {
   4200             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
   4201         }
   4202     }
   4203 
   4204     @Override
   4205     public boolean getPackageAskScreenCompat(String packageName) {
   4206         enforceNotIsolatedCaller("getPackageAskScreenCompat");
   4207         synchronized (this) {
   4208             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
   4209         }
   4210     }
   4211 
   4212     @Override
   4213     public void setPackageAskScreenCompat(String packageName, boolean ask) {
   4214         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   4215                 "setPackageAskScreenCompat");
   4216         synchronized (this) {
   4217             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
   4218         }
   4219     }
   4220 
   4221     private boolean hasUsageStatsPermission(String callingPackage) {
   4222         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
   4223                 Binder.getCallingUid(), callingPackage);
   4224         if (mode == AppOpsManager.MODE_DEFAULT) {
   4225             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
   4226                     == PackageManager.PERMISSION_GRANTED;
   4227         }
   4228         return mode == AppOpsManager.MODE_ALLOWED;
   4229     }
   4230 
   4231     @Override
   4232     public int getPackageProcessState(String packageName, String callingPackage) {
   4233         if (!hasUsageStatsPermission(callingPackage)) {
   4234             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
   4235                     "getPackageProcessState");
   4236         }
   4237 
   4238         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
   4239         synchronized (this) {
   4240             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   4241                 final ProcessRecord proc = mLruProcesses.get(i);
   4242                 if (procState > proc.setProcState) {
   4243                     if (proc.pkgList.containsKey(packageName) ||
   4244                             (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
   4245                         procState = proc.setProcState;
   4246                     }
   4247                 }
   4248             }
   4249         }
   4250         return procState;
   4251     }
   4252 
   4253     @Override
   4254     public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
   4255             throws RemoteException {
   4256         synchronized (this) {
   4257             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
   4258             if (app == null) {
   4259                 throw new IllegalArgumentException("Unknown process: " + process);
   4260             }
   4261             if (app.thread == null) {
   4262                 throw new IllegalArgumentException("Process has no app thread");
   4263             }
   4264             if (app.trimMemoryLevel >= level) {
   4265                 throw new IllegalArgumentException(
   4266                         "Unable to set a higher trim level than current level");
   4267             }
   4268             if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
   4269                     app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
   4270                 throw new IllegalArgumentException("Unable to set a background trim level "
   4271                     + "on a foreground process");
   4272             }
   4273             app.thread.scheduleTrimMemory(level);
   4274             app.trimMemoryLevel = level;
   4275             return true;
   4276         }
   4277     }
   4278 
   4279     private void dispatchProcessesChanged() {
   4280         int N;
   4281         synchronized (this) {
   4282             N = mPendingProcessChanges.size();
   4283             if (mActiveProcessChanges.length < N) {
   4284                 mActiveProcessChanges = new ProcessChangeItem[N];
   4285             }
   4286             mPendingProcessChanges.toArray(mActiveProcessChanges);
   4287             mPendingProcessChanges.clear();
   4288             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   4289                     "*** Delivering " + N + " process changes");
   4290         }
   4291 
   4292         int i = mProcessObservers.beginBroadcast();
   4293         while (i > 0) {
   4294             i--;
   4295             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   4296             if (observer != null) {
   4297                 try {
   4298                     for (int j=0; j<N; j++) {
   4299                         ProcessChangeItem item = mActiveProcessChanges[j];
   4300                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
   4301                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   4302                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
   4303                                     + item.uid + ": " + item.foregroundActivities);
   4304                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
   4305                                     item.foregroundActivities);
   4306                         }
   4307                     }
   4308                 } catch (RemoteException e) {
   4309                 }
   4310             }
   4311         }
   4312         mProcessObservers.finishBroadcast();
   4313 
   4314         synchronized (this) {
   4315             for (int j=0; j<N; j++) {
   4316                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
   4317             }
   4318         }
   4319     }
   4320 
   4321     private void dispatchProcessDied(int pid, int uid) {
   4322         int i = mProcessObservers.beginBroadcast();
   4323         while (i > 0) {
   4324             i--;
   4325             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   4326             if (observer != null) {
   4327                 try {
   4328                     observer.onProcessDied(pid, uid);
   4329                 } catch (RemoteException e) {
   4330                 }
   4331             }
   4332         }
   4333         mProcessObservers.finishBroadcast();
   4334     }
   4335 
   4336     @VisibleForTesting
   4337     void dispatchUidsChanged() {
   4338         int N;
   4339         synchronized (this) {
   4340             N = mPendingUidChanges.size();
   4341             if (mActiveUidChanges.length < N) {
   4342                 mActiveUidChanges = new UidRecord.ChangeItem[N];
   4343             }
   4344             for (int i=0; i<N; i++) {
   4345                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
   4346                 mActiveUidChanges[i] = change;
   4347                 if (change.uidRecord != null) {
   4348                     change.uidRecord.pendingChange = null;
   4349                     change.uidRecord = null;
   4350                 }
   4351             }
   4352             mPendingUidChanges.clear();
   4353             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4354                     "*** Delivering " + N + " uid changes");
   4355         }
   4356 
   4357         int i = mUidObservers.beginBroadcast();
   4358         while (i > 0) {
   4359             i--;
   4360             dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
   4361                     (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
   4362         }
   4363         mUidObservers.finishBroadcast();
   4364 
   4365         if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
   4366             for (int j = 0; j < N; ++j) {
   4367                 final UidRecord.ChangeItem item = mActiveUidChanges[j];
   4368                 if (item.change == UidRecord.CHANGE_GONE
   4369                         || item.change == UidRecord.CHANGE_GONE_IDLE) {
   4370                     mValidateUids.remove(item.uid);
   4371                 } else {
   4372                     UidRecord validateUid = mValidateUids.get(item.uid);
   4373                     if (validateUid == null) {
   4374                         validateUid = new UidRecord(item.uid);
   4375                         mValidateUids.put(item.uid, validateUid);
   4376                     }
   4377                     if (item.change == UidRecord.CHANGE_IDLE) {
   4378                         validateUid.idle = true;
   4379                     } else if (item.change == UidRecord.CHANGE_ACTIVE) {
   4380                         validateUid.idle = false;
   4381                     }
   4382                     validateUid.curProcState = validateUid.setProcState = item.processState;
   4383                     validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
   4384                 }
   4385             }
   4386         }
   4387 
   4388         synchronized (this) {
   4389             for (int j = 0; j < N; j++) {
   4390                 mAvailUidChanges.add(mActiveUidChanges[j]);
   4391             }
   4392         }
   4393     }
   4394 
   4395     private void dispatchUidsChangedForObserver(IUidObserver observer,
   4396             UidObserverRegistration reg, int changesSize) {
   4397         if (observer == null) {
   4398             return;
   4399         }
   4400         try {
   4401             for (int j = 0; j < changesSize; j++) {
   4402                 UidRecord.ChangeItem item = mActiveUidChanges[j];
   4403                 final int change = item.change;
   4404                 if (change == UidRecord.CHANGE_IDLE
   4405                         || change == UidRecord.CHANGE_GONE_IDLE) {
   4406                     if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
   4407                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4408                                 "UID idle uid=" + item.uid);
   4409                         observer.onUidIdle(item.uid, item.ephemeral);
   4410                     }
   4411                 } else if (change == UidRecord.CHANGE_ACTIVE) {
   4412                     if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
   4413                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4414                                 "UID active uid=" + item.uid);
   4415                         observer.onUidActive(item.uid);
   4416                     }
   4417                 }
   4418                 if (change == UidRecord.CHANGE_GONE
   4419                         || change == UidRecord.CHANGE_GONE_IDLE) {
   4420                     if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
   4421                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4422                                 "UID gone uid=" + item.uid);
   4423                         observer.onUidGone(item.uid, item.ephemeral);
   4424                     }
   4425                     if (reg.lastProcStates != null) {
   4426                         reg.lastProcStates.delete(item.uid);
   4427                     }
   4428                 } else {
   4429                     if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
   4430                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4431                                 "UID CHANGED uid=" + item.uid
   4432                                         + ": " + item.processState);
   4433                         boolean doReport = true;
   4434                         if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
   4435                             final int lastState = reg.lastProcStates.get(item.uid,
   4436                                     ActivityManager.PROCESS_STATE_UNKNOWN);
   4437                             if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
   4438                                 final boolean lastAboveCut = lastState <= reg.cutpoint;
   4439                                 final boolean newAboveCut = item.processState <= reg.cutpoint;
   4440                                 doReport = lastAboveCut != newAboveCut;
   4441                             } else {
   4442                                 doReport = item.processState
   4443                                         != ActivityManager.PROCESS_STATE_NONEXISTENT;
   4444                             }
   4445                         }
   4446                         if (doReport) {
   4447                             if (reg.lastProcStates != null) {
   4448                                 reg.lastProcStates.put(item.uid, item.processState);
   4449                             }
   4450                             observer.onUidStateChanged(item.uid, item.processState,
   4451                                     item.procStateSeq);
   4452                         }
   4453                     }
   4454                 }
   4455             }
   4456         } catch (RemoteException e) {
   4457         }
   4458     }
   4459 
   4460     @Override
   4461     public final int startActivity(IApplicationThread caller, String callingPackage,
   4462             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   4463             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
   4464         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
   4465                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
   4466                 UserHandle.getCallingUserId());
   4467     }
   4468 
   4469     final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
   4470         enforceNotIsolatedCaller("ActivityContainer.startActivity");
   4471         final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
   4472                 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
   4473                 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
   4474 
   4475         // TODO: Switch to user app stacks here.
   4476         String mimeType = intent.getType();
   4477         final Uri data = intent.getData();
   4478         if (mimeType == null && data != null && "content".equals(data.getScheme())) {
   4479             mimeType = getProviderMimeType(data, userId);
   4480         }
   4481         container.checkEmbeddedAllowedInner(userId, intent, mimeType);
   4482 
   4483         intent.addFlags(FORCE_NEW_TASK_FLAGS);
   4484         return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null,
   4485                 null, null, 0, 0, null, null, null, null, false, userId, container, null,
   4486                 "startActivity");
   4487     }
   4488 
   4489     @Override
   4490     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
   4491             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   4492             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
   4493         enforceNotIsolatedCaller("startActivity");
   4494         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4495                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
   4496         // TODO: Switch to user app stacks here.
   4497         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
   4498                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
   4499                 profilerInfo, null, null, bOptions, false, userId, null, null,
   4500                 "startActivityAsUser");
   4501     }
   4502 
   4503     @Override
   4504     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
   4505             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   4506             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
   4507             int userId) {
   4508 
   4509         // This is very dangerous -- it allows you to perform a start activity (including
   4510         // permission grants) as any app that may launch one of your own activities.  So
   4511         // we will only allow this to be done from activities that are part of the core framework,
   4512         // and then only when they are running as the system.
   4513         final ActivityRecord sourceRecord;
   4514         final int targetUid;
   4515         final String targetPackage;
   4516         synchronized (this) {
   4517             if (resultTo == null) {
   4518                 throw new SecurityException("Must be called from an activity");
   4519             }
   4520             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
   4521             if (sourceRecord == null) {
   4522                 throw new SecurityException("Called with bad activity token: " + resultTo);
   4523             }
   4524             if (!sourceRecord.info.packageName.equals("android")) {
   4525                 throw new SecurityException(
   4526                         "Must be called from an activity that is declared in the android package");
   4527             }
   4528             if (sourceRecord.app == null) {
   4529                 throw new SecurityException("Called without a process attached to activity");
   4530             }
   4531             if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
   4532                 // This is still okay, as long as this activity is running under the
   4533                 // uid of the original calling activity.
   4534                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
   4535                     throw new SecurityException(
   4536                             "Calling activity in uid " + sourceRecord.app.uid
   4537                                     + " must be system uid or original calling uid "
   4538                                     + sourceRecord.launchedFromUid);
   4539                 }
   4540             }
   4541             if (ignoreTargetSecurity) {
   4542                 if (intent.getComponent() == null) {
   4543                     throw new SecurityException(
   4544                             "Component must be specified with ignoreTargetSecurity");
   4545                 }
   4546                 if (intent.getSelector() != null) {
   4547                     throw new SecurityException(
   4548                             "Selector not allowed with ignoreTargetSecurity");
   4549                 }
   4550             }
   4551             targetUid = sourceRecord.launchedFromUid;
   4552             targetPackage = sourceRecord.launchedFromPackage;
   4553         }
   4554 
   4555         if (userId == UserHandle.USER_NULL) {
   4556             userId = UserHandle.getUserId(sourceRecord.app.uid);
   4557         }
   4558 
   4559         // TODO: Switch to user app stacks here.
   4560         try {
   4561             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
   4562                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
   4563                     null, null, bOptions, ignoreTargetSecurity, userId, null, null,
   4564                     "startActivityAsCaller");
   4565             return ret;
   4566         } catch (SecurityException e) {
   4567             // XXX need to figure out how to propagate to original app.
   4568             // A SecurityException here is generally actually a fault of the original
   4569             // calling activity (such as a fairly granting permissions), so propagate it
   4570             // back to them.
   4571             /*
   4572             StringBuilder msg = new StringBuilder();
   4573             msg.append("While launching");
   4574             msg.append(intent.toString());
   4575             msg.append(": ");
   4576             msg.append(e.getMessage());
   4577             */
   4578             throw e;
   4579         }
   4580     }
   4581 
   4582     @Override
   4583     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
   4584             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   4585             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
   4586         enforceNotIsolatedCaller("startActivityAndWait");
   4587         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4588                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
   4589         WaitResult res = new WaitResult();
   4590         // TODO: Switch to user app stacks here.
   4591         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
   4592                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
   4593                 bOptions, false, userId, null, null, "startActivityAndWait");
   4594         return res;
   4595     }
   4596 
   4597     @Override
   4598     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
   4599             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   4600             int startFlags, Configuration config, Bundle bOptions, int userId) {
   4601         enforceNotIsolatedCaller("startActivityWithConfig");
   4602         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4603                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
   4604         // TODO: Switch to user app stacks here.
   4605         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
   4606                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
   4607                 null, null, config, bOptions, false, userId, null, null, "startActivityWithConfig");
   4608         return ret;
   4609     }
   4610 
   4611     @Override
   4612     public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
   4613             IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
   4614             String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
   4615             throws TransactionTooLargeException {
   4616         enforceNotIsolatedCaller("startActivityIntentSender");
   4617         // Refuse possible leaked file descriptors
   4618         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
   4619             throw new IllegalArgumentException("File descriptors passed in Intent");
   4620         }
   4621 
   4622         if (!(target instanceof PendingIntentRecord)) {
   4623             throw new IllegalArgumentException("Bad PendingIntent object");
   4624         }
   4625 
   4626         PendingIntentRecord pir = (PendingIntentRecord)target;
   4627 
   4628         synchronized (this) {
   4629             // If this is coming from the currently resumed activity, it is
   4630             // effectively saying that app switches are allowed at this point.
   4631             final ActivityStack stack = getFocusedStack();
   4632             if (stack.mResumedActivity != null &&
   4633                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
   4634                 mAppSwitchesAllowedTime = 0;
   4635             }
   4636         }
   4637         int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
   4638                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
   4639         return ret;
   4640     }
   4641 
   4642     @Override
   4643     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
   4644             Intent intent, String resolvedType, IVoiceInteractionSession session,
   4645             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
   4646             Bundle bOptions, int userId) {
   4647         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
   4648                 != PackageManager.PERMISSION_GRANTED) {
   4649             String msg = "Permission Denial: startVoiceActivity() from pid="
   4650                     + Binder.getCallingPid()
   4651                     + ", uid=" + Binder.getCallingUid()
   4652                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
   4653             Slog.w(TAG, msg);
   4654             throw new SecurityException(msg);
   4655         }
   4656         if (session == null || interactor == null) {
   4657             throw new NullPointerException("null session or interactor");
   4658         }
   4659         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
   4660                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
   4661         // TODO: Switch to user app stacks here.
   4662         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
   4663                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
   4664                 null, bOptions, false, userId, null, null, "startVoiceActivity");
   4665     }
   4666 
   4667     @Override
   4668     public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
   4669             Intent intent, String resolvedType, Bundle bOptions, int userId) {
   4670         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
   4671                 != PackageManager.PERMISSION_GRANTED) {
   4672             final String msg = "Permission Denial: startAssistantActivity() from pid="
   4673                     + Binder.getCallingPid()
   4674                     + ", uid=" + Binder.getCallingUid()
   4675                     + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
   4676             Slog.w(TAG, msg);
   4677             throw new SecurityException(msg);
   4678         }
   4679         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
   4680                 ALLOW_FULL_ONLY, "startAssistantActivity", null);
   4681         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
   4682                 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
   4683                 userId, null, null, "startAssistantActivity");
   4684     }
   4685 
   4686     @Override
   4687     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
   4688             throws RemoteException {
   4689         Slog.i(TAG, "Activity tried to startVoiceInteraction");
   4690         synchronized (this) {
   4691             ActivityRecord activity = getFocusedStack().topActivity();
   4692             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
   4693                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
   4694             }
   4695             if (mRunningVoice != null || activity.getTask().voiceSession != null
   4696                     || activity.voiceSession != null) {
   4697                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
   4698                 return;
   4699             }
   4700             if (activity.pendingVoiceInteractionStart) {
   4701                 Slog.w(TAG, "Pending start of voice interaction already.");
   4702                 return;
   4703             }
   4704             activity.pendingVoiceInteractionStart = true;
   4705         }
   4706         LocalServices.getService(VoiceInteractionManagerInternal.class)
   4707                 .startLocalVoiceInteraction(callingActivity, options);
   4708     }
   4709 
   4710     @Override
   4711     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
   4712         LocalServices.getService(VoiceInteractionManagerInternal.class)
   4713                 .stopLocalVoiceInteraction(callingActivity);
   4714     }
   4715 
   4716     @Override
   4717     public boolean supportsLocalVoiceInteraction() throws RemoteException {
   4718         return LocalServices.getService(VoiceInteractionManagerInternal.class)
   4719                 .supportsLocalVoiceInteraction();
   4720     }
   4721 
   4722     void onLocalVoiceInteractionStartedLocked(IBinder activity,
   4723             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
   4724         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
   4725         if (activityToCallback == null) return;
   4726         activityToCallback.setVoiceSessionLocked(voiceSession);
   4727 
   4728         // Inform the activity
   4729         try {
   4730             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
   4731                     voiceInteractor);
   4732             long token = Binder.clearCallingIdentity();
   4733             try {
   4734                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
   4735             } finally {
   4736                 Binder.restoreCallingIdentity(token);
   4737             }
   4738             // TODO: VI Should we cache the activity so that it's easier to find later
   4739             // rather than scan through all the stacks and activities?
   4740         } catch (RemoteException re) {
   4741             activityToCallback.clearVoiceSessionLocked();
   4742             // TODO: VI Should this terminate the voice session?
   4743         }
   4744     }
   4745 
   4746     @Override
   4747     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
   4748         synchronized (this) {
   4749             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
   4750                 if (keepAwake) {
   4751                     mVoiceWakeLock.acquire();
   4752                 } else {
   4753                     mVoiceWakeLock.release();
   4754                 }
   4755             }
   4756         }
   4757     }
   4758 
   4759     @Override
   4760     public boolean startNextMatchingActivity(IBinder callingActivity,
   4761             Intent intent, Bundle bOptions) {
   4762         // Refuse possible leaked file descriptors
   4763         if (intent != null && intent.hasFileDescriptors() == true) {
   4764             throw new IllegalArgumentException("File descriptors passed in Intent");
   4765         }
   4766         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
   4767 
   4768         synchronized (this) {
   4769             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
   4770             if (r == null) {
   4771                 ActivityOptions.abort(options);
   4772                 return false;
   4773             }
   4774             if (r.app == null || r.app.thread == null) {
   4775                 // The caller is not running...  d'oh!
   4776                 ActivityOptions.abort(options);
   4777                 return false;
   4778             }
   4779             intent = new Intent(intent);
   4780             // The caller is not allowed to change the data.
   4781             intent.setDataAndType(r.intent.getData(), r.intent.getType());
   4782             // And we are resetting to find the next component...
   4783             intent.setComponent(null);
   4784 
   4785             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
   4786 
   4787             ActivityInfo aInfo = null;
   4788             try {
   4789                 List<ResolveInfo> resolves =
   4790                     AppGlobals.getPackageManager().queryIntentActivities(
   4791                             intent, r.resolvedType,
   4792                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
   4793                             UserHandle.getCallingUserId()).getList();
   4794 
   4795                 // Look for the original activity in the list...
   4796                 final int N = resolves != null ? resolves.size() : 0;
   4797                 for (int i=0; i<N; i++) {
   4798                     ResolveInfo rInfo = resolves.get(i);
   4799                     if (rInfo.activityInfo.packageName.equals(r.packageName)
   4800                             && rInfo.activityInfo.name.equals(r.info.name)) {
   4801                         // We found the current one...  the next matching is
   4802                         // after it.
   4803                         i++;
   4804                         if (i<N) {
   4805                             aInfo = resolves.get(i).activityInfo;
   4806                         }
   4807                         if (debug) {
   4808                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
   4809                                     + "/" + r.info.name);
   4810                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
   4811                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
   4812                         }
   4813                         break;
   4814                     }
   4815                 }
   4816             } catch (RemoteException e) {
   4817             }
   4818 
   4819             if (aInfo == null) {
   4820                 // Nobody who is next!
   4821                 ActivityOptions.abort(options);
   4822                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
   4823                 return false;
   4824             }
   4825 
   4826             intent.setComponent(new ComponentName(
   4827                     aInfo.applicationInfo.packageName, aInfo.name));
   4828             intent.setFlags(intent.getFlags()&~(
   4829                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
   4830                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
   4831                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
   4832                     Intent.FLAG_ACTIVITY_NEW_TASK));
   4833 
   4834             // Okay now we need to start the new activity, replacing the
   4835             // currently running activity.  This is a little tricky because
   4836             // we want to start the new one as if the current one is finished,
   4837             // but not finish the current one first so that there is no flicker.
   4838             // And thus...
   4839             final boolean wasFinishing = r.finishing;
   4840             r.finishing = true;
   4841 
   4842             // Propagate reply information over to the new activity.
   4843             final ActivityRecord resultTo = r.resultTo;
   4844             final String resultWho = r.resultWho;
   4845             final int requestCode = r.requestCode;
   4846             r.resultTo = null;
   4847             if (resultTo != null) {
   4848                 resultTo.removeResultsLocked(r, resultWho, requestCode);
   4849             }
   4850 
   4851             final long origId = Binder.clearCallingIdentity();
   4852             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
   4853                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
   4854                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
   4855                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
   4856                     false, false, null, null, null, "startNextMatchingActivity");
   4857             Binder.restoreCallingIdentity(origId);
   4858 
   4859             r.finishing = wasFinishing;
   4860             if (res != ActivityManager.START_SUCCESS) {
   4861                 return false;
   4862             }
   4863             return true;
   4864         }
   4865     }
   4866 
   4867     @Override
   4868     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
   4869         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
   4870             String msg = "Permission Denial: startActivityFromRecents called without " +
   4871                     START_TASKS_FROM_RECENTS;
   4872             Slog.w(TAG, msg);
   4873             throw new SecurityException(msg);
   4874         }
   4875         final long origId = Binder.clearCallingIdentity();
   4876         try {
   4877             synchronized (this) {
   4878                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
   4879             }
   4880         } finally {
   4881             Binder.restoreCallingIdentity(origId);
   4882         }
   4883     }
   4884 
   4885     final int startActivityInPackage(int uid, String callingPackage,
   4886             Intent intent, String resolvedType, IBinder resultTo,
   4887             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
   4888             IActivityContainer container, TaskRecord inTask, String reason) {
   4889 
   4890         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4891                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
   4892 
   4893         // TODO: Switch to user app stacks here.
   4894         int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
   4895                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
   4896                 null, null, null, bOptions, false, userId, container, inTask, reason);
   4897         return ret;
   4898     }
   4899 
   4900     @Override
   4901     public final int startActivities(IApplicationThread caller, String callingPackage,
   4902             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
   4903             int userId) {
   4904         final String reason = "startActivities";
   4905         enforceNotIsolatedCaller(reason);
   4906         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4907                 userId, false, ALLOW_FULL_ONLY, reason, null);
   4908         // TODO: Switch to user app stacks here.
   4909         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
   4910                 resolvedTypes, resultTo, bOptions, userId, reason);
   4911         return ret;
   4912     }
   4913 
   4914     final int startActivitiesInPackage(int uid, String callingPackage,
   4915             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
   4916             Bundle bOptions, int userId) {
   4917 
   4918         final String reason = "startActivityInPackage";
   4919         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4920                 userId, false, ALLOW_FULL_ONLY, reason, null);
   4921         // TODO: Switch to user app stacks here.
   4922         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
   4923                 resultTo, bOptions, userId, reason);
   4924         return ret;
   4925     }
   4926 
   4927     @Override
   4928     public void reportActivityFullyDrawn(IBinder token) {
   4929         synchronized (this) {
   4930             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4931             if (r == null) {
   4932                 return;
   4933             }
   4934             r.reportFullyDrawnLocked();
   4935         }
   4936     }
   4937 
   4938     @Override
   4939     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
   4940         synchronized (this) {
   4941             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4942             if (r == null) {
   4943                 return;
   4944             }
   4945             final long origId = Binder.clearCallingIdentity();
   4946             try {
   4947                 r.setRequestedOrientation(requestedOrientation);
   4948             } finally {
   4949                 Binder.restoreCallingIdentity(origId);
   4950             }
   4951         }
   4952     }
   4953 
   4954     @Override
   4955     public int getRequestedOrientation(IBinder token) {
   4956         synchronized (this) {
   4957             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4958             if (r == null) {
   4959                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
   4960             }
   4961             return r.getRequestedOrientation();
   4962         }
   4963     }
   4964 
   4965     @Override
   4966     public final void requestActivityRelaunch(IBinder token) {
   4967         synchronized(this) {
   4968             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4969             if (r == null) {
   4970                 return;
   4971             }
   4972             final long origId = Binder.clearCallingIdentity();
   4973             try {
   4974                 r.forceNewConfig = true;
   4975                 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
   4976                         true /* preserveWindow */);
   4977             } finally {
   4978                 Binder.restoreCallingIdentity(origId);
   4979             }
   4980         }
   4981     }
   4982 
   4983     /**
   4984      * This is the internal entry point for handling Activity.finish().
   4985      *
   4986      * @param token The Binder token referencing the Activity we want to finish.
   4987      * @param resultCode Result code, if any, from this Activity.
   4988      * @param resultData Result data (Intent), if any, from this Activity.
   4989      * @param finishTask Whether to finish the task associated with this Activity.
   4990      *
   4991      * @return Returns true if the activity successfully finished, or false if it is still running.
   4992      */
   4993     @Override
   4994     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
   4995             int finishTask) {
   4996         // Refuse possible leaked file descriptors
   4997         if (resultData != null && resultData.hasFileDescriptors() == true) {
   4998             throw new IllegalArgumentException("File descriptors passed in Intent");
   4999         }
   5000 
   5001         synchronized(this) {
   5002             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   5003             if (r == null) {
   5004                 return true;
   5005             }
   5006             // Keep track of the root activity of the task before we finish it
   5007             TaskRecord tr = r.getTask();
   5008             ActivityRecord rootR = tr.getRootActivity();
   5009             if (rootR == null) {
   5010                 Slog.w(TAG, "Finishing task with all activities already finished");
   5011             }
   5012             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
   5013             // finish.
   5014             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
   5015                     mStackSupervisor.isLastLockedTask(tr)) {
   5016                 Slog.i(TAG, "Not finishing task in lock task mode");
   5017                 mStackSupervisor.showLockTaskToast();
   5018                 return false;
   5019             }
   5020             if (mController != null) {
   5021                 // Find the first activity that is not finishing.
   5022                 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
   5023                 if (next != null) {
   5024                     // ask watcher if this is allowed
   5025                     boolean resumeOK = true;
   5026                     try {
   5027                         resumeOK = mController.activityResuming(next.packageName);
   5028                     } catch (RemoteException e) {
   5029                         mController = null;
   5030                         Watchdog.getInstance().setActivityController(null);
   5031                     }
   5032 
   5033                     if (!resumeOK) {
   5034                         Slog.i(TAG, "Not finishing activity because controller resumed");
   5035                         return false;
   5036                     }
   5037                 }
   5038             }
   5039             final long origId = Binder.clearCallingIdentity();
   5040             try {
   5041                 boolean res;
   5042                 final boolean finishWithRootActivity =
   5043                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
   5044                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
   5045                         || (finishWithRootActivity && r == rootR)) {
   5046                     // If requested, remove the task that is associated to this activity only if it
   5047                     // was the root activity in the task. The result code and data is ignored
   5048                     // because we don't support returning them across task boundaries. Also, to
   5049                     // keep backwards compatibility we remove the task from recents when finishing
   5050                     // task with root activity.
   5051                     res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
   5052                     if (!res) {
   5053                         Slog.i(TAG, "Removing task failed to finish activity");
   5054                     }
   5055                 } else {
   5056                     res = tr.getStack().requestFinishActivityLocked(token, resultCode,
   5057                             resultData, "app-request", true);
   5058                     if (!res) {
   5059                         Slog.i(TAG, "Failed to finish by app-request");
   5060                     }
   5061                 }
   5062                 return res;
   5063             } finally {
   5064                 Binder.restoreCallingIdentity(origId);
   5065             }
   5066         }
   5067     }
   5068 
   5069     @Override
   5070     public final void finishHeavyWeightApp() {
   5071         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   5072                 != PackageManager.PERMISSION_GRANTED) {
   5073             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
   5074                     + Binder.getCallingPid()
   5075                     + ", uid=" + Binder.getCallingUid()
   5076                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   5077             Slog.w(TAG, msg);
   5078             throw new SecurityException(msg);
   5079         }
   5080 
   5081         synchronized(this) {
   5082             if (mHeavyWeightProcess == null) {
   5083                 return;
   5084             }
   5085 
   5086             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
   5087             for (int i = 0; i < activities.size(); i++) {
   5088                 ActivityRecord r = activities.get(i);
   5089                 if (!r.finishing && r.isInStackLocked()) {
   5090                     r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
   5091                             null, "finish-heavy", true);
   5092                 }
   5093             }
   5094 
   5095             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   5096                     mHeavyWeightProcess.userId, 0));
   5097             mHeavyWeightProcess = null;
   5098         }
   5099     }
   5100 
   5101     @Override
   5102     public void crashApplication(int uid, int initialPid, String packageName, int userId,
   5103             String message) {
   5104         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   5105                 != PackageManager.PERMISSION_GRANTED) {
   5106             String msg = "Permission Denial: crashApplication() from pid="
   5107                     + Binder.getCallingPid()
   5108                     + ", uid=" + Binder.getCallingUid()
   5109                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   5110             Slog.w(TAG, msg);
   5111             throw new SecurityException(msg);
   5112         }
   5113 
   5114         synchronized(this) {
   5115             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
   5116         }
   5117     }
   5118 
   5119     @Override
   5120     public final void finishSubActivity(IBinder token, String resultWho,
   5121             int requestCode) {
   5122         synchronized(this) {
   5123             final long origId = Binder.clearCallingIdentity();
   5124             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   5125             if (r != null) {
   5126                 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
   5127             }
   5128             Binder.restoreCallingIdentity(origId);
   5129         }
   5130     }
   5131 
   5132     @Override
   5133     public boolean finishActivityAffinity(IBinder token) {
   5134         synchronized(this) {
   5135             final long origId = Binder.clearCallingIdentity();
   5136             try {
   5137                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
   5138                 if (r == null) {
   5139                     return false;
   5140                 }
   5141 
   5142                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
   5143                 // can finish.
   5144                 final TaskRecord task = r.getTask();
   5145                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
   5146                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
   5147                     mStackSupervisor.showLockTaskToast();
   5148                     return false;
   5149                 }
   5150                 return task.getStack().finishActivityAffinityLocked(r);
   5151             } finally {
   5152                 Binder.restoreCallingIdentity(origId);
   5153             }
   5154         }
   5155     }
   5156 
   5157     @Override
   5158     public void finishVoiceTask(IVoiceInteractionSession session) {
   5159         synchronized (this) {
   5160             final long origId = Binder.clearCallingIdentity();
   5161             try {
   5162                 // TODO: VI Consider treating local voice interactions and voice tasks
   5163                 // differently here
   5164                 mStackSupervisor.finishVoiceTask(session);
   5165             } finally {
   5166                 Binder.restoreCallingIdentity(origId);
   5167             }
   5168         }
   5169 
   5170     }
   5171 
   5172     @Override
   5173     public boolean releaseActivityInstance(IBinder token) {
   5174         synchronized(this) {
   5175             final long origId = Binder.clearCallingIdentity();
   5176             try {
   5177                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
   5178                 if (r == null) {
   5179                     return false;
   5180                 }
   5181                 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
   5182             } finally {
   5183                 Binder.restoreCallingIdentity(origId);
   5184             }
   5185         }
   5186     }
   5187 
   5188     @Override
   5189     public void releaseSomeActivities(IApplicationThread appInt) {
   5190         synchronized(this) {
   5191             final long origId = Binder.clearCallingIdentity();
   5192             try {
   5193                 ProcessRecord app = getRecordForAppLocked(appInt);
   5194                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
   5195             } finally {
   5196                 Binder.restoreCallingIdentity(origId);
   5197             }
   5198         }
   5199     }
   5200 
   5201     @Override
   5202     public boolean willActivityBeVisible(IBinder token) {
   5203         synchronized(this) {
   5204             ActivityStack stack = ActivityRecord.getStackLocked(token);
   5205             if (stack != null) {
   5206                 return stack.willActivityBeVisibleLocked(token);
   5207             }
   5208             return false;
   5209         }
   5210     }
   5211 
   5212     @Override
   5213     public void overridePendingTransition(IBinder token, String packageName,
   5214             int enterAnim, int exitAnim) {
   5215         synchronized(this) {
   5216             ActivityRecord self = ActivityRecord.isInStackLocked(token);
   5217             if (self == null) {
   5218                 return;
   5219             }
   5220 
   5221             final long origId = Binder.clearCallingIdentity();
   5222 
   5223             if (self.state == ActivityState.RESUMED
   5224                     || self.state == ActivityState.PAUSING) {
   5225                 mWindowManager.overridePendingAppTransition(packageName,
   5226                         enterAnim, exitAnim, null);
   5227             }
   5228 
   5229             Binder.restoreCallingIdentity(origId);
   5230         }
   5231     }
   5232 
   5233     /**
   5234      * Main function for removing an existing process from the activity manager
   5235      * as a result of that process going away.  Clears out all connections
   5236      * to the process.
   5237      */
   5238     private final void handleAppDiedLocked(ProcessRecord app,
   5239             boolean restarting, boolean allowRestart) {
   5240         int pid = app.pid;
   5241         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
   5242                 false /*replacingPid*/);
   5243         if (!kept && !restarting) {
   5244             removeLruProcessLocked(app);
   5245             if (pid > 0) {
   5246                 ProcessList.remove(pid);
   5247             }
   5248         }
   5249 
   5250         if (mProfileProc == app) {
   5251             clearProfilerLocked();
   5252         }
   5253 
   5254         // Remove this application's activities from active lists.
   5255         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
   5256 
   5257         app.activities.clear();
   5258 
   5259         if (app.instr != null) {
   5260             Slog.w(TAG, "Crash of app " + app.processName
   5261                   + " running instrumentation " + app.instr.mClass);
   5262             Bundle info = new Bundle();
   5263             info.putString("shortMsg", "Process crashed.");
   5264             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
   5265         }
   5266 
   5267         mWindowManager.deferSurfaceLayout();
   5268         try {
   5269             if (!restarting && hasVisibleActivities
   5270                     && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
   5271                 // If there was nothing to resume, and we are not already restarting this process, but
   5272                 // there is a visible activity that is hosted by the process...  then make sure all
   5273                 // visible activities are running, taking care of restarting this process.
   5274                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   5275             }
   5276         } finally {
   5277             mWindowManager.continueSurfaceLayout();
   5278         }
   5279     }
   5280 
   5281     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
   5282         final IBinder threadBinder = thread.asBinder();
   5283         // Find the application record.
   5284         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   5285             final ProcessRecord rec = mLruProcesses.get(i);
   5286             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
   5287                 return i;
   5288             }
   5289         }
   5290         return -1;
   5291     }
   5292 
   5293     final ProcessRecord getRecordForAppLocked(
   5294             IApplicationThread thread) {
   5295         if (thread == null) {
   5296             return null;
   5297         }
   5298 
   5299         int appIndex = getLRURecordIndexForAppLocked(thread);
   5300         if (appIndex >= 0) {
   5301             return mLruProcesses.get(appIndex);
   5302         }
   5303 
   5304         // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
   5305         // double-check that.
   5306         final IBinder threadBinder = thread.asBinder();
   5307         final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
   5308         for (int i = pmap.size()-1; i >= 0; i--) {
   5309             final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
   5310             for (int j = procs.size()-1; j >= 0; j--) {
   5311                 final ProcessRecord proc = procs.valueAt(j);
   5312                 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
   5313                     Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
   5314                             + proc);
   5315                     return proc;
   5316                 }
   5317             }
   5318         }
   5319 
   5320         return null;
   5321     }
   5322 
   5323     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
   5324         // If there are no longer any background processes running,
   5325         // and the app that died was not running instrumentation,
   5326         // then tell everyone we are now low on memory.
   5327         boolean haveBg = false;
   5328         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   5329             ProcessRecord rec = mLruProcesses.get(i);
   5330             if (rec.thread != null
   5331                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   5332                 haveBg = true;
   5333                 break;
   5334             }
   5335         }
   5336 
   5337         if (!haveBg) {
   5338             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   5339             if (doReport) {
   5340                 long now = SystemClock.uptimeMillis();
   5341                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
   5342                     doReport = false;
   5343                 } else {
   5344                     mLastMemUsageReportTime = now;
   5345                 }
   5346             }
   5347             final ArrayList<ProcessMemInfo> memInfos
   5348                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
   5349             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
   5350             long now = SystemClock.uptimeMillis();
   5351             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   5352                 ProcessRecord rec = mLruProcesses.get(i);
   5353                 if (rec == dyingProc || rec.thread == null) {
   5354                     continue;
   5355                 }
   5356                 if (doReport) {
   5357                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
   5358                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
   5359                 }
   5360                 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
   5361                     // The low memory report is overriding any current
   5362                     // state for a GC request.  Make sure to do
   5363                     // heavy/important/visible/foreground processes first.
   5364                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   5365                         rec.lastRequestedGc = 0;
   5366                     } else {
   5367                         rec.lastRequestedGc = rec.lastLowMemory;
   5368                     }
   5369                     rec.reportLowMemory = true;
   5370                     rec.lastLowMemory = now;
   5371                     mProcessesToGc.remove(rec);
   5372                     addProcessToGcListLocked(rec);
   5373                 }
   5374             }
   5375             if (doReport) {
   5376                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
   5377                 mHandler.sendMessage(msg);
   5378             }
   5379             scheduleAppGcsLocked();
   5380         }
   5381     }
   5382 
   5383     final void appDiedLocked(ProcessRecord app) {
   5384        appDiedLocked(app, app.pid, app.thread, false);
   5385     }
   5386 
   5387     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
   5388             boolean fromBinderDied) {
   5389         // First check if this ProcessRecord is actually active for the pid.
   5390         synchronized (mPidsSelfLocked) {
   5391             ProcessRecord curProc = mPidsSelfLocked.get(pid);
   5392             if (curProc != app) {
   5393                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
   5394                 return;
   5395             }
   5396         }
   5397 
   5398         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   5399         synchronized (stats) {
   5400             stats.noteProcessDiedLocked(app.info.uid, pid);
   5401         }
   5402 
   5403         if (!app.killed) {
   5404             if (!fromBinderDied) {
   5405                 killProcessQuiet(pid);
   5406             }
   5407             killProcessGroup(app.uid, pid);
   5408             app.killed = true;
   5409         }
   5410 
   5411         // Clean up already done if the process has been re-started.
   5412         if (app.pid == pid && app.thread != null &&
   5413                 app.thread.asBinder() == thread.asBinder()) {
   5414             boolean doLowMem = app.instr == null;
   5415             boolean doOomAdj = doLowMem;
   5416             if (!app.killedByAm) {
   5417                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
   5418                         + ProcessList.makeOomAdjString(app.setAdj)
   5419                         + ProcessList.makeProcStateString(app.setProcState));
   5420                 mAllowLowerMemLevel = true;
   5421             } else {
   5422                 // Note that we always want to do oom adj to update our state with the
   5423                 // new number of procs.
   5424                 mAllowLowerMemLevel = false;
   5425                 doLowMem = false;
   5426             }
   5427             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
   5428                     app.setAdj, app.setProcState);
   5429             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
   5430                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
   5431             handleAppDiedLocked(app, false, true);
   5432 
   5433             if (doOomAdj) {
   5434                 updateOomAdjLocked();
   5435             }
   5436             if (doLowMem) {
   5437                 doLowMemReportIfNeededLocked(app);
   5438             }
   5439         } else if (app.pid != pid) {
   5440             // A new process has already been started.
   5441             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   5442                     + ") has died and restarted (pid " + app.pid + ").");
   5443             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   5444         } else if (DEBUG_PROCESSES) {
   5445             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
   5446                     + thread.asBinder());
   5447         }
   5448     }
   5449 
   5450     /**
   5451      * If a stack trace dump file is configured, dump process stack traces.
   5452      * @param clearTraces causes the dump file to be erased prior to the new
   5453      *    traces being written, if true; when false, the new traces will be
   5454      *    appended to any existing file content.
   5455      * @param firstPids of dalvik VM processes to dump stack traces for first
   5456      * @param lastPids of dalvik VM processes to dump stack traces for last
   5457      * @param nativePids optional list of native pids to dump stack crawls
   5458      * @return file containing stack traces, or null if no dump file is configured
   5459      */
   5460     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
   5461             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
   5462             ArrayList<Integer> nativePids) {
   5463         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   5464         if (tracesPath == null || tracesPath.length() == 0) {
   5465             return null;
   5466         }
   5467 
   5468         File tracesFile = new File(tracesPath);
   5469         try {
   5470             if (clearTraces && tracesFile.exists()) tracesFile.delete();
   5471             tracesFile.createNewFile();
   5472             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   5473         } catch (IOException e) {
   5474             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
   5475             return null;
   5476         }
   5477 
   5478         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativePids);
   5479         return tracesFile;
   5480     }
   5481 
   5482     public static class DumpStackFileObserver extends FileObserver {
   5483         // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
   5484         private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
   5485         static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
   5486 
   5487         private final String mTracesPath;
   5488         private boolean mClosed;
   5489 
   5490         public DumpStackFileObserver(String tracesPath) {
   5491             super(tracesPath, FileObserver.CLOSE_WRITE);
   5492             mTracesPath = tracesPath;
   5493         }
   5494 
   5495         @Override
   5496         public synchronized void onEvent(int event, String path) {
   5497             mClosed = true;
   5498             notify();
   5499         }
   5500 
   5501         public long dumpWithTimeout(int pid, long timeout) {
   5502             sendSignal(pid, SIGNAL_QUIT);
   5503             final long start = SystemClock.elapsedRealtime();
   5504 
   5505             final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
   5506             synchronized (this) {
   5507                 try {
   5508                     wait(waitTime); // Wait for traces file to be closed.
   5509                 } catch (InterruptedException e) {
   5510                     Slog.wtf(TAG, e);
   5511                 }
   5512             }
   5513 
   5514             // This avoids a corner case of passing a negative time to the native
   5515             // trace in case we've already hit the overall timeout.
   5516             final long timeWaited = SystemClock.elapsedRealtime() - start;
   5517             if (timeWaited >= timeout) {
   5518                 return timeWaited;
   5519             }
   5520 
   5521             if (!mClosed) {
   5522                 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
   5523                        ". Attempting native stack collection.");
   5524 
   5525                 final long nativeDumpTimeoutMs = Math.min(
   5526                         NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
   5527 
   5528                 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
   5529                         (int) (nativeDumpTimeoutMs / 1000));
   5530             }
   5531 
   5532             final long end = SystemClock.elapsedRealtime();
   5533             mClosed = false;
   5534 
   5535             return (end - start);
   5536         }
   5537     }
   5538 
   5539     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
   5540             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
   5541             ArrayList<Integer> nativePids) {
   5542         // Use a FileObserver to detect when traces finish writing.
   5543         // The order of traces is considered important to maintain for legibility.
   5544         DumpStackFileObserver observer = new DumpStackFileObserver(tracesPath);
   5545 
   5546         // We must complete all stack dumps within 20 seconds.
   5547         long remainingTime = 20 * 1000;
   5548         try {
   5549             observer.startWatching();
   5550 
   5551             // First collect all of the stacks of the most important pids.
   5552             if (firstPids != null) {
   5553                 int num = firstPids.size();
   5554                 for (int i = 0; i < num; i++) {
   5555                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
   5556                             + firstPids.get(i));
   5557                     final long timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
   5558 
   5559                     remainingTime -= timeTaken;
   5560                     if (remainingTime <= 0) {
   5561                         Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
   5562                             "); deadline exceeded.");
   5563                         return;
   5564                     }
   5565 
   5566                     if (DEBUG_ANR) {
   5567                         Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
   5568                     }
   5569                 }
   5570             }
   5571 
   5572             // Next collect the stacks of the native pids
   5573             if (nativePids != null) {
   5574                 for (int pid : nativePids) {
   5575                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
   5576                     final long nativeDumpTimeoutMs = Math.min(
   5577                             DumpStackFileObserver.NATIVE_DUMP_TIMEOUT_MS, remainingTime);
   5578 
   5579                     final long start = SystemClock.elapsedRealtime();
   5580                     Debug.dumpNativeBacktraceToFileTimeout(
   5581                             pid, tracesPath, (int) (nativeDumpTimeoutMs / 1000));
   5582                     final long timeTaken = SystemClock.elapsedRealtime() - start;
   5583 
   5584                     remainingTime -= timeTaken;
   5585                     if (remainingTime <= 0) {
   5586                         Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
   5587                             "); deadline exceeded.");
   5588                         return;
   5589                     }
   5590 
   5591                     if (DEBUG_ANR) {
   5592                         Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
   5593                     }
   5594                 }
   5595             }
   5596 
   5597             // Lastly, measure CPU usage.
   5598             if (processCpuTracker != null) {
   5599                 processCpuTracker.init();
   5600                 System.gc();
   5601                 processCpuTracker.update();
   5602                 try {
   5603                     synchronized (processCpuTracker) {
   5604                         processCpuTracker.wait(500); // measure over 1/2 second.
   5605                     }
   5606                 } catch (InterruptedException e) {
   5607                 }
   5608                 processCpuTracker.update();
   5609 
   5610                 // We'll take the stack crawls of just the top apps using CPU.
   5611                 final int N = processCpuTracker.countWorkingStats();
   5612                 int numProcs = 0;
   5613                 for (int i=0; i<N && numProcs<5; i++) {
   5614                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
   5615                     if (lastPids.indexOfKey(stats.pid) >= 0) {
   5616                         numProcs++;
   5617 
   5618                         if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
   5619 
   5620                         final long timeTaken = observer.dumpWithTimeout(stats.pid, remainingTime);
   5621                         remainingTime -= timeTaken;
   5622                         if (remainingTime <= 0) {
   5623                             Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + stats.pid +
   5624                                 "); deadline exceeded.");
   5625                             return;
   5626                         }
   5627 
   5628                         if (DEBUG_ANR) {
   5629                             Slog.d(TAG, "Done with extra pid " + stats.pid + " in " + timeTaken + "ms");
   5630                         }
   5631                     } else if (DEBUG_ANR) {
   5632                         Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
   5633                                 + stats.pid);
   5634                     }
   5635                 }
   5636             }
   5637         } finally {
   5638             observer.stopWatching();
   5639         }
   5640     }
   5641 
   5642     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
   5643         if (true || IS_USER_BUILD) {
   5644             return;
   5645         }
   5646         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   5647         if (tracesPath == null || tracesPath.length() == 0) {
   5648             return;
   5649         }
   5650 
   5651         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
   5652         StrictMode.allowThreadDiskWrites();
   5653         try {
   5654             final File tracesFile = new File(tracesPath);
   5655             final File tracesDir = tracesFile.getParentFile();
   5656             final File tracesTmp = new File(tracesDir, "__tmp__");
   5657             try {
   5658                 if (tracesFile.exists()) {
   5659                     tracesTmp.delete();
   5660                     tracesFile.renameTo(tracesTmp);
   5661                 }
   5662                 StringBuilder sb = new StringBuilder();
   5663                 Time tobj = new Time();
   5664                 tobj.set(System.currentTimeMillis());
   5665                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
   5666                 sb.append(": ");
   5667                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
   5668                 sb.append(" since ");
   5669                 sb.append(msg);
   5670                 FileOutputStream fos = new FileOutputStream(tracesFile);
   5671                 fos.write(sb.toString().getBytes());
   5672                 if (app == null) {
   5673                     fos.write("\n*** No application process!".getBytes());
   5674                 }
   5675                 fos.close();
   5676                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   5677             } catch (IOException e) {
   5678                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
   5679                 return;
   5680             }
   5681 
   5682             if (app != null) {
   5683                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
   5684                 firstPids.add(app.pid);
   5685                 dumpStackTraces(tracesPath, firstPids, null, null, null);
   5686             }
   5687 
   5688             File lastTracesFile = null;
   5689             File curTracesFile = null;
   5690             for (int i=9; i>=0; i--) {
   5691                 String name = String.format(Locale.US, "slow%02d.txt", i);
   5692                 curTracesFile = new File(tracesDir, name);
   5693                 if (curTracesFile.exists()) {
   5694                     if (lastTracesFile != null) {
   5695                         curTracesFile.renameTo(lastTracesFile);
   5696                     } else {
   5697                         curTracesFile.delete();
   5698                     }
   5699                 }
   5700                 lastTracesFile = curTracesFile;
   5701             }
   5702             tracesFile.renameTo(curTracesFile);
   5703             if (tracesTmp.exists()) {
   5704                 tracesTmp.renameTo(tracesFile);
   5705             }
   5706         } finally {
   5707             StrictMode.setThreadPolicy(oldPolicy);
   5708         }
   5709     }
   5710 
   5711     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
   5712         if (!mLaunchWarningShown) {
   5713             mLaunchWarningShown = true;
   5714             mUiHandler.post(new Runnable() {
   5715                 @Override
   5716                 public void run() {
   5717                     synchronized (ActivityManagerService.this) {
   5718                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
   5719                         d.show();
   5720                         mUiHandler.postDelayed(new Runnable() {
   5721                             @Override
   5722                             public void run() {
   5723                                 synchronized (ActivityManagerService.this) {
   5724                                     d.dismiss();
   5725                                     mLaunchWarningShown = false;
   5726                                 }
   5727                             }
   5728                         }, 4000);
   5729                     }
   5730                 }
   5731             });
   5732         }
   5733     }
   5734 
   5735     @Override
   5736     public boolean clearApplicationUserData(final String packageName,
   5737             final IPackageDataObserver observer, int userId) {
   5738         enforceNotIsolatedCaller("clearApplicationUserData");
   5739         int uid = Binder.getCallingUid();
   5740         int pid = Binder.getCallingPid();
   5741         userId = mUserController.handleIncomingUser(pid, uid, userId, false,
   5742                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
   5743 
   5744 
   5745         long callingId = Binder.clearCallingIdentity();
   5746         try {
   5747             IPackageManager pm = AppGlobals.getPackageManager();
   5748             int pkgUid = -1;
   5749             synchronized(this) {
   5750                 if (getPackageManagerInternalLocked().isPackageDataProtected(
   5751                         userId, packageName)) {
   5752                     throw new SecurityException(
   5753                             "Cannot clear data for a protected package: " + packageName);
   5754                 }
   5755 
   5756                 try {
   5757                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
   5758                 } catch (RemoteException e) {
   5759                 }
   5760                 if (pkgUid == -1) {
   5761                     Slog.w(TAG, "Invalid packageName: " + packageName);
   5762                     if (observer != null) {
   5763                         try {
   5764                             observer.onRemoveCompleted(packageName, false);
   5765                         } catch (RemoteException e) {
   5766                             Slog.i(TAG, "Observer no longer exists.");
   5767                         }
   5768                     }
   5769                     return false;
   5770                 }
   5771                 if (uid == pkgUid || checkComponentPermission(
   5772                         android.Manifest.permission.CLEAR_APP_USER_DATA,
   5773                         pid, uid, -1, true)
   5774                         == PackageManager.PERMISSION_GRANTED) {
   5775                     forceStopPackageLocked(packageName, pkgUid, "clear data");
   5776                 } else {
   5777                     throw new SecurityException("PID " + pid + " does not have permission "
   5778                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
   5779                                     + " of package " + packageName);
   5780                 }
   5781 
   5782                 // Remove all tasks match the cleared application package and user
   5783                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
   5784                     final TaskRecord tr = mRecentTasks.get(i);
   5785                     final String taskPackageName =
   5786                             tr.getBaseIntent().getComponent().getPackageName();
   5787                     if (tr.userId != userId) continue;
   5788                     if (!taskPackageName.equals(packageName)) continue;
   5789                     mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
   5790                 }
   5791             }
   5792 
   5793             final int pkgUidF = pkgUid;
   5794             final int userIdF = userId;
   5795             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
   5796                 @Override
   5797                 public void onRemoveCompleted(String packageName, boolean succeeded)
   5798                         throws RemoteException {
   5799                     synchronized (ActivityManagerService.this) {
   5800                         finishForceStopPackageLocked(packageName, pkgUidF);
   5801                     }
   5802 
   5803                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
   5804                             Uri.fromParts("package", packageName, null));
   5805                     intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
   5806                     intent.putExtra(Intent.EXTRA_UID, pkgUidF);
   5807                     intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
   5808                     broadcastIntentInPackage("android", SYSTEM_UID, intent,
   5809                             null, null, 0, null, null, null, null, false, false, userIdF);
   5810 
   5811                     if (observer != null) {
   5812                         observer.onRemoveCompleted(packageName, succeeded);
   5813                     }
   5814                 }
   5815             };
   5816 
   5817             try {
   5818                 // Clear application user data
   5819                 pm.clearApplicationUserData(packageName, localObserver, userId);
   5820 
   5821                 synchronized(this) {
   5822                     // Remove all permissions granted from/to this package
   5823                     removeUriPermissionsForPackageLocked(packageName, userId, true);
   5824                 }
   5825 
   5826                 // Reset notification settings.
   5827                 INotificationManager inm = NotificationManager.getService();
   5828                 inm.clearData(packageName, pkgUidF, uid == pkgUidF);
   5829             } catch (RemoteException e) {
   5830             }
   5831         } finally {
   5832             Binder.restoreCallingIdentity(callingId);
   5833         }
   5834         return true;
   5835     }
   5836 
   5837     @Override
   5838     public void killBackgroundProcesses(final String packageName, int userId) {
   5839         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   5840                 != PackageManager.PERMISSION_GRANTED &&
   5841                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
   5842                         != PackageManager.PERMISSION_GRANTED) {
   5843             String msg = "Permission Denial: killBackgroundProcesses() from pid="
   5844                     + Binder.getCallingPid()
   5845                     + ", uid=" + Binder.getCallingUid()
   5846                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   5847             Slog.w(TAG, msg);
   5848             throw new SecurityException(msg);
   5849         }
   5850 
   5851         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   5852                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
   5853         long callingId = Binder.clearCallingIdentity();
   5854         try {
   5855             IPackageManager pm = AppGlobals.getPackageManager();
   5856             synchronized(this) {
   5857                 int appId = -1;
   5858                 try {
   5859                     appId = UserHandle.getAppId(
   5860                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
   5861                 } catch (RemoteException e) {
   5862                 }
   5863                 if (appId == -1) {
   5864                     Slog.w(TAG, "Invalid packageName: " + packageName);
   5865                     return;
   5866                 }
   5867                 killPackageProcessesLocked(packageName, appId, userId,
   5868                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
   5869             }
   5870         } finally {
   5871             Binder.restoreCallingIdentity(callingId);
   5872         }
   5873     }
   5874 
   5875     @Override
   5876     public void killAllBackgroundProcesses() {
   5877         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   5878                 != PackageManager.PERMISSION_GRANTED) {
   5879             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
   5880                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   5881                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   5882             Slog.w(TAG, msg);
   5883             throw new SecurityException(msg);
   5884         }
   5885 
   5886         final long callingId = Binder.clearCallingIdentity();
   5887         try {
   5888             synchronized (this) {
   5889                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
   5890                 final int NP = mProcessNames.getMap().size();
   5891                 for (int ip = 0; ip < NP; ip++) {
   5892                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   5893                     final int NA = apps.size();
   5894                     for (int ia = 0; ia < NA; ia++) {
   5895                         final ProcessRecord app = apps.valueAt(ia);
   5896                         if (app.persistent) {
   5897                             // We don't kill persistent processes.
   5898                             continue;
   5899                         }
   5900                         if (app.removed) {
   5901                             procs.add(app);
   5902                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   5903                             app.removed = true;
   5904                             procs.add(app);
   5905                         }
   5906                     }
   5907                 }
   5908 
   5909                 final int N = procs.size();
   5910                 for (int i = 0; i < N; i++) {
   5911                     removeProcessLocked(procs.get(i), false, true, "kill all background");
   5912                 }
   5913 
   5914                 mAllowLowerMemLevel = true;
   5915 
   5916                 updateOomAdjLocked();
   5917                 doLowMemReportIfNeededLocked(null);
   5918             }
   5919         } finally {
   5920             Binder.restoreCallingIdentity(callingId);
   5921         }
   5922     }
   5923 
   5924     /**
   5925      * Kills all background processes, except those matching any of the
   5926      * specified properties.
   5927      *
   5928      * @param minTargetSdk the target SDK version at or above which to preserve
   5929      *                     processes, or {@code -1} to ignore the target SDK
   5930      * @param maxProcState the process state at or below which to preserve
   5931      *                     processes, or {@code -1} to ignore the process state
   5932      */
   5933     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
   5934         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   5935                 != PackageManager.PERMISSION_GRANTED) {
   5936             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
   5937                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   5938                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   5939             Slog.w(TAG, msg);
   5940             throw new SecurityException(msg);
   5941         }
   5942 
   5943         final long callingId = Binder.clearCallingIdentity();
   5944         try {
   5945             synchronized (this) {
   5946                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
   5947                 final int NP = mProcessNames.getMap().size();
   5948                 for (int ip = 0; ip < NP; ip++) {
   5949                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   5950                     final int NA = apps.size();
   5951                     for (int ia = 0; ia < NA; ia++) {
   5952                         final ProcessRecord app = apps.valueAt(ia);
   5953                         if (app.removed) {
   5954                             procs.add(app);
   5955                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
   5956                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
   5957                             app.removed = true;
   5958                             procs.add(app);
   5959                         }
   5960                     }
   5961                 }
   5962 
   5963                 final int N = procs.size();
   5964                 for (int i = 0; i < N; i++) {
   5965                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
   5966                 }
   5967             }
   5968         } finally {
   5969             Binder.restoreCallingIdentity(callingId);
   5970         }
   5971     }
   5972 
   5973     @Override
   5974     public void forceStopPackage(final String packageName, int userId) {
   5975         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   5976                 != PackageManager.PERMISSION_GRANTED) {
   5977             String msg = "Permission Denial: forceStopPackage() from pid="
   5978                     + Binder.getCallingPid()
   5979                     + ", uid=" + Binder.getCallingUid()
   5980                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   5981             Slog.w(TAG, msg);
   5982             throw new SecurityException(msg);
   5983         }
   5984         final int callingPid = Binder.getCallingPid();
   5985         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
   5986                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
   5987         long callingId = Binder.clearCallingIdentity();
   5988         try {
   5989             IPackageManager pm = AppGlobals.getPackageManager();
   5990             synchronized(this) {
   5991                 int[] users = userId == UserHandle.USER_ALL
   5992                         ? mUserController.getUsers() : new int[] { userId };
   5993                 for (int user : users) {
   5994                     int pkgUid = -1;
   5995                     try {
   5996                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
   5997                                 user);
   5998                     } catch (RemoteException e) {
   5999                     }
   6000                     if (pkgUid == -1) {
   6001                         Slog.w(TAG, "Invalid packageName: " + packageName);
   6002                         continue;
   6003                     }
   6004                     try {
   6005                         pm.setPackageStoppedState(packageName, true, user);
   6006                     } catch (RemoteException e) {
   6007                     } catch (IllegalArgumentException e) {
   6008                         Slog.w(TAG, "Failed trying to unstop package "
   6009                                 + packageName + ": " + e);
   6010                     }
   6011                     if (mUserController.isUserRunningLocked(user, 0)) {
   6012                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
   6013                         finishForceStopPackageLocked(packageName, pkgUid);
   6014                     }
   6015                 }
   6016             }
   6017         } finally {
   6018             Binder.restoreCallingIdentity(callingId);
   6019         }
   6020     }
   6021 
   6022     @Override
   6023     public void addPackageDependency(String packageName) {
   6024         synchronized (this) {
   6025             int callingPid = Binder.getCallingPid();
   6026             if (callingPid == myPid()) {
   6027                 //  Yeah, um, no.
   6028                 return;
   6029             }
   6030             ProcessRecord proc;
   6031             synchronized (mPidsSelfLocked) {
   6032                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   6033             }
   6034             if (proc != null) {
   6035                 if (proc.pkgDeps == null) {
   6036                     proc.pkgDeps = new ArraySet<String>(1);
   6037                 }
   6038                 proc.pkgDeps.add(packageName);
   6039             }
   6040         }
   6041     }
   6042 
   6043     /*
   6044      * The pkg name and app id have to be specified.
   6045      */
   6046     @Override
   6047     public void killApplication(String pkg, int appId, int userId, String reason) {
   6048         if (pkg == null) {
   6049             return;
   6050         }
   6051         // Make sure the uid is valid.
   6052         if (appId < 0) {
   6053             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
   6054             return;
   6055         }
   6056         int callerUid = Binder.getCallingUid();
   6057         // Only the system server can kill an application
   6058         if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
   6059             // Post an aysnc message to kill the application
   6060             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
   6061             msg.arg1 = appId;
   6062             msg.arg2 = userId;
   6063             Bundle bundle = new Bundle();
   6064             bundle.putString("pkg", pkg);
   6065             bundle.putString("reason", reason);
   6066             msg.obj = bundle;
   6067             mHandler.sendMessage(msg);
   6068         } else {
   6069             throw new SecurityException(callerUid + " cannot kill pkg: " +
   6070                     pkg);
   6071         }
   6072     }
   6073 
   6074     @Override
   6075     public void closeSystemDialogs(String reason) {
   6076         enforceNotIsolatedCaller("closeSystemDialogs");
   6077 
   6078         final int pid = Binder.getCallingPid();
   6079         final int uid = Binder.getCallingUid();
   6080         final long origId = Binder.clearCallingIdentity();
   6081         try {
   6082             synchronized (this) {
   6083                 // Only allow this from foreground processes, so that background
   6084                 // applications can't abuse it to prevent system UI from being shown.
   6085                 if (uid >= FIRST_APPLICATION_UID) {
   6086                     ProcessRecord proc;
   6087                     synchronized (mPidsSelfLocked) {
   6088                         proc = mPidsSelfLocked.get(pid);
   6089                     }
   6090                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   6091                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
   6092                                 + " from background process " + proc);
   6093                         return;
   6094                     }
   6095                 }
   6096                 closeSystemDialogsLocked(reason);
   6097             }
   6098         } finally {
   6099             Binder.restoreCallingIdentity(origId);
   6100         }
   6101     }
   6102 
   6103     void closeSystemDialogsLocked(String reason) {
   6104         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
   6105         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   6106                 | Intent.FLAG_RECEIVER_FOREGROUND);
   6107         if (reason != null) {
   6108             intent.putExtra("reason", reason);
   6109         }
   6110         mWindowManager.closeSystemDialogs(reason);
   6111 
   6112         mStackSupervisor.closeSystemDialogsLocked();
   6113 
   6114         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
   6115                 AppOpsManager.OP_NONE, null, false, false,
   6116                 -1, SYSTEM_UID, UserHandle.USER_ALL);
   6117     }
   6118 
   6119     @Override
   6120     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
   6121         enforceNotIsolatedCaller("getProcessMemoryInfo");
   6122         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
   6123         for (int i=pids.length-1; i>=0; i--) {
   6124             ProcessRecord proc;
   6125             int oomAdj;
   6126             synchronized (this) {
   6127                 synchronized (mPidsSelfLocked) {
   6128                     proc = mPidsSelfLocked.get(pids[i]);
   6129                     oomAdj = proc != null ? proc.setAdj : 0;
   6130                 }
   6131             }
   6132             infos[i] = new Debug.MemoryInfo();
   6133             Debug.getMemoryInfo(pids[i], infos[i]);
   6134             if (proc != null) {
   6135                 synchronized (this) {
   6136                     if (proc.thread != null && proc.setAdj == oomAdj) {
   6137                         // Record this for posterity if the process has been stable.
   6138                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
   6139                                 infos[i].getTotalUss(), false, proc.pkgList);
   6140                     }
   6141                 }
   6142             }
   6143         }
   6144         return infos;
   6145     }
   6146 
   6147     @Override
   6148     public long[] getProcessPss(int[] pids) {
   6149         enforceNotIsolatedCaller("getProcessPss");
   6150         long[] pss = new long[pids.length];
   6151         for (int i=pids.length-1; i>=0; i--) {
   6152             ProcessRecord proc;
   6153             int oomAdj;
   6154             synchronized (this) {
   6155                 synchronized (mPidsSelfLocked) {
   6156                     proc = mPidsSelfLocked.get(pids[i]);
   6157                     oomAdj = proc != null ? proc.setAdj : 0;
   6158                 }
   6159             }
   6160             long[] tmpUss = new long[1];
   6161             pss[i] = Debug.getPss(pids[i], tmpUss, null);
   6162             if (proc != null) {
   6163                 synchronized (this) {
   6164                     if (proc.thread != null && proc.setAdj == oomAdj) {
   6165                         // Record this for posterity if the process has been stable.
   6166                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
   6167                     }
   6168                 }
   6169             }
   6170         }
   6171         return pss;
   6172     }
   6173 
   6174     @Override
   6175     public void killApplicationProcess(String processName, int uid) {
   6176         if (processName == null) {
   6177             return;
   6178         }
   6179 
   6180         int callerUid = Binder.getCallingUid();
   6181         // Only the system server can kill an application
   6182         if (callerUid == SYSTEM_UID) {
   6183             synchronized (this) {
   6184                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
   6185                 if (app != null && app.thread != null) {
   6186                     try {
   6187                         app.thread.scheduleSuicide();
   6188                     } catch (RemoteException e) {
   6189                         // If the other end already died, then our work here is done.
   6190                     }
   6191                 } else {
   6192                     Slog.w(TAG, "Process/uid not found attempting kill of "
   6193                             + processName + " / " + uid);
   6194                 }
   6195             }
   6196         } else {
   6197             throw new SecurityException(callerUid + " cannot kill app process: " +
   6198                     processName);
   6199         }
   6200     }
   6201 
   6202     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
   6203         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
   6204                 false, true, false, false, UserHandle.getUserId(uid), reason);
   6205     }
   6206 
   6207     private void finishForceStopPackageLocked(final String packageName, int uid) {
   6208         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
   6209                 Uri.fromParts("package", packageName, null));
   6210         if (!mProcessesReady) {
   6211             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   6212                     | Intent.FLAG_RECEIVER_FOREGROUND);
   6213         }
   6214         intent.putExtra(Intent.EXTRA_UID, uid);
   6215         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
   6216         broadcastIntentLocked(null, null, intent,
   6217                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   6218                 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
   6219     }
   6220 
   6221 
   6222     private final boolean killPackageProcessesLocked(String packageName, int appId,
   6223             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
   6224             boolean doit, boolean evenPersistent, String reason) {
   6225         ArrayList<ProcessRecord> procs = new ArrayList<>();
   6226 
   6227         // Remove all processes this package may have touched: all with the
   6228         // same UID (except for the system or root user), and all whose name
   6229         // matches the package name.
   6230         final int NP = mProcessNames.getMap().size();
   6231         for (int ip=0; ip<NP; ip++) {
   6232             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   6233             final int NA = apps.size();
   6234             for (int ia=0; ia<NA; ia++) {
   6235                 ProcessRecord app = apps.valueAt(ia);
   6236                 if (app.persistent && !evenPersistent) {
   6237                     // we don't kill persistent processes
   6238                     continue;
   6239                 }
   6240                 if (app.removed) {
   6241                     if (doit) {
   6242                         procs.add(app);
   6243                     }
   6244                     continue;
   6245                 }
   6246 
   6247                 // Skip process if it doesn't meet our oom adj requirement.
   6248                 if (app.setAdj < minOomAdj) {
   6249                     continue;
   6250                 }
   6251 
   6252                 // If no package is specified, we call all processes under the
   6253                 // give user id.
   6254                 if (packageName == null) {
   6255                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
   6256                         continue;
   6257                     }
   6258                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
   6259                         continue;
   6260                     }
   6261                 // Package has been specified, we want to hit all processes
   6262                 // that match it.  We need to qualify this by the processes
   6263                 // that are running under the specified app and user ID.
   6264                 } else {
   6265                     final boolean isDep = app.pkgDeps != null
   6266                             && app.pkgDeps.contains(packageName);
   6267                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
   6268                         continue;
   6269                     }
   6270                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
   6271                         continue;
   6272                     }
   6273                     if (!app.pkgList.containsKey(packageName) && !isDep) {
   6274                         continue;
   6275                     }
   6276                 }
   6277 
   6278                 // Process has passed all conditions, kill it!
   6279                 if (!doit) {
   6280                     return true;
   6281                 }
   6282                 app.removed = true;
   6283                 procs.add(app);
   6284             }
   6285         }
   6286 
   6287         int N = procs.size();
   6288         for (int i=0; i<N; i++) {
   6289             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
   6290         }
   6291         updateOomAdjLocked();
   6292         return N > 0;
   6293     }
   6294 
   6295     private void cleanupDisabledPackageComponentsLocked(
   6296             String packageName, int userId, boolean killProcess, String[] changedClasses) {
   6297 
   6298         Set<String> disabledClasses = null;
   6299         boolean packageDisabled = false;
   6300         IPackageManager pm = AppGlobals.getPackageManager();
   6301 
   6302         if (changedClasses == null) {
   6303             // Nothing changed...
   6304             return;
   6305         }
   6306 
   6307         // Determine enable/disable state of the package and its components.
   6308         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
   6309         for (int i = changedClasses.length - 1; i >= 0; i--) {
   6310             final String changedClass = changedClasses[i];
   6311 
   6312             if (changedClass.equals(packageName)) {
   6313                 try {
   6314                     // Entire package setting changed
   6315                     enabled = pm.getApplicationEnabledSetting(packageName,
   6316                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
   6317                 } catch (Exception e) {
   6318                     // No such package/component; probably racing with uninstall.  In any
   6319                     // event it means we have nothing further to do here.
   6320                     return;
   6321                 }
   6322                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
   6323                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
   6324                 if (packageDisabled) {
   6325                     // Entire package is disabled.
   6326                     // No need to continue to check component states.
   6327                     disabledClasses = null;
   6328                     break;
   6329                 }
   6330             } else {
   6331                 try {
   6332                     enabled = pm.getComponentEnabledSetting(
   6333                             new ComponentName(packageName, changedClass),
   6334                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
   6335                 } catch (Exception e) {
   6336                     // As above, probably racing with uninstall.
   6337                     return;
   6338                 }
   6339                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
   6340                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
   6341                     if (disabledClasses == null) {
   6342                         disabledClasses = new ArraySet<>(changedClasses.length);
   6343                     }
   6344                     disabledClasses.add(changedClass);
   6345                 }
   6346             }
   6347         }
   6348 
   6349         if (!packageDisabled && disabledClasses == null) {
   6350             // Nothing to do here...
   6351             return;
   6352         }
   6353 
   6354         // Clean-up disabled activities.
   6355         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
   6356                 packageName, disabledClasses, true, false, userId) && mBooted) {
   6357             mStackSupervisor.resumeFocusedStackTopActivityLocked();
   6358             mStackSupervisor.scheduleIdleLocked();
   6359         }
   6360 
   6361         // Clean-up disabled tasks
   6362         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
   6363 
   6364         // Clean-up disabled services.
   6365         mServices.bringDownDisabledPackageServicesLocked(
   6366                 packageName, disabledClasses, userId, false, killProcess, true);
   6367 
   6368         // Clean-up disabled providers.
   6369         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
   6370         mProviderMap.collectPackageProvidersLocked(
   6371                 packageName, disabledClasses, true, false, userId, providers);
   6372         for (int i = providers.size() - 1; i >= 0; i--) {
   6373             removeDyingProviderLocked(null, providers.get(i), true);
   6374         }
   6375 
   6376         // Clean-up disabled broadcast receivers.
   6377         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
   6378             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
   6379                     packageName, disabledClasses, userId, true);
   6380         }
   6381 
   6382     }
   6383 
   6384     final boolean clearBroadcastQueueForUserLocked(int userId) {
   6385         boolean didSomething = false;
   6386         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
   6387             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
   6388                     null, null, userId, true);
   6389         }
   6390         return didSomething;
   6391     }
   6392 
   6393     final boolean forceStopPackageLocked(String packageName, int appId,
   6394             boolean callerWillRestart, boolean purgeCache, boolean doit,
   6395             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
   6396         int i;
   6397 
   6398         if (userId == UserHandle.USER_ALL && packageName == null) {
   6399             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
   6400         }
   6401 
   6402         if (appId < 0 && packageName != null) {
   6403             try {
   6404                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
   6405                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
   6406             } catch (RemoteException e) {
   6407             }
   6408         }
   6409 
   6410         if (doit) {
   6411             if (packageName != null) {
   6412                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
   6413                         + " user=" + userId + ": " + reason);
   6414             } else {
   6415                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
   6416             }
   6417 
   6418             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
   6419         }
   6420 
   6421         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
   6422                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
   6423                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
   6424 
   6425         didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
   6426 
   6427         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
   6428                 packageName, null, doit, evenPersistent, userId)) {
   6429             if (!doit) {
   6430                 return true;
   6431             }
   6432             didSomething = true;
   6433         }
   6434 
   6435         if (mServices.bringDownDisabledPackageServicesLocked(
   6436                 packageName, null, userId, evenPersistent, true, doit)) {
   6437             if (!doit) {
   6438                 return true;
   6439             }
   6440             didSomething = true;
   6441         }
   6442 
   6443         if (packageName == null) {
   6444             // Remove all sticky broadcasts from this user.
   6445             mStickyBroadcasts.remove(userId);
   6446         }
   6447 
   6448         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
   6449         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
   6450                 userId, providers)) {
   6451             if (!doit) {
   6452                 return true;
   6453             }
   6454             didSomething = true;
   6455         }
   6456         for (i = providers.size() - 1; i >= 0; i--) {
   6457             removeDyingProviderLocked(null, providers.get(i), true);
   6458         }
   6459 
   6460         // Remove transient permissions granted from/to this package/user
   6461         removeUriPermissionsForPackageLocked(packageName, userId, false);
   6462 
   6463         if (doit) {
   6464             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
   6465                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
   6466                         packageName, null, userId, doit);
   6467             }
   6468         }
   6469 
   6470         if (packageName == null || uninstalling) {
   6471             // Remove pending intents.  For now we only do this when force
   6472             // stopping users, because we have some problems when doing this
   6473             // for packages -- app widgets are not currently cleaned up for
   6474             // such packages, so they can be left with bad pending intents.
   6475             if (mIntentSenderRecords.size() > 0) {
   6476                 Iterator<WeakReference<PendingIntentRecord>> it
   6477                         = mIntentSenderRecords.values().iterator();
   6478                 while (it.hasNext()) {
   6479                     WeakReference<PendingIntentRecord> wpir = it.next();
   6480                     if (wpir == null) {
   6481                         it.remove();
   6482                         continue;
   6483                     }
   6484                     PendingIntentRecord pir = wpir.get();
   6485                     if (pir == null) {
   6486                         it.remove();
   6487                         continue;
   6488                     }
   6489                     if (packageName == null) {
   6490                         // Stopping user, remove all objects for the user.
   6491                         if (pir.key.userId != userId) {
   6492                             // Not the same user, skip it.
   6493                             continue;
   6494                         }
   6495                     } else {
   6496                         if (UserHandle.getAppId(pir.uid) != appId) {
   6497                             // Different app id, skip it.
   6498                             continue;
   6499                         }
   6500                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
   6501                             // Different user, skip it.
   6502                             continue;
   6503                         }
   6504                         if (!pir.key.packageName.equals(packageName)) {
   6505                             // Different package, skip it.
   6506                             continue;
   6507                         }
   6508                     }
   6509                     if (!doit) {
   6510                         return true;
   6511                     }
   6512                     didSomething = true;
   6513                     it.remove();
   6514                     makeIntentSenderCanceledLocked(pir);
   6515                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
   6516                         pir.key.activity.pendingResults.remove(pir.ref);
   6517                     }
   6518                 }
   6519             }
   6520         }
   6521 
   6522         if (doit) {
   6523             if (purgeCache && packageName != null) {
   6524                 AttributeCache ac = AttributeCache.instance();
   6525                 if (ac != null) {
   6526                     ac.removePackage(packageName);
   6527                 }
   6528             }
   6529             if (mBooted) {
   6530                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
   6531                 mStackSupervisor.scheduleIdleLocked();
   6532             }
   6533         }
   6534 
   6535         return didSomething;
   6536     }
   6537 
   6538     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
   6539         return removeProcessNameLocked(name, uid, null);
   6540     }
   6541 
   6542     private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
   6543             final ProcessRecord expecting) {
   6544         ProcessRecord old = mProcessNames.get(name, uid);
   6545         // Only actually remove when the currently recorded value matches the
   6546         // record that we expected; if it doesn't match then we raced with a
   6547         // newly created process and we don't want to destroy the new one.
   6548         if ((expecting == null) || (old == expecting)) {
   6549             mProcessNames.remove(name, uid);
   6550         }
   6551         if (old != null && old.uidRecord != null) {
   6552             old.uidRecord.numProcs--;
   6553             if (old.uidRecord.numProcs == 0) {
   6554                 // No more processes using this uid, tell clients it is gone.
   6555                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   6556                         "No more processes in " + old.uidRecord);
   6557                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
   6558                 EventLogTags.writeAmUidStopped(uid);
   6559                 mActiveUids.remove(uid);
   6560                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
   6561             }
   6562             old.uidRecord = null;
   6563         }
   6564         mIsolatedProcesses.remove(uid);
   6565         return old;
   6566     }
   6567 
   6568     private final void addProcessNameLocked(ProcessRecord proc) {
   6569         // We shouldn't already have a process under this name, but just in case we
   6570         // need to clean up whatever may be there now.
   6571         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
   6572         if (old == proc && proc.persistent) {
   6573             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
   6574             Slog.w(TAG, "Re-adding persistent process " + proc);
   6575         } else if (old != null) {
   6576             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
   6577         }
   6578         UidRecord uidRec = mActiveUids.get(proc.uid);
   6579         if (uidRec == null) {
   6580             uidRec = new UidRecord(proc.uid);
   6581             // This is the first appearance of the uid, report it now!
   6582             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   6583                     "Creating new process uid: " + uidRec);
   6584             if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
   6585                     || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
   6586                 uidRec.setWhitelist = uidRec.curWhitelist = true;
   6587             }
   6588             uidRec.updateHasInternetPermission();
   6589             mActiveUids.put(proc.uid, uidRec);
   6590             EventLogTags.writeAmUidRunning(uidRec.uid);
   6591             noteUidProcessState(uidRec.uid, uidRec.curProcState);
   6592             enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
   6593         }
   6594         proc.uidRecord = uidRec;
   6595 
   6596         // Reset render thread tid if it was already set, so new process can set it again.
   6597         proc.renderThreadTid = 0;
   6598         uidRec.numProcs++;
   6599         mProcessNames.put(proc.processName, proc.uid, proc);
   6600         if (proc.isolated) {
   6601             mIsolatedProcesses.put(proc.uid, proc);
   6602         }
   6603     }
   6604 
   6605     boolean removeProcessLocked(ProcessRecord app,
   6606             boolean callerWillRestart, boolean allowRestart, String reason) {
   6607         final String name = app.processName;
   6608         final int uid = app.uid;
   6609         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
   6610             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
   6611 
   6612         ProcessRecord old = mProcessNames.get(name, uid);
   6613         if (old != app) {
   6614             // This process is no longer active, so nothing to do.
   6615             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
   6616             return false;
   6617         }
   6618         removeProcessNameLocked(name, uid);
   6619         if (mHeavyWeightProcess == app) {
   6620             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   6621                     mHeavyWeightProcess.userId, 0));
   6622             mHeavyWeightProcess = null;
   6623         }
   6624         boolean needRestart = false;
   6625         if (app.pid > 0 && app.pid != MY_PID) {
   6626             int pid = app.pid;
   6627             synchronized (mPidsSelfLocked) {
   6628                 mPidsSelfLocked.remove(pid);
   6629                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   6630             }
   6631             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   6632             if (app.isolated) {
   6633                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   6634                 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
   6635             }
   6636             boolean willRestart = false;
   6637             if (app.persistent && !app.isolated) {
   6638                 if (!callerWillRestart) {
   6639                     willRestart = true;
   6640                 } else {
   6641                     needRestart = true;
   6642                 }
   6643             }
   6644             app.kill(reason, true);
   6645             handleAppDiedLocked(app, willRestart, allowRestart);
   6646             if (willRestart) {
   6647                 removeLruProcessLocked(app);
   6648                 addAppLocked(app.info, null, false, null /* ABI override */);
   6649             }
   6650         } else {
   6651             mRemovedProcesses.add(app);
   6652         }
   6653 
   6654         return needRestart;
   6655     }
   6656 
   6657     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
   6658         cleanupAppInLaunchingProvidersLocked(app, true);
   6659         removeProcessLocked(app, false, true, "timeout publishing content providers");
   6660     }
   6661 
   6662     private final void processStartTimedOutLocked(ProcessRecord app) {
   6663         final int pid = app.pid;
   6664         boolean gone = false;
   6665         synchronized (mPidsSelfLocked) {
   6666             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
   6667             if (knownApp != null && knownApp.thread == null) {
   6668                 mPidsSelfLocked.remove(pid);
   6669                 gone = true;
   6670             }
   6671         }
   6672 
   6673         if (gone) {
   6674             Slog.w(TAG, "Process " + app + " failed to attach");
   6675             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
   6676                     pid, app.uid, app.processName);
   6677             removeProcessNameLocked(app.processName, app.uid);
   6678             if (mHeavyWeightProcess == app) {
   6679                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   6680                         mHeavyWeightProcess.userId, 0));
   6681                 mHeavyWeightProcess = null;
   6682             }
   6683             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   6684             if (app.isolated) {
   6685                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   6686             }
   6687             // Take care of any launching providers waiting for this process.
   6688             cleanupAppInLaunchingProvidersLocked(app, true);
   6689             // Take care of any services that are waiting for the process.
   6690             mServices.processStartTimedOutLocked(app);
   6691             app.kill("start timeout", true);
   6692             removeLruProcessLocked(app);
   6693             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
   6694                 Slog.w(TAG, "Unattached app died before backup, skipping");
   6695                 mHandler.post(new Runnable() {
   6696                 @Override
   6697                     public void run(){
   6698                         try {
   6699                             IBackupManager bm = IBackupManager.Stub.asInterface(
   6700                                     ServiceManager.getService(Context.BACKUP_SERVICE));
   6701                             bm.agentDisconnected(app.info.packageName);
   6702                         } catch (RemoteException e) {
   6703                             // Can't happen; the backup manager is local
   6704                         }
   6705                     }
   6706                 });
   6707             }
   6708             if (isPendingBroadcastProcessLocked(pid)) {
   6709                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   6710                 skipPendingBroadcastLocked(pid);
   6711             }
   6712         } else {
   6713             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
   6714         }
   6715     }
   6716 
   6717     private final boolean attachApplicationLocked(IApplicationThread thread,
   6718             int pid) {
   6719 
   6720         // Find the application record that is being attached...  either via
   6721         // the pid if we are running in multiple processes, or just pull the
   6722         // next app record if we are emulating process with anonymous threads.
   6723         ProcessRecord app;
   6724         long startTime = SystemClock.uptimeMillis();
   6725         if (pid != MY_PID && pid >= 0) {
   6726             synchronized (mPidsSelfLocked) {
   6727                 app = mPidsSelfLocked.get(pid);
   6728             }
   6729         } else {
   6730             app = null;
   6731         }
   6732 
   6733         if (app == null) {
   6734             Slog.w(TAG, "No pending application record for pid " + pid
   6735                     + " (IApplicationThread " + thread + "); dropping process");
   6736             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
   6737             if (pid > 0 && pid != MY_PID) {
   6738                 killProcessQuiet(pid);
   6739                 //TODO: killProcessGroup(app.info.uid, pid);
   6740             } else {
   6741                 try {
   6742                     thread.scheduleExit();
   6743                 } catch (Exception e) {
   6744                     // Ignore exceptions.
   6745                 }
   6746             }
   6747             return false;
   6748         }
   6749 
   6750         // If this application record is still attached to a previous
   6751         // process, clean it up now.
   6752         if (app.thread != null) {
   6753             handleAppDiedLocked(app, true, true);
   6754         }
   6755 
   6756         // Tell the process all about itself.
   6757 
   6758         if (DEBUG_ALL) Slog.v(
   6759                 TAG, "Binding process pid " + pid + " to record " + app);
   6760 
   6761         final String processName = app.processName;
   6762         try {
   6763             AppDeathRecipient adr = new AppDeathRecipient(
   6764                     app, pid, thread);
   6765             thread.asBinder().linkToDeath(adr, 0);
   6766             app.deathRecipient = adr;
   6767         } catch (RemoteException e) {
   6768             app.resetPackageList(mProcessStats);
   6769             startProcessLocked(app, "link fail", processName);
   6770             return false;
   6771         }
   6772 
   6773         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
   6774 
   6775         app.makeActive(thread, mProcessStats);
   6776         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
   6777         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   6778         app.forcingToImportant = null;
   6779         updateProcessForegroundLocked(app, false, false);
   6780         app.hasShownUi = false;
   6781         app.debugging = false;
   6782         app.cached = false;
   6783         app.killedByAm = false;
   6784         app.killed = false;
   6785 
   6786 
   6787         // We carefully use the same state that PackageManager uses for
   6788         // filtering, since we use this flag to decide if we need to install
   6789         // providers when user is unlocked later
   6790         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
   6791 
   6792         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   6793 
   6794         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
   6795         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
   6796 
   6797         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
   6798             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
   6799             msg.obj = app;
   6800             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
   6801         }
   6802 
   6803         checkTime(startTime, "attachApplicationLocked: before bindApplication");
   6804 
   6805         if (!normalMode) {
   6806             Slog.i(TAG, "Launching preboot mode app: " + app);
   6807         }
   6808 
   6809         if (DEBUG_ALL) Slog.v(
   6810             TAG, "New app record " + app
   6811             + " thread=" + thread.asBinder() + " pid=" + pid);
   6812         try {
   6813             int testMode = ApplicationThreadConstants.DEBUG_OFF;
   6814             if (mDebugApp != null && mDebugApp.equals(processName)) {
   6815                 testMode = mWaitForDebugger
   6816                     ? ApplicationThreadConstants.DEBUG_WAIT
   6817                     : ApplicationThreadConstants.DEBUG_ON;
   6818                 app.debugging = true;
   6819                 if (mDebugTransient) {
   6820                     mDebugApp = mOrigDebugApp;
   6821                     mWaitForDebugger = mOrigWaitForDebugger;
   6822                 }
   6823             }
   6824             String profileFile = app.instr != null ? app.instr.mProfileFile : null;
   6825             ParcelFileDescriptor profileFd = null;
   6826             int samplingInterval = 0;
   6827             boolean profileAutoStop = false;
   6828             boolean profileStreamingOutput = false;
   6829             if (mProfileApp != null && mProfileApp.equals(processName)) {
   6830                 mProfileProc = app;
   6831                 profileFile = mProfileFile;
   6832                 profileFd = mProfileFd;
   6833                 samplingInterval = mSamplingInterval;
   6834                 profileAutoStop = mAutoStopProfiler;
   6835                 profileStreamingOutput = mStreamingOutput;
   6836             }
   6837             boolean enableTrackAllocation = false;
   6838             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
   6839                 enableTrackAllocation = true;
   6840                 mTrackAllocationApp = null;
   6841             }
   6842 
   6843             // If the app is being launched for restore or full backup, set it up specially
   6844             boolean isRestrictedBackupMode = false;
   6845             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
   6846                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
   6847                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
   6848                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
   6849                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
   6850             }
   6851 
   6852             if (app.instr != null) {
   6853                 notifyPackageUse(app.instr.mClass.getPackageName(),
   6854                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
   6855             }
   6856             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
   6857                     + processName + " with config " + getGlobalConfiguration());
   6858             ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
   6859             app.compat = compatibilityInfoForPackageLocked(appInfo);
   6860             if (profileFd != null) {
   6861                 profileFd = profileFd.dup();
   6862             }
   6863             ProfilerInfo profilerInfo = profileFile == null ? null
   6864                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
   6865                                        profileStreamingOutput);
   6866 
   6867             // We deprecated Build.SERIAL and it is not accessible to
   6868             // apps that target the v2 security sandbox. Since access to
   6869             // the serial is now behind a permission we push down the value.
   6870             String buildSerial = Build.UNKNOWN;
   6871             if (appInfo.targetSandboxVersion != 2) {
   6872                 buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
   6873                         ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
   6874                         .getSerial();
   6875             }
   6876 
   6877             // Check if this is a secondary process that should be incorporated into some
   6878             // currently active instrumentation.  (Note we do this AFTER all of the profiling
   6879             // stuff above because profiling can currently happen only in the primary
   6880             // instrumentation process.)
   6881             if (mActiveInstrumentation.size() > 0 && app.instr == null) {
   6882                 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
   6883                     ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
   6884                     if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
   6885                         if (aInstr.mTargetProcesses.length == 0) {
   6886                             // This is the wildcard mode, where every process brought up for
   6887                             // the target instrumentation should be included.
   6888                             if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
   6889                                 app.instr = aInstr;
   6890                                 aInstr.mRunningProcesses.add(app);
   6891                             }
   6892                         } else {
   6893                             for (String proc : aInstr.mTargetProcesses) {
   6894                                 if (proc.equals(app.processName)) {
   6895                                     app.instr = aInstr;
   6896                                     aInstr.mRunningProcesses.add(app);
   6897                                     break;
   6898                                 }
   6899                             }
   6900                         }
   6901                     }
   6902                 }
   6903             }
   6904 
   6905             checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
   6906             mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
   6907             if (app.instr != null) {
   6908                 thread.bindApplication(processName, appInfo, providers,
   6909                         app.instr.mClass,
   6910                         profilerInfo, app.instr.mArguments,
   6911                         app.instr.mWatcher,
   6912                         app.instr.mUiAutomationConnection, testMode,
   6913                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
   6914                         isRestrictedBackupMode || !normalMode, app.persistent,
   6915                         new Configuration(getGlobalConfiguration()), app.compat,
   6916                         getCommonServicesLocked(app.isolated),
   6917                         mCoreSettingsObserver.getCoreSettingsLocked(),
   6918                         buildSerial);
   6919             } else {
   6920                 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
   6921                         null, null, null, testMode,
   6922                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
   6923                         isRestrictedBackupMode || !normalMode, app.persistent,
   6924                         new Configuration(getGlobalConfiguration()), app.compat,
   6925                         getCommonServicesLocked(app.isolated),
   6926                         mCoreSettingsObserver.getCoreSettingsLocked(),
   6927                         buildSerial);
   6928             }
   6929 
   6930             checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
   6931             updateLruProcessLocked(app, false, null);
   6932             checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
   6933             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
   6934         } catch (Exception e) {
   6935             // todo: Yikes!  What should we do?  For now we will try to
   6936             // start another process, but that could easily get us in
   6937             // an infinite loop of restarting processes...
   6938             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
   6939 
   6940             app.resetPackageList(mProcessStats);
   6941             app.unlinkDeathRecipient();
   6942             startProcessLocked(app, "bind fail", processName);
   6943             return false;
   6944         }
   6945 
   6946         // Remove this record from the list of starting applications.
   6947         mPersistentStartingProcesses.remove(app);
   6948         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
   6949                 "Attach application locked removing on hold: " + app);
   6950         mProcessesOnHold.remove(app);
   6951 
   6952         boolean badApp = false;
   6953         boolean didSomething = false;
   6954 
   6955         // See if the top visible activity is waiting to run in this process...
   6956         if (normalMode) {
   6957             try {
   6958                 if (mStackSupervisor.attachApplicationLocked(app)) {
   6959                     didSomething = true;
   6960                 }
   6961             } catch (Exception e) {
   6962                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
   6963                 badApp = true;
   6964             }
   6965         }
   6966 
   6967         // Find any services that should be running in this process...
   6968         if (!badApp) {
   6969             try {
   6970                 didSomething |= mServices.attachApplicationLocked(app, processName);
   6971                 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
   6972             } catch (Exception e) {
   6973                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
   6974                 badApp = true;
   6975             }
   6976         }
   6977 
   6978         // Check if a next-broadcast receiver is in this process...
   6979         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
   6980             try {
   6981                 didSomething |= sendPendingBroadcastsLocked(app);
   6982                 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
   6983             } catch (Exception e) {
   6984                 // If the app died trying to launch the receiver we declare it 'bad'
   6985                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
   6986                 badApp = true;
   6987             }
   6988         }
   6989 
   6990         // Check whether the next backup agent is in this process...
   6991         if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
   6992             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
   6993                     "New app is backup target, launching agent for " + app);
   6994             notifyPackageUse(mBackupTarget.appInfo.packageName,
   6995                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
   6996             try {
   6997                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
   6998                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
   6999                         mBackupTarget.backupMode);
   7000             } catch (Exception e) {
   7001                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
   7002                 badApp = true;
   7003             }
   7004         }
   7005 
   7006         if (badApp) {
   7007             app.kill("error during init", true);
   7008             handleAppDiedLocked(app, false, true);
   7009             return false;
   7010         }
   7011 
   7012         if (!didSomething) {
   7013             updateOomAdjLocked();
   7014             checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
   7015         }
   7016 
   7017         return true;
   7018     }
   7019 
   7020     @Override
   7021     public final void attachApplication(IApplicationThread thread) {
   7022         synchronized (this) {
   7023             int callingPid = Binder.getCallingPid();
   7024             final long origId = Binder.clearCallingIdentity();
   7025             attachApplicationLocked(thread, callingPid);
   7026             Binder.restoreCallingIdentity(origId);
   7027         }
   7028     }
   7029 
   7030     @Override
   7031     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
   7032         final long origId = Binder.clearCallingIdentity();
   7033         synchronized (this) {
   7034             ActivityStack stack = ActivityRecord.getStackLocked(token);
   7035             if (stack != null) {
   7036                 ActivityRecord r =
   7037                         mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
   7038                                 false /* processPausingActivities */, config);
   7039                 if (stopProfiling) {
   7040                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
   7041                         try {
   7042                             mProfileFd.close();
   7043                         } catch (IOException e) {
   7044                         }
   7045                         clearProfilerLocked();
   7046                     }
   7047                 }
   7048             }
   7049         }
   7050         Binder.restoreCallingIdentity(origId);
   7051     }
   7052 
   7053     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
   7054         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
   7055                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
   7056     }
   7057 
   7058     void enableScreenAfterBoot() {
   7059         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
   7060                 SystemClock.uptimeMillis());
   7061         mWindowManager.enableScreenAfterBoot();
   7062 
   7063         synchronized (this) {
   7064             updateEventDispatchingLocked();
   7065         }
   7066     }
   7067 
   7068     @Override
   7069     public void showBootMessage(final CharSequence msg, final boolean always) {
   7070         if (Binder.getCallingUid() != myUid()) {
   7071             throw new SecurityException();
   7072         }
   7073         mWindowManager.showBootMessage(msg, always);
   7074     }
   7075 
   7076     @Override
   7077     public void keyguardGoingAway(int flags) {
   7078         enforceNotIsolatedCaller("keyguardGoingAway");
   7079         final long token = Binder.clearCallingIdentity();
   7080         try {
   7081             synchronized (this) {
   7082                 mKeyguardController.keyguardGoingAway(flags);
   7083             }
   7084         } finally {
   7085             Binder.restoreCallingIdentity(token);
   7086         }
   7087     }
   7088 
   7089     /**
   7090      * @return whther the keyguard is currently locked.
   7091      */
   7092     boolean isKeyguardLocked() {
   7093         return mKeyguardController.isKeyguardLocked();
   7094     }
   7095 
   7096     final void finishBooting() {
   7097         synchronized (this) {
   7098             if (!mBootAnimationComplete) {
   7099                 mCallFinishBooting = true;
   7100                 return;
   7101             }
   7102             mCallFinishBooting = false;
   7103         }
   7104 
   7105         ArraySet<String> completedIsas = new ArraySet<String>();
   7106         for (String abi : Build.SUPPORTED_ABIS) {
   7107             zygoteProcess.establishZygoteConnectionForAbi(abi);
   7108             final String instructionSet = VMRuntime.getInstructionSet(abi);
   7109             if (!completedIsas.contains(instructionSet)) {
   7110                 try {
   7111                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
   7112                 } catch (InstallerException e) {
   7113                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
   7114                             e.getMessage() +")");
   7115                 }
   7116                 completedIsas.add(instructionSet);
   7117             }
   7118         }
   7119 
   7120         IntentFilter pkgFilter = new IntentFilter();
   7121         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
   7122         pkgFilter.addDataScheme("package");
   7123         mContext.registerReceiver(new BroadcastReceiver() {
   7124             @Override
   7125             public void onReceive(Context context, Intent intent) {
   7126                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
   7127                 if (pkgs != null) {
   7128                     for (String pkg : pkgs) {
   7129                         synchronized (ActivityManagerService.this) {
   7130                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
   7131                                     0, "query restart")) {
   7132                                 setResultCode(Activity.RESULT_OK);
   7133                                 return;
   7134                             }
   7135                         }
   7136                     }
   7137                 }
   7138             }
   7139         }, pkgFilter);
   7140 
   7141         IntentFilter dumpheapFilter = new IntentFilter();
   7142         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
   7143         mContext.registerReceiver(new BroadcastReceiver() {
   7144             @Override
   7145             public void onReceive(Context context, Intent intent) {
   7146                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
   7147                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
   7148                 } else {
   7149                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
   7150                 }
   7151             }
   7152         }, dumpheapFilter);
   7153 
   7154         // Let system services know.
   7155         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
   7156 
   7157         synchronized (this) {
   7158             // Ensure that any processes we had put on hold are now started
   7159             // up.
   7160             final int NP = mProcessesOnHold.size();
   7161             if (NP > 0) {
   7162                 ArrayList<ProcessRecord> procs =
   7163                     new ArrayList<ProcessRecord>(mProcessesOnHold);
   7164                 for (int ip=0; ip<NP; ip++) {
   7165                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
   7166                             + procs.get(ip));
   7167                     startProcessLocked(procs.get(ip), "on-hold", null);
   7168                 }
   7169             }
   7170 
   7171             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   7172                 // Start looking for apps that are abusing wake locks.
   7173                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   7174                 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
   7175                 // Tell anyone interested that we are done booting!
   7176                 SystemProperties.set("sys.boot_completed", "1");
   7177 
   7178                 // And trigger dev.bootcomplete if we are not showing encryption progress
   7179                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
   7180                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
   7181                     SystemProperties.set("dev.bootcomplete", "1");
   7182                 }
   7183                 mUserController.sendBootCompletedLocked(
   7184                         new IIntentReceiver.Stub() {
   7185                             @Override
   7186                             public void performReceive(Intent intent, int resultCode,
   7187                                     String data, Bundle extras, boolean ordered,
   7188                                     boolean sticky, int sendingUser) {
   7189                                 synchronized (ActivityManagerService.this) {
   7190                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
   7191                                             true, false);
   7192                                 }
   7193                             }
   7194                         });
   7195                 scheduleStartProfilesLocked();
   7196             }
   7197         }
   7198     }
   7199 
   7200     @Override
   7201     public void bootAnimationComplete() {
   7202         final boolean callFinishBooting;
   7203         synchronized (this) {
   7204             callFinishBooting = mCallFinishBooting;
   7205             mBootAnimationComplete = true;
   7206         }
   7207         if (callFinishBooting) {
   7208             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
   7209             finishBooting();
   7210             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   7211         }
   7212     }
   7213 
   7214     final void ensureBootCompleted() {
   7215         boolean booting;
   7216         boolean enableScreen;
   7217         synchronized (this) {
   7218             booting = mBooting;
   7219             mBooting = false;
   7220             enableScreen = !mBooted;
   7221             mBooted = true;
   7222         }
   7223 
   7224         if (booting) {
   7225             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
   7226             finishBooting();
   7227             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   7228         }
   7229 
   7230         if (enableScreen) {
   7231             enableScreenAfterBoot();
   7232         }
   7233     }
   7234 
   7235     @Override
   7236     public final void activityResumed(IBinder token) {
   7237         final long origId = Binder.clearCallingIdentity();
   7238         synchronized(this) {
   7239             ActivityRecord.activityResumedLocked(token);
   7240             mWindowManager.notifyAppResumedFinished(token);
   7241         }
   7242         Binder.restoreCallingIdentity(origId);
   7243     }
   7244 
   7245     @Override
   7246     public final void activityPaused(IBinder token) {
   7247         final long origId = Binder.clearCallingIdentity();
   7248         synchronized(this) {
   7249             ActivityStack stack = ActivityRecord.getStackLocked(token);
   7250             if (stack != null) {
   7251                 stack.activityPausedLocked(token, false);
   7252             }
   7253         }
   7254         Binder.restoreCallingIdentity(origId);
   7255     }
   7256 
   7257     @Override
   7258     public final void activityStopped(IBinder token, Bundle icicle,
   7259             PersistableBundle persistentState, CharSequence description) {
   7260         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
   7261 
   7262         // Refuse possible leaked file descriptors
   7263         if (icicle != null && icicle.hasFileDescriptors()) {
   7264             throw new IllegalArgumentException("File descriptors passed in Bundle");
   7265         }
   7266 
   7267         final long origId = Binder.clearCallingIdentity();
   7268 
   7269         synchronized (this) {
   7270             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   7271             if (r != null) {
   7272                 r.activityStoppedLocked(icicle, persistentState, description);
   7273             }
   7274         }
   7275 
   7276         trimApplications();
   7277 
   7278         Binder.restoreCallingIdentity(origId);
   7279     }
   7280 
   7281     @Override
   7282     public final void activityDestroyed(IBinder token) {
   7283         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
   7284         synchronized (this) {
   7285             ActivityStack stack = ActivityRecord.getStackLocked(token);
   7286             if (stack != null) {
   7287                 stack.activityDestroyedLocked(token, "activityDestroyed");
   7288             }
   7289         }
   7290     }
   7291 
   7292     @Override
   7293     public final void activityRelaunched(IBinder token) {
   7294         final long origId = Binder.clearCallingIdentity();
   7295         synchronized (this) {
   7296             mStackSupervisor.activityRelaunchedLocked(token);
   7297         }
   7298         Binder.restoreCallingIdentity(origId);
   7299     }
   7300 
   7301     @Override
   7302     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
   7303             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
   7304         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
   7305                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
   7306         synchronized (this) {
   7307             ActivityRecord record = ActivityRecord.isInStackLocked(token);
   7308             if (record == null) {
   7309                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
   7310                         + "found for: " + token);
   7311             }
   7312             record.setSizeConfigurations(horizontalSizeConfiguration,
   7313                     verticalSizeConfigurations, smallestSizeConfigurations);
   7314         }
   7315     }
   7316 
   7317     @Override
   7318     public final void backgroundResourcesReleased(IBinder token) {
   7319         final long origId = Binder.clearCallingIdentity();
   7320         try {
   7321             synchronized (this) {
   7322                 ActivityStack stack = ActivityRecord.getStackLocked(token);
   7323                 if (stack != null) {
   7324                     stack.backgroundResourcesReleased();
   7325                 }
   7326             }
   7327         } finally {
   7328             Binder.restoreCallingIdentity(origId);
   7329         }
   7330     }
   7331 
   7332     @Override
   7333     public final void notifyLaunchTaskBehindComplete(IBinder token) {
   7334         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
   7335     }
   7336 
   7337     @Override
   7338     public final void notifyEnterAnimationComplete(IBinder token) {
   7339         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
   7340     }
   7341 
   7342     @Override
   7343     public String getCallingPackage(IBinder token) {
   7344         synchronized (this) {
   7345             ActivityRecord r = getCallingRecordLocked(token);
   7346             return r != null ? r.info.packageName : null;
   7347         }
   7348     }
   7349 
   7350     @Override
   7351     public ComponentName getCallingActivity(IBinder token) {
   7352         synchronized (this) {
   7353             ActivityRecord r = getCallingRecordLocked(token);
   7354             return r != null ? r.intent.getComponent() : null;
   7355         }
   7356     }
   7357 
   7358     private ActivityRecord getCallingRecordLocked(IBinder token) {
   7359         ActivityRecord r = ActivityRecord.isInStackLocked(token);
   7360         if (r == null) {
   7361             return null;
   7362         }
   7363         return r.resultTo;
   7364     }
   7365 
   7366     @Override
   7367     public ComponentName getActivityClassForToken(IBinder token) {
   7368         synchronized(this) {
   7369             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   7370             if (r == null) {
   7371                 return null;
   7372             }
   7373             return r.intent.getComponent();
   7374         }
   7375     }
   7376 
   7377     @Override
   7378     public String getPackageForToken(IBinder token) {
   7379         synchronized(this) {
   7380             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   7381             if (r == null) {
   7382                 return null;
   7383             }
   7384             return r.packageName;
   7385         }
   7386     }
   7387 
   7388     @Override
   7389     public boolean isRootVoiceInteraction(IBinder token) {
   7390         synchronized(this) {
   7391             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   7392             if (r == null) {
   7393                 return false;
   7394             }
   7395             return r.rootVoiceInteraction;
   7396         }
   7397     }
   7398 
   7399     @Override
   7400     public IIntentSender getIntentSender(int type,
   7401             String packageName, IBinder token, String resultWho,
   7402             int requestCode, Intent[] intents, String[] resolvedTypes,
   7403             int flags, Bundle bOptions, int userId) {
   7404         enforceNotIsolatedCaller("getIntentSender");
   7405         // Refuse possible leaked file descriptors
   7406         if (intents != null) {
   7407             if (intents.length < 1) {
   7408                 throw new IllegalArgumentException("Intents array length must be >= 1");
   7409             }
   7410             for (int i=0; i<intents.length; i++) {
   7411                 Intent intent = intents[i];
   7412                 if (intent != null) {
   7413                     if (intent.hasFileDescriptors()) {
   7414                         throw new IllegalArgumentException("File descriptors passed in Intent");
   7415                     }
   7416                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
   7417                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   7418                         throw new IllegalArgumentException(
   7419                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   7420                     }
   7421                     intents[i] = new Intent(intent);
   7422                 }
   7423             }
   7424             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
   7425                 throw new IllegalArgumentException(
   7426                         "Intent array length does not match resolvedTypes length");
   7427             }
   7428         }
   7429         if (bOptions != null) {
   7430             if (bOptions.hasFileDescriptors()) {
   7431                 throw new IllegalArgumentException("File descriptors passed in options");
   7432             }
   7433         }
   7434 
   7435         synchronized(this) {
   7436             int callingUid = Binder.getCallingUid();
   7437             int origUserId = userId;
   7438             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
   7439                     type == ActivityManager.INTENT_SENDER_BROADCAST,
   7440                     ALLOW_NON_FULL, "getIntentSender", null);
   7441             if (origUserId == UserHandle.USER_CURRENT) {
   7442                 // We don't want to evaluate this until the pending intent is
   7443                 // actually executed.  However, we do want to always do the
   7444                 // security checking for it above.
   7445                 userId = UserHandle.USER_CURRENT;
   7446             }
   7447             try {
   7448                 if (callingUid != 0 && callingUid != SYSTEM_UID) {
   7449                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
   7450                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
   7451                     if (!UserHandle.isSameApp(callingUid, uid)) {
   7452                         String msg = "Permission Denial: getIntentSender() from pid="
   7453                             + Binder.getCallingPid()
   7454                             + ", uid=" + Binder.getCallingUid()
   7455                             + ", (need uid=" + uid + ")"
   7456                             + " is not allowed to send as package " + packageName;
   7457                         Slog.w(TAG, msg);
   7458                         throw new SecurityException(msg);
   7459                     }
   7460                 }
   7461 
   7462                 return getIntentSenderLocked(type, packageName, callingUid, userId,
   7463                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
   7464 
   7465             } catch (RemoteException e) {
   7466                 throw new SecurityException(e);
   7467             }
   7468         }
   7469     }
   7470 
   7471     IIntentSender getIntentSenderLocked(int type, String packageName,
   7472             int callingUid, int userId, IBinder token, String resultWho,
   7473             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
   7474             Bundle bOptions) {
   7475         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
   7476         ActivityRecord activity = null;
   7477         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   7478             activity = ActivityRecord.isInStackLocked(token);
   7479             if (activity == null) {
   7480                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
   7481                 return null;
   7482             }
   7483             if (activity.finishing) {
   7484                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
   7485                 return null;
   7486             }
   7487         }
   7488 
   7489         // We're going to be splicing together extras before sending, so we're
   7490         // okay poking into any contained extras.
   7491         if (intents != null) {
   7492             for (int i = 0; i < intents.length; i++) {
   7493                 intents[i].setDefusable(true);
   7494             }
   7495         }
   7496         Bundle.setDefusable(bOptions, true);
   7497 
   7498         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
   7499         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
   7500         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
   7501         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
   7502                 |PendingIntent.FLAG_UPDATE_CURRENT);
   7503 
   7504         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
   7505                 type, packageName, activity, resultWho,
   7506                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
   7507         WeakReference<PendingIntentRecord> ref;
   7508         ref = mIntentSenderRecords.get(key);
   7509         PendingIntentRecord rec = ref != null ? ref.get() : null;
   7510         if (rec != null) {
   7511             if (!cancelCurrent) {
   7512                 if (updateCurrent) {
   7513                     if (rec.key.requestIntent != null) {
   7514                         rec.key.requestIntent.replaceExtras(intents != null ?
   7515                                 intents[intents.length - 1] : null);
   7516                     }
   7517                     if (intents != null) {
   7518                         intents[intents.length-1] = rec.key.requestIntent;
   7519                         rec.key.allIntents = intents;
   7520                         rec.key.allResolvedTypes = resolvedTypes;
   7521                     } else {
   7522                         rec.key.allIntents = null;
   7523                         rec.key.allResolvedTypes = null;
   7524                     }
   7525                 }
   7526                 return rec;
   7527             }
   7528             makeIntentSenderCanceledLocked(rec);
   7529             mIntentSenderRecords.remove(key);
   7530         }
   7531         if (noCreate) {
   7532             return rec;
   7533         }
   7534         rec = new PendingIntentRecord(this, key, callingUid);
   7535         mIntentSenderRecords.put(key, rec.ref);
   7536         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   7537             if (activity.pendingResults == null) {
   7538                 activity.pendingResults
   7539                         = new HashSet<WeakReference<PendingIntentRecord>>();
   7540             }
   7541             activity.pendingResults.add(rec.ref);
   7542         }
   7543         return rec;
   7544     }
   7545 
   7546     @Override
   7547     public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
   7548             Intent intent, String resolvedType,
   7549             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
   7550         if (target instanceof PendingIntentRecord) {
   7551             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
   7552                     whitelistToken, finishedReceiver, requiredPermission, options);
   7553         } else {
   7554             if (intent == null) {
   7555                 // Weird case: someone has given us their own custom IIntentSender, and now
   7556                 // they have someone else trying to send to it but of course this isn't
   7557                 // really a PendingIntent, so there is no base Intent, and the caller isn't
   7558                 // supplying an Intent... but we never want to dispatch a null Intent to
   7559                 // a receiver, so um...  let's make something up.
   7560                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
   7561                 intent = new Intent(Intent.ACTION_MAIN);
   7562             }
   7563             try {
   7564                 target.send(code, intent, resolvedType, whitelistToken, null,
   7565                         requiredPermission, options);
   7566             } catch (RemoteException e) {
   7567             }
   7568             // Platform code can rely on getting a result back when the send is done, but if
   7569             // this intent sender is from outside of the system we can't rely on it doing that.
   7570             // So instead we don't give it the result receiver, and instead just directly
   7571             // report the finish immediately.
   7572             if (finishedReceiver != null) {
   7573                 try {
   7574                     finishedReceiver.performReceive(intent, 0,
   7575                             null, null, false, false, UserHandle.getCallingUserId());
   7576                 } catch (RemoteException e) {
   7577                 }
   7578             }
   7579             return 0;
   7580         }
   7581     }
   7582 
   7583     @Override
   7584     public void cancelIntentSender(IIntentSender sender) {
   7585         if (!(sender instanceof PendingIntentRecord)) {
   7586             return;
   7587         }
   7588         synchronized(this) {
   7589             PendingIntentRecord rec = (PendingIntentRecord)sender;
   7590             try {
   7591                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
   7592                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
   7593                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
   7594                     String msg = "Permission Denial: cancelIntentSender() from pid="
   7595                         + Binder.getCallingPid()
   7596                         + ", uid=" + Binder.getCallingUid()
   7597                         + " is not allowed to cancel package "
   7598                         + rec.key.packageName;
   7599                     Slog.w(TAG, msg);
   7600                     throw new SecurityException(msg);
   7601                 }
   7602             } catch (RemoteException e) {
   7603                 throw new SecurityException(e);
   7604             }
   7605             cancelIntentSenderLocked(rec, true);
   7606         }
   7607     }
   7608 
   7609     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
   7610         makeIntentSenderCanceledLocked(rec);
   7611         mIntentSenderRecords.remove(rec.key);
   7612         if (cleanActivity && rec.key.activity != null) {
   7613             rec.key.activity.pendingResults.remove(rec.ref);
   7614         }
   7615     }
   7616 
   7617     void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
   7618         rec.canceled = true;
   7619         RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
   7620         if (callbacks != null) {
   7621             mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
   7622         }
   7623     }
   7624 
   7625     @Override
   7626     public String getPackageForIntentSender(IIntentSender pendingResult) {
   7627         if (!(pendingResult instanceof PendingIntentRecord)) {
   7628             return null;
   7629         }
   7630         try {
   7631             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   7632             return res.key.packageName;
   7633         } catch (ClassCastException e) {
   7634         }
   7635         return null;
   7636     }
   7637 
   7638     @Override
   7639     public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
   7640         if (!(sender instanceof PendingIntentRecord)) {
   7641             return;
   7642         }
   7643         synchronized(this) {
   7644             ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
   7645         }
   7646     }
   7647 
   7648     @Override
   7649     public void unregisterIntentSenderCancelListener(IIntentSender sender,
   7650             IResultReceiver receiver) {
   7651         if (!(sender instanceof PendingIntentRecord)) {
   7652             return;
   7653         }
   7654         synchronized(this) {
   7655             ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
   7656         }
   7657     }
   7658 
   7659     @Override
   7660     public int getUidForIntentSender(IIntentSender sender) {
   7661         if (sender instanceof PendingIntentRecord) {
   7662             try {
   7663                 PendingIntentRecord res = (PendingIntentRecord)sender;
   7664                 return res.uid;
   7665             } catch (ClassCastException e) {
   7666             }
   7667         }
   7668         return -1;
   7669     }
   7670 
   7671     @Override
   7672     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
   7673         if (!(pendingResult instanceof PendingIntentRecord)) {
   7674             return false;
   7675         }
   7676         try {
   7677             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   7678             if (res.key.allIntents == null) {
   7679                 return false;
   7680             }
   7681             for (int i=0; i<res.key.allIntents.length; i++) {
   7682                 Intent intent = res.key.allIntents[i];
   7683                 if (intent.getPackage() != null && intent.getComponent() != null) {
   7684                     return false;
   7685                 }
   7686             }
   7687             return true;
   7688         } catch (ClassCastException e) {
   7689         }
   7690         return false;
   7691     }
   7692 
   7693     @Override
   7694     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
   7695         if (!(pendingResult instanceof PendingIntentRecord)) {
   7696             return false;
   7697         }
   7698         try {
   7699             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   7700             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
   7701                 return true;
   7702             }
   7703             return false;
   7704         } catch (ClassCastException e) {
   7705         }
   7706         return false;
   7707     }
   7708 
   7709     @Override
   7710     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
   7711         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
   7712                 "getIntentForIntentSender()");
   7713         if (!(pendingResult instanceof PendingIntentRecord)) {
   7714             return null;
   7715         }
   7716         try {
   7717             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   7718             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
   7719         } catch (ClassCastException e) {
   7720         }
   7721         return null;
   7722     }
   7723 
   7724     @Override
   7725     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
   7726         if (!(pendingResult instanceof PendingIntentRecord)) {
   7727             return null;
   7728         }
   7729         try {
   7730             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   7731             synchronized (this) {
   7732                 return getTagForIntentSenderLocked(res, prefix);
   7733             }
   7734         } catch (ClassCastException e) {
   7735         }
   7736         return null;
   7737     }
   7738 
   7739     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
   7740         final Intent intent = res.key.requestIntent;
   7741         if (intent != null) {
   7742             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
   7743                     || res.lastTagPrefix.equals(prefix))) {
   7744                 return res.lastTag;
   7745             }
   7746             res.lastTagPrefix = prefix;
   7747             final StringBuilder sb = new StringBuilder(128);
   7748             if (prefix != null) {
   7749                 sb.append(prefix);
   7750             }
   7751             if (intent.getAction() != null) {
   7752                 sb.append(intent.getAction());
   7753             } else if (intent.getComponent() != null) {
   7754                 intent.getComponent().appendShortString(sb);
   7755             } else {
   7756                 sb.append("?");
   7757             }
   7758             return res.lastTag = sb.toString();
   7759         }
   7760         return null;
   7761     }
   7762 
   7763     @Override
   7764     public void setProcessLimit(int max) {
   7765         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   7766                 "setProcessLimit()");
   7767         synchronized (this) {
   7768             mConstants.setOverrideMaxCachedProcesses(max);
   7769         }
   7770         trimApplications();
   7771     }
   7772 
   7773     @Override
   7774     public int getProcessLimit() {
   7775         synchronized (this) {
   7776             return mConstants.getOverrideMaxCachedProcesses();
   7777         }
   7778     }
   7779 
   7780     void importanceTokenDied(ImportanceToken token) {
   7781         synchronized (ActivityManagerService.this) {
   7782             synchronized (mPidsSelfLocked) {
   7783                 ImportanceToken cur
   7784                     = mImportantProcesses.get(token.pid);
   7785                 if (cur != token) {
   7786                     return;
   7787                 }
   7788                 mImportantProcesses.remove(token.pid);
   7789                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
   7790                 if (pr == null) {
   7791                     return;
   7792                 }
   7793                 pr.forcingToImportant = null;
   7794                 updateProcessForegroundLocked(pr, false, false);
   7795             }
   7796             updateOomAdjLocked();
   7797         }
   7798     }
   7799 
   7800     @Override
   7801     public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
   7802         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   7803                 "setProcessImportant()");
   7804         synchronized(this) {
   7805             boolean changed = false;
   7806 
   7807             synchronized (mPidsSelfLocked) {
   7808                 ProcessRecord pr = mPidsSelfLocked.get(pid);
   7809                 if (pr == null && isForeground) {
   7810                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
   7811                     return;
   7812                 }
   7813                 ImportanceToken oldToken = mImportantProcesses.get(pid);
   7814                 if (oldToken != null) {
   7815                     oldToken.token.unlinkToDeath(oldToken, 0);
   7816                     mImportantProcesses.remove(pid);
   7817                     if (pr != null) {
   7818                         pr.forcingToImportant = null;
   7819                     }
   7820                     changed = true;
   7821                 }
   7822                 if (isForeground && token != null) {
   7823                     ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
   7824                         @Override
   7825                         public void binderDied() {
   7826                             importanceTokenDied(this);
   7827                         }
   7828                     };
   7829                     try {
   7830                         token.linkToDeath(newToken, 0);
   7831                         mImportantProcesses.put(pid, newToken);
   7832                         pr.forcingToImportant = newToken;
   7833                         changed = true;
   7834                     } catch (RemoteException e) {
   7835                         // If the process died while doing this, we will later
   7836                         // do the cleanup with the process death link.
   7837                     }
   7838                 }
   7839             }
   7840 
   7841             if (changed) {
   7842                 updateOomAdjLocked();
   7843             }
   7844         }
   7845     }
   7846 
   7847     @Override
   7848     public boolean isAppForeground(int uid) throws RemoteException {
   7849         synchronized (this) {
   7850             UidRecord uidRec = mActiveUids.get(uid);
   7851             if (uidRec == null || uidRec.idle) {
   7852                 return false;
   7853             }
   7854             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   7855         }
   7856     }
   7857 
   7858     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
   7859     // be guarded by permission checking.
   7860     int getUidState(int uid) {
   7861         synchronized (this) {
   7862             return getUidStateLocked(uid);
   7863         }
   7864     }
   7865 
   7866     int getUidStateLocked(int uid) {
   7867         UidRecord uidRec = mActiveUids.get(uid);
   7868         return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
   7869     }
   7870 
   7871     @Override
   7872     public boolean isInMultiWindowMode(IBinder token) {
   7873         final long origId = Binder.clearCallingIdentity();
   7874         try {
   7875             synchronized(this) {
   7876                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   7877                 if (r == null) {
   7878                     return false;
   7879                 }
   7880                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
   7881                 return !r.getTask().mFullscreen;
   7882             }
   7883         } finally {
   7884             Binder.restoreCallingIdentity(origId);
   7885         }
   7886     }
   7887 
   7888     @Override
   7889     public boolean isInPictureInPictureMode(IBinder token) {
   7890         final long origId = Binder.clearCallingIdentity();
   7891         try {
   7892             synchronized(this) {
   7893                 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
   7894             }
   7895         } finally {
   7896             Binder.restoreCallingIdentity(origId);
   7897         }
   7898     }
   7899 
   7900     private boolean isInPictureInPictureMode(ActivityRecord r) {
   7901         if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
   7902                 r.getStack().isInStackLocked(r) == null) {
   7903             return false;
   7904         }
   7905 
   7906         // If we are animating to fullscreen then we have already dispatched the PIP mode
   7907         // changed, so we should reflect that check here as well.
   7908         final PinnedActivityStack stack = r.getStack();
   7909         final PinnedStackWindowController windowController = stack.getWindowContainerController();
   7910         return !windowController.isAnimatingBoundsToFullscreen();
   7911     }
   7912 
   7913     @Override
   7914     public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
   7915         final long origId = Binder.clearCallingIdentity();
   7916         try {
   7917             synchronized(this) {
   7918                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
   7919                         "enterPictureInPictureMode", token, params);
   7920 
   7921                 // If the activity is already in picture in picture mode, then just return early
   7922                 if (isInPictureInPictureMode(r)) {
   7923                     return true;
   7924                 }
   7925 
   7926                 // Activity supports picture-in-picture, now check that we can enter PiP at this
   7927                 // point, if it is
   7928                 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
   7929                         false /* noThrow */, false /* beforeStopping */)) {
   7930                     return false;
   7931                 }
   7932 
   7933                 final Runnable enterPipRunnable = () -> {
   7934                     // Only update the saved args from the args that are set
   7935                     r.pictureInPictureArgs.copyOnlySet(params);
   7936                     final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
   7937                     final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
   7938                     // Adjust the source bounds by the insets for the transition down
   7939                     final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
   7940                     mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
   7941                             true /* moveHomeStackToFront */, "enterPictureInPictureMode");
   7942                     final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
   7943                     stack.setPictureInPictureAspectRatio(aspectRatio);
   7944                     stack.setPictureInPictureActions(actions);
   7945 
   7946                     MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
   7947                             r.supportsPictureInPictureWhilePausing);
   7948                     logPictureInPictureArgs(params);
   7949                 };
   7950 
   7951                 if (isKeyguardLocked()) {
   7952                     // If the keyguard is showing or occluded, then try and dismiss it before
   7953                     // entering picture-in-picture (this will prompt the user to authenticate if the
   7954                     // device is currently locked).
   7955                     try {
   7956                         dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
   7957                             @Override
   7958                             public void onDismissError() throws RemoteException {
   7959                                 // Do nothing
   7960                             }
   7961 
   7962                             @Override
   7963                             public void onDismissSucceeded() throws RemoteException {
   7964                                 mHandler.post(enterPipRunnable);
   7965                             }
   7966 
   7967                             @Override
   7968                             public void onDismissCancelled() throws RemoteException {
   7969                                 // Do nothing
   7970                             }
   7971                         });
   7972                     } catch (RemoteException e) {
   7973                         // Local call
   7974                     }
   7975                 } else {
   7976                     // Enter picture in picture immediately otherwise
   7977                     enterPipRunnable.run();
   7978                 }
   7979                 return true;
   7980             }
   7981         } finally {
   7982             Binder.restoreCallingIdentity(origId);
   7983         }
   7984     }
   7985 
   7986     @Override
   7987     public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
   7988         final long origId = Binder.clearCallingIdentity();
   7989         try {
   7990             synchronized(this) {
   7991                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
   7992                         "setPictureInPictureParams", token, params);
   7993 
   7994                 // Only update the saved args from the args that are set
   7995                 r.pictureInPictureArgs.copyOnlySet(params);
   7996                 if (r.getStack().getStackId() == PINNED_STACK_ID) {
   7997                     // If the activity is already in picture-in-picture, update the pinned stack now
   7998                     // if it is not already expanding to fullscreen. Otherwise, the arguments will
   7999                     // be used the next time the activity enters PiP
   8000                     final PinnedActivityStack stack = r.getStack();
   8001                     if (!stack.isAnimatingBoundsToFullscreen()) {
   8002                         stack.setPictureInPictureAspectRatio(
   8003                                 r.pictureInPictureArgs.getAspectRatio());
   8004                         stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
   8005                     }
   8006                 }
   8007                 logPictureInPictureArgs(params);
   8008             }
   8009         } finally {
   8010             Binder.restoreCallingIdentity(origId);
   8011         }
   8012     }
   8013 
   8014     @Override
   8015     public int getMaxNumPictureInPictureActions(IBinder token) {
   8016         // Currently, this is a static constant, but later, we may change this to be dependent on
   8017         // the context of the activity
   8018         return 3;
   8019     }
   8020 
   8021     private void logPictureInPictureArgs(PictureInPictureParams params) {
   8022         if (params.hasSetActions()) {
   8023             MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
   8024                     params.getActions().size());
   8025         }
   8026         if (params.hasSetAspectRatio()) {
   8027             LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
   8028             lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
   8029             MetricsLogger.action(lm);
   8030         }
   8031     }
   8032 
   8033     /**
   8034      * Checks the state of the system and the activity associated with the given {@param token} to
   8035      * verify that picture-in-picture is supported for that activity.
   8036      *
   8037      * @return the activity record for the given {@param token} if all the checks pass.
   8038      */
   8039     private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
   8040             IBinder token, PictureInPictureParams params) {
   8041         if (!mSupportsPictureInPicture) {
   8042             throw new IllegalStateException(caller
   8043                     + ": Device doesn't support picture-in-picture mode.");
   8044         }
   8045 
   8046         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   8047         if (r == null) {
   8048             throw new IllegalStateException(caller
   8049                     + ": Can't find activity for token=" + token);
   8050         }
   8051 
   8052         if (!r.supportsPictureInPicture()) {
   8053             throw new IllegalStateException(caller
   8054                     + ": Current activity does not support picture-in-picture.");
   8055         }
   8056 
   8057         if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
   8058             throw new IllegalStateException(caller
   8059                     + ": Activities on the home, assistant, or recents stack not supported");
   8060         }
   8061 
   8062         if (params.hasSetAspectRatio()
   8063                 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
   8064                         params.getAspectRatio())) {
   8065             final float minAspectRatio = mContext.getResources().getFloat(
   8066                     com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
   8067             final float maxAspectRatio = mContext.getResources().getFloat(
   8068                     com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
   8069             throw new IllegalArgumentException(String.format(caller
   8070                     + ": Aspect ratio is too extreme (must be between %f and %f).",
   8071                             minAspectRatio, maxAspectRatio));
   8072         }
   8073 
   8074         // Truncate the number of actions if necessary
   8075         params.truncateActions(getMaxNumPictureInPictureActions(token));
   8076 
   8077         return r;
   8078     }
   8079 
   8080     // =========================================================
   8081     // PROCESS INFO
   8082     // =========================================================
   8083 
   8084     static class ProcessInfoService extends IProcessInfoService.Stub {
   8085         final ActivityManagerService mActivityManagerService;
   8086         ProcessInfoService(ActivityManagerService activityManagerService) {
   8087             mActivityManagerService = activityManagerService;
   8088         }
   8089 
   8090         @Override
   8091         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
   8092             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
   8093                     /*in*/ pids, /*out*/ states, null);
   8094         }
   8095 
   8096         @Override
   8097         public void getProcessStatesAndOomScoresFromPids(
   8098                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
   8099             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
   8100                     /*in*/ pids, /*out*/ states, /*out*/ scores);
   8101         }
   8102     }
   8103 
   8104     /**
   8105      * For each PID in the given input array, write the current process state
   8106      * for that process into the states array, or -1 to indicate that no
   8107      * process with the given PID exists. If scores array is provided, write
   8108      * the oom score for the process into the scores array, with INVALID_ADJ
   8109      * indicating the PID doesn't exist.
   8110      */
   8111     public void getProcessStatesAndOomScoresForPIDs(
   8112             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
   8113         if (scores != null) {
   8114             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
   8115                     "getProcessStatesAndOomScoresForPIDs()");
   8116         }
   8117 
   8118         if (pids == null) {
   8119             throw new NullPointerException("pids");
   8120         } else if (states == null) {
   8121             throw new NullPointerException("states");
   8122         } else if (pids.length != states.length) {
   8123             throw new IllegalArgumentException("pids and states arrays have different lengths!");
   8124         } else if (scores != null && pids.length != scores.length) {
   8125             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
   8126         }
   8127 
   8128         synchronized (mPidsSelfLocked) {
   8129             for (int i = 0; i < pids.length; i++) {
   8130                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
   8131                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
   8132                         pr.curProcState;
   8133                 if (scores != null) {
   8134                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
   8135                 }
   8136             }
   8137         }
   8138     }
   8139 
   8140     // =========================================================
   8141     // PERMISSIONS
   8142     // =========================================================
   8143 
   8144     static class PermissionController extends IPermissionController.Stub {
   8145         ActivityManagerService mActivityManagerService;
   8146         PermissionController(ActivityManagerService activityManagerService) {
   8147             mActivityManagerService = activityManagerService;
   8148         }
   8149 
   8150         @Override
   8151         public boolean checkPermission(String permission, int pid, int uid) {
   8152             return mActivityManagerService.checkPermission(permission, pid,
   8153                     uid) == PackageManager.PERMISSION_GRANTED;
   8154         }
   8155 
   8156         @Override
   8157         public String[] getPackagesForUid(int uid) {
   8158             return mActivityManagerService.mContext.getPackageManager()
   8159                     .getPackagesForUid(uid);
   8160         }
   8161 
   8162         @Override
   8163         public boolean isRuntimePermission(String permission) {
   8164             try {
   8165                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
   8166                         .getPermissionInfo(permission, 0);
   8167                 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
   8168                         == PermissionInfo.PROTECTION_DANGEROUS;
   8169             } catch (NameNotFoundException nnfe) {
   8170                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
   8171             }
   8172             return false;
   8173         }
   8174     }
   8175 
   8176     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
   8177         @Override
   8178         public int checkComponentPermission(String permission, int pid, int uid,
   8179                 int owningUid, boolean exported) {
   8180             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
   8181                     owningUid, exported);
   8182         }
   8183 
   8184         @Override
   8185         public Object getAMSLock() {
   8186             return ActivityManagerService.this;
   8187         }
   8188     }
   8189 
   8190     /**
   8191      * This can be called with or without the global lock held.
   8192      */
   8193     int checkComponentPermission(String permission, int pid, int uid,
   8194             int owningUid, boolean exported) {
   8195         if (pid == MY_PID) {
   8196             return PackageManager.PERMISSION_GRANTED;
   8197         }
   8198         return ActivityManager.checkComponentPermission(permission, uid,
   8199                 owningUid, exported);
   8200     }
   8201 
   8202     /**
   8203      * As the only public entry point for permissions checking, this method
   8204      * can enforce the semantic that requesting a check on a null global
   8205      * permission is automatically denied.  (Internally a null permission
   8206      * string is used when calling {@link #checkComponentPermission} in cases
   8207      * when only uid-based security is needed.)
   8208      *
   8209      * This can be called with or without the global lock held.
   8210      */
   8211     @Override
   8212     public int checkPermission(String permission, int pid, int uid) {
   8213         if (permission == null) {
   8214             return PackageManager.PERMISSION_DENIED;
   8215         }
   8216         return checkComponentPermission(permission, pid, uid, -1, true);
   8217     }
   8218 
   8219     @Override
   8220     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
   8221         if (permission == null) {
   8222             return PackageManager.PERMISSION_DENIED;
   8223         }
   8224 
   8225         // We might be performing an operation on behalf of an indirect binder
   8226         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
   8227         // client identity accordingly before proceeding.
   8228         Identity tlsIdentity = sCallerIdentity.get();
   8229         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
   8230             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
   8231                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
   8232             uid = tlsIdentity.uid;
   8233             pid = tlsIdentity.pid;
   8234         }
   8235 
   8236         return checkComponentPermission(permission, pid, uid, -1, true);
   8237     }
   8238 
   8239     /**
   8240      * Binder IPC calls go through the public entry point.
   8241      * This can be called with or without the global lock held.
   8242      */
   8243     int checkCallingPermission(String permission) {
   8244         return checkPermission(permission,
   8245                 Binder.getCallingPid(),
   8246                 UserHandle.getAppId(Binder.getCallingUid()));
   8247     }
   8248 
   8249     /**
   8250      * This can be called with or without the global lock held.
   8251      */
   8252     void enforceCallingPermission(String permission, String func) {
   8253         if (checkCallingPermission(permission)
   8254                 == PackageManager.PERMISSION_GRANTED) {
   8255             return;
   8256         }
   8257 
   8258         String msg = "Permission Denial: " + func + " from pid="
   8259                 + Binder.getCallingPid()
   8260                 + ", uid=" + Binder.getCallingUid()
   8261                 + " requires " + permission;
   8262         Slog.w(TAG, msg);
   8263         throw new SecurityException(msg);
   8264     }
   8265 
   8266     /**
   8267      * Determine if UID is holding permissions required to access {@link Uri} in
   8268      * the given {@link ProviderInfo}. Final permission checking is always done
   8269      * in {@link ContentProvider}.
   8270      */
   8271     private final boolean checkHoldingPermissionsLocked(
   8272             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
   8273         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8274                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
   8275         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
   8276             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
   8277                     != PERMISSION_GRANTED) {
   8278                 return false;
   8279             }
   8280         }
   8281         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
   8282     }
   8283 
   8284     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
   8285             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
   8286         if (pi.applicationInfo.uid == uid) {
   8287             return true;
   8288         } else if (!pi.exported) {
   8289             return false;
   8290         }
   8291 
   8292         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
   8293         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
   8294         try {
   8295             // check if target holds top-level <provider> permissions
   8296             if (!readMet && pi.readPermission != null && considerUidPermissions
   8297                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
   8298                 readMet = true;
   8299             }
   8300             if (!writeMet && pi.writePermission != null && considerUidPermissions
   8301                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
   8302                 writeMet = true;
   8303             }
   8304 
   8305             // track if unprotected read/write is allowed; any denied
   8306             // <path-permission> below removes this ability
   8307             boolean allowDefaultRead = pi.readPermission == null;
   8308             boolean allowDefaultWrite = pi.writePermission == null;
   8309 
   8310             // check if target holds any <path-permission> that match uri
   8311             final PathPermission[] pps = pi.pathPermissions;
   8312             if (pps != null) {
   8313                 final String path = grantUri.uri.getPath();
   8314                 int i = pps.length;
   8315                 while (i > 0 && (!readMet || !writeMet)) {
   8316                     i--;
   8317                     PathPermission pp = pps[i];
   8318                     if (pp.match(path)) {
   8319                         if (!readMet) {
   8320                             final String pprperm = pp.getReadPermission();
   8321                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8322                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
   8323                                     + ": match=" + pp.match(path)
   8324                                     + " check=" + pm.checkUidPermission(pprperm, uid));
   8325                             if (pprperm != null) {
   8326                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
   8327                                         == PERMISSION_GRANTED) {
   8328                                     readMet = true;
   8329                                 } else {
   8330                                     allowDefaultRead = false;
   8331                                 }
   8332                             }
   8333                         }
   8334                         if (!writeMet) {
   8335                             final String ppwperm = pp.getWritePermission();
   8336                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8337                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
   8338                                     + ": match=" + pp.match(path)
   8339                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
   8340                             if (ppwperm != null) {
   8341                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
   8342                                         == PERMISSION_GRANTED) {
   8343                                     writeMet = true;
   8344                                 } else {
   8345                                     allowDefaultWrite = false;
   8346                                 }
   8347                             }
   8348                         }
   8349                     }
   8350                 }
   8351             }
   8352 
   8353             // grant unprotected <provider> read/write, if not blocked by
   8354             // <path-permission> above
   8355             if (allowDefaultRead) readMet = true;
   8356             if (allowDefaultWrite) writeMet = true;
   8357 
   8358         } catch (RemoteException e) {
   8359             return false;
   8360         }
   8361 
   8362         return readMet && writeMet;
   8363     }
   8364 
   8365     public boolean isAppStartModeDisabled(int uid, String packageName) {
   8366         synchronized (this) {
   8367             return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
   8368                     == ActivityManager.APP_START_MODE_DISABLED;
   8369         }
   8370     }
   8371 
   8372     // Unified app-op and target sdk check
   8373     int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
   8374         // Apps that target O+ are always subject to background check
   8375         if (packageTargetSdk >= Build.VERSION_CODES.O) {
   8376             if (DEBUG_BACKGROUND_CHECK) {
   8377                 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
   8378             }
   8379             return ActivityManager.APP_START_MODE_DELAYED_RIGID;
   8380         }
   8381         // ...and legacy apps get an AppOp check
   8382         int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
   8383                 uid, packageName);
   8384         if (DEBUG_BACKGROUND_CHECK) {
   8385             Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
   8386         }
   8387         switch (appop) {
   8388             case AppOpsManager.MODE_ALLOWED:
   8389                 return ActivityManager.APP_START_MODE_NORMAL;
   8390             case AppOpsManager.MODE_IGNORED:
   8391                 return ActivityManager.APP_START_MODE_DELAYED;
   8392             default:
   8393                 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
   8394         }
   8395     }
   8396 
   8397     // Service launch is available to apps with run-in-background exemptions but
   8398     // some other background operations are not.  If we're doing a check
   8399     // of service-launch policy, allow those callers to proceed unrestricted.
   8400     int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
   8401         // Persistent app?
   8402         if (mPackageManagerInt.isPackagePersistent(packageName)) {
   8403             if (DEBUG_BACKGROUND_CHECK) {
   8404                 Slog.i(TAG, "App " + uid + "/" + packageName
   8405                         + " is persistent; not restricted in background");
   8406             }
   8407             return ActivityManager.APP_START_MODE_NORMAL;
   8408         }
   8409 
   8410         // Non-persistent but background whitelisted?
   8411         if (uidOnBackgroundWhitelist(uid)) {
   8412             if (DEBUG_BACKGROUND_CHECK) {
   8413                 Slog.i(TAG, "App " + uid + "/" + packageName
   8414                         + " on background whitelist; not restricted in background");
   8415             }
   8416             return ActivityManager.APP_START_MODE_NORMAL;
   8417         }
   8418 
   8419         // Is this app on the battery whitelist?
   8420         if (isOnDeviceIdleWhitelistLocked(uid)) {
   8421             if (DEBUG_BACKGROUND_CHECK) {
   8422                 Slog.i(TAG, "App " + uid + "/" + packageName
   8423                         + " on idle whitelist; not restricted in background");
   8424             }
   8425             return ActivityManager.APP_START_MODE_NORMAL;
   8426         }
   8427 
   8428         // None of the service-policy criteria apply, so we apply the common criteria
   8429         return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
   8430     }
   8431 
   8432     int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
   8433             int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
   8434         UidRecord uidRec = mActiveUids.get(uid);
   8435         if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
   8436                 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
   8437                 + (uidRec != null ? uidRec.idle : false));
   8438         if (uidRec == null || alwaysRestrict || uidRec.idle) {
   8439             boolean ephemeral;
   8440             if (uidRec == null) {
   8441                 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
   8442                         UserHandle.getUserId(uid), packageName);
   8443             } else {
   8444                 ephemeral = uidRec.ephemeral;
   8445             }
   8446 
   8447             if (ephemeral) {
   8448                 // We are hard-core about ephemeral apps not running in the background.
   8449                 return ActivityManager.APP_START_MODE_DISABLED;
   8450             } else {
   8451                 if (disabledOnly) {
   8452                     // The caller is only interested in whether app starts are completely
   8453                     // disabled for the given package (that is, it is an instant app).  So
   8454                     // we don't need to go further, which is all just seeing if we should
   8455                     // apply a "delayed" mode for a regular app.
   8456                     return ActivityManager.APP_START_MODE_NORMAL;
   8457                 }
   8458                 final int startMode = (alwaysRestrict)
   8459                         ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
   8460                         : appServicesRestrictedInBackgroundLocked(uid, packageName,
   8461                                 packageTargetSdk);
   8462                 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
   8463                         + " pkg=" + packageName + " startMode=" + startMode
   8464                         + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
   8465                 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
   8466                     // This is an old app that has been forced into a "compatible as possible"
   8467                     // mode of background check.  To increase compatibility, we will allow other
   8468                     // foreground apps to cause its services to start.
   8469                     if (callingPid >= 0) {
   8470                         ProcessRecord proc;
   8471                         synchronized (mPidsSelfLocked) {
   8472                             proc = mPidsSelfLocked.get(callingPid);
   8473                         }
   8474                         if (proc != null &&
   8475                                 !ActivityManager.isProcStateBackground(proc.curProcState)) {
   8476                             // Whoever is instigating this is in the foreground, so we will allow it
   8477                             // to go through.
   8478                             return ActivityManager.APP_START_MODE_NORMAL;
   8479                         }
   8480                     }
   8481                 }
   8482                 return startMode;
   8483             }
   8484         }
   8485         return ActivityManager.APP_START_MODE_NORMAL;
   8486     }
   8487 
   8488     boolean isOnDeviceIdleWhitelistLocked(int uid) {
   8489         final int appId = UserHandle.getAppId(uid);
   8490         return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
   8491                 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
   8492                 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
   8493     }
   8494 
   8495     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
   8496         ProviderInfo pi = null;
   8497         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
   8498         if (cpr != null) {
   8499             pi = cpr.info;
   8500         } else {
   8501             try {
   8502                 pi = AppGlobals.getPackageManager().resolveContentProvider(
   8503                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
   8504                         userHandle);
   8505             } catch (RemoteException ex) {
   8506             }
   8507         }
   8508         return pi;
   8509     }
   8510 
   8511     void grantEphemeralAccessLocked(int userId, Intent intent,
   8512             int targetAppId, int ephemeralAppId) {
   8513         getPackageManagerInternalLocked().
   8514                 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
   8515     }
   8516 
   8517     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
   8518         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
   8519         if (targetUris != null) {
   8520             return targetUris.get(grantUri);
   8521         }
   8522         return null;
   8523     }
   8524 
   8525     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
   8526             String targetPkg, int targetUid, GrantUri grantUri) {
   8527         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
   8528         if (targetUris == null) {
   8529             targetUris = Maps.newArrayMap();
   8530             mGrantedUriPermissions.put(targetUid, targetUris);
   8531         }
   8532 
   8533         UriPermission perm = targetUris.get(grantUri);
   8534         if (perm == null) {
   8535             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
   8536             targetUris.put(grantUri, perm);
   8537         }
   8538 
   8539         return perm;
   8540     }
   8541 
   8542     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
   8543             final int modeFlags) {
   8544         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
   8545         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
   8546                 : UriPermission.STRENGTH_OWNED;
   8547 
   8548         // Root gets to do everything.
   8549         if (uid == 0) {
   8550             return true;
   8551         }
   8552 
   8553         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   8554         if (perms == null) return false;
   8555 
   8556         // First look for exact match
   8557         final UriPermission exactPerm = perms.get(grantUri);
   8558         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
   8559             return true;
   8560         }
   8561 
   8562         // No exact match, look for prefixes
   8563         final int N = perms.size();
   8564         for (int i = 0; i < N; i++) {
   8565             final UriPermission perm = perms.valueAt(i);
   8566             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
   8567                     && perm.getStrength(modeFlags) >= minStrength) {
   8568                 return true;
   8569             }
   8570         }
   8571 
   8572         return false;
   8573     }
   8574 
   8575     /**
   8576      * @param uri This uri must NOT contain an embedded userId.
   8577      * @param userId The userId in which the uri is to be resolved.
   8578      */
   8579     @Override
   8580     public int checkUriPermission(Uri uri, int pid, int uid,
   8581             final int modeFlags, int userId, IBinder callerToken) {
   8582         enforceNotIsolatedCaller("checkUriPermission");
   8583 
   8584         // Another redirected-binder-call permissions check as in
   8585         // {@link checkPermissionWithToken}.
   8586         Identity tlsIdentity = sCallerIdentity.get();
   8587         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
   8588             uid = tlsIdentity.uid;
   8589             pid = tlsIdentity.pid;
   8590         }
   8591 
   8592         // Our own process gets to do everything.
   8593         if (pid == MY_PID) {
   8594             return PackageManager.PERMISSION_GRANTED;
   8595         }
   8596         synchronized (this) {
   8597             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
   8598                     ? PackageManager.PERMISSION_GRANTED
   8599                     : PackageManager.PERMISSION_DENIED;
   8600         }
   8601     }
   8602 
   8603     /**
   8604      * Check if the targetPkg can be granted permission to access uri by
   8605      * the callingUid using the given modeFlags.  Throws a security exception
   8606      * if callingUid is not allowed to do this.  Returns the uid of the target
   8607      * if the URI permission grant should be performed; returns -1 if it is not
   8608      * needed (for example targetPkg already has permission to access the URI).
   8609      * If you already know the uid of the target, you can supply it in
   8610      * lastTargetUid else set that to -1.
   8611      */
   8612     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
   8613             final int modeFlags, int lastTargetUid) {
   8614         if (!Intent.isAccessUriMode(modeFlags)) {
   8615             return -1;
   8616         }
   8617 
   8618         if (targetPkg != null) {
   8619             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8620                     "Checking grant " + targetPkg + " permission to " + grantUri);
   8621         }
   8622 
   8623         final IPackageManager pm = AppGlobals.getPackageManager();
   8624 
   8625         // If this is not a content: uri, we can't do anything with it.
   8626         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
   8627             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8628                     "Can't grant URI permission for non-content URI: " + grantUri);
   8629             return -1;
   8630         }
   8631 
   8632         final String authority = grantUri.uri.getAuthority();
   8633         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
   8634                 MATCH_DEBUG_TRIAGED_MISSING);
   8635         if (pi == null) {
   8636             Slog.w(TAG, "No content provider found for permission check: " +
   8637                     grantUri.uri.toSafeString());
   8638             return -1;
   8639         }
   8640 
   8641         int targetUid = lastTargetUid;
   8642         if (targetUid < 0 && targetPkg != null) {
   8643             try {
   8644                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
   8645                         UserHandle.getUserId(callingUid));
   8646                 if (targetUid < 0) {
   8647                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8648                             "Can't grant URI permission no uid for: " + targetPkg);
   8649                     return -1;
   8650                 }
   8651             } catch (RemoteException ex) {
   8652                 return -1;
   8653             }
   8654         }
   8655 
   8656         // If we're extending a persistable grant, then we always need to create
   8657         // the grant data structure so that take/release APIs work
   8658         if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
   8659             return targetUid;
   8660         }
   8661 
   8662         if (targetUid >= 0) {
   8663             // First...  does the target actually need this permission?
   8664             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
   8665                 // No need to grant the target this permission.
   8666                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8667                         "Target " + targetPkg + " already has full permission to " + grantUri);
   8668                 return -1;
   8669             }
   8670         } else {
   8671             // First...  there is no target package, so can anyone access it?
   8672             boolean allowed = pi.exported;
   8673             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   8674                 if (pi.readPermission != null) {
   8675                     allowed = false;
   8676                 }
   8677             }
   8678             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   8679                 if (pi.writePermission != null) {
   8680                     allowed = false;
   8681                 }
   8682             }
   8683             if (allowed) {
   8684                 return -1;
   8685             }
   8686         }
   8687 
   8688         /* There is a special cross user grant if:
   8689          * - The target is on another user.
   8690          * - Apps on the current user can access the uri without any uid permissions.
   8691          * In this case, we grant a uri permission, even if the ContentProvider does not normally
   8692          * grant uri permissions.
   8693          */
   8694         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
   8695                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
   8696                 modeFlags, false /*without considering the uid permissions*/);
   8697 
   8698         // Second...  is the provider allowing granting of URI permissions?
   8699         if (!specialCrossUserGrant) {
   8700             if (!pi.grantUriPermissions) {
   8701                 throw new SecurityException("Provider " + pi.packageName
   8702                         + "/" + pi.name
   8703                         + " does not allow granting of Uri permissions (uri "
   8704                         + grantUri + ")");
   8705             }
   8706             if (pi.uriPermissionPatterns != null) {
   8707                 final int N = pi.uriPermissionPatterns.length;
   8708                 boolean allowed = false;
   8709                 for (int i=0; i<N; i++) {
   8710                     if (pi.uriPermissionPatterns[i] != null
   8711                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
   8712                         allowed = true;
   8713                         break;
   8714                     }
   8715                 }
   8716                 if (!allowed) {
   8717                     throw new SecurityException("Provider " + pi.packageName
   8718                             + "/" + pi.name
   8719                             + " does not allow granting of permission to path of Uri "
   8720                             + grantUri);
   8721                 }
   8722             }
   8723         }
   8724 
   8725         // Third...  does the caller itself have permission to access
   8726         // this uri?
   8727         final int callingAppId = UserHandle.getAppId(callingUid);
   8728         if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
   8729             if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
   8730                 // Exempted authority for cropping user photos in Settings app
   8731             } else {
   8732                 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
   8733                         + " grant to " + grantUri + "; use startActivityAsCaller() instead");
   8734                 return -1;
   8735             }
   8736         }
   8737         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
   8738             // Require they hold a strong enough Uri permission
   8739             if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
   8740                 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
   8741                     throw new SecurityException(
   8742                             "UID " + callingUid + " does not have permission to " + grantUri
   8743                                     + "; you could obtain access using ACTION_OPEN_DOCUMENT "
   8744                                     + "or related APIs");
   8745                 } else {
   8746                     throw new SecurityException(
   8747                             "UID " + callingUid + " does not have permission to " + grantUri);
   8748                 }
   8749             }
   8750         }
   8751         return targetUid;
   8752     }
   8753 
   8754     /**
   8755      * @param uri This uri must NOT contain an embedded userId.
   8756      * @param userId The userId in which the uri is to be resolved.
   8757      */
   8758     @Override
   8759     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
   8760             final int modeFlags, int userId) {
   8761         enforceNotIsolatedCaller("checkGrantUriPermission");
   8762         synchronized(this) {
   8763             return checkGrantUriPermissionLocked(callingUid, targetPkg,
   8764                     new GrantUri(userId, uri, false), modeFlags, -1);
   8765         }
   8766     }
   8767 
   8768     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
   8769             final int modeFlags, UriPermissionOwner owner) {
   8770         if (!Intent.isAccessUriMode(modeFlags)) {
   8771             return;
   8772         }
   8773 
   8774         // So here we are: the caller has the assumed permission
   8775         // to the uri, and the target doesn't.  Let's now give this to
   8776         // the target.
   8777 
   8778         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8779                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
   8780 
   8781         final String authority = grantUri.uri.getAuthority();
   8782         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
   8783                 MATCH_DEBUG_TRIAGED_MISSING);
   8784         if (pi == null) {
   8785             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
   8786             return;
   8787         }
   8788 
   8789         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
   8790             grantUri.prefix = true;
   8791         }
   8792         final UriPermission perm = findOrCreateUriPermissionLocked(
   8793                 pi.packageName, targetPkg, targetUid, grantUri);
   8794         perm.grantModes(modeFlags, owner);
   8795     }
   8796 
   8797     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
   8798             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
   8799         if (targetPkg == null) {
   8800             throw new NullPointerException("targetPkg");
   8801         }
   8802         int targetUid;
   8803         final IPackageManager pm = AppGlobals.getPackageManager();
   8804         try {
   8805             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
   8806         } catch (RemoteException ex) {
   8807             return;
   8808         }
   8809 
   8810         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
   8811                 targetUid);
   8812         if (targetUid < 0) {
   8813             return;
   8814         }
   8815 
   8816         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
   8817                 owner);
   8818     }
   8819 
   8820     static class NeededUriGrants extends ArrayList<GrantUri> {
   8821         final String targetPkg;
   8822         final int targetUid;
   8823         final int flags;
   8824 
   8825         NeededUriGrants(String targetPkg, int targetUid, int flags) {
   8826             this.targetPkg = targetPkg;
   8827             this.targetUid = targetUid;
   8828             this.flags = flags;
   8829         }
   8830     }
   8831 
   8832     /**
   8833      * Like checkGrantUriPermissionLocked, but takes an Intent.
   8834      */
   8835     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
   8836             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
   8837         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8838                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
   8839                 + " clip=" + (intent != null ? intent.getClipData() : null)
   8840                 + " from " + intent + "; flags=0x"
   8841                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
   8842 
   8843         if (targetPkg == null) {
   8844             throw new NullPointerException("targetPkg");
   8845         }
   8846 
   8847         if (intent == null) {
   8848             return null;
   8849         }
   8850         Uri data = intent.getData();
   8851         ClipData clip = intent.getClipData();
   8852         if (data == null && clip == null) {
   8853             return null;
   8854         }
   8855         // Default userId for uris in the intent (if they don't specify it themselves)
   8856         int contentUserHint = intent.getContentUserHint();
   8857         if (contentUserHint == UserHandle.USER_CURRENT) {
   8858             contentUserHint = UserHandle.getUserId(callingUid);
   8859         }
   8860         final IPackageManager pm = AppGlobals.getPackageManager();
   8861         int targetUid;
   8862         if (needed != null) {
   8863             targetUid = needed.targetUid;
   8864         } else {
   8865             try {
   8866                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
   8867                         targetUserId);
   8868             } catch (RemoteException ex) {
   8869                 return null;
   8870             }
   8871             if (targetUid < 0) {
   8872                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8873                         "Can't grant URI permission no uid for: " + targetPkg
   8874                         + " on user " + targetUserId);
   8875                 return null;
   8876             }
   8877         }
   8878         if (data != null) {
   8879             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
   8880             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
   8881                     targetUid);
   8882             if (targetUid > 0) {
   8883                 if (needed == null) {
   8884                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
   8885                 }
   8886                 needed.add(grantUri);
   8887             }
   8888         }
   8889         if (clip != null) {
   8890             for (int i=0; i<clip.getItemCount(); i++) {
   8891                 Uri uri = clip.getItemAt(i).getUri();
   8892                 if (uri != null) {
   8893                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
   8894                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
   8895                             targetUid);
   8896                     if (targetUid > 0) {
   8897                         if (needed == null) {
   8898                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
   8899                         }
   8900                         needed.add(grantUri);
   8901                     }
   8902                 } else {
   8903                     Intent clipIntent = clip.getItemAt(i).getIntent();
   8904                     if (clipIntent != null) {
   8905                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
   8906                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
   8907                         if (newNeeded != null) {
   8908                             needed = newNeeded;
   8909                         }
   8910                     }
   8911                 }
   8912             }
   8913         }
   8914 
   8915         return needed;
   8916     }
   8917 
   8918     /**
   8919      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
   8920      */
   8921     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
   8922             UriPermissionOwner owner) {
   8923         if (needed != null) {
   8924             for (int i=0; i<needed.size(); i++) {
   8925                 GrantUri grantUri = needed.get(i);
   8926                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
   8927                         grantUri, needed.flags, owner);
   8928             }
   8929         }
   8930     }
   8931 
   8932     void grantUriPermissionFromIntentLocked(int callingUid,
   8933             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
   8934         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
   8935                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
   8936         if (needed == null) {
   8937             return;
   8938         }
   8939 
   8940         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
   8941     }
   8942 
   8943     /**
   8944      * @param uri This uri must NOT contain an embedded userId.
   8945      * @param userId The userId in which the uri is to be resolved.
   8946      */
   8947     @Override
   8948     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
   8949             final int modeFlags, int userId) {
   8950         enforceNotIsolatedCaller("grantUriPermission");
   8951         GrantUri grantUri = new GrantUri(userId, uri, false);
   8952         synchronized(this) {
   8953             final ProcessRecord r = getRecordForAppLocked(caller);
   8954             if (r == null) {
   8955                 throw new SecurityException("Unable to find app for caller "
   8956                         + caller
   8957                         + " when granting permission to uri " + grantUri);
   8958             }
   8959             if (targetPkg == null) {
   8960                 throw new IllegalArgumentException("null target");
   8961             }
   8962             if (grantUri == null) {
   8963                 throw new IllegalArgumentException("null uri");
   8964             }
   8965 
   8966             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
   8967                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
   8968                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
   8969                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
   8970 
   8971             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
   8972                     UserHandle.getUserId(r.uid));
   8973         }
   8974     }
   8975 
   8976     void removeUriPermissionIfNeededLocked(UriPermission perm) {
   8977         if (perm.modeFlags == 0) {
   8978             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
   8979                     perm.targetUid);
   8980             if (perms != null) {
   8981                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8982                         "Removing " + perm.targetUid + " permission to " + perm.uri);
   8983 
   8984                 perms.remove(perm.uri);
   8985                 if (perms.isEmpty()) {
   8986                     mGrantedUriPermissions.remove(perm.targetUid);
   8987                 }
   8988             }
   8989         }
   8990     }
   8991 
   8992     private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
   8993             final int modeFlags) {
   8994         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   8995                 "Revoking all granted permissions to " + grantUri);
   8996 
   8997         final IPackageManager pm = AppGlobals.getPackageManager();
   8998         final String authority = grantUri.uri.getAuthority();
   8999         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
   9000                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
   9001         if (pi == null) {
   9002             Slog.w(TAG, "No content provider found for permission revoke: "
   9003                     + grantUri.toSafeString());
   9004             return;
   9005         }
   9006 
   9007         // Does the caller have this permission on the URI?
   9008         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
   9009             // If they don't have direct access to the URI, then revoke any
   9010             // ownerless URI permissions that have been granted to them.
   9011             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   9012             if (perms != null) {
   9013                 boolean persistChanged = false;
   9014                 for (int i = perms.size()-1; i >= 0; i--) {
   9015                     final UriPermission perm = perms.valueAt(i);
   9016                     if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
   9017                         continue;
   9018                     }
   9019                     if (perm.uri.sourceUserId == grantUri.sourceUserId
   9020                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
   9021                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   9022                                 "Revoking non-owned " + perm.targetUid
   9023                                 + " permission to " + perm.uri);
   9024                         persistChanged |= perm.revokeModes(
   9025                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
   9026                         if (perm.modeFlags == 0) {
   9027                             perms.removeAt(i);
   9028                         }
   9029                     }
   9030                 }
   9031                 if (perms.isEmpty()) {
   9032                     mGrantedUriPermissions.remove(callingUid);
   9033                 }
   9034                 if (persistChanged) {
   9035                     schedulePersistUriGrants();
   9036                 }
   9037             }
   9038             return;
   9039         }
   9040 
   9041         boolean persistChanged = false;
   9042 
   9043         // Go through all of the permissions and remove any that match.
   9044         for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
   9045             final int targetUid = mGrantedUriPermissions.keyAt(i);
   9046             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   9047 
   9048             for (int j = perms.size()-1; j >= 0; j--) {
   9049                 final UriPermission perm = perms.valueAt(j);
   9050                 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
   9051                     continue;
   9052                 }
   9053                 if (perm.uri.sourceUserId == grantUri.sourceUserId
   9054                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
   9055                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   9056                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
   9057                     persistChanged |= perm.revokeModes(
   9058                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
   9059                             targetPackage == null);
   9060                     if (perm.modeFlags == 0) {
   9061                         perms.removeAt(j);
   9062                     }
   9063                 }
   9064             }
   9065 
   9066             if (perms.isEmpty()) {
   9067                 mGrantedUriPermissions.removeAt(i);
   9068             }
   9069         }
   9070 
   9071         if (persistChanged) {
   9072             schedulePersistUriGrants();
   9073         }
   9074     }
   9075 
   9076     /**
   9077      * @param uri This uri must NOT contain an embedded userId.
   9078      * @param userId The userId in which the uri is to be resolved.
   9079      */
   9080     @Override
   9081     public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
   9082             final int modeFlags, int userId) {
   9083         enforceNotIsolatedCaller("revokeUriPermission");
   9084         synchronized(this) {
   9085             final ProcessRecord r = getRecordForAppLocked(caller);
   9086             if (r == null) {
   9087                 throw new SecurityException("Unable to find app for caller "
   9088                         + caller
   9089                         + " when revoking permission to uri " + uri);
   9090             }
   9091             if (uri == null) {
   9092                 Slog.w(TAG, "revokeUriPermission: null uri");
   9093                 return;
   9094             }
   9095 
   9096             if (!Intent.isAccessUriMode(modeFlags)) {
   9097                 return;
   9098             }
   9099 
   9100             final String authority = uri.getAuthority();
   9101             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
   9102                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
   9103             if (pi == null) {
   9104                 Slog.w(TAG, "No content provider found for permission revoke: "
   9105                         + uri.toSafeString());
   9106                 return;
   9107             }
   9108 
   9109             revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
   9110                     modeFlags);
   9111         }
   9112     }
   9113 
   9114     /**
   9115      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
   9116      * given package.
   9117      *
   9118      * @param packageName Package name to match, or {@code null} to apply to all
   9119      *            packages.
   9120      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
   9121      *            to all users.
   9122      * @param persistable If persistable grants should be removed.
   9123      */
   9124     private void removeUriPermissionsForPackageLocked(
   9125             String packageName, int userHandle, boolean persistable) {
   9126         if (userHandle == UserHandle.USER_ALL && packageName == null) {
   9127             throw new IllegalArgumentException("Must narrow by either package or user");
   9128         }
   9129 
   9130         boolean persistChanged = false;
   9131 
   9132         int N = mGrantedUriPermissions.size();
   9133         for (int i = 0; i < N; i++) {
   9134             final int targetUid = mGrantedUriPermissions.keyAt(i);
   9135             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   9136 
   9137             // Only inspect grants matching user
   9138             if (userHandle == UserHandle.USER_ALL
   9139                     || userHandle == UserHandle.getUserId(targetUid)) {
   9140                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
   9141                     final UriPermission perm = it.next();
   9142 
   9143                     // Only inspect grants matching package
   9144                     if (packageName == null || perm.sourcePkg.equals(packageName)
   9145                             || perm.targetPkg.equals(packageName)) {
   9146                         // Hacky solution as part of fixing a security bug; ignore
   9147                         // grants associated with DownloadManager so we don't have
   9148                         // to immediately launch it to regrant the permissions
   9149                         if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
   9150                                 && !persistable) continue;
   9151 
   9152                         persistChanged |= perm.revokeModes(persistable
   9153                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
   9154 
   9155                         // Only remove when no modes remain; any persisted grants
   9156                         // will keep this alive.
   9157                         if (perm.modeFlags == 0) {
   9158                             it.remove();
   9159                         }
   9160                     }
   9161                 }
   9162 
   9163                 if (perms.isEmpty()) {
   9164                     mGrantedUriPermissions.remove(targetUid);
   9165                     N--;
   9166                     i--;
   9167                 }
   9168             }
   9169         }
   9170 
   9171         if (persistChanged) {
   9172             schedulePersistUriGrants();
   9173         }
   9174     }
   9175 
   9176     @Override
   9177     public IBinder newUriPermissionOwner(String name) {
   9178         enforceNotIsolatedCaller("newUriPermissionOwner");
   9179         synchronized(this) {
   9180             UriPermissionOwner owner = new UriPermissionOwner(this, name);
   9181             return owner.getExternalTokenLocked();
   9182         }
   9183     }
   9184 
   9185     @Override
   9186     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
   9187         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
   9188         synchronized(this) {
   9189             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
   9190             if (r == null) {
   9191                 throw new IllegalArgumentException("Activity does not exist; token="
   9192                         + activityToken);
   9193             }
   9194             return r.getUriPermissionsLocked().getExternalTokenLocked();
   9195         }
   9196     }
   9197     /**
   9198      * @param uri This uri must NOT contain an embedded userId.
   9199      * @param sourceUserId The userId in which the uri is to be resolved.
   9200      * @param targetUserId The userId of the app that receives the grant.
   9201      */
   9202     @Override
   9203     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
   9204             final int modeFlags, int sourceUserId, int targetUserId) {
   9205         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
   9206                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
   9207                 "grantUriPermissionFromOwner", null);
   9208         synchronized(this) {
   9209             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   9210             if (owner == null) {
   9211                 throw new IllegalArgumentException("Unknown owner: " + token);
   9212             }
   9213             if (fromUid != Binder.getCallingUid()) {
   9214                 if (Binder.getCallingUid() != myUid()) {
   9215                     // Only system code can grant URI permissions on behalf
   9216                     // of other users.
   9217                     throw new SecurityException("nice try");
   9218                 }
   9219             }
   9220             if (targetPkg == null) {
   9221                 throw new IllegalArgumentException("null target");
   9222             }
   9223             if (uri == null) {
   9224                 throw new IllegalArgumentException("null uri");
   9225             }
   9226 
   9227             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
   9228                     modeFlags, owner, targetUserId);
   9229         }
   9230     }
   9231 
   9232     /**
   9233      * @param uri This uri must NOT contain an embedded userId.
   9234      * @param userId The userId in which the uri is to be resolved.
   9235      */
   9236     @Override
   9237     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
   9238         synchronized(this) {
   9239             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   9240             if (owner == null) {
   9241                 throw new IllegalArgumentException("Unknown owner: " + token);
   9242             }
   9243 
   9244             if (uri == null) {
   9245                 owner.removeUriPermissionsLocked(mode);
   9246             } else {
   9247                 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
   9248                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
   9249             }
   9250         }
   9251     }
   9252 
   9253     private void schedulePersistUriGrants() {
   9254         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
   9255             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
   9256                     10 * DateUtils.SECOND_IN_MILLIS);
   9257         }
   9258     }
   9259 
   9260     private void writeGrantedUriPermissions() {
   9261         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
   9262 
   9263         // Snapshot permissions so we can persist without lock
   9264         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
   9265         synchronized (this) {
   9266             final int size = mGrantedUriPermissions.size();
   9267             for (int i = 0; i < size; i++) {
   9268                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   9269                 for (UriPermission perm : perms.values()) {
   9270                     if (perm.persistedModeFlags != 0) {
   9271                         persist.add(perm.snapshot());
   9272                     }
   9273                 }
   9274             }
   9275         }
   9276 
   9277         FileOutputStream fos = null;
   9278         try {
   9279             fos = mGrantFile.startWrite();
   9280 
   9281             XmlSerializer out = new FastXmlSerializer();
   9282             out.setOutput(fos, StandardCharsets.UTF_8.name());
   9283             out.startDocument(null, true);
   9284             out.startTag(null, TAG_URI_GRANTS);
   9285             for (UriPermission.Snapshot perm : persist) {
   9286                 out.startTag(null, TAG_URI_GRANT);
   9287                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
   9288                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
   9289                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
   9290                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
   9291                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
   9292                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
   9293                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
   9294                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
   9295                 out.endTag(null, TAG_URI_GRANT);
   9296             }
   9297             out.endTag(null, TAG_URI_GRANTS);
   9298             out.endDocument();
   9299 
   9300             mGrantFile.finishWrite(fos);
   9301         } catch (IOException e) {
   9302             if (fos != null) {
   9303                 mGrantFile.failWrite(fos);
   9304             }
   9305         }
   9306     }
   9307 
   9308     private void readGrantedUriPermissionsLocked() {
   9309         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
   9310 
   9311         final long now = System.currentTimeMillis();
   9312 
   9313         FileInputStream fis = null;
   9314         try {
   9315             fis = mGrantFile.openRead();
   9316             final XmlPullParser in = Xml.newPullParser();
   9317             in.setInput(fis, StandardCharsets.UTF_8.name());
   9318 
   9319             int type;
   9320             while ((type = in.next()) != END_DOCUMENT) {
   9321                 final String tag = in.getName();
   9322                 if (type == START_TAG) {
   9323                     if (TAG_URI_GRANT.equals(tag)) {
   9324                         final int sourceUserId;
   9325                         final int targetUserId;
   9326                         final int userHandle = readIntAttribute(in,
   9327                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
   9328                         if (userHandle != UserHandle.USER_NULL) {
   9329                             // For backwards compatibility.
   9330                             sourceUserId = userHandle;
   9331                             targetUserId = userHandle;
   9332                         } else {
   9333                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
   9334                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
   9335                         }
   9336                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
   9337                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
   9338                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
   9339                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
   9340                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
   9341                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
   9342 
   9343                         // Sanity check that provider still belongs to source package
   9344                         // Both direct boot aware and unaware packages are fine as we
   9345                         // will do filtering at query time to avoid multiple parsing.
   9346                         final ProviderInfo pi = getProviderInfoLocked(
   9347                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
   9348                                         | MATCH_DIRECT_BOOT_UNAWARE);
   9349                         if (pi != null && sourcePkg.equals(pi.packageName)) {
   9350                             int targetUid = -1;
   9351                             try {
   9352                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
   9353                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
   9354                             } catch (RemoteException e) {
   9355                             }
   9356                             if (targetUid != -1) {
   9357                                 final UriPermission perm = findOrCreateUriPermissionLocked(
   9358                                         sourcePkg, targetPkg, targetUid,
   9359                                         new GrantUri(sourceUserId, uri, prefix));
   9360                                 perm.initPersistedModes(modeFlags, createdTime);
   9361                             }
   9362                         } else {
   9363                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
   9364                                     + " but instead found " + pi);
   9365                         }
   9366                     }
   9367                 }
   9368             }
   9369         } catch (FileNotFoundException e) {
   9370             // Missing grants is okay
   9371         } catch (IOException e) {
   9372             Slog.wtf(TAG, "Failed reading Uri grants", e);
   9373         } catch (XmlPullParserException e) {
   9374             Slog.wtf(TAG, "Failed reading Uri grants", e);
   9375         } finally {
   9376             IoUtils.closeQuietly(fis);
   9377         }
   9378     }
   9379 
   9380     /**
   9381      * @param uri This uri must NOT contain an embedded userId.
   9382      * @param userId The userId in which the uri is to be resolved.
   9383      */
   9384     @Override
   9385     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
   9386         enforceNotIsolatedCaller("takePersistableUriPermission");
   9387 
   9388         Preconditions.checkFlagsArgument(modeFlags,
   9389                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   9390 
   9391         synchronized (this) {
   9392             final int callingUid = Binder.getCallingUid();
   9393             boolean persistChanged = false;
   9394             GrantUri grantUri = new GrantUri(userId, uri, false);
   9395 
   9396             UriPermission exactPerm = findUriPermissionLocked(callingUid,
   9397                     new GrantUri(userId, uri, false));
   9398             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
   9399                     new GrantUri(userId, uri, true));
   9400 
   9401             final boolean exactValid = (exactPerm != null)
   9402                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
   9403             final boolean prefixValid = (prefixPerm != null)
   9404                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
   9405 
   9406             if (!(exactValid || prefixValid)) {
   9407                 throw new SecurityException("No persistable permission grants found for UID "
   9408                         + callingUid + " and Uri " + grantUri.toSafeString());
   9409             }
   9410 
   9411             if (exactValid) {
   9412                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
   9413             }
   9414             if (prefixValid) {
   9415                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
   9416             }
   9417 
   9418             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
   9419 
   9420             if (persistChanged) {
   9421                 schedulePersistUriGrants();
   9422             }
   9423         }
   9424     }
   9425 
   9426     /**
   9427      * @param uri This uri must NOT contain an embedded userId.
   9428      * @param userId The userId in which the uri is to be resolved.
   9429      */
   9430     @Override
   9431     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
   9432         enforceNotIsolatedCaller("releasePersistableUriPermission");
   9433 
   9434         Preconditions.checkFlagsArgument(modeFlags,
   9435                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   9436 
   9437         synchronized (this) {
   9438             final int callingUid = Binder.getCallingUid();
   9439             boolean persistChanged = false;
   9440 
   9441             UriPermission exactPerm = findUriPermissionLocked(callingUid,
   9442                     new GrantUri(userId, uri, false));
   9443             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
   9444                     new GrantUri(userId, uri, true));
   9445             if (exactPerm == null && prefixPerm == null) {
   9446                 throw new SecurityException("No permission grants found for UID " + callingUid
   9447                         + " and Uri " + uri.toSafeString());
   9448             }
   9449 
   9450             if (exactPerm != null) {
   9451                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
   9452                 removeUriPermissionIfNeededLocked(exactPerm);
   9453             }
   9454             if (prefixPerm != null) {
   9455                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
   9456                 removeUriPermissionIfNeededLocked(prefixPerm);
   9457             }
   9458 
   9459             if (persistChanged) {
   9460                 schedulePersistUriGrants();
   9461             }
   9462         }
   9463     }
   9464 
   9465     /**
   9466      * Prune any older {@link UriPermission} for the given UID until outstanding
   9467      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
   9468      *
   9469      * @return if any mutations occured that require persisting.
   9470      */
   9471     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
   9472         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   9473         if (perms == null) return false;
   9474         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
   9475 
   9476         final ArrayList<UriPermission> persisted = Lists.newArrayList();
   9477         for (UriPermission perm : perms.values()) {
   9478             if (perm.persistedModeFlags != 0) {
   9479                 persisted.add(perm);
   9480             }
   9481         }
   9482 
   9483         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
   9484         if (trimCount <= 0) return false;
   9485 
   9486         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
   9487         for (int i = 0; i < trimCount; i++) {
   9488             final UriPermission perm = persisted.get(i);
   9489 
   9490             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   9491                     "Trimming grant created at " + perm.persistedCreateTime);
   9492 
   9493             perm.releasePersistableModes(~0);
   9494             removeUriPermissionIfNeededLocked(perm);
   9495         }
   9496 
   9497         return true;
   9498     }
   9499 
   9500     @Override
   9501     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
   9502             String packageName, boolean incoming) {
   9503         enforceNotIsolatedCaller("getPersistedUriPermissions");
   9504         Preconditions.checkNotNull(packageName, "packageName");
   9505 
   9506         final int callingUid = Binder.getCallingUid();
   9507         final int callingUserId = UserHandle.getUserId(callingUid);
   9508         final IPackageManager pm = AppGlobals.getPackageManager();
   9509         try {
   9510             final int packageUid = pm.getPackageUid(packageName,
   9511                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
   9512             if (packageUid != callingUid) {
   9513                 throw new SecurityException(
   9514                         "Package " + packageName + " does not belong to calling UID " + callingUid);
   9515             }
   9516         } catch (RemoteException e) {
   9517             throw new SecurityException("Failed to verify package name ownership");
   9518         }
   9519 
   9520         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
   9521         synchronized (this) {
   9522             if (incoming) {
   9523                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
   9524                         callingUid);
   9525                 if (perms == null) {
   9526                     Slog.w(TAG, "No permission grants found for " + packageName);
   9527                 } else {
   9528                     for (UriPermission perm : perms.values()) {
   9529                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
   9530                             result.add(perm.buildPersistedPublicApiObject());
   9531                         }
   9532                     }
   9533                 }
   9534             } else {
   9535                 final int size = mGrantedUriPermissions.size();
   9536                 for (int i = 0; i < size; i++) {
   9537                     final ArrayMap<GrantUri, UriPermission> perms =
   9538                             mGrantedUriPermissions.valueAt(i);
   9539                     for (UriPermission perm : perms.values()) {
   9540                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
   9541                             result.add(perm.buildPersistedPublicApiObject());
   9542                         }
   9543                     }
   9544                 }
   9545             }
   9546         }
   9547         return new ParceledListSlice<android.content.UriPermission>(result);
   9548     }
   9549 
   9550     @Override
   9551     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
   9552             String packageName, int userId) {
   9553         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
   9554                 "getGrantedUriPermissions");
   9555 
   9556         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
   9557         synchronized (this) {
   9558             final int size = mGrantedUriPermissions.size();
   9559             for (int i = 0; i < size; i++) {
   9560                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   9561                 for (UriPermission perm : perms.values()) {
   9562                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
   9563                             && perm.persistedModeFlags != 0) {
   9564                         result.add(perm.buildPersistedPublicApiObject());
   9565                     }
   9566                 }
   9567             }
   9568         }
   9569         return new ParceledListSlice<android.content.UriPermission>(result);
   9570     }
   9571 
   9572     @Override
   9573     public void clearGrantedUriPermissions(String packageName, int userId) {
   9574         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
   9575                 "clearGrantedUriPermissions");
   9576         removeUriPermissionsForPackageLocked(packageName, userId, true);
   9577     }
   9578 
   9579     @Override
   9580     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
   9581         synchronized (this) {
   9582             ProcessRecord app =
   9583                 who != null ? getRecordForAppLocked(who) : null;
   9584             if (app == null) return;
   9585 
   9586             Message msg = Message.obtain();
   9587             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
   9588             msg.obj = app;
   9589             msg.arg1 = waiting ? 1 : 0;
   9590             mUiHandler.sendMessage(msg);
   9591         }
   9592     }
   9593 
   9594     @Override
   9595     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
   9596         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
   9597         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
   9598         outInfo.availMem = getFreeMemory();
   9599         outInfo.totalMem = getTotalMemory();
   9600         outInfo.threshold = homeAppMem;
   9601         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
   9602         outInfo.hiddenAppThreshold = cachedAppMem;
   9603         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
   9604                 ProcessList.SERVICE_ADJ);
   9605         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
   9606                 ProcessList.VISIBLE_APP_ADJ);
   9607         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
   9608                 ProcessList.FOREGROUND_APP_ADJ);
   9609     }
   9610 
   9611     // =========================================================
   9612     // TASK MANAGEMENT
   9613     // =========================================================
   9614 
   9615     @Override
   9616     public List<IBinder> getAppTasks(String callingPackage) {
   9617         int callingUid = Binder.getCallingUid();
   9618         long ident = Binder.clearCallingIdentity();
   9619 
   9620         synchronized(this) {
   9621             ArrayList<IBinder> list = new ArrayList<IBinder>();
   9622             try {
   9623                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
   9624 
   9625                 final int N = mRecentTasks.size();
   9626                 for (int i = 0; i < N; i++) {
   9627                     TaskRecord tr = mRecentTasks.get(i);
   9628                     // Skip tasks that do not match the caller.  We don't need to verify
   9629                     // callingPackage, because we are also limiting to callingUid and know
   9630                     // that will limit to the correct security sandbox.
   9631                     if (tr.effectiveUid != callingUid) {
   9632                         continue;
   9633                     }
   9634                     Intent intent = tr.getBaseIntent();
   9635                     if (intent == null ||
   9636                             !callingPackage.equals(intent.getComponent().getPackageName())) {
   9637                         continue;
   9638                     }
   9639                     ActivityManager.RecentTaskInfo taskInfo =
   9640                             createRecentTaskInfoFromTaskRecord(tr);
   9641                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
   9642                     list.add(taskImpl.asBinder());
   9643                 }
   9644             } finally {
   9645                 Binder.restoreCallingIdentity(ident);
   9646             }
   9647             return list;
   9648         }
   9649     }
   9650 
   9651     @Override
   9652     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
   9653         final int callingUid = Binder.getCallingUid();
   9654         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
   9655 
   9656         synchronized(this) {
   9657             if (DEBUG_ALL) Slog.v(
   9658                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
   9659 
   9660             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
   9661                     callingUid);
   9662 
   9663             // TODO: Improve with MRU list from all ActivityStacks.
   9664             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
   9665         }
   9666 
   9667         return list;
   9668     }
   9669 
   9670     /**
   9671      * Creates a new RecentTaskInfo from a TaskRecord.
   9672      */
   9673     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
   9674         // Update the task description to reflect any changes in the task stack
   9675         tr.updateTaskDescription();
   9676 
   9677         // Compose the recent task info
   9678         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
   9679         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
   9680         rti.persistentId = tr.taskId;
   9681         rti.baseIntent = new Intent(tr.getBaseIntent());
   9682         rti.origActivity = tr.origActivity;
   9683         rti.realActivity = tr.realActivity;
   9684         rti.description = tr.lastDescription;
   9685         rti.stackId = tr.getStackId();
   9686         rti.userId = tr.userId;
   9687         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
   9688         rti.firstActiveTime = tr.firstActiveTime;
   9689         rti.lastActiveTime = tr.lastActiveTime;
   9690         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
   9691         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
   9692         rti.numActivities = 0;
   9693         if (tr.mBounds != null) {
   9694             rti.bounds = new Rect(tr.mBounds);
   9695         }
   9696         rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
   9697         rti.resizeMode = tr.mResizeMode;
   9698 
   9699         ActivityRecord base = null;
   9700         ActivityRecord top = null;
   9701         ActivityRecord tmp;
   9702 
   9703         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
   9704             tmp = tr.mActivities.get(i);
   9705             if (tmp.finishing) {
   9706                 continue;
   9707             }
   9708             base = tmp;
   9709             if (top == null || (top.state == ActivityState.INITIALIZING)) {
   9710                 top = base;
   9711             }
   9712             rti.numActivities++;
   9713         }
   9714 
   9715         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
   9716         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
   9717 
   9718         return rti;
   9719     }
   9720 
   9721     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
   9722         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
   9723                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
   9724         if (!allowed) {
   9725             if (checkPermission(android.Manifest.permission.GET_TASKS,
   9726                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
   9727                 // Temporary compatibility: some existing apps on the system image may
   9728                 // still be requesting the old permission and not switched to the new
   9729                 // one; if so, we'll still allow them full access.  This means we need
   9730                 // to see if they are holding the old permission and are a system app.
   9731                 try {
   9732                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
   9733                         allowed = true;
   9734                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
   9735                                 + " is using old GET_TASKS but privileged; allowing");
   9736                     }
   9737                 } catch (RemoteException e) {
   9738                 }
   9739             }
   9740         }
   9741         if (!allowed) {
   9742             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
   9743                     + " does not hold REAL_GET_TASKS; limiting output");
   9744         }
   9745         return allowed;
   9746     }
   9747 
   9748     @Override
   9749     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
   9750             int userId) {
   9751         final int callingUid = Binder.getCallingUid();
   9752         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
   9753                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
   9754 
   9755         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
   9756         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
   9757         synchronized (this) {
   9758             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
   9759                     callingUid);
   9760             final boolean detailed = checkCallingPermission(
   9761                     android.Manifest.permission.GET_DETAILED_TASKS)
   9762                     == PackageManager.PERMISSION_GRANTED;
   9763 
   9764             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
   9765                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
   9766                 return ParceledListSlice.emptyList();
   9767             }
   9768             mRecentTasks.loadUserRecentsLocked(userId);
   9769 
   9770             final int recentsCount = mRecentTasks.size();
   9771             ArrayList<ActivityManager.RecentTaskInfo> res =
   9772                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
   9773 
   9774             final Set<Integer> includedUsers;
   9775             if (includeProfiles) {
   9776                 includedUsers = mUserController.getProfileIds(userId);
   9777             } else {
   9778                 includedUsers = new HashSet<>();
   9779             }
   9780             includedUsers.add(Integer.valueOf(userId));
   9781 
   9782             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
   9783                 TaskRecord tr = mRecentTasks.get(i);
   9784                 // Only add calling user or related users recent tasks
   9785                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
   9786                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
   9787                     continue;
   9788                 }
   9789 
   9790                 if (tr.realActivitySuspended) {
   9791                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
   9792                     continue;
   9793                 }
   9794 
   9795                 // Return the entry if desired by the caller.  We always return
   9796                 // the first entry, because callers always expect this to be the
   9797                 // foreground app.  We may filter others if the caller has
   9798                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
   9799                 // we should exclude the entry.
   9800 
   9801                 if (i == 0
   9802                         || withExcluded
   9803                         || (tr.intent == null)
   9804                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
   9805                                 == 0)) {
   9806                     if (!allowed) {
   9807                         // If the caller doesn't have the GET_TASKS permission, then only
   9808                         // allow them to see a small subset of tasks -- their own and home.
   9809                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
   9810                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
   9811                             continue;
   9812                         }
   9813                     }
   9814                     final ActivityStack stack = tr.getStack();
   9815                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
   9816                         if (stack != null && stack.isHomeOrRecentsStack()) {
   9817                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9818                                     "Skipping, home or recents stack task: " + tr);
   9819                             continue;
   9820                         }
   9821                     }
   9822                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
   9823                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
   9824                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9825                                     "Skipping, top task in docked stack: " + tr);
   9826                             continue;
   9827                         }
   9828                     }
   9829                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
   9830                         if (stack != null && stack.isPinnedStack()) {
   9831                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9832                                     "Skipping, pinned stack task: " + tr);
   9833                             continue;
   9834                         }
   9835                     }
   9836                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
   9837                         // Don't include auto remove tasks that are finished or finishing.
   9838                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9839                                 "Skipping, auto-remove without activity: " + tr);
   9840                         continue;
   9841                     }
   9842                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
   9843                             && !tr.isAvailable) {
   9844                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9845                                 "Skipping, unavail real act: " + tr);
   9846                         continue;
   9847                     }
   9848 
   9849                     if (!tr.mUserSetupComplete) {
   9850                         // Don't include task launched while user is not done setting-up.
   9851                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
   9852                                 "Skipping, user setup not complete: " + tr);
   9853                         continue;
   9854                     }
   9855 
   9856                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
   9857                     if (!detailed) {
   9858                         rti.baseIntent.replaceExtras((Bundle)null);
   9859                     }
   9860 
   9861                     res.add(rti);
   9862                     maxNum--;
   9863                 }
   9864             }
   9865             return new ParceledListSlice<>(res);
   9866         }
   9867     }
   9868 
   9869     @Override
   9870     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
   9871         synchronized (this) {
   9872             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
   9873                     "getTaskThumbnail()");
   9874             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
   9875                     id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
   9876             if (tr != null) {
   9877                 return tr.getTaskThumbnailLocked();
   9878             }
   9879         }
   9880         return null;
   9881     }
   9882 
   9883     @Override
   9884     public ActivityManager.TaskDescription getTaskDescription(int id) {
   9885         synchronized (this) {
   9886             enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   9887                     "getTaskDescription()");
   9888             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
   9889                     MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
   9890             if (tr != null) {
   9891                 return tr.lastTaskDescription;
   9892             }
   9893         }
   9894         return null;
   9895     }
   9896 
   9897     @Override
   9898     public int addAppTask(IBinder activityToken, Intent intent,
   9899             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
   9900         final int callingUid = Binder.getCallingUid();
   9901         final long callingIdent = Binder.clearCallingIdentity();
   9902 
   9903         try {
   9904             synchronized (this) {
   9905                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
   9906                 if (r == null) {
   9907                     throw new IllegalArgumentException("Activity does not exist; token="
   9908                             + activityToken);
   9909                 }
   9910                 ComponentName comp = intent.getComponent();
   9911                 if (comp == null) {
   9912                     throw new IllegalArgumentException("Intent " + intent
   9913                             + " must specify explicit component");
   9914                 }
   9915                 if (thumbnail.getWidth() != mThumbnailWidth
   9916                         || thumbnail.getHeight() != mThumbnailHeight) {
   9917                     throw new IllegalArgumentException("Bad thumbnail size: got "
   9918                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
   9919                             + mThumbnailWidth + "x" + mThumbnailHeight);
   9920                 }
   9921                 if (intent.getSelector() != null) {
   9922                     intent.setSelector(null);
   9923                 }
   9924                 if (intent.getSourceBounds() != null) {
   9925                     intent.setSourceBounds(null);
   9926                 }
   9927                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
   9928                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
   9929                         // The caller has added this as an auto-remove task...  that makes no
   9930                         // sense, so turn off auto-remove.
   9931                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
   9932                     }
   9933                 }
   9934                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
   9935                     mLastAddedTaskActivity = null;
   9936                 }
   9937                 ActivityInfo ainfo = mLastAddedTaskActivity;
   9938                 if (ainfo == null) {
   9939                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
   9940                             comp, 0, UserHandle.getUserId(callingUid));
   9941                     if (ainfo.applicationInfo.uid != callingUid) {
   9942                         throw new SecurityException(
   9943                                 "Can't add task for another application: target uid="
   9944                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
   9945                     }
   9946                 }
   9947 
   9948                 TaskRecord task = new TaskRecord(this,
   9949                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
   9950                         ainfo, intent, description, new TaskThumbnailInfo());
   9951 
   9952                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
   9953                 if (trimIdx >= 0) {
   9954                     // If this would have caused a trim, then we'll abort because that
   9955                     // means it would be added at the end of the list but then just removed.
   9956                     return INVALID_TASK_ID;
   9957                 }
   9958 
   9959                 final int N = mRecentTasks.size();
   9960                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
   9961                     final TaskRecord tr = mRecentTasks.remove(N - 1);
   9962                     tr.removedFromRecents();
   9963                 }
   9964 
   9965                 task.inRecents = true;
   9966                 mRecentTasks.add(task);
   9967                 r.getStack().addTask(task, false, "addAppTask");
   9968 
   9969                 task.setLastThumbnailLocked(thumbnail);
   9970                 task.freeLastThumbnail();
   9971                 return task.taskId;
   9972             }
   9973         } finally {
   9974             Binder.restoreCallingIdentity(callingIdent);
   9975         }
   9976     }
   9977 
   9978     @Override
   9979     public Point getAppTaskThumbnailSize() {
   9980         synchronized (this) {
   9981             return new Point(mThumbnailWidth,  mThumbnailHeight);
   9982         }
   9983     }
   9984 
   9985     @Override
   9986     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
   9987         synchronized (this) {
   9988             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   9989             if (r != null) {
   9990                 r.setTaskDescription(td);
   9991                 final TaskRecord task = r.getTask();
   9992                 task.updateTaskDescription();
   9993                 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
   9994             }
   9995         }
   9996     }
   9997 
   9998     @Override
   9999     public void setTaskResizeable(int taskId, int resizeableMode) {
   10000         synchronized (this) {
   10001             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
   10002                     taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
   10003             if (task == null) {
   10004                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
   10005                 return;
   10006             }
   10007             task.setResizeMode(resizeableMode);
   10008         }
   10009     }
   10010 
   10011     @Override
   10012     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
   10013         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
   10014         long ident = Binder.clearCallingIdentity();
   10015         try {
   10016             synchronized (this) {
   10017                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   10018                 if (task == null) {
   10019                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
   10020                     return;
   10021                 }
   10022                 // Place the task in the right stack if it isn't there already based on
   10023                 // the requested bounds.
   10024                 // The stack transition logic is:
   10025                 // - a null bounds on a freeform task moves that task to fullscreen
   10026                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
   10027                 //   that task to freeform
   10028                 // - otherwise the task is not moved
   10029                 int stackId = task.getStackId();
   10030                 if (!StackId.isTaskResizeAllowed(stackId)) {
   10031                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
   10032                 }
   10033                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
   10034                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
   10035                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
   10036                     stackId = FREEFORM_WORKSPACE_STACK_ID;
   10037                 }
   10038 
   10039                 // Reparent the task to the right stack if necessary
   10040                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
   10041                 if (stackId != task.getStackId()) {
   10042                     // Defer resume until the task is resized below
   10043                     task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
   10044                             DEFER_RESUME, "resizeTask");
   10045                     preserveWindow = false;
   10046                 }
   10047 
   10048                 // After reparenting (which only resizes the task to the stack bounds), resize the
   10049                 // task to the actual bounds provided
   10050                 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
   10051             }
   10052         } finally {
   10053             Binder.restoreCallingIdentity(ident);
   10054         }
   10055     }
   10056 
   10057     @Override
   10058     public Rect getTaskBounds(int taskId) {
   10059         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
   10060         long ident = Binder.clearCallingIdentity();
   10061         Rect rect = new Rect();
   10062         try {
   10063             synchronized (this) {
   10064                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
   10065                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
   10066                 if (task == null) {
   10067                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
   10068                     return rect;
   10069                 }
   10070                 if (task.getStack() != null) {
   10071                     // Return the bounds from window manager since it will be adjusted for various
   10072                     // things like the presense of a docked stack for tasks that aren't resizeable.
   10073                     task.getWindowContainerBounds(rect);
   10074                 } else {
   10075                     // Task isn't in window manager yet since it isn't associated with a stack.
   10076                     // Return the persist value from activity manager
   10077                     if (task.mBounds != null) {
   10078                         rect.set(task.mBounds);
   10079                     } else if (task.mLastNonFullscreenBounds != null) {
   10080                         rect.set(task.mLastNonFullscreenBounds);
   10081                     }
   10082                 }
   10083             }
   10084         } finally {
   10085             Binder.restoreCallingIdentity(ident);
   10086         }
   10087         return rect;
   10088     }
   10089 
   10090     @Override
   10091     public void cancelTaskWindowTransition(int taskId) {
   10092         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
   10093         final long ident = Binder.clearCallingIdentity();
   10094         try {
   10095             synchronized (this) {
   10096                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
   10097                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
   10098                 if (task == null) {
   10099                     Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
   10100                     return;
   10101                 }
   10102                 task.cancelWindowTransition();
   10103             }
   10104         } finally {
   10105             Binder.restoreCallingIdentity(ident);
   10106         }
   10107     }
   10108 
   10109     @Override
   10110     public void cancelTaskThumbnailTransition(int taskId) {
   10111         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
   10112         final long ident = Binder.clearCallingIdentity();
   10113         try {
   10114             synchronized (this) {
   10115                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
   10116                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
   10117                 if (task == null) {
   10118                     Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
   10119                     return;
   10120                 }
   10121                 task.cancelThumbnailTransition();
   10122             }
   10123         } finally {
   10124             Binder.restoreCallingIdentity(ident);
   10125         }
   10126     }
   10127 
   10128     @Override
   10129     public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
   10130         enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
   10131         final long ident = Binder.clearCallingIdentity();
   10132         try {
   10133             final TaskRecord task;
   10134             synchronized (this) {
   10135                 task = mStackSupervisor.anyTaskForIdLocked(taskId,
   10136                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
   10137                 if (task == null) {
   10138                     Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
   10139                     return null;
   10140                 }
   10141             }
   10142             // Don't call this while holding the lock as this operation might hit the disk.
   10143             return task.getSnapshot(reducedResolution);
   10144         } finally {
   10145             Binder.restoreCallingIdentity(ident);
   10146         }
   10147     }
   10148 
   10149     @Override
   10150     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
   10151         if (userId != UserHandle.getCallingUserId()) {
   10152             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   10153                     "getTaskDescriptionIcon");
   10154         }
   10155         final File passedIconFile = new File(filePath);
   10156         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
   10157                 passedIconFile.getName());
   10158         if (!legitIconFile.getPath().equals(filePath)
   10159                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
   10160             throw new IllegalArgumentException("Bad file path: " + filePath
   10161                     + " passed for userId " + userId);
   10162         }
   10163         return mRecentTasks.getTaskDescriptionIcon(filePath);
   10164     }
   10165 
   10166     @Override
   10167     public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
   10168             throws RemoteException {
   10169         final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
   10170         if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
   10171                 activityOptions.getCustomInPlaceResId() == 0) {
   10172             throw new IllegalArgumentException("Expected in-place ActivityOption " +
   10173                     "with valid animation");
   10174         }
   10175         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
   10176         mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
   10177                 activityOptions.getCustomInPlaceResId());
   10178         mWindowManager.executeAppTransition();
   10179     }
   10180 
   10181     private void removeTasksByPackageNameLocked(String packageName, int userId) {
   10182         // Remove all tasks with activities in the specified package from the list of recent tasks
   10183         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
   10184             TaskRecord tr = mRecentTasks.get(i);
   10185             if (tr.userId != userId) continue;
   10186 
   10187             ComponentName cn = tr.intent.getComponent();
   10188             if (cn != null && cn.getPackageName().equals(packageName)) {
   10189                 // If the package name matches, remove the task.
   10190                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
   10191             }
   10192         }
   10193     }
   10194 
   10195     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
   10196             int userId) {
   10197 
   10198         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
   10199             TaskRecord tr = mRecentTasks.get(i);
   10200             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
   10201                 continue;
   10202             }
   10203 
   10204             ComponentName cn = tr.intent.getComponent();
   10205             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
   10206                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
   10207             if (sameComponent) {
   10208                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
   10209             }
   10210         }
   10211     }
   10212 
   10213     @Override
   10214     public void removeStack(int stackId) {
   10215         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
   10216         if (StackId.isHomeOrRecentsStack(stackId)) {
   10217             throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
   10218         }
   10219 
   10220         synchronized (this) {
   10221             final long ident = Binder.clearCallingIdentity();
   10222             try {
   10223                 mStackSupervisor.removeStackLocked(stackId);
   10224             } finally {
   10225                 Binder.restoreCallingIdentity(ident);
   10226             }
   10227         }
   10228     }
   10229 
   10230     @Override
   10231     public void moveStackToDisplay(int stackId, int displayId) {
   10232         enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
   10233 
   10234         synchronized (this) {
   10235             final long ident = Binder.clearCallingIdentity();
   10236             try {
   10237                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
   10238                         + " to displayId=" + displayId);
   10239                 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
   10240             } finally {
   10241                 Binder.restoreCallingIdentity(ident);
   10242             }
   10243         }
   10244     }
   10245 
   10246     @Override
   10247     public boolean removeTask(int taskId) {
   10248         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
   10249         synchronized (this) {
   10250             final long ident = Binder.clearCallingIdentity();
   10251             try {
   10252                 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
   10253             } finally {
   10254                 Binder.restoreCallingIdentity(ident);
   10255             }
   10256         }
   10257     }
   10258 
   10259     /**
   10260      * TODO: Add mController hook
   10261      */
   10262     @Override
   10263     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
   10264         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
   10265 
   10266         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
   10267         synchronized(this) {
   10268             moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
   10269         }
   10270     }
   10271 
   10272     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
   10273         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
   10274 
   10275         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   10276                 Binder.getCallingUid(), -1, -1, "Task to front")) {
   10277             ActivityOptions.abort(options);
   10278             return;
   10279         }
   10280         final long origId = Binder.clearCallingIdentity();
   10281         try {
   10282             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   10283             if (task == null) {
   10284                 Slog.d(TAG, "Could not find task for id: "+ taskId);
   10285                 return;
   10286             }
   10287             if (mStackSupervisor.isLockTaskModeViolation(task)) {
   10288                 mStackSupervisor.showLockTaskToast();
   10289                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
   10290                 return;
   10291             }
   10292             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
   10293             if (prev != null) {
   10294                 task.setTaskToReturnTo(prev);
   10295             }
   10296             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
   10297                     false /* forceNonResizable */);
   10298 
   10299             final ActivityRecord topActivity = task.getTopActivity();
   10300             if (topActivity != null) {
   10301 
   10302                 // We are reshowing a task, use a starting window to hide the initial draw delay
   10303                 // so the transition can start earlier.
   10304                 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
   10305                         true /* taskSwitch */, fromRecents);
   10306             }
   10307         } finally {
   10308             Binder.restoreCallingIdentity(origId);
   10309         }
   10310         ActivityOptions.abort(options);
   10311     }
   10312 
   10313     /**
   10314      * Attempts to move a task backwards in z-order (the order of activities within the task is
   10315      * unchanged).
   10316      *
   10317      * There are several possible results of this call:
   10318      * - if the task is locked, then we will show the lock toast
   10319      * - if there is a task behind the provided task, then that task is made visible and resumed as
   10320      *   this task is moved to the back
   10321      * - otherwise, if there are no other tasks in the stack:
   10322      *     - if this task is in the pinned stack, then we remove the stack completely, which will
   10323      *       have the effect of moving the task to the top or bottom of the fullscreen stack
   10324      *       (depending on whether it is visible)
   10325      *     - otherwise, we simply return home and hide this task
   10326      *
   10327      * @param token A reference to the activity we wish to move
   10328      * @param nonRoot If false then this only works if the activity is the root
   10329      *                of a task; if true it will work for any activity in a task.
   10330      * @return Returns true if the move completed, false if not.
   10331      */
   10332     @Override
   10333     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
   10334         enforceNotIsolatedCaller("moveActivityTaskToBack");
   10335         synchronized(this) {
   10336             final long origId = Binder.clearCallingIdentity();
   10337             try {
   10338                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
   10339                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   10340                 if (task != null) {
   10341                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
   10342                 }
   10343             } finally {
   10344                 Binder.restoreCallingIdentity(origId);
   10345             }
   10346         }
   10347         return false;
   10348     }
   10349 
   10350     @Override
   10351     public void moveTaskBackwards(int task) {
   10352         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   10353                 "moveTaskBackwards()");
   10354 
   10355         synchronized(this) {
   10356             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   10357                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
   10358                 return;
   10359             }
   10360             final long origId = Binder.clearCallingIdentity();
   10361             moveTaskBackwardsLocked(task);
   10362             Binder.restoreCallingIdentity(origId);
   10363         }
   10364     }
   10365 
   10366     private final void moveTaskBackwardsLocked(int task) {
   10367         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
   10368     }
   10369 
   10370     @Override
   10371     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
   10372             IActivityContainerCallback callback) throws RemoteException {
   10373         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
   10374         synchronized (this) {
   10375             if (parentActivityToken == null) {
   10376                 throw new IllegalArgumentException("parent token must not be null");
   10377             }
   10378             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
   10379             if (r == null) {
   10380                 return null;
   10381             }
   10382             if (callback == null) {
   10383                 throw new IllegalArgumentException("callback must not be null");
   10384             }
   10385             return mStackSupervisor.createVirtualActivityContainer(r, callback);
   10386         }
   10387     }
   10388 
   10389     @Override
   10390     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
   10391         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
   10392         synchronized (this) {
   10393             final int stackId = mStackSupervisor.getNextStackId();
   10394             final ActivityStack stack =
   10395                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
   10396             if (stack == null) {
   10397                 return null;
   10398             }
   10399             return stack.mActivityContainer;
   10400         }
   10401     }
   10402 
   10403     @Override
   10404     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
   10405         synchronized (this) {
   10406             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
   10407             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
   10408                 return stack.mActivityContainer.getDisplayId();
   10409             }
   10410             return DEFAULT_DISPLAY;
   10411         }
   10412     }
   10413 
   10414     @Override
   10415     public int getActivityStackId(IBinder token) throws RemoteException {
   10416         synchronized (this) {
   10417             ActivityStack stack = ActivityRecord.getStackLocked(token);
   10418             if (stack == null) {
   10419                 return INVALID_STACK_ID;
   10420             }
   10421             return stack.mStackId;
   10422         }
   10423     }
   10424 
   10425     @Override
   10426     public void exitFreeformMode(IBinder token) throws RemoteException {
   10427         synchronized (this) {
   10428             long ident = Binder.clearCallingIdentity();
   10429             try {
   10430                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   10431                 if (r == null) {
   10432                     throw new IllegalArgumentException(
   10433                             "exitFreeformMode: No activity record matching token=" + token);
   10434                 }
   10435 
   10436                 final ActivityStack stack = r.getStack();
   10437                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
   10438                     throw new IllegalStateException(
   10439                             "exitFreeformMode: You can only go fullscreen from freeform.");
   10440                 }
   10441 
   10442                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
   10443                 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
   10444                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
   10445             } finally {
   10446                 Binder.restoreCallingIdentity(ident);
   10447             }
   10448         }
   10449     }
   10450 
   10451     @Override
   10452     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
   10453         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
   10454         if (StackId.isHomeOrRecentsStack(stackId)) {
   10455             throw new IllegalArgumentException(
   10456                     "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
   10457         }
   10458         synchronized (this) {
   10459             long ident = Binder.clearCallingIdentity();
   10460             try {
   10461                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   10462                 if (task == null) {
   10463                     Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
   10464                     return;
   10465                 }
   10466 
   10467                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
   10468                         + " to stackId=" + stackId + " toTop=" + toTop);
   10469                 if (stackId == DOCKED_STACK_ID) {
   10470                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
   10471                             null /* initialBounds */);
   10472                 }
   10473                 task.reparent(stackId, toTop,
   10474                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
   10475             } finally {
   10476                 Binder.restoreCallingIdentity(ident);
   10477             }
   10478         }
   10479     }
   10480 
   10481     @Override
   10482     public void swapDockedAndFullscreenStack() throws RemoteException {
   10483         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
   10484         synchronized (this) {
   10485             long ident = Binder.clearCallingIdentity();
   10486             try {
   10487                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
   10488                         FULLSCREEN_WORKSPACE_STACK_ID);
   10489                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
   10490                         : null;
   10491                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
   10492                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
   10493                         : null;
   10494                 if (topTask == null || tasks == null || tasks.size() == 0) {
   10495                     Slog.w(TAG,
   10496                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
   10497                     return;
   10498                 }
   10499 
   10500                 // TODO: App transition
   10501                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
   10502 
   10503                 // Defer the resume until we move all the docked tasks to the fullscreen stack below
   10504                 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
   10505                         DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
   10506                 final int size = tasks.size();
   10507                 for (int i = 0; i < size; i++) {
   10508                     final int id = tasks.get(i).taskId;
   10509                     if (id == topTask.taskId) {
   10510                         continue;
   10511                     }
   10512 
   10513                     // Defer the resume until after all the tasks have been moved
   10514                     tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
   10515                             REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
   10516                             "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
   10517                 }
   10518 
   10519                 // Because we deferred the resume to avoid conflicts with stack switches while
   10520                 // resuming, we need to do it after all the tasks are moved.
   10521                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   10522                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
   10523 
   10524                 mWindowManager.executeAppTransition();
   10525             } finally {
   10526                 Binder.restoreCallingIdentity(ident);
   10527             }
   10528         }
   10529     }
   10530 
   10531     /**
   10532      * Moves the input task to the docked stack.
   10533      *
   10534      * @param taskId Id of task to move.
   10535      * @param createMode The mode the docked stack should be created in if it doesn't exist
   10536      *                   already. See
   10537      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
   10538      *                   and
   10539      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
   10540      * @param toTop If the task and stack should be moved to the top.
   10541      * @param animate Whether we should play an animation for the moving the task
   10542      * @param initialBounds If the docked stack gets created, it will use these bounds for the
   10543      *                      docked stack. Pass {@code null} to use default bounds.
   10544      */
   10545     @Override
   10546     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
   10547             Rect initialBounds) {
   10548         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
   10549         synchronized (this) {
   10550             long ident = Binder.clearCallingIdentity();
   10551             try {
   10552                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   10553                 if (task == null) {
   10554                     Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
   10555                     return false;
   10556                 }
   10557 
   10558                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
   10559                         + " to createMode=" + createMode + " toTop=" + toTop);
   10560                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
   10561 
   10562                 // Defer resuming until we move the home stack to the front below
   10563                 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
   10564                         REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
   10565                         "moveTaskToDockedStack");
   10566                 if (moved) {
   10567                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   10568                 }
   10569                 return moved;
   10570             } finally {
   10571                 Binder.restoreCallingIdentity(ident);
   10572             }
   10573         }
   10574     }
   10575 
   10576     /**
   10577      * Moves the top activity in the input stackId to the pinned stack.
   10578      *
   10579      * @param stackId Id of stack to move the top activity to pinned stack.
   10580      * @param bounds Bounds to use for pinned stack.
   10581      *
   10582      * @return True if the top activity of the input stack was successfully moved to the pinned
   10583      *          stack.
   10584      */
   10585     @Override
   10586     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
   10587         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
   10588         synchronized (this) {
   10589             if (!mSupportsPictureInPicture) {
   10590                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
   10591                         + "Device doesn't support picture-in-picture mode");
   10592             }
   10593 
   10594             long ident = Binder.clearCallingIdentity();
   10595             try {
   10596                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
   10597             } finally {
   10598                 Binder.restoreCallingIdentity(ident);
   10599             }
   10600         }
   10601     }
   10602 
   10603     @Override
   10604     public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
   10605             boolean preserveWindows, boolean animate, int animationDuration) {
   10606         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
   10607         long ident = Binder.clearCallingIdentity();
   10608         try {
   10609             synchronized (this) {
   10610                 if (animate) {
   10611                     if (stackId == PINNED_STACK_ID) {
   10612                         final PinnedActivityStack pinnedStack =
   10613                                 mStackSupervisor.getStack(PINNED_STACK_ID);
   10614                         if (pinnedStack != null) {
   10615                             pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
   10616                                     destBounds, animationDuration, false /* fromFullscreen */);
   10617                         }
   10618                     } else {
   10619                         throw new IllegalArgumentException("Stack: " + stackId
   10620                                 + " doesn't support animated resize.");
   10621                     }
   10622                 } else {
   10623                     mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
   10624                             null /* tempTaskInsetBounds */, preserveWindows,
   10625                             allowResizeInDockedMode, !DEFER_RESUME);
   10626                 }
   10627             }
   10628         } finally {
   10629             Binder.restoreCallingIdentity(ident);
   10630         }
   10631     }
   10632 
   10633     @Override
   10634     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
   10635             Rect tempDockedTaskInsetBounds,
   10636             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
   10637         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   10638                 "resizeDockedStack()");
   10639         long ident = Binder.clearCallingIdentity();
   10640         try {
   10641             synchronized (this) {
   10642                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
   10643                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
   10644                         PRESERVE_WINDOWS);
   10645             }
   10646         } finally {
   10647             Binder.restoreCallingIdentity(ident);
   10648         }
   10649     }
   10650 
   10651     @Override
   10652     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
   10653         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   10654                 "resizePinnedStack()");
   10655         final long ident = Binder.clearCallingIdentity();
   10656         try {
   10657             synchronized (this) {
   10658                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
   10659             }
   10660         } finally {
   10661             Binder.restoreCallingIdentity(ident);
   10662         }
   10663     }
   10664 
   10665     /**
   10666      * Try to place task to provided position. The final position might be different depending on
   10667      * current user and stacks state. The task will be moved to target stack if it's currently in
   10668      * different stack.
   10669      */
   10670     @Override
   10671     public void positionTaskInStack(int taskId, int stackId, int position) {
   10672         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
   10673         if (StackId.isHomeOrRecentsStack(stackId)) {
   10674             throw new IllegalArgumentException(
   10675                     "positionTaskInStack: Attempt to change the position of task "
   10676                     + taskId + " in/to home/recents stack");
   10677         }
   10678         synchronized (this) {
   10679             long ident = Binder.clearCallingIdentity();
   10680             try {
   10681                 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
   10682                         + taskId + " in stackId=" + stackId + " at position=" + position);
   10683                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   10684                 if (task == null) {
   10685                     throw new IllegalArgumentException("positionTaskInStack: no task for id="
   10686                             + taskId);
   10687                 }
   10688 
   10689                 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
   10690                         !ON_TOP);
   10691 
   10692                 // TODO: Have the callers of this API call a separate reparent method if that is
   10693                 // what they intended to do vs. having this method also do reparenting.
   10694                 if (task.getStack() == stack) {
   10695                     // Change position in current stack.
   10696                     stack.positionChildAt(task, position);
   10697                 } else {
   10698                     // Reparent to new stack.
   10699                     task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
   10700                             !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
   10701                 }
   10702             } finally {
   10703                 Binder.restoreCallingIdentity(ident);
   10704             }
   10705         }
   10706     }
   10707 
   10708     @Override
   10709     public List<StackInfo> getAllStackInfos() {
   10710         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
   10711         long ident = Binder.clearCallingIdentity();
   10712         try {
   10713             synchronized (this) {
   10714                 return mStackSupervisor.getAllStackInfosLocked();
   10715             }
   10716         } finally {
   10717             Binder.restoreCallingIdentity(ident);
   10718         }
   10719     }
   10720 
   10721     @Override
   10722     public StackInfo getStackInfo(int stackId) {
   10723         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
   10724         long ident = Binder.clearCallingIdentity();
   10725         try {
   10726             synchronized (this) {
   10727                 return mStackSupervisor.getStackInfoLocked(stackId);
   10728             }
   10729         } finally {
   10730             Binder.restoreCallingIdentity(ident);
   10731         }
   10732     }
   10733 
   10734     @Override
   10735     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
   10736         synchronized(this) {
   10737             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
   10738         }
   10739     }
   10740 
   10741     @Override
   10742     public void updateDeviceOwner(String packageName) {
   10743         final int callingUid = Binder.getCallingUid();
   10744         if (callingUid != 0 && callingUid != SYSTEM_UID) {
   10745             throw new SecurityException("updateDeviceOwner called from non-system process");
   10746         }
   10747         synchronized (this) {
   10748             mDeviceOwnerName = packageName;
   10749         }
   10750     }
   10751 
   10752     @Override
   10753     public void updateLockTaskPackages(int userId, String[] packages) {
   10754         final int callingUid = Binder.getCallingUid();
   10755         if (callingUid != 0 && callingUid != SYSTEM_UID) {
   10756             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
   10757                     "updateLockTaskPackages()");
   10758         }
   10759         synchronized (this) {
   10760             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
   10761                     Arrays.toString(packages));
   10762             mLockTaskPackages.put(userId, packages);
   10763             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
   10764         }
   10765     }
   10766 
   10767 
   10768     void startLockTaskModeLocked(TaskRecord task) {
   10769         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
   10770         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
   10771             return;
   10772         }
   10773 
   10774         // When a task is locked, dismiss the pinned stack if it exists
   10775         final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
   10776                 PINNED_STACK_ID);
   10777         if (pinnedStack != null) {
   10778             mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
   10779         }
   10780 
   10781         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
   10782         // is initiated by system after the pinning request was shown and locked mode is initiated
   10783         // by an authorized app directly
   10784         final int callingUid = Binder.getCallingUid();
   10785         boolean isSystemInitiated = callingUid == SYSTEM_UID;
   10786         long ident = Binder.clearCallingIdentity();
   10787         try {
   10788             if (!isSystemInitiated) {
   10789                 task.mLockTaskUid = callingUid;
   10790                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
   10791                     // startLockTask() called by app and task mode is lockTaskModeDefault.
   10792                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
   10793                     StatusBarManagerInternal statusBarManager =
   10794                             LocalServices.getService(StatusBarManagerInternal.class);
   10795                     if (statusBarManager != null) {
   10796                         statusBarManager.showScreenPinningRequest(task.taskId);
   10797                     }
   10798                     return;
   10799                 }
   10800 
   10801                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
   10802                 if (stack == null || task != stack.topTask()) {
   10803                     throw new IllegalArgumentException("Invalid task, not in foreground");
   10804                 }
   10805             }
   10806             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
   10807                     "Locking fully");
   10808             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
   10809                     ActivityManager.LOCK_TASK_MODE_PINNED :
   10810                     ActivityManager.LOCK_TASK_MODE_LOCKED,
   10811                     "startLockTask", true);
   10812         } finally {
   10813             Binder.restoreCallingIdentity(ident);
   10814         }
   10815     }
   10816 
   10817     @Override
   10818     public void startLockTaskModeById(int taskId) {
   10819         synchronized (this) {
   10820             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   10821             if (task != null) {
   10822                 startLockTaskModeLocked(task);
   10823             }
   10824         }
   10825     }
   10826 
   10827     @Override
   10828     public void startLockTaskModeByToken(IBinder token) {
   10829         synchronized (this) {
   10830             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   10831             if (r == null) {
   10832                 return;
   10833             }
   10834             final TaskRecord task = r.getTask();
   10835             if (task != null) {
   10836                 startLockTaskModeLocked(task);
   10837             }
   10838         }
   10839     }
   10840 
   10841     @Override
   10842     public void startSystemLockTaskMode(int taskId) throws RemoteException {
   10843         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
   10844         // This makes inner call to look as if it was initiated by system.
   10845         long ident = Binder.clearCallingIdentity();
   10846         try {
   10847             synchronized (this) {
   10848                 startLockTaskModeById(taskId);
   10849             }
   10850         } finally {
   10851             Binder.restoreCallingIdentity(ident);
   10852         }
   10853     }
   10854 
   10855     @Override
   10856     public void stopLockTaskMode() {
   10857         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
   10858         if (lockTask == null) {
   10859             // Our work here is done.
   10860             return;
   10861         }
   10862 
   10863         final int callingUid = Binder.getCallingUid();
   10864         final int lockTaskUid = lockTask.mLockTaskUid;
   10865         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
   10866         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
   10867             // Done.
   10868             return;
   10869         } else {
   10870             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
   10871             // It is possible lockTaskMode was started by the system process because
   10872             // android:lockTaskMode is set to a locking value in the application manifest
   10873             // instead of the app calling startLockTaskMode. In this case
   10874             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
   10875             // {@link TaskRecord.effectiveUid} instead. Also caller with
   10876             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
   10877             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
   10878                     && callingUid != lockTaskUid
   10879                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
   10880                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
   10881                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
   10882             }
   10883         }
   10884         long ident = Binder.clearCallingIdentity();
   10885         try {
   10886             Log.d(TAG, "stopLockTaskMode");
   10887             // Stop lock task
   10888             synchronized (this) {
   10889                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
   10890                         "stopLockTask", true);
   10891             }
   10892             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
   10893             if (tm != null) {
   10894                 tm.showInCallScreen(false);
   10895             }
   10896         } finally {
   10897             Binder.restoreCallingIdentity(ident);
   10898         }
   10899     }
   10900 
   10901     /**
   10902      * This API should be called by SystemUI only when user perform certain action to dismiss
   10903      * lock task mode. We should only dismiss pinned lock task mode in this case.
   10904      */
   10905     @Override
   10906     public void stopSystemLockTaskMode() throws RemoteException {
   10907         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
   10908             stopLockTaskMode();
   10909         } else {
   10910             mStackSupervisor.showLockTaskToast();
   10911         }
   10912     }
   10913 
   10914     @Override
   10915     public boolean isInLockTaskMode() {
   10916         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
   10917     }
   10918 
   10919     @Override
   10920     public int getLockTaskModeState() {
   10921         synchronized (this) {
   10922             return mStackSupervisor.getLockTaskModeState();
   10923         }
   10924     }
   10925 
   10926     @Override
   10927     public void showLockTaskEscapeMessage(IBinder token) {
   10928         synchronized (this) {
   10929             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   10930             if (r == null) {
   10931                 return;
   10932             }
   10933             mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
   10934         }
   10935     }
   10936 
   10937     @Override
   10938     public void setDisablePreviewScreenshots(IBinder token, boolean disable)
   10939             throws RemoteException {
   10940         synchronized (this) {
   10941             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10942             if (r == null) {
   10943                 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
   10944                         + token);
   10945                 return;
   10946             }
   10947             final long origId = Binder.clearCallingIdentity();
   10948             try {
   10949                 r.setDisablePreviewScreenshots(disable);
   10950             } finally {
   10951                 Binder.restoreCallingIdentity(origId);
   10952             }
   10953         }
   10954     }
   10955 
   10956     // =========================================================
   10957     // CONTENT PROVIDERS
   10958     // =========================================================
   10959 
   10960     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
   10961         List<ProviderInfo> providers = null;
   10962         try {
   10963             providers = AppGlobals.getPackageManager()
   10964                     .queryContentProviders(app.processName, app.uid,
   10965                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
   10966                                     | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
   10967                     .getList();
   10968         } catch (RemoteException ex) {
   10969         }
   10970         if (DEBUG_MU) Slog.v(TAG_MU,
   10971                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
   10972         int userId = app.userId;
   10973         if (providers != null) {
   10974             int N = providers.size();
   10975             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
   10976             for (int i=0; i<N; i++) {
   10977                 // TODO: keep logic in sync with installEncryptionUnawareProviders
   10978                 ProviderInfo cpi =
   10979                     (ProviderInfo)providers.get(i);
   10980                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   10981                         cpi.name, cpi.flags);
   10982                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
   10983                     // This is a singleton provider, but a user besides the
   10984                     // default user is asking to initialize a process it runs
   10985                     // in...  well, no, it doesn't actually run in this process,
   10986                     // it runs in the process of the default user.  Get rid of it.
   10987                     providers.remove(i);
   10988                     N--;
   10989                     i--;
   10990                     continue;
   10991                 }
   10992 
   10993                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   10994                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
   10995                 if (cpr == null) {
   10996                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
   10997                     mProviderMap.putProviderByClass(comp, cpr);
   10998                 }
   10999                 if (DEBUG_MU) Slog.v(TAG_MU,
   11000                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
   11001                 app.pubProviders.put(cpi.name, cpr);
   11002                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
   11003                     // Don't add this if it is a platform component that is marked
   11004                     // to run in multiple processes, because this is actually
   11005                     // part of the framework so doesn't make sense to track as a
   11006                     // separate apk in the process.
   11007                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
   11008                             mProcessStats);
   11009                 }
   11010                 notifyPackageUse(cpi.applicationInfo.packageName,
   11011                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
   11012             }
   11013         }
   11014         return providers;
   11015     }
   11016 
   11017     /**
   11018      * Check if the calling UID has a possible chance at accessing the provider
   11019      * at the given authority and user.
   11020      */
   11021     public String checkContentProviderAccess(String authority, int userId) {
   11022         if (userId == UserHandle.USER_ALL) {
   11023             mContext.enforceCallingOrSelfPermission(
   11024                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
   11025             userId = UserHandle.getCallingUserId();
   11026         }
   11027 
   11028         ProviderInfo cpi = null;
   11029         try {
   11030             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
   11031                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
   11032                             | PackageManager.MATCH_DISABLED_COMPONENTS
   11033                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
   11034                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
   11035                     userId);
   11036         } catch (RemoteException ignored) {
   11037         }
   11038         if (cpi == null) {
   11039             return "Failed to find provider " + authority + " for user " + userId
   11040                     + "; expected to find a valid ContentProvider for this authority";
   11041         }
   11042 
   11043         ProcessRecord r = null;
   11044         synchronized (mPidsSelfLocked) {
   11045             r = mPidsSelfLocked.get(Binder.getCallingPid());
   11046         }
   11047         if (r == null) {
   11048             return "Failed to find PID " + Binder.getCallingPid();
   11049         }
   11050 
   11051         synchronized (this) {
   11052             return checkContentProviderPermissionLocked(cpi, r, userId, true);
   11053         }
   11054     }
   11055 
   11056     /**
   11057      * Check if {@link ProcessRecord} has a possible chance at accessing the
   11058      * given {@link ProviderInfo}. Final permission checking is always done
   11059      * in {@link ContentProvider}.
   11060      */
   11061     private final String checkContentProviderPermissionLocked(
   11062             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
   11063         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
   11064         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
   11065         boolean checkedGrants = false;
   11066         if (checkUser) {
   11067             // Looking for cross-user grants before enforcing the typical cross-users permissions
   11068             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
   11069             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
   11070                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
   11071                     return null;
   11072                 }
   11073                 checkedGrants = true;
   11074             }
   11075             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
   11076                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
   11077             if (userId != tmpTargetUserId) {
   11078                 // When we actually went to determine the final targer user ID, this ended
   11079                 // up different than our initial check for the authority.  This is because
   11080                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
   11081                 // SELF.  So we need to re-check the grants again.
   11082                 checkedGrants = false;
   11083             }
   11084         }
   11085         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
   11086                 cpi.applicationInfo.uid, cpi.exported)
   11087                 == PackageManager.PERMISSION_GRANTED) {
   11088             return null;
   11089         }
   11090         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
   11091                 cpi.applicationInfo.uid, cpi.exported)
   11092                 == PackageManager.PERMISSION_GRANTED) {
   11093             return null;
   11094         }
   11095 
   11096         PathPermission[] pps = cpi.pathPermissions;
   11097         if (pps != null) {
   11098             int i = pps.length;
   11099             while (i > 0) {
   11100                 i--;
   11101                 PathPermission pp = pps[i];
   11102                 String pprperm = pp.getReadPermission();
   11103                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
   11104                         cpi.applicationInfo.uid, cpi.exported)
   11105                         == PackageManager.PERMISSION_GRANTED) {
   11106                     return null;
   11107                 }
   11108                 String ppwperm = pp.getWritePermission();
   11109                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
   11110                         cpi.applicationInfo.uid, cpi.exported)
   11111                         == PackageManager.PERMISSION_GRANTED) {
   11112                     return null;
   11113                 }
   11114             }
   11115         }
   11116         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
   11117             return null;
   11118         }
   11119 
   11120         final String suffix;
   11121         if (!cpi.exported) {
   11122             suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
   11123         } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
   11124             suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
   11125         } else {
   11126             suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
   11127         }
   11128         final String msg = "Permission Denial: opening provider " + cpi.name
   11129                 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   11130                 + ", uid=" + callingUid + ")" + suffix;
   11131         Slog.w(TAG, msg);
   11132         return msg;
   11133     }
   11134 
   11135     /**
   11136      * Returns if the ContentProvider has granted a uri to callingUid
   11137      */
   11138     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
   11139         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   11140         if (perms != null) {
   11141             for (int i=perms.size()-1; i>=0; i--) {
   11142                 GrantUri grantUri = perms.keyAt(i);
   11143                 if (grantUri.sourceUserId == userId || !checkUser) {
   11144                     if (matchesProvider(grantUri.uri, cpi)) {
   11145                         return true;
   11146                     }
   11147                 }
   11148             }
   11149         }
   11150         return false;
   11151     }
   11152 
   11153     /**
   11154      * Returns true if the uri authority is one of the authorities specified in the provider.
   11155      */
   11156     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
   11157         String uriAuth = uri.getAuthority();
   11158         String cpiAuth = cpi.authority;
   11159         if (cpiAuth.indexOf(';') == -1) {
   11160             return cpiAuth.equals(uriAuth);
   11161         }
   11162         String[] cpiAuths = cpiAuth.split(";");
   11163         int length = cpiAuths.length;
   11164         for (int i = 0; i < length; i++) {
   11165             if (cpiAuths[i].equals(uriAuth)) return true;
   11166         }
   11167         return false;
   11168     }
   11169 
   11170     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
   11171             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   11172         if (r != null) {
   11173             for (int i=0; i<r.conProviders.size(); i++) {
   11174                 ContentProviderConnection conn = r.conProviders.get(i);
   11175                 if (conn.provider == cpr) {
   11176                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
   11177                             "Adding provider requested by "
   11178                             + r.processName + " from process "
   11179                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   11180                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   11181                     if (stable) {
   11182                         conn.stableCount++;
   11183                         conn.numStableIncs++;
   11184                     } else {
   11185                         conn.unstableCount++;
   11186                         conn.numUnstableIncs++;
   11187                     }
   11188                     return conn;
   11189                 }
   11190             }
   11191             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
   11192             if (stable) {
   11193                 conn.stableCount = 1;
   11194                 conn.numStableIncs = 1;
   11195             } else {
   11196                 conn.unstableCount = 1;
   11197                 conn.numUnstableIncs = 1;
   11198             }
   11199             cpr.connections.add(conn);
   11200             r.conProviders.add(conn);
   11201             startAssociationLocked(r.uid, r.processName, r.curProcState,
   11202                     cpr.uid, cpr.name, cpr.info.processName);
   11203             return conn;
   11204         }
   11205         cpr.addExternalProcessHandleLocked(externalProcessToken);
   11206         return null;
   11207     }
   11208 
   11209     boolean decProviderCountLocked(ContentProviderConnection conn,
   11210             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   11211         if (conn != null) {
   11212             cpr = conn.provider;
   11213             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
   11214                     "Removing provider requested by "
   11215                     + conn.client.processName + " from process "
   11216                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   11217                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   11218             if (stable) {
   11219                 conn.stableCount--;
   11220             } else {
   11221                 conn.unstableCount--;
   11222             }
   11223             if (conn.stableCount == 0 && conn.unstableCount == 0) {
   11224                 cpr.connections.remove(conn);
   11225                 conn.client.conProviders.remove(conn);
   11226                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   11227                     // The client is more important than last activity -- note the time this
   11228                     // is happening, so we keep the old provider process around a bit as last
   11229                     // activity to avoid thrashing it.
   11230                     if (cpr.proc != null) {
   11231                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
   11232                     }
   11233                 }
   11234                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
   11235                 return true;
   11236             }
   11237             return false;
   11238         }
   11239         cpr.removeExternalProcessHandleLocked(externalProcessToken);
   11240         return false;
   11241     }
   11242 
   11243     private void checkTime(long startTime, String where) {
   11244         long now = SystemClock.uptimeMillis();
   11245         if ((now-startTime) > 50) {
   11246             // If we are taking more than 50ms, log about it.
   11247             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
   11248         }
   11249     }
   11250 
   11251     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
   11252             PROC_SPACE_TERM,
   11253             PROC_SPACE_TERM|PROC_PARENS,
   11254             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
   11255     };
   11256 
   11257     private final long[] mProcessStateStatsLongs = new long[1];
   11258 
   11259     boolean isProcessAliveLocked(ProcessRecord proc) {
   11260         if (proc.procStatFile == null) {
   11261             proc.procStatFile = "/proc/" + proc.pid + "/stat";
   11262         }
   11263         mProcessStateStatsLongs[0] = 0;
   11264         if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
   11265                 mProcessStateStatsLongs, null)) {
   11266             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
   11267             return false;
   11268         }
   11269         final long state = mProcessStateStatsLongs[0];
   11270         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
   11271                 + (char)state);
   11272         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
   11273     }
   11274 
   11275     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
   11276             String name, IBinder token, boolean stable, int userId) {
   11277         ContentProviderRecord cpr;
   11278         ContentProviderConnection conn = null;
   11279         ProviderInfo cpi = null;
   11280 
   11281         synchronized(this) {
   11282             long startTime = SystemClock.uptimeMillis();
   11283 
   11284             ProcessRecord r = null;
   11285             if (caller != null) {
   11286                 r = getRecordForAppLocked(caller);
   11287                 if (r == null) {
   11288                     throw new SecurityException(
   11289                             "Unable to find app for caller " + caller
   11290                           + " (pid=" + Binder.getCallingPid()
   11291                           + ") when getting content provider " + name);
   11292                 }
   11293             }
   11294 
   11295             boolean checkCrossUser = true;
   11296 
   11297             checkTime(startTime, "getContentProviderImpl: getProviderByName");
   11298 
   11299             // First check if this content provider has been published...
   11300             cpr = mProviderMap.getProviderByName(name, userId);
   11301             // If that didn't work, check if it exists for user 0 and then
   11302             // verify that it's a singleton provider before using it.
   11303             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
   11304                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
   11305                 if (cpr != null) {
   11306                     cpi = cpr.info;
   11307                     if (isSingleton(cpi.processName, cpi.applicationInfo,
   11308                             cpi.name, cpi.flags)
   11309                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
   11310                         userId = UserHandle.USER_SYSTEM;
   11311                         checkCrossUser = false;
   11312                     } else {
   11313                         cpr = null;
   11314                         cpi = null;
   11315                     }
   11316                 }
   11317             }
   11318 
   11319             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
   11320             if (providerRunning) {
   11321                 cpi = cpr.info;
   11322                 String msg;
   11323                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
   11324                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
   11325                         != null) {
   11326                     throw new SecurityException(msg);
   11327                 }
   11328                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
   11329 
   11330                 if (r != null && cpr.canRunHere(r)) {
   11331                     // This provider has been published or is in the process
   11332                     // of being published...  but it is also allowed to run
   11333                     // in the caller's process, so don't make a connection
   11334                     // and just let the caller instantiate its own instance.
   11335                     ContentProviderHolder holder = cpr.newHolder(null);
   11336                     // don't give caller the provider object, it needs
   11337                     // to make its own.
   11338                     holder.provider = null;
   11339                     return holder;
   11340                 }
   11341                 // Don't expose providers between normal apps and instant apps
   11342                 try {
   11343                     if (AppGlobals.getPackageManager()
   11344                             .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
   11345                         return null;
   11346                     }
   11347                 } catch (RemoteException e) {
   11348                 }
   11349 
   11350                 final long origId = Binder.clearCallingIdentity();
   11351 
   11352                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
   11353 
   11354                 // In this case the provider instance already exists, so we can
   11355                 // return it right away.
   11356                 conn = incProviderCountLocked(r, cpr, token, stable);
   11357                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
   11358                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   11359                         // If this is a perceptible app accessing the provider,
   11360                         // make sure to count it as being accessed and thus
   11361                         // back up on the LRU list.  This is good because
   11362                         // content providers are often expensive to start.
   11363                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
   11364                         updateLruProcessLocked(cpr.proc, false, null);
   11365                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
   11366                     }
   11367                 }
   11368 
   11369                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
   11370                 final int verifiedAdj = cpr.proc.verifiedAdj;
   11371                 boolean success = updateOomAdjLocked(cpr.proc, true);
   11372                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
   11373                 // if the process has been successfully adjusted.  So to reduce races with
   11374                 // it, we will check whether the process still exists.  Note that this doesn't
   11375                 // completely get rid of races with LMK killing the process, but should make
   11376                 // them much smaller.
   11377                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
   11378                     success = false;
   11379                 }
   11380                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
   11381                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
   11382                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
   11383                 // NOTE: there is still a race here where a signal could be
   11384                 // pending on the process even though we managed to update its
   11385                 // adj level.  Not sure what to do about this, but at least
   11386                 // the race is now smaller.
   11387                 if (!success) {
   11388                     // Uh oh...  it looks like the provider's process
   11389                     // has been killed on us.  We need to wait for a new
   11390                     // process to be started, and make sure its death
   11391                     // doesn't kill our process.
   11392                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
   11393                             + " is crashing; detaching " + r);
   11394                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
   11395                     checkTime(startTime, "getContentProviderImpl: before appDied");
   11396                     appDiedLocked(cpr.proc);
   11397                     checkTime(startTime, "getContentProviderImpl: after appDied");
   11398                     if (!lastRef) {
   11399                         // This wasn't the last ref our process had on
   11400                         // the provider...  we have now been killed, bail.
   11401                         return null;
   11402                     }
   11403                     providerRunning = false;
   11404                     conn = null;
   11405                 } else {
   11406                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
   11407                 }
   11408 
   11409                 Binder.restoreCallingIdentity(origId);
   11410             }
   11411 
   11412             if (!providerRunning) {
   11413                 try {
   11414                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
   11415                     cpi = AppGlobals.getPackageManager().
   11416                         resolveContentProvider(name,
   11417                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
   11418                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
   11419                 } catch (RemoteException ex) {
   11420                 }
   11421                 if (cpi == null) {
   11422                     return null;
   11423                 }
   11424                 // If the provider is a singleton AND
   11425                 // (it's a call within the same user || the provider is a
   11426                 // privileged app)
   11427                 // Then allow connecting to the singleton provider
   11428                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   11429                         cpi.name, cpi.flags)
   11430                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
   11431                 if (singleton) {
   11432                     userId = UserHandle.USER_SYSTEM;
   11433                 }
   11434                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
   11435                 checkTime(startTime, "getContentProviderImpl: got app info for user");
   11436 
   11437                 String msg;
   11438                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
   11439                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
   11440                         != null) {
   11441                     throw new SecurityException(msg);
   11442                 }
   11443                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
   11444 
   11445                 if (!mProcessesReady
   11446                         && !cpi.processName.equals("system")) {
   11447                     // If this content provider does not run in the system
   11448                     // process, and the system is not yet ready to run other
   11449                     // processes, then fail fast instead of hanging.
   11450                     throw new IllegalArgumentException(
   11451                             "Attempt to launch content provider before system ready");
   11452                 }
   11453 
   11454                 // Make sure that the user who owns this provider is running.  If not,
   11455                 // we don't want to allow it to run.
   11456                 if (!mUserController.isUserRunningLocked(userId, 0)) {
   11457                     Slog.w(TAG, "Unable to launch app "
   11458                             + cpi.applicationInfo.packageName + "/"
   11459                             + cpi.applicationInfo.uid + " for provider "
   11460                             + name + ": user " + userId + " is stopped");
   11461                     return null;
   11462                 }
   11463 
   11464                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   11465                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
   11466                 cpr = mProviderMap.getProviderByClass(comp, userId);
   11467                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
   11468                 final boolean firstClass = cpr == null;
   11469                 if (firstClass) {
   11470                     final long ident = Binder.clearCallingIdentity();
   11471 
   11472                     // If permissions need a review before any of the app components can run,
   11473                     // we return no provider and launch a review activity if the calling app
   11474                     // is in the foreground.
   11475                     if (mPermissionReviewRequired) {
   11476                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
   11477                             return null;
   11478                         }
   11479                     }
   11480 
   11481                     try {
   11482                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
   11483                         ApplicationInfo ai =
   11484                             AppGlobals.getPackageManager().
   11485                                 getApplicationInfo(
   11486                                         cpi.applicationInfo.packageName,
   11487                                         STOCK_PM_FLAGS, userId);
   11488                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
   11489                         if (ai == null) {
   11490                             Slog.w(TAG, "No package info for content provider "
   11491                                     + cpi.name);
   11492                             return null;
   11493                         }
   11494                         ai = getAppInfoForUser(ai, userId);
   11495                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
   11496                     } catch (RemoteException ex) {
   11497                         // pm is in same process, this will never happen.
   11498                     } finally {
   11499                         Binder.restoreCallingIdentity(ident);
   11500                     }
   11501                 }
   11502 
   11503                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
   11504 
   11505                 if (r != null && cpr.canRunHere(r)) {
   11506                     // If this is a multiprocess provider, then just return its
   11507                     // info and allow the caller to instantiate it.  Only do
   11508                     // this if the provider is the same user as the caller's
   11509                     // process, or can run as root (so can be in any process).
   11510                     return cpr.newHolder(null);
   11511                 }
   11512 
   11513                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
   11514                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
   11515                             + cpr.info.name + " callers=" + Debug.getCallers(6));
   11516 
   11517                 // This is single process, and our app is now connecting to it.
   11518                 // See if we are already in the process of launching this
   11519                 // provider.
   11520                 final int N = mLaunchingProviders.size();
   11521                 int i;
   11522                 for (i = 0; i < N; i++) {
   11523                     if (mLaunchingProviders.get(i) == cpr) {
   11524                         break;
   11525                     }
   11526                 }
   11527 
   11528                 // If the provider is not already being launched, then get it
   11529                 // started.
   11530                 if (i >= N) {
   11531                     final long origId = Binder.clearCallingIdentity();
   11532 
   11533                     try {
   11534                         // Content provider is now in use, its package can't be stopped.
   11535                         try {
   11536                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
   11537                             AppGlobals.getPackageManager().setPackageStoppedState(
   11538                                     cpr.appInfo.packageName, false, userId);
   11539                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
   11540                         } catch (RemoteException e) {
   11541                         } catch (IllegalArgumentException e) {
   11542                             Slog.w(TAG, "Failed trying to unstop package "
   11543                                     + cpr.appInfo.packageName + ": " + e);
   11544                         }
   11545 
   11546                         // Use existing process if already started
   11547                         checkTime(startTime, "getContentProviderImpl: looking for process record");
   11548                         ProcessRecord proc = getProcessRecordLocked(
   11549                                 cpi.processName, cpr.appInfo.uid, false);
   11550                         if (proc != null && proc.thread != null && !proc.killed) {
   11551                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
   11552                                     "Installing in existing process " + proc);
   11553                             if (!proc.pubProviders.containsKey(cpi.name)) {
   11554                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
   11555                                 proc.pubProviders.put(cpi.name, cpr);
   11556                                 try {
   11557                                     proc.thread.scheduleInstallProvider(cpi);
   11558                                 } catch (RemoteException e) {
   11559                                 }
   11560                             }
   11561                         } else {
   11562                             checkTime(startTime, "getContentProviderImpl: before start process");
   11563                             proc = startProcessLocked(cpi.processName,
   11564                                     cpr.appInfo, false, 0, "content provider",
   11565                                     new ComponentName(cpi.applicationInfo.packageName,
   11566                                             cpi.name), false, false, false);
   11567                             checkTime(startTime, "getContentProviderImpl: after start process");
   11568                             if (proc == null) {
   11569                                 Slog.w(TAG, "Unable to launch app "
   11570                                         + cpi.applicationInfo.packageName + "/"
   11571                                         + cpi.applicationInfo.uid + " for provider "
   11572                                         + name + ": process is bad");
   11573                                 return null;
   11574                             }
   11575                         }
   11576                         cpr.launchingApp = proc;
   11577                         mLaunchingProviders.add(cpr);
   11578                     } finally {
   11579                         Binder.restoreCallingIdentity(origId);
   11580                     }
   11581                 }
   11582 
   11583                 checkTime(startTime, "getContentProviderImpl: updating data structures");
   11584 
   11585                 // Make sure the provider is published (the same provider class
   11586                 // may be published under multiple names).
   11587                 if (firstClass) {
   11588                     mProviderMap.putProviderByClass(comp, cpr);
   11589                 }
   11590 
   11591                 mProviderMap.putProviderByName(name, cpr);
   11592                 conn = incProviderCountLocked(r, cpr, token, stable);
   11593                 if (conn != null) {
   11594                     conn.waiting = true;
   11595                 }
   11596             }
   11597             checkTime(startTime, "getContentProviderImpl: done!");
   11598 
   11599             grantEphemeralAccessLocked(userId, null /*intent*/,
   11600                     cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
   11601         }
   11602 
   11603         // Wait for the provider to be published...
   11604         synchronized (cpr) {
   11605             while (cpr.provider == null) {
   11606                 if (cpr.launchingApp == null) {
   11607                     Slog.w(TAG, "Unable to launch app "
   11608                             + cpi.applicationInfo.packageName + "/"
   11609                             + cpi.applicationInfo.uid + " for provider "
   11610                             + name + ": launching app became null");
   11611                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
   11612                             UserHandle.getUserId(cpi.applicationInfo.uid),
   11613                             cpi.applicationInfo.packageName,
   11614                             cpi.applicationInfo.uid, name);
   11615                     return null;
   11616                 }
   11617                 try {
   11618                     if (DEBUG_MU) Slog.v(TAG_MU,
   11619                             "Waiting to start provider " + cpr
   11620                             + " launchingApp=" + cpr.launchingApp);
   11621                     if (conn != null) {
   11622                         conn.waiting = true;
   11623                     }
   11624                     cpr.wait();
   11625                 } catch (InterruptedException ex) {
   11626                 } finally {
   11627                     if (conn != null) {
   11628                         conn.waiting = false;
   11629                     }
   11630                 }
   11631             }
   11632         }
   11633         return cpr != null ? cpr.newHolder(conn) : null;
   11634     }
   11635 
   11636     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
   11637             ProcessRecord r, final int userId) {
   11638         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
   11639                 cpi.packageName, userId)) {
   11640 
   11641             final boolean callerForeground = r == null || r.setSchedGroup
   11642                     != ProcessList.SCHED_GROUP_BACKGROUND;
   11643 
   11644             // Show a permission review UI only for starting from a foreground app
   11645             if (!callerForeground) {
   11646                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
   11647                         + cpi.packageName + " requires a permissions review");
   11648                 return false;
   11649             }
   11650 
   11651             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
   11652             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
   11653                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
   11654             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
   11655 
   11656             if (DEBUG_PERMISSIONS_REVIEW) {
   11657                 Slog.i(TAG, "u" + userId + " Launching permission review "
   11658                         + "for package " + cpi.packageName);
   11659             }
   11660 
   11661             final UserHandle userHandle = new UserHandle(userId);
   11662             mHandler.post(new Runnable() {
   11663                 @Override
   11664                 public void run() {
   11665                     mContext.startActivityAsUser(intent, userHandle);
   11666                 }
   11667             });
   11668 
   11669             return false;
   11670         }
   11671 
   11672         return true;
   11673     }
   11674 
   11675     PackageManagerInternal getPackageManagerInternalLocked() {
   11676         if (mPackageManagerInt == null) {
   11677             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
   11678         }
   11679         return mPackageManagerInt;
   11680     }
   11681 
   11682     @Override
   11683     public final ContentProviderHolder getContentProvider(
   11684             IApplicationThread caller, String name, int userId, boolean stable) {
   11685         enforceNotIsolatedCaller("getContentProvider");
   11686         if (caller == null) {
   11687             String msg = "null IApplicationThread when getting content provider "
   11688                     + name;
   11689             Slog.w(TAG, msg);
   11690             throw new SecurityException(msg);
   11691         }
   11692         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
   11693         // with cross-user grant.
   11694         return getContentProviderImpl(caller, name, null, stable, userId);
   11695     }
   11696 
   11697     public ContentProviderHolder getContentProviderExternal(
   11698             String name, int userId, IBinder token) {
   11699         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   11700             "Do not have permission in call getContentProviderExternal()");
   11701         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   11702                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
   11703         return getContentProviderExternalUnchecked(name, token, userId);
   11704     }
   11705 
   11706     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
   11707             IBinder token, int userId) {
   11708         return getContentProviderImpl(null, name, token, true, userId);
   11709     }
   11710 
   11711     /**
   11712      * Drop a content provider from a ProcessRecord's bookkeeping
   11713      */
   11714     public void removeContentProvider(IBinder connection, boolean stable) {
   11715         enforceNotIsolatedCaller("removeContentProvider");
   11716         long ident = Binder.clearCallingIdentity();
   11717         try {
   11718             synchronized (this) {
   11719                 ContentProviderConnection conn;
   11720                 try {
   11721                     conn = (ContentProviderConnection)connection;
   11722                 } catch (ClassCastException e) {
   11723                     String msg ="removeContentProvider: " + connection
   11724                             + " not a ContentProviderConnection";
   11725                     Slog.w(TAG, msg);
   11726                     throw new IllegalArgumentException(msg);
   11727                 }
   11728                 if (conn == null) {
   11729                     throw new NullPointerException("connection is null");
   11730                 }
   11731                 if (decProviderCountLocked(conn, null, null, stable)) {
   11732                     updateOomAdjLocked();
   11733                 }
   11734             }
   11735         } finally {
   11736             Binder.restoreCallingIdentity(ident);
   11737         }
   11738     }
   11739 
   11740     public void removeContentProviderExternal(String name, IBinder token) {
   11741         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   11742             "Do not have permission in call removeContentProviderExternal()");
   11743         int userId = UserHandle.getCallingUserId();
   11744         long ident = Binder.clearCallingIdentity();
   11745         try {
   11746             removeContentProviderExternalUnchecked(name, token, userId);
   11747         } finally {
   11748             Binder.restoreCallingIdentity(ident);
   11749         }
   11750     }
   11751 
   11752     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
   11753         synchronized (this) {
   11754             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
   11755             if(cpr == null) {
   11756                 //remove from mProvidersByClass
   11757                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
   11758                 return;
   11759             }
   11760 
   11761             //update content provider record entry info
   11762             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
   11763             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
   11764             if (localCpr.hasExternalProcessHandles()) {
   11765                 if (localCpr.removeExternalProcessHandleLocked(token)) {
   11766                     updateOomAdjLocked();
   11767                 } else {
   11768                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
   11769                             + " with no external reference for token: "
   11770                             + token + ".");
   11771                 }
   11772             } else {
   11773                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
   11774                         + " with no external references.");
   11775             }
   11776         }
   11777     }
   11778 
   11779     public final void publishContentProviders(IApplicationThread caller,
   11780             List<ContentProviderHolder> providers) {
   11781         if (providers == null) {
   11782             return;
   11783         }
   11784 
   11785         enforceNotIsolatedCaller("publishContentProviders");
   11786         synchronized (this) {
   11787             final ProcessRecord r = getRecordForAppLocked(caller);
   11788             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
   11789             if (r == null) {
   11790                 throw new SecurityException(
   11791                         "Unable to find app for caller " + caller
   11792                       + " (pid=" + Binder.getCallingPid()
   11793                       + ") when publishing content providers");
   11794             }
   11795 
   11796             final long origId = Binder.clearCallingIdentity();
   11797 
   11798             final int N = providers.size();
   11799             for (int i = 0; i < N; i++) {
   11800                 ContentProviderHolder src = providers.get(i);
   11801                 if (src == null || src.info == null || src.provider == null) {
   11802                     continue;
   11803                 }
   11804                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
   11805                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
   11806                 if (dst != null) {
   11807                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
   11808                     mProviderMap.putProviderByClass(comp, dst);
   11809                     String names[] = dst.info.authority.split(";");
   11810                     for (int j = 0; j < names.length; j++) {
   11811                         mProviderMap.putProviderByName(names[j], dst);
   11812                     }
   11813 
   11814                     int launchingCount = mLaunchingProviders.size();
   11815                     int j;
   11816                     boolean wasInLaunchingProviders = false;
   11817                     for (j = 0; j < launchingCount; j++) {
   11818                         if (mLaunchingProviders.get(j) == dst) {
   11819                             mLaunchingProviders.remove(j);
   11820                             wasInLaunchingProviders = true;
   11821                             j--;
   11822                             launchingCount--;
   11823                         }
   11824                     }
   11825                     if (wasInLaunchingProviders) {
   11826                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
   11827                     }
   11828                     synchronized (dst) {
   11829                         dst.provider = src.provider;
   11830                         dst.proc = r;
   11831                         dst.notifyAll();
   11832                     }
   11833                     updateOomAdjLocked(r, true);
   11834                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
   11835                             src.info.authority);
   11836                 }
   11837             }
   11838 
   11839             Binder.restoreCallingIdentity(origId);
   11840         }
   11841     }
   11842 
   11843     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
   11844         ContentProviderConnection conn;
   11845         try {
   11846             conn = (ContentProviderConnection)connection;
   11847         } catch (ClassCastException e) {
   11848             String msg ="refContentProvider: " + connection
   11849                     + " not a ContentProviderConnection";
   11850             Slog.w(TAG, msg);
   11851             throw new IllegalArgumentException(msg);
   11852         }
   11853         if (conn == null) {
   11854             throw new NullPointerException("connection is null");
   11855         }
   11856 
   11857         synchronized (this) {
   11858             if (stable > 0) {
   11859                 conn.numStableIncs += stable;
   11860             }
   11861             stable = conn.stableCount + stable;
   11862             if (stable < 0) {
   11863                 throw new IllegalStateException("stableCount < 0: " + stable);
   11864             }
   11865 
   11866             if (unstable > 0) {
   11867                 conn.numUnstableIncs += unstable;
   11868             }
   11869             unstable = conn.unstableCount + unstable;
   11870             if (unstable < 0) {
   11871                 throw new IllegalStateException("unstableCount < 0: " + unstable);
   11872             }
   11873 
   11874             if ((stable+unstable) <= 0) {
   11875                 throw new IllegalStateException("ref counts can't go to zero here: stable="
   11876                         + stable + " unstable=" + unstable);
   11877             }
   11878             conn.stableCount = stable;
   11879             conn.unstableCount = unstable;
   11880             return !conn.dead;
   11881         }
   11882     }
   11883 
   11884     public void unstableProviderDied(IBinder connection) {
   11885         ContentProviderConnection conn;
   11886         try {
   11887             conn = (ContentProviderConnection)connection;
   11888         } catch (ClassCastException e) {
   11889             String msg ="refContentProvider: " + connection
   11890                     + " not a ContentProviderConnection";
   11891             Slog.w(TAG, msg);
   11892             throw new IllegalArgumentException(msg);
   11893         }
   11894         if (conn == null) {
   11895             throw new NullPointerException("connection is null");
   11896         }
   11897 
   11898         // Safely retrieve the content provider associated with the connection.
   11899         IContentProvider provider;
   11900         synchronized (this) {
   11901             provider = conn.provider.provider;
   11902         }
   11903 
   11904         if (provider == null) {
   11905             // Um, yeah, we're way ahead of you.
   11906             return;
   11907         }
   11908 
   11909         // Make sure the caller is being honest with us.
   11910         if (provider.asBinder().pingBinder()) {
   11911             // Er, no, still looks good to us.
   11912             synchronized (this) {
   11913                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
   11914                         + " says " + conn + " died, but we don't agree");
   11915                 return;
   11916             }
   11917         }
   11918 
   11919         // Well look at that!  It's dead!
   11920         synchronized (this) {
   11921             if (conn.provider.provider != provider) {
   11922                 // But something changed...  good enough.
   11923                 return;
   11924             }
   11925 
   11926             ProcessRecord proc = conn.provider.proc;
   11927             if (proc == null || proc.thread == null) {
   11928                 // Seems like the process is already cleaned up.
   11929                 return;
   11930             }
   11931 
   11932             // As far as we're concerned, this is just like receiving a
   11933             // death notification...  just a bit prematurely.
   11934             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
   11935                     + ") early provider death");
   11936             final long ident = Binder.clearCallingIdentity();
   11937             try {
   11938                 appDiedLocked(proc);
   11939             } finally {
   11940                 Binder.restoreCallingIdentity(ident);
   11941             }
   11942         }
   11943     }
   11944 
   11945     @Override
   11946     public void appNotRespondingViaProvider(IBinder connection) {
   11947         enforceCallingPermission(
   11948                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
   11949 
   11950         final ContentProviderConnection conn = (ContentProviderConnection) connection;
   11951         if (conn == null) {
   11952             Slog.w(TAG, "ContentProviderConnection is null");
   11953             return;
   11954         }
   11955 
   11956         final ProcessRecord host = conn.provider.proc;
   11957         if (host == null) {
   11958             Slog.w(TAG, "Failed to find hosting ProcessRecord");
   11959             return;
   11960         }
   11961 
   11962         mHandler.post(new Runnable() {
   11963             @Override
   11964             public void run() {
   11965                 mAppErrors.appNotResponding(host, null, null, false,
   11966                         "ContentProvider not responding");
   11967             }
   11968         });
   11969     }
   11970 
   11971     public final void installSystemProviders() {
   11972         List<ProviderInfo> providers;
   11973         synchronized (this) {
   11974             ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
   11975             providers = generateApplicationProvidersLocked(app);
   11976             if (providers != null) {
   11977                 for (int i=providers.size()-1; i>=0; i--) {
   11978                     ProviderInfo pi = (ProviderInfo)providers.get(i);
   11979                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   11980                         Slog.w(TAG, "Not installing system proc provider " + pi.name
   11981                                 + ": not system .apk");
   11982                         providers.remove(i);
   11983                     }
   11984                 }
   11985             }
   11986         }
   11987         if (providers != null) {
   11988             mSystemThread.installSystemProviders(providers);
   11989         }
   11990 
   11991         mConstants.start(mContext.getContentResolver());
   11992         mCoreSettingsObserver = new CoreSettingsObserver(this);
   11993         mFontScaleSettingObserver = new FontScaleSettingObserver();
   11994 
   11995         // Now that the settings provider is published we can consider sending
   11996         // in a rescue party.
   11997         RescueParty.onSettingsProviderPublished(mContext);
   11998 
   11999         //mUsageStatsService.monitorPackages();
   12000     }
   12001 
   12002     private void startPersistentApps(int matchFlags) {
   12003         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
   12004 
   12005         synchronized (this) {
   12006             try {
   12007                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
   12008                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
   12009                 for (ApplicationInfo app : apps) {
   12010                     if (!"android".equals(app.packageName)) {
   12011                         addAppLocked(app, null, false, null /* ABI override */);
   12012                     }
   12013                 }
   12014             } catch (RemoteException ex) {
   12015             }
   12016         }
   12017     }
   12018 
   12019     /**
   12020      * When a user is unlocked, we need to install encryption-unaware providers
   12021      * belonging to any running apps.
   12022      */
   12023     private void installEncryptionUnawareProviders(int userId) {
   12024         // We're only interested in providers that are encryption unaware, and
   12025         // we don't care about uninstalled apps, since there's no way they're
   12026         // running at this point.
   12027         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
   12028 
   12029         synchronized (this) {
   12030             final int NP = mProcessNames.getMap().size();
   12031             for (int ip = 0; ip < NP; ip++) {
   12032                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   12033                 final int NA = apps.size();
   12034                 for (int ia = 0; ia < NA; ia++) {
   12035                     final ProcessRecord app = apps.valueAt(ia);
   12036                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
   12037 
   12038                     final int NG = app.pkgList.size();
   12039                     for (int ig = 0; ig < NG; ig++) {
   12040                         try {
   12041                             final String pkgName = app.pkgList.keyAt(ig);
   12042                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
   12043                                     .getPackageInfo(pkgName, matchFlags, userId);
   12044                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
   12045                                 for (ProviderInfo pi : pkgInfo.providers) {
   12046                                     // TODO: keep in sync with generateApplicationProvidersLocked
   12047                                     final boolean processMatch = Objects.equals(pi.processName,
   12048                                             app.processName) || pi.multiprocess;
   12049                                     final boolean userMatch = isSingleton(pi.processName,
   12050                                             pi.applicationInfo, pi.name, pi.flags)
   12051                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
   12052                                     if (processMatch && userMatch) {
   12053                                         Log.v(TAG, "Installing " + pi);
   12054                                         app.thread.scheduleInstallProvider(pi);
   12055                                     } else {
   12056                                         Log.v(TAG, "Skipping " + pi);
   12057                                     }
   12058                                 }
   12059                             }
   12060                         } catch (RemoteException ignored) {
   12061                         }
   12062                     }
   12063                 }
   12064             }
   12065         }
   12066     }
   12067 
   12068     /**
   12069      * Allows apps to retrieve the MIME type of a URI.
   12070      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
   12071      * users, then it does not need permission to access the ContentProvider.
   12072      * Either, it needs cross-user uri grants.
   12073      *
   12074      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
   12075      *
   12076      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
   12077      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
   12078      */
   12079     public String getProviderMimeType(Uri uri, int userId) {
   12080         enforceNotIsolatedCaller("getProviderMimeType");
   12081         final String name = uri.getAuthority();
   12082         int callingUid = Binder.getCallingUid();
   12083         int callingPid = Binder.getCallingPid();
   12084         long ident = 0;
   12085         boolean clearedIdentity = false;
   12086         synchronized (this) {
   12087             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
   12088         }
   12089         if (canClearIdentity(callingPid, callingUid, userId)) {
   12090             clearedIdentity = true;
   12091             ident = Binder.clearCallingIdentity();
   12092         }
   12093         ContentProviderHolder holder = null;
   12094         try {
   12095             holder = getContentProviderExternalUnchecked(name, null, userId);
   12096             if (holder != null) {
   12097                 return holder.provider.getType(uri);
   12098             }
   12099         } catch (RemoteException e) {
   12100             Log.w(TAG, "Content provider dead retrieving " + uri, e);
   12101             return null;
   12102         } catch (Exception e) {
   12103             Log.w(TAG, "Exception while determining type of " + uri, e);
   12104             return null;
   12105         } finally {
   12106             // We need to clear the identity to call removeContentProviderExternalUnchecked
   12107             if (!clearedIdentity) {
   12108                 ident = Binder.clearCallingIdentity();
   12109             }
   12110             try {
   12111                 if (holder != null) {
   12112                     removeContentProviderExternalUnchecked(name, null, userId);
   12113                 }
   12114             } finally {
   12115                 Binder.restoreCallingIdentity(ident);
   12116             }
   12117         }
   12118 
   12119         return null;
   12120     }
   12121 
   12122     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
   12123         if (UserHandle.getUserId(callingUid) == userId) {
   12124             return true;
   12125         }
   12126         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
   12127                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
   12128                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
   12129                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
   12130                 return true;
   12131         }
   12132         return false;
   12133     }
   12134 
   12135     // =========================================================
   12136     // GLOBAL MANAGEMENT
   12137     // =========================================================
   12138 
   12139     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
   12140             boolean isolated, int isolatedUid) {
   12141         String proc = customProcess != null ? customProcess : info.processName;
   12142         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   12143         final int userId = UserHandle.getUserId(info.uid);
   12144         int uid = info.uid;
   12145         if (isolated) {
   12146             if (isolatedUid == 0) {
   12147                 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
   12148                 while (true) {
   12149                     if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
   12150                             || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
   12151                         mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
   12152                     }
   12153                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
   12154                     mNextIsolatedProcessUid++;
   12155                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
   12156                         // No process for this uid, use it.
   12157                         break;
   12158                     }
   12159                     stepsLeft--;
   12160                     if (stepsLeft <= 0) {
   12161                         return null;
   12162                     }
   12163                 }
   12164             } else {
   12165                 // Special case for startIsolatedProcess (internal only), where
   12166                 // the uid of the isolated process is specified by the caller.
   12167                 uid = isolatedUid;
   12168             }
   12169             getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
   12170 
   12171             // Register the isolated UID with this application so BatteryStats knows to
   12172             // attribute resource usage to the application.
   12173             //
   12174             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
   12175             // about the process state of the isolated UID *before* it is registered with the
   12176             // owning application.
   12177             mBatteryStatsService.addIsolatedUid(uid, info.uid);
   12178         }
   12179         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
   12180         if (!mBooted && !mBooting
   12181                 && userId == UserHandle.USER_SYSTEM
   12182                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
   12183             r.persistent = true;
   12184             r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
   12185         }
   12186         addProcessNameLocked(r);
   12187         return r;
   12188     }
   12189 
   12190     private boolean uidOnBackgroundWhitelist(final int uid) {
   12191         final int appId = UserHandle.getAppId(uid);
   12192         final int[] whitelist = mBackgroundAppIdWhitelist;
   12193         final int N = whitelist.length;
   12194         for (int i = 0; i < N; i++) {
   12195             if (appId == whitelist[i]) {
   12196                 return true;
   12197             }
   12198         }
   12199         return false;
   12200     }
   12201 
   12202     @Override
   12203     public void backgroundWhitelistUid(final int uid) {
   12204         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   12205             throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
   12206         }
   12207 
   12208         if (DEBUG_BACKGROUND_CHECK) {
   12209             Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
   12210         }
   12211         synchronized (this) {
   12212             final int N = mBackgroundAppIdWhitelist.length;
   12213             int[] newList = new int[N+1];
   12214             System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
   12215             newList[N] = UserHandle.getAppId(uid);
   12216             mBackgroundAppIdWhitelist = newList;
   12217         }
   12218     }
   12219 
   12220     final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
   12221             String abiOverride) {
   12222         ProcessRecord app;
   12223         if (!isolated) {
   12224             app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
   12225                     info.uid, true);
   12226         } else {
   12227             app = null;
   12228         }
   12229 
   12230         if (app == null) {
   12231             app = newProcessRecordLocked(info, customProcess, isolated, 0);
   12232             updateLruProcessLocked(app, false, null);
   12233             updateOomAdjLocked();
   12234         }
   12235 
   12236         // This package really, really can not be stopped.
   12237         try {
   12238             AppGlobals.getPackageManager().setPackageStoppedState(
   12239                     info.packageName, false, UserHandle.getUserId(app.uid));
   12240         } catch (RemoteException e) {
   12241         } catch (IllegalArgumentException e) {
   12242             Slog.w(TAG, "Failed trying to unstop package "
   12243                     + info.packageName + ": " + e);
   12244         }
   12245 
   12246         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
   12247             app.persistent = true;
   12248             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
   12249         }
   12250         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
   12251             mPersistentStartingProcesses.add(app);
   12252             startProcessLocked(app, "added application",
   12253                     customProcess != null ? customProcess : app.processName, abiOverride,
   12254                     null /* entryPoint */, null /* entryPointArgs */);
   12255         }
   12256 
   12257         return app;
   12258     }
   12259 
   12260     public void unhandledBack() {
   12261         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
   12262                 "unhandledBack()");
   12263 
   12264         synchronized(this) {
   12265             final long origId = Binder.clearCallingIdentity();
   12266             try {
   12267                 getFocusedStack().unhandledBackLocked();
   12268             } finally {
   12269                 Binder.restoreCallingIdentity(origId);
   12270             }
   12271         }
   12272     }
   12273 
   12274     public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
   12275         enforceNotIsolatedCaller("openContentUri");
   12276         final int userId = UserHandle.getCallingUserId();
   12277         final Uri uri = Uri.parse(uriString);
   12278         String name = uri.getAuthority();
   12279         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
   12280         ParcelFileDescriptor pfd = null;
   12281         if (cph != null) {
   12282             // We record the binder invoker's uid in thread-local storage before
   12283             // going to the content provider to open the file.  Later, in the code
   12284             // that handles all permissions checks, we look for this uid and use
   12285             // that rather than the Activity Manager's own uid.  The effect is that
   12286             // we do the check against the caller's permissions even though it looks
   12287             // to the content provider like the Activity Manager itself is making
   12288             // the request.
   12289             Binder token = new Binder();
   12290             sCallerIdentity.set(new Identity(
   12291                     token, Binder.getCallingPid(), Binder.getCallingUid()));
   12292             try {
   12293                 pfd = cph.provider.openFile(null, uri, "r", null, token);
   12294             } catch (FileNotFoundException e) {
   12295                 // do nothing; pfd will be returned null
   12296             } finally {
   12297                 // Ensure that whatever happens, we clean up the identity state
   12298                 sCallerIdentity.remove();
   12299                 // Ensure we're done with the provider.
   12300                 removeContentProviderExternalUnchecked(name, null, userId);
   12301             }
   12302         } else {
   12303             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
   12304         }
   12305         return pfd;
   12306     }
   12307 
   12308     // Actually is sleeping or shutting down or whatever else in the future
   12309     // is an inactive state.
   12310     boolean isSleepingOrShuttingDownLocked() {
   12311         return isSleepingLocked() || mShuttingDown;
   12312     }
   12313 
   12314     boolean isShuttingDownLocked() {
   12315         return mShuttingDown;
   12316     }
   12317 
   12318     boolean isSleepingLocked() {
   12319         return mSleeping;
   12320     }
   12321 
   12322     void onWakefulnessChanged(int wakefulness) {
   12323         synchronized(this) {
   12324             mWakefulness = wakefulness;
   12325             updateSleepIfNeededLocked();
   12326         }
   12327     }
   12328 
   12329     void finishRunningVoiceLocked() {
   12330         if (mRunningVoice != null) {
   12331             mRunningVoice = null;
   12332             mVoiceWakeLock.release();
   12333             updateSleepIfNeededLocked();
   12334         }
   12335     }
   12336 
   12337     void startTimeTrackingFocusedActivityLocked() {
   12338         final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
   12339         if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
   12340             mCurAppTimeTracker.start(resumedActivity.packageName);
   12341         }
   12342     }
   12343 
   12344     void updateSleepIfNeededLocked() {
   12345         final boolean shouldSleep = shouldSleepLocked();
   12346         if (mSleeping && !shouldSleep) {
   12347             mSleeping = false;
   12348             startTimeTrackingFocusedActivityLocked();
   12349             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
   12350             mStackSupervisor.comeOutOfSleepIfNeededLocked();
   12351             sendNotifyVrManagerOfSleepState(false);
   12352             updateOomAdjLocked();
   12353         } else if (!mSleeping && shouldSleep) {
   12354             mSleeping = true;
   12355             if (mCurAppTimeTracker != null) {
   12356                 mCurAppTimeTracker.stop();
   12357             }
   12358             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
   12359             mStackSupervisor.goingToSleepLocked();
   12360             sendNotifyVrManagerOfSleepState(true);
   12361             updateOomAdjLocked();
   12362 
   12363             // Initialize the wake times of all processes.
   12364             checkExcessivePowerUsageLocked(false);
   12365             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   12366             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   12367             mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
   12368         }
   12369 
   12370         // Also update state in a special way for running foreground services UI.
   12371         switch (mWakefulness) {
   12372             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
   12373             case PowerManagerInternal.WAKEFULNESS_DREAMING:
   12374             case PowerManagerInternal.WAKEFULNESS_DOZING:
   12375                 mServices.updateScreenStateLocked(false);
   12376                 break;
   12377             case PowerManagerInternal.WAKEFULNESS_AWAKE:
   12378             default:
   12379                 mServices.updateScreenStateLocked(true);
   12380                 break;
   12381         }
   12382     }
   12383 
   12384     private boolean shouldSleepLocked() {
   12385         // Resume applications while running a voice interactor.
   12386         if (mRunningVoice != null) {
   12387             return false;
   12388         }
   12389 
   12390         // TODO: Transform the lock screen state into a sleep token instead.
   12391         switch (mWakefulness) {
   12392             case PowerManagerInternal.WAKEFULNESS_AWAKE:
   12393             case PowerManagerInternal.WAKEFULNESS_DREAMING:
   12394             case PowerManagerInternal.WAKEFULNESS_DOZING:
   12395                 // Pause applications whenever the lock screen is shown or any sleep
   12396                 // tokens have been acquired.
   12397                 return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
   12398             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
   12399             default:
   12400                 // If we're asleep then pause applications unconditionally.
   12401                 return true;
   12402         }
   12403     }
   12404 
   12405     /** Pokes the task persister. */
   12406     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
   12407         mRecentTasks.notifyTaskPersisterLocked(task, flush);
   12408     }
   12409 
   12410     /**
   12411      * Notifies all listeners when the pinned stack animation starts.
   12412      */
   12413     @Override
   12414     public void notifyPinnedStackAnimationStarted() {
   12415         mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
   12416     }
   12417 
   12418     /**
   12419      * Notifies all listeners when the pinned stack animation ends.
   12420      */
   12421     @Override
   12422     public void notifyPinnedStackAnimationEnded() {
   12423         mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
   12424     }
   12425 
   12426     @Override
   12427     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
   12428         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
   12429     }
   12430 
   12431     @Override
   12432     public boolean shutdown(int timeout) {
   12433         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
   12434                 != PackageManager.PERMISSION_GRANTED) {
   12435             throw new SecurityException("Requires permission "
   12436                     + android.Manifest.permission.SHUTDOWN);
   12437         }
   12438 
   12439         boolean timedout = false;
   12440 
   12441         synchronized(this) {
   12442             mShuttingDown = true;
   12443             updateEventDispatchingLocked();
   12444             timedout = mStackSupervisor.shutdownLocked(timeout);
   12445         }
   12446 
   12447         mAppOpsService.shutdown();
   12448         if (mUsageStatsService != null) {
   12449             mUsageStatsService.prepareShutdown();
   12450         }
   12451         mBatteryStatsService.shutdown();
   12452         synchronized (this) {
   12453             mProcessStats.shutdownLocked();
   12454             notifyTaskPersisterLocked(null, true);
   12455         }
   12456 
   12457         return timedout;
   12458     }
   12459 
   12460     public final void activitySlept(IBinder token) {
   12461         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
   12462 
   12463         final long origId = Binder.clearCallingIdentity();
   12464 
   12465         synchronized (this) {
   12466             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   12467             if (r != null) {
   12468                 mStackSupervisor.activitySleptLocked(r);
   12469             }
   12470         }
   12471 
   12472         Binder.restoreCallingIdentity(origId);
   12473     }
   12474 
   12475     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
   12476         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
   12477         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
   12478         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
   12479             boolean wasRunningVoice = mRunningVoice != null;
   12480             mRunningVoice = session;
   12481             if (!wasRunningVoice) {
   12482                 mVoiceWakeLock.acquire();
   12483                 updateSleepIfNeededLocked();
   12484             }
   12485         }
   12486     }
   12487 
   12488     private void updateEventDispatchingLocked() {
   12489         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
   12490     }
   12491 
   12492     @Override
   12493     public void setLockScreenShown(boolean showing) {
   12494         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   12495                 != PackageManager.PERMISSION_GRANTED) {
   12496             throw new SecurityException("Requires permission "
   12497                     + android.Manifest.permission.DEVICE_POWER);
   12498         }
   12499 
   12500         synchronized(this) {
   12501             long ident = Binder.clearCallingIdentity();
   12502             try {
   12503                 mKeyguardController.setKeyguardShown(showing);
   12504             } finally {
   12505                 Binder.restoreCallingIdentity(ident);
   12506             }
   12507         }
   12508     }
   12509 
   12510     @Override
   12511     public void notifyLockedProfile(@UserIdInt int userId) {
   12512         try {
   12513             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
   12514                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
   12515             }
   12516         } catch (RemoteException ex) {
   12517             throw new SecurityException("Fail to check is caller a privileged app", ex);
   12518         }
   12519 
   12520         synchronized (this) {
   12521             final long ident = Binder.clearCallingIdentity();
   12522             try {
   12523                 if (mUserController.shouldConfirmCredentials(userId)) {
   12524                     if (mKeyguardController.isKeyguardLocked()) {
   12525                         // Showing launcher to avoid user entering credential twice.
   12526                         final int currentUserId = mUserController.getCurrentUserIdLocked();
   12527                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
   12528                     }
   12529                     mStackSupervisor.lockAllProfileTasks(userId);
   12530                 }
   12531             } finally {
   12532                 Binder.restoreCallingIdentity(ident);
   12533             }
   12534         }
   12535     }
   12536 
   12537     @Override
   12538     public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
   12539         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
   12540         synchronized (this) {
   12541             final long ident = Binder.clearCallingIdentity();
   12542             try {
   12543                 mActivityStarter.startConfirmCredentialIntent(intent, options);
   12544             } finally {
   12545                 Binder.restoreCallingIdentity(ident);
   12546             }
   12547         }
   12548     }
   12549 
   12550     @Override
   12551     public void stopAppSwitches() {
   12552         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   12553                 != PackageManager.PERMISSION_GRANTED) {
   12554             throw new SecurityException("viewquires permission "
   12555                     + android.Manifest.permission.STOP_APP_SWITCHES);
   12556         }
   12557 
   12558         synchronized(this) {
   12559             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
   12560                     + APP_SWITCH_DELAY_TIME;
   12561             mDidAppSwitch = false;
   12562             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   12563             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   12564             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
   12565         }
   12566     }
   12567 
   12568     public void resumeAppSwitches() {
   12569         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   12570                 != PackageManager.PERMISSION_GRANTED) {
   12571             throw new SecurityException("Requires permission "
   12572                     + android.Manifest.permission.STOP_APP_SWITCHES);
   12573         }
   12574 
   12575         synchronized(this) {
   12576             // Note that we don't execute any pending app switches... we will
   12577             // let those wait until either the timeout, or the next start
   12578             // activity request.
   12579             mAppSwitchesAllowedTime = 0;
   12580         }
   12581     }
   12582 
   12583     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
   12584             int callingPid, int callingUid, String name) {
   12585         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
   12586             return true;
   12587         }
   12588 
   12589         int perm = checkComponentPermission(
   12590                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
   12591                 sourceUid, -1, true);
   12592         if (perm == PackageManager.PERMISSION_GRANTED) {
   12593             return true;
   12594         }
   12595 
   12596         // If the actual IPC caller is different from the logical source, then
   12597         // also see if they are allowed to control app switches.
   12598         if (callingUid != -1 && callingUid != sourceUid) {
   12599             perm = checkComponentPermission(
   12600                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
   12601                     callingUid, -1, true);
   12602             if (perm == PackageManager.PERMISSION_GRANTED) {
   12603                 return true;
   12604             }
   12605         }
   12606 
   12607         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
   12608         return false;
   12609     }
   12610 
   12611     public void setDebugApp(String packageName, boolean waitForDebugger,
   12612             boolean persistent) {
   12613         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   12614                 "setDebugApp()");
   12615 
   12616         long ident = Binder.clearCallingIdentity();
   12617         try {
   12618             // Note that this is not really thread safe if there are multiple
   12619             // callers into it at the same time, but that's not a situation we
   12620             // care about.
   12621             if (persistent) {
   12622                 final ContentResolver resolver = mContext.getContentResolver();
   12623                 Settings.Global.putString(
   12624                     resolver, Settings.Global.DEBUG_APP,
   12625                     packageName);
   12626                 Settings.Global.putInt(
   12627                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
   12628                     waitForDebugger ? 1 : 0);
   12629             }
   12630 
   12631             synchronized (this) {
   12632                 if (!persistent) {
   12633                     mOrigDebugApp = mDebugApp;
   12634                     mOrigWaitForDebugger = mWaitForDebugger;
   12635                 }
   12636                 mDebugApp = packageName;
   12637                 mWaitForDebugger = waitForDebugger;
   12638                 mDebugTransient = !persistent;
   12639                 if (packageName != null) {
   12640                     forceStopPackageLocked(packageName, -1, false, false, true, true,
   12641                             false, UserHandle.USER_ALL, "set debug app");
   12642                 }
   12643             }
   12644         } finally {
   12645             Binder.restoreCallingIdentity(ident);
   12646         }
   12647     }
   12648 
   12649     void setTrackAllocationApp(ApplicationInfo app, String processName) {
   12650         synchronized (this) {
   12651             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   12652             if (!isDebuggable) {
   12653                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   12654                     throw new SecurityException("Process not debuggable: " + app.packageName);
   12655                 }
   12656             }
   12657 
   12658             mTrackAllocationApp = processName;
   12659         }
   12660     }
   12661 
   12662     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
   12663         synchronized (this) {
   12664             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   12665             if (!isDebuggable) {
   12666                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   12667                     throw new SecurityException("Process not debuggable: " + app.packageName);
   12668                 }
   12669             }
   12670             mProfileApp = processName;
   12671             mProfileFile = profilerInfo.profileFile;
   12672             if (mProfileFd != null) {
   12673                 try {
   12674                     mProfileFd.close();
   12675                 } catch (IOException e) {
   12676                 }
   12677                 mProfileFd = null;
   12678             }
   12679             mProfileFd = profilerInfo.profileFd;
   12680             mSamplingInterval = profilerInfo.samplingInterval;
   12681             mAutoStopProfiler = profilerInfo.autoStopProfiler;
   12682             mStreamingOutput = profilerInfo.streamingOutput;
   12683             mProfileType = 0;
   12684         }
   12685     }
   12686 
   12687     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
   12688         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   12689         if (!isDebuggable) {
   12690             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   12691                 throw new SecurityException("Process not debuggable: " + app.packageName);
   12692             }
   12693         }
   12694         mNativeDebuggingApp = processName;
   12695     }
   12696 
   12697     @Override
   12698     public void setAlwaysFinish(boolean enabled) {
   12699         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
   12700                 "setAlwaysFinish()");
   12701 
   12702         long ident = Binder.clearCallingIdentity();
   12703         try {
   12704             Settings.Global.putInt(
   12705                     mContext.getContentResolver(),
   12706                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
   12707 
   12708             synchronized (this) {
   12709                 mAlwaysFinishActivities = enabled;
   12710             }
   12711         } finally {
   12712             Binder.restoreCallingIdentity(ident);
   12713         }
   12714     }
   12715 
   12716     @Override
   12717     public void setActivityController(IActivityController controller, boolean imAMonkey) {
   12718         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   12719                 "setActivityController()");
   12720         synchronized (this) {
   12721             mController = controller;
   12722             mControllerIsAMonkey = imAMonkey;
   12723             Watchdog.getInstance().setActivityController(controller);
   12724         }
   12725     }
   12726 
   12727     @Override
   12728     public void setUserIsMonkey(boolean userIsMonkey) {
   12729         synchronized (this) {
   12730             synchronized (mPidsSelfLocked) {
   12731                 final int callingPid = Binder.getCallingPid();
   12732                 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
   12733                 if (proc == null) {
   12734                     throw new SecurityException("Unknown process: " + callingPid);
   12735                 }
   12736                 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
   12737                     throw new SecurityException("Only an instrumentation process "
   12738                             + "with a UiAutomation can call setUserIsMonkey");
   12739                 }
   12740             }
   12741             mUserIsMonkey = userIsMonkey;
   12742         }
   12743     }
   12744 
   12745     @Override
   12746     public boolean isUserAMonkey() {
   12747         synchronized (this) {
   12748             // If there is a controller also implies the user is a monkey.
   12749             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
   12750         }
   12751     }
   12752 
   12753     /**
   12754      * @deprecated This method is only used by a few internal components and it will soon be
   12755      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
   12756      * No new code should be calling it.
   12757      */
   12758     @Deprecated
   12759     @Override
   12760     public void requestBugReport(int bugreportType) {
   12761         String extraOptions = null;
   12762         switch (bugreportType) {
   12763             case ActivityManager.BUGREPORT_OPTION_FULL:
   12764                 // Default options.
   12765                 break;
   12766             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
   12767                 extraOptions = "bugreportplus";
   12768                 break;
   12769             case ActivityManager.BUGREPORT_OPTION_REMOTE:
   12770                 extraOptions = "bugreportremote";
   12771                 break;
   12772             case ActivityManager.BUGREPORT_OPTION_WEAR:
   12773                 extraOptions = "bugreportwear";
   12774                 break;
   12775             case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
   12776                 extraOptions = "bugreporttelephony";
   12777                 break;
   12778             default:
   12779                 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
   12780                         + bugreportType);
   12781         }
   12782         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
   12783         if (extraOptions != null) {
   12784             SystemProperties.set("dumpstate.options", extraOptions);
   12785         }
   12786         SystemProperties.set("ctl.start", "bugreport");
   12787     }
   12788 
   12789     /**
   12790      * @deprecated This method is only used by a few internal components and it will soon be
   12791      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
   12792      * No new code should be calling it.
   12793      */
   12794     @Deprecated
   12795     @Override
   12796     public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
   12797 
   12798         if (!TextUtils.isEmpty(shareTitle)) {
   12799             if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
   12800                 String errorStr = "shareTitle should be less than " +
   12801                         MAX_BUGREPORT_TITLE_SIZE + " characters";
   12802                 throw new IllegalArgumentException(errorStr);
   12803             } else {
   12804                 if (!TextUtils.isEmpty(shareDescription)) {
   12805                     int length;
   12806                     try {
   12807                         length = shareDescription.getBytes("UTF-8").length;
   12808                     } catch (UnsupportedEncodingException e) {
   12809                         String errorStr = "shareDescription: UnsupportedEncodingException";
   12810                         throw new IllegalArgumentException(errorStr);
   12811                     }
   12812                     if (length > SystemProperties.PROP_VALUE_MAX) {
   12813                         String errorStr = "shareTitle should be less than " +
   12814                                 SystemProperties.PROP_VALUE_MAX + " bytes";
   12815                         throw new IllegalArgumentException(errorStr);
   12816                     } else {
   12817                         SystemProperties.set("dumpstate.options.description", shareDescription);
   12818                     }
   12819                 }
   12820                 SystemProperties.set("dumpstate.options.title", shareTitle);
   12821             }
   12822         }
   12823 
   12824         Slog.d(TAG, "Bugreport notification title " + shareTitle
   12825                 + " description " + shareDescription);
   12826         requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
   12827     }
   12828 
   12829     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
   12830         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
   12831     }
   12832 
   12833     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
   12834         if (r != null && (r.instr != null || r.usingWrapper)) {
   12835             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
   12836         }
   12837         return KEY_DISPATCHING_TIMEOUT;
   12838     }
   12839 
   12840     @Override
   12841     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
   12842         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   12843                 != PackageManager.PERMISSION_GRANTED) {
   12844             throw new SecurityException("Requires permission "
   12845                     + android.Manifest.permission.FILTER_EVENTS);
   12846         }
   12847         ProcessRecord proc;
   12848         long timeout;
   12849         synchronized (this) {
   12850             synchronized (mPidsSelfLocked) {
   12851                 proc = mPidsSelfLocked.get(pid);
   12852             }
   12853             timeout = getInputDispatchingTimeoutLocked(proc);
   12854         }
   12855 
   12856         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
   12857             return -1;
   12858         }
   12859 
   12860         return timeout;
   12861     }
   12862 
   12863     /**
   12864      * Handle input dispatching timeouts.
   12865      * Returns whether input dispatching should be aborted or not.
   12866      */
   12867     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
   12868             final ActivityRecord activity, final ActivityRecord parent,
   12869             final boolean aboveSystem, String reason) {
   12870         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   12871                 != PackageManager.PERMISSION_GRANTED) {
   12872             throw new SecurityException("Requires permission "
   12873                     + android.Manifest.permission.FILTER_EVENTS);
   12874         }
   12875 
   12876         final String annotation;
   12877         if (reason == null) {
   12878             annotation = "Input dispatching timed out";
   12879         } else {
   12880             annotation = "Input dispatching timed out (" + reason + ")";
   12881         }
   12882 
   12883         if (proc != null) {
   12884             synchronized (this) {
   12885                 if (proc.debugging) {
   12886                     return false;
   12887                 }
   12888 
   12889                 if (mDidDexOpt) {
   12890                     // Give more time since we were dexopting.
   12891                     mDidDexOpt = false;
   12892                     return false;
   12893                 }
   12894 
   12895                 if (proc.instr != null) {
   12896                     Bundle info = new Bundle();
   12897                     info.putString("shortMsg", "keyDispatchingTimedOut");
   12898                     info.putString("longMsg", annotation);
   12899                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
   12900                     return true;
   12901                 }
   12902             }
   12903             mHandler.post(new Runnable() {
   12904                 @Override
   12905                 public void run() {
   12906                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
   12907                 }
   12908             });
   12909         }
   12910 
   12911         return true;
   12912     }
   12913 
   12914     @Override
   12915     public Bundle getAssistContextExtras(int requestType) {
   12916         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
   12917                 null, null, true /* focused */, true /* newSessionId */,
   12918                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
   12919         if (pae == null) {
   12920             return null;
   12921         }
   12922         synchronized (pae) {
   12923             while (!pae.haveResult) {
   12924                 try {
   12925                     pae.wait();
   12926                 } catch (InterruptedException e) {
   12927                 }
   12928             }
   12929         }
   12930         synchronized (this) {
   12931             buildAssistBundleLocked(pae, pae.result);
   12932             mPendingAssistExtras.remove(pae);
   12933             mUiHandler.removeCallbacks(pae);
   12934         }
   12935         return pae.extras;
   12936     }
   12937 
   12938     @Override
   12939     public boolean isAssistDataAllowedOnCurrentActivity() {
   12940         int userId;
   12941         synchronized (this) {
   12942             final ActivityStack focusedStack = getFocusedStack();
   12943             if (focusedStack == null || focusedStack.isAssistantStack()) {
   12944                 return false;
   12945             }
   12946 
   12947             final ActivityRecord activity = focusedStack.topActivity();
   12948             if (activity == null) {
   12949                 return false;
   12950             }
   12951             userId = activity.userId;
   12952         }
   12953         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
   12954                 Context.DEVICE_POLICY_SERVICE);
   12955         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
   12956     }
   12957 
   12958     @Override
   12959     public boolean showAssistFromActivity(IBinder token, Bundle args) {
   12960         long ident = Binder.clearCallingIdentity();
   12961         try {
   12962             synchronized (this) {
   12963                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
   12964                 ActivityRecord top = getFocusedStack().topActivity();
   12965                 if (top != caller) {
   12966                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
   12967                             + " is not current top " + top);
   12968                     return false;
   12969                 }
   12970                 if (!top.nowVisible) {
   12971                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
   12972                             + " is not visible");
   12973                     return false;
   12974                 }
   12975             }
   12976             return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
   12977                     token);
   12978         } finally {
   12979             Binder.restoreCallingIdentity(ident);
   12980         }
   12981     }
   12982 
   12983     @Override
   12984     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
   12985             Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
   12986         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
   12987                 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
   12988                 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
   12989     }
   12990 
   12991     @Override
   12992     public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
   12993             IBinder activityToken, int flags) {
   12994         return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
   12995                 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
   12996                 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
   12997     }
   12998 
   12999     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
   13000             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
   13001             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
   13002             int flags) {
   13003         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
   13004                 "enqueueAssistContext()");
   13005 
   13006         synchronized (this) {
   13007             ActivityRecord activity = getFocusedStack().topActivity();
   13008             if (activity == null) {
   13009                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
   13010                 return null;
   13011             }
   13012             if (activity.app == null || activity.app.thread == null) {
   13013                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
   13014                 return null;
   13015             }
   13016             if (focused) {
   13017                 if (activityToken != null) {
   13018                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
   13019                     if (activity != caller) {
   13020                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
   13021                                 + " is not current top " + activity);
   13022                         return null;
   13023                     }
   13024                 }
   13025             } else {
   13026                 activity = ActivityRecord.forTokenLocked(activityToken);
   13027                 if (activity == null) {
   13028                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
   13029                             + " couldn't be found");
   13030                     return null;
   13031                 }
   13032             }
   13033 
   13034             PendingAssistExtras pae;
   13035             Bundle extras = new Bundle();
   13036             if (args != null) {
   13037                 extras.putAll(args);
   13038             }
   13039             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
   13040             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
   13041 
   13042             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
   13043                     userHandle);
   13044             pae.isHome = activity.isHomeActivity();
   13045 
   13046             // Increment the sessionId if necessary
   13047             if (newSessionId) {
   13048                 mViSessionId++;
   13049             }
   13050             try {
   13051                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
   13052                         mViSessionId, flags);
   13053                 mPendingAssistExtras.add(pae);
   13054                 mUiHandler.postDelayed(pae, timeout);
   13055             } catch (RemoteException e) {
   13056                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
   13057                 return null;
   13058             }
   13059             return pae;
   13060         }
   13061     }
   13062 
   13063     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
   13064         IResultReceiver receiver;
   13065         synchronized (this) {
   13066             mPendingAssistExtras.remove(pae);
   13067             receiver = pae.receiver;
   13068         }
   13069         if (receiver != null) {
   13070             // Caller wants result sent back to them.
   13071             Bundle sendBundle = new Bundle();
   13072             // At least return the receiver extras
   13073             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
   13074                     pae.receiverExtras);
   13075             try {
   13076                 pae.receiver.send(0, sendBundle);
   13077             } catch (RemoteException e) {
   13078             }
   13079         }
   13080     }
   13081 
   13082     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
   13083         if (result != null) {
   13084             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
   13085         }
   13086         if (pae.hint != null) {
   13087             pae.extras.putBoolean(pae.hint, true);
   13088         }
   13089     }
   13090 
   13091     /** Called from an app when assist data is ready. */
   13092     @Override
   13093     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
   13094             AssistContent content, Uri referrer) {
   13095         PendingAssistExtras pae = (PendingAssistExtras)token;
   13096         synchronized (pae) {
   13097             pae.result = extras;
   13098             pae.structure = structure;
   13099             pae.content = content;
   13100             if (referrer != null) {
   13101                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
   13102             }
   13103             if (structure != null) {
   13104                 structure.setHomeActivity(pae.isHome);
   13105             }
   13106             pae.haveResult = true;
   13107             pae.notifyAll();
   13108             if (pae.intent == null && pae.receiver == null) {
   13109                 // Caller is just waiting for the result.
   13110                 return;
   13111             }
   13112         }
   13113 
   13114         // We are now ready to launch the assist activity.
   13115         IResultReceiver sendReceiver = null;
   13116         Bundle sendBundle = null;
   13117         synchronized (this) {
   13118             buildAssistBundleLocked(pae, extras);
   13119             boolean exists = mPendingAssistExtras.remove(pae);
   13120             mUiHandler.removeCallbacks(pae);
   13121             if (!exists) {
   13122                 // Timed out.
   13123                 return;
   13124             }
   13125             if ((sendReceiver=pae.receiver) != null) {
   13126                 // Caller wants result sent back to them.
   13127                 sendBundle = new Bundle();
   13128                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
   13129                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
   13130                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
   13131                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
   13132                         pae.receiverExtras);
   13133             }
   13134         }
   13135         if (sendReceiver != null) {
   13136             try {
   13137                 sendReceiver.send(0, sendBundle);
   13138             } catch (RemoteException e) {
   13139             }
   13140             return;
   13141         }
   13142 
   13143         long ident = Binder.clearCallingIdentity();
   13144         try {
   13145             pae.intent.replaceExtras(pae.extras);
   13146             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
   13147                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
   13148                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
   13149             closeSystemDialogs("assist");
   13150             try {
   13151                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
   13152             } catch (ActivityNotFoundException e) {
   13153                 Slog.w(TAG, "No activity to handle assist action.", e);
   13154             }
   13155         } finally {
   13156             Binder.restoreCallingIdentity(ident);
   13157         }
   13158     }
   13159 
   13160     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
   13161             Bundle args) {
   13162         return enqueueAssistContext(requestType, intent, hint, null, null, null,
   13163                 true /* focused */, true /* newSessionId */, userHandle, args,
   13164                 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
   13165     }
   13166 
   13167     public void registerProcessObserver(IProcessObserver observer) {
   13168         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   13169                 "registerProcessObserver()");
   13170         synchronized (this) {
   13171             mProcessObservers.register(observer);
   13172         }
   13173     }
   13174 
   13175     @Override
   13176     public void unregisterProcessObserver(IProcessObserver observer) {
   13177         synchronized (this) {
   13178             mProcessObservers.unregister(observer);
   13179         }
   13180     }
   13181 
   13182     @Override
   13183     public int getUidProcessState(int uid, String callingPackage) {
   13184         if (!hasUsageStatsPermission(callingPackage)) {
   13185             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
   13186                     "getUidProcessState");
   13187         }
   13188 
   13189         synchronized (this) {
   13190             UidRecord uidRec = mActiveUids.get(uid);
   13191             return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
   13192         }
   13193     }
   13194 
   13195     @Override
   13196     public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
   13197             String callingPackage) {
   13198         if (!hasUsageStatsPermission(callingPackage)) {
   13199             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
   13200                     "registerUidObserver");
   13201         }
   13202         synchronized (this) {
   13203             mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
   13204                     callingPackage, which, cutpoint));
   13205         }
   13206     }
   13207 
   13208     @Override
   13209     public void unregisterUidObserver(IUidObserver observer) {
   13210         synchronized (this) {
   13211             mUidObservers.unregister(observer);
   13212         }
   13213     }
   13214 
   13215     @Override
   13216     public boolean convertFromTranslucent(IBinder token) {
   13217         final long origId = Binder.clearCallingIdentity();
   13218         try {
   13219             synchronized (this) {
   13220                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   13221                 if (r == null) {
   13222                     return false;
   13223                 }
   13224                 final boolean translucentChanged = r.changeWindowTranslucency(true);
   13225                 if (translucentChanged) {
   13226                     r.getStack().releaseBackgroundResources(r);
   13227                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   13228                 }
   13229                 mWindowManager.setAppFullscreen(token, true);
   13230                 return translucentChanged;
   13231             }
   13232         } finally {
   13233             Binder.restoreCallingIdentity(origId);
   13234         }
   13235     }
   13236 
   13237     @Override
   13238     public boolean convertToTranslucent(IBinder token, Bundle options) {
   13239         final long origId = Binder.clearCallingIdentity();
   13240         try {
   13241             synchronized (this) {
   13242                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   13243                 if (r == null) {
   13244                     return false;
   13245                 }
   13246                 final TaskRecord task = r.getTask();
   13247                 int index = task.mActivities.lastIndexOf(r);
   13248                 if (index > 0) {
   13249                     ActivityRecord under = task.mActivities.get(index - 1);
   13250                     under.returningOptions = ActivityOptions.fromBundle(options);
   13251                 }
   13252                 final boolean translucentChanged = r.changeWindowTranslucency(false);
   13253                 if (translucentChanged) {
   13254                     r.getStack().convertActivityToTranslucent(r);
   13255                 }
   13256                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   13257                 mWindowManager.setAppFullscreen(token, false);
   13258                 return translucentChanged;
   13259             }
   13260         } finally {
   13261             Binder.restoreCallingIdentity(origId);
   13262         }
   13263     }
   13264 
   13265     @Override
   13266     public boolean requestVisibleBehind(IBinder token, boolean visible) {
   13267         final long origId = Binder.clearCallingIdentity();
   13268         try {
   13269             synchronized (this) {
   13270                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   13271                 if (r != null) {
   13272                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
   13273                 }
   13274             }
   13275             return false;
   13276         } finally {
   13277             Binder.restoreCallingIdentity(origId);
   13278         }
   13279     }
   13280 
   13281     @Override
   13282     public boolean isBackgroundVisibleBehind(IBinder token) {
   13283         final long origId = Binder.clearCallingIdentity();
   13284         try {
   13285             synchronized (this) {
   13286                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
   13287                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
   13288                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
   13289                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
   13290                 return visible;
   13291             }
   13292         } finally {
   13293             Binder.restoreCallingIdentity(origId);
   13294         }
   13295     }
   13296 
   13297     @Override
   13298     public Bundle getActivityOptions(IBinder token) {
   13299         final long origId = Binder.clearCallingIdentity();
   13300         try {
   13301             synchronized (this) {
   13302                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   13303                 if (r != null) {
   13304                     final ActivityOptions activityOptions = r.pendingOptions;
   13305                     r.pendingOptions = null;
   13306                     return activityOptions == null ? null : activityOptions.toBundle();
   13307                 }
   13308                 return null;
   13309             }
   13310         } finally {
   13311             Binder.restoreCallingIdentity(origId);
   13312         }
   13313     }
   13314 
   13315     @Override
   13316     public void setImmersive(IBinder token, boolean immersive) {
   13317         synchronized(this) {
   13318             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   13319             if (r == null) {
   13320                 throw new IllegalArgumentException();
   13321             }
   13322             r.immersive = immersive;
   13323 
   13324             // update associated state if we're frontmost
   13325             if (r == mStackSupervisor.getResumedActivityLocked()) {
   13326                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
   13327                 applyUpdateLockStateLocked(r);
   13328             }
   13329         }
   13330     }
   13331 
   13332     @Override
   13333     public boolean isImmersive(IBinder token) {
   13334         synchronized (this) {
   13335             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   13336             if (r == null) {
   13337                 throw new IllegalArgumentException();
   13338             }
   13339             return r.immersive;
   13340         }
   13341     }
   13342 
   13343     @Override
   13344     public void setVrThread(int tid) {
   13345         enforceSystemHasVrFeature();
   13346         synchronized (this) {
   13347             synchronized (mPidsSelfLocked) {
   13348                 final int pid = Binder.getCallingPid();
   13349                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
   13350                 mVrController.setVrThreadLocked(tid, pid, proc);
   13351             }
   13352         }
   13353     }
   13354 
   13355     @Override
   13356     public void setPersistentVrThread(int tid) {
   13357         if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
   13358             final String msg = "Permission Denial: setPersistentVrThread() from pid="
   13359                     + Binder.getCallingPid()
   13360                     + ", uid=" + Binder.getCallingUid()
   13361                     + " requires " + permission.RESTRICTED_VR_ACCESS;
   13362             Slog.w(TAG, msg);
   13363             throw new SecurityException(msg);
   13364         }
   13365         enforceSystemHasVrFeature();
   13366         synchronized (this) {
   13367             synchronized (mPidsSelfLocked) {
   13368                 final int pid = Binder.getCallingPid();
   13369                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
   13370                 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
   13371             }
   13372         }
   13373     }
   13374 
   13375     /**
   13376      * Schedule the given thread a normal scheduling priority.
   13377      *
   13378      * @param newTid the tid of the thread to adjust the scheduling of.
   13379      * @param suppressLogs {@code true} if any error logging should be disabled.
   13380      *
   13381      * @return {@code true} if this succeeded.
   13382      */
   13383     static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
   13384         try {
   13385             Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
   13386             return true;
   13387         } catch (IllegalArgumentException e) {
   13388             if (!suppressLogs) {
   13389                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
   13390             }
   13391         }
   13392         return false;
   13393     }
   13394 
   13395     /**
   13396      * Schedule the given thread an FIFO scheduling priority.
   13397      *
   13398      * @param newTid the tid of the thread to adjust the scheduling of.
   13399      * @param suppressLogs {@code true} if any error logging should be disabled.
   13400      *
   13401      * @return {@code true} if this succeeded.
   13402      */
   13403     static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
   13404         try {
   13405             Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
   13406             return true;
   13407         } catch (IllegalArgumentException e) {
   13408             if (!suppressLogs) {
   13409                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
   13410             }
   13411         }
   13412         return false;
   13413     }
   13414 
   13415     /**
   13416      * Check that we have the features required for VR-related API calls, and throw an exception if
   13417      * not.
   13418      */
   13419     private void enforceSystemHasVrFeature() {
   13420         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
   13421             throw new UnsupportedOperationException("VR mode not supported on this device!");
   13422         }
   13423     }
   13424 
   13425     @Override
   13426     public void setRenderThread(int tid) {
   13427         synchronized (this) {
   13428             ProcessRecord proc;
   13429             int pid = Binder.getCallingPid();
   13430             if (pid == Process.myPid()) {
   13431                 demoteSystemServerRenderThread(tid);
   13432                 return;
   13433             }
   13434             synchronized (mPidsSelfLocked) {
   13435                 proc = mPidsSelfLocked.get(pid);
   13436                 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
   13437                     // ensure the tid belongs to the process
   13438                     if (!isThreadInProcess(pid, tid)) {
   13439                         throw new IllegalArgumentException(
   13440                             "Render thread does not belong to process");
   13441                     }
   13442                     proc.renderThreadTid = tid;
   13443                     if (DEBUG_OOM_ADJ) {
   13444                         Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
   13445                     }
   13446                     // promote to FIFO now
   13447                     if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
   13448                         if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
   13449                         if (mUseFifoUiScheduling) {
   13450                             setThreadScheduler(proc.renderThreadTid,
   13451                                 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
   13452                         } else {
   13453                             setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
   13454                         }
   13455                     }
   13456                 } else {
   13457                     if (DEBUG_OOM_ADJ) {
   13458                         Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
   13459                                "PID: " + pid + ", TID: " + tid + " FIFO: " +
   13460                                mUseFifoUiScheduling);
   13461                     }
   13462                 }
   13463             }
   13464         }
   13465     }
   13466 
   13467     /**
   13468      * We only use RenderThread in system_server to store task snapshots to the disk, which should
   13469      * happen in the background. Thus, demote render thread from system_server to a lower priority.
   13470      *
   13471      * @param tid the tid of the RenderThread
   13472      */
   13473     private void demoteSystemServerRenderThread(int tid) {
   13474         setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
   13475     }
   13476 
   13477     @Override
   13478     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
   13479         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
   13480             throw new UnsupportedOperationException("VR mode not supported on this device!");
   13481         }
   13482 
   13483         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
   13484 
   13485         ActivityRecord r;
   13486         synchronized (this) {
   13487             r = ActivityRecord.isInStackLocked(token);
   13488         }
   13489 
   13490         if (r == null) {
   13491             throw new IllegalArgumentException();
   13492         }
   13493 
   13494         int err;
   13495         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
   13496                 VrManagerInternal.NO_ERROR) {
   13497             return err;
   13498         }
   13499 
   13500         synchronized(this) {
   13501             r.requestedVrComponent = (enabled) ? packageName : null;
   13502 
   13503             // Update associated state if this activity is currently focused
   13504             if (r == mStackSupervisor.getResumedActivityLocked()) {
   13505                 applyUpdateVrModeLocked(r);
   13506             }
   13507             return 0;
   13508         }
   13509     }
   13510 
   13511     @Override
   13512     public boolean isVrModePackageEnabled(ComponentName packageName) {
   13513         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
   13514             throw new UnsupportedOperationException("VR mode not supported on this device!");
   13515         }
   13516 
   13517         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
   13518 
   13519         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
   13520                 VrManagerInternal.NO_ERROR;
   13521     }
   13522 
   13523     public boolean isTopActivityImmersive() {
   13524         enforceNotIsolatedCaller("startActivity");
   13525         synchronized (this) {
   13526             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
   13527             return (r != null) ? r.immersive : false;
   13528         }
   13529     }
   13530 
   13531     /**
   13532      * @return whether the system should disable UI modes incompatible with VR mode.
   13533      */
   13534     boolean shouldDisableNonVrUiLocked() {
   13535         return mVrController.shouldDisableNonVrUiLocked();
   13536     }
   13537 
   13538     @Override
   13539     public boolean isTopOfTask(IBinder token) {
   13540         synchronized (this) {
   13541             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   13542             if (r == null) {
   13543                 throw new IllegalArgumentException();
   13544             }
   13545             return r.getTask().getTopActivity() == r;
   13546         }
   13547     }
   13548 
   13549     @Override
   13550     public void setHasTopUi(boolean hasTopUi) throws RemoteException {
   13551         if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
   13552             String msg = "Permission Denial: setHasTopUi() from pid="
   13553                     + Binder.getCallingPid()
   13554                     + ", uid=" + Binder.getCallingUid()
   13555                     + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
   13556             Slog.w(TAG, msg);
   13557             throw new SecurityException(msg);
   13558         }
   13559         final int pid = Binder.getCallingPid();
   13560         final long origId = Binder.clearCallingIdentity();
   13561         try {
   13562             synchronized (this) {
   13563                 boolean changed = false;
   13564                 ProcessRecord pr;
   13565                 synchronized (mPidsSelfLocked) {
   13566                     pr = mPidsSelfLocked.get(pid);
   13567                     if (pr == null) {
   13568                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
   13569                         return;
   13570                     }
   13571                     if (pr.hasTopUi != hasTopUi) {
   13572                         if (DEBUG_OOM_ADJ) {
   13573                             Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
   13574                         }
   13575                         pr.hasTopUi = hasTopUi;
   13576                         changed = true;
   13577                     }
   13578                 }
   13579                 if (changed) {
   13580                     updateOomAdjLocked(pr, true);
   13581                 }
   13582             }
   13583         } finally {
   13584             Binder.restoreCallingIdentity(origId);
   13585         }
   13586     }
   13587 
   13588     public final void enterSafeMode() {
   13589         synchronized(this) {
   13590             // It only makes sense to do this before the system is ready
   13591             // and started launching other packages.
   13592             if (!mSystemReady) {
   13593                 try {
   13594                     AppGlobals.getPackageManager().enterSafeMode();
   13595                 } catch (RemoteException e) {
   13596                 }
   13597             }
   13598 
   13599             mSafeMode = true;
   13600         }
   13601     }
   13602 
   13603     public final void showSafeModeOverlay() {
   13604         View v = LayoutInflater.from(mContext).inflate(
   13605                 com.android.internal.R.layout.safe_mode, null);
   13606         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
   13607         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
   13608         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
   13609         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
   13610         lp.gravity = Gravity.BOTTOM | Gravity.START;
   13611         lp.format = v.getBackground().getOpacity();
   13612         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
   13613                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
   13614         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
   13615         ((WindowManager)mContext.getSystemService(
   13616                 Context.WINDOW_SERVICE)).addView(v, lp);
   13617     }
   13618 
   13619     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
   13620         if (sender != null && !(sender instanceof PendingIntentRecord)) {
   13621             return;
   13622         }
   13623         final PendingIntentRecord rec = (PendingIntentRecord)sender;
   13624         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   13625         synchronized (stats) {
   13626             if (mBatteryStatsService.isOnBattery()) {
   13627                 mBatteryStatsService.enforceCallingPermission();
   13628                 int MY_UID = Binder.getCallingUid();
   13629                 final int uid;
   13630                 if (sender == null) {
   13631                     uid = sourceUid;
   13632                 } else {
   13633                     uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
   13634                 }
   13635                 BatteryStatsImpl.Uid.Pkg pkg =
   13636                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
   13637                             sourcePkg != null ? sourcePkg : rec.key.packageName);
   13638                 pkg.noteWakeupAlarmLocked(tag);
   13639             }
   13640         }
   13641     }
   13642 
   13643     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
   13644         if (sender != null && !(sender instanceof PendingIntentRecord)) {
   13645             return;
   13646         }
   13647         final PendingIntentRecord rec = (PendingIntentRecord)sender;
   13648         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   13649         synchronized (stats) {
   13650             mBatteryStatsService.enforceCallingPermission();
   13651             int MY_UID = Binder.getCallingUid();
   13652             final int uid;
   13653             if (sender == null) {
   13654                 uid = sourceUid;
   13655             } else {
   13656                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
   13657             }
   13658             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
   13659         }
   13660     }
   13661 
   13662     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
   13663         if (sender != null && !(sender instanceof PendingIntentRecord)) {
   13664             return;
   13665         }
   13666         final PendingIntentRecord rec = (PendingIntentRecord)sender;
   13667         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   13668         synchronized (stats) {
   13669             mBatteryStatsService.enforceCallingPermission();
   13670             int MY_UID = Binder.getCallingUid();
   13671             final int uid;
   13672             if (sender == null) {
   13673                 uid = sourceUid;
   13674             } else {
   13675                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
   13676             }
   13677             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
   13678         }
   13679     }
   13680 
   13681     public boolean killPids(int[] pids, String pReason, boolean secure) {
   13682         if (Binder.getCallingUid() != SYSTEM_UID) {
   13683             throw new SecurityException("killPids only available to the system");
   13684         }
   13685         String reason = (pReason == null) ? "Unknown" : pReason;
   13686         // XXX Note: don't acquire main activity lock here, because the window
   13687         // manager calls in with its locks held.
   13688 
   13689         boolean killed = false;
   13690         synchronized (mPidsSelfLocked) {
   13691             int worstType = 0;
   13692             for (int i=0; i<pids.length; i++) {
   13693                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   13694                 if (proc != null) {
   13695                     int type = proc.setAdj;
   13696                     if (type > worstType) {
   13697                         worstType = type;
   13698                     }
   13699                 }
   13700             }
   13701 
   13702             // If the worst oom_adj is somewhere in the cached proc LRU range,
   13703             // then constrain it so we will kill all cached procs.
   13704             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
   13705                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
   13706                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
   13707             }
   13708 
   13709             // If this is not a secure call, don't let it kill processes that
   13710             // are important.
   13711             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
   13712                 worstType = ProcessList.SERVICE_ADJ;
   13713             }
   13714 
   13715             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
   13716             for (int i=0; i<pids.length; i++) {
   13717                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   13718                 if (proc == null) {
   13719                     continue;
   13720                 }
   13721                 int adj = proc.setAdj;
   13722                 if (adj >= worstType && !proc.killedByAm) {
   13723                     proc.kill(reason, true);
   13724                     killed = true;
   13725                 }
   13726             }
   13727         }
   13728         return killed;
   13729     }
   13730 
   13731     @Override
   13732     public void killUid(int appId, int userId, String reason) {
   13733         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
   13734         synchronized (this) {
   13735             final long identity = Binder.clearCallingIdentity();
   13736             try {
   13737                 killPackageProcessesLocked(null, appId, userId,
   13738                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
   13739                         reason != null ? reason : "kill uid");
   13740             } finally {
   13741                 Binder.restoreCallingIdentity(identity);
   13742             }
   13743         }
   13744     }
   13745 
   13746     @Override
   13747     public boolean killProcessesBelowForeground(String reason) {
   13748         if (Binder.getCallingUid() != SYSTEM_UID) {
   13749             throw new SecurityException("killProcessesBelowForeground() only available to system");
   13750         }
   13751 
   13752         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
   13753     }
   13754 
   13755     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
   13756         if (Binder.getCallingUid() != SYSTEM_UID) {
   13757             throw new SecurityException("killProcessesBelowAdj() only available to system");
   13758         }
   13759 
   13760         boolean killed = false;
   13761         synchronized (mPidsSelfLocked) {
   13762             final int size = mPidsSelfLocked.size();
   13763             for (int i = 0; i < size; i++) {
   13764                 final int pid = mPidsSelfLocked.keyAt(i);
   13765                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   13766                 if (proc == null) continue;
   13767 
   13768                 final int adj = proc.setAdj;
   13769                 if (adj > belowAdj && !proc.killedByAm) {
   13770                     proc.kill(reason, true);
   13771                     killed = true;
   13772                 }
   13773             }
   13774         }
   13775         return killed;
   13776     }
   13777 
   13778     @Override
   13779     public void hang(final IBinder who, boolean allowRestart) {
   13780         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   13781                 != PackageManager.PERMISSION_GRANTED) {
   13782             throw new SecurityException("Requires permission "
   13783                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   13784         }
   13785 
   13786         final IBinder.DeathRecipient death = new DeathRecipient() {
   13787             @Override
   13788             public void binderDied() {
   13789                 synchronized (this) {
   13790                     notifyAll();
   13791                 }
   13792             }
   13793         };
   13794 
   13795         try {
   13796             who.linkToDeath(death, 0);
   13797         } catch (RemoteException e) {
   13798             Slog.w(TAG, "hang: given caller IBinder is already dead.");
   13799             return;
   13800         }
   13801 
   13802         synchronized (this) {
   13803             Watchdog.getInstance().setAllowRestart(allowRestart);
   13804             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
   13805             synchronized (death) {
   13806                 while (who.isBinderAlive()) {
   13807                     try {
   13808                         death.wait();
   13809                     } catch (InterruptedException e) {
   13810                     }
   13811                 }
   13812             }
   13813             Watchdog.getInstance().setAllowRestart(true);
   13814         }
   13815     }
   13816 
   13817     @Override
   13818     public void restart() {
   13819         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   13820                 != PackageManager.PERMISSION_GRANTED) {
   13821             throw new SecurityException("Requires permission "
   13822                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   13823         }
   13824 
   13825         Log.i(TAG, "Sending shutdown broadcast...");
   13826 
   13827         BroadcastReceiver br = new BroadcastReceiver() {
   13828             @Override public void onReceive(Context context, Intent intent) {
   13829                 // Now the broadcast is done, finish up the low-level shutdown.
   13830                 Log.i(TAG, "Shutting down activity manager...");
   13831                 shutdown(10000);
   13832                 Log.i(TAG, "Shutdown complete, restarting!");
   13833                 killProcess(myPid());
   13834                 System.exit(10);
   13835             }
   13836         };
   13837 
   13838         // First send the high-level shut down broadcast.
   13839         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
   13840         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   13841         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
   13842         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
   13843         mContext.sendOrderedBroadcastAsUser(intent,
   13844                 UserHandle.ALL, null, br, mHandler, 0, null, null);
   13845         */
   13846         br.onReceive(mContext, intent);
   13847     }
   13848 
   13849     private long getLowRamTimeSinceIdle(long now) {
   13850         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
   13851     }
   13852 
   13853     @Override
   13854     public void performIdleMaintenance() {
   13855         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   13856                 != PackageManager.PERMISSION_GRANTED) {
   13857             throw new SecurityException("Requires permission "
   13858                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   13859         }
   13860 
   13861         synchronized (this) {
   13862             final long now = SystemClock.uptimeMillis();
   13863             final long timeSinceLastIdle = now - mLastIdleTime;
   13864             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
   13865             mLastIdleTime = now;
   13866             mLowRamTimeSinceLastIdle = 0;
   13867             if (mLowRamStartTime != 0) {
   13868                 mLowRamStartTime = now;
   13869             }
   13870 
   13871             StringBuilder sb = new StringBuilder(128);
   13872             sb.append("Idle maintenance over ");
   13873             TimeUtils.formatDuration(timeSinceLastIdle, sb);
   13874             sb.append(" low RAM for ");
   13875             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
   13876             Slog.i(TAG, sb.toString());
   13877 
   13878             // If at least 1/3 of our time since the last idle period has been spent
   13879             // with RAM low, then we want to kill processes.
   13880             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
   13881 
   13882             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   13883                 ProcessRecord proc = mLruProcesses.get(i);
   13884                 if (proc.notCachedSinceIdle) {
   13885                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
   13886                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
   13887                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
   13888                         if (doKilling && proc.initialIdlePss != 0
   13889                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
   13890                             sb = new StringBuilder(128);
   13891                             sb.append("Kill");
   13892                             sb.append(proc.processName);
   13893                             sb.append(" in idle maint: pss=");
   13894                             sb.append(proc.lastPss);
   13895                             sb.append(", swapPss=");
   13896                             sb.append(proc.lastSwapPss);
   13897                             sb.append(", initialPss=");
   13898                             sb.append(proc.initialIdlePss);
   13899                             sb.append(", period=");
   13900                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
   13901                             sb.append(", lowRamPeriod=");
   13902                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
   13903                             Slog.wtfQuiet(TAG, sb.toString());
   13904                             proc.kill("idle maint (pss " + proc.lastPss
   13905                                     + " from " + proc.initialIdlePss + ")", true);
   13906                         }
   13907                     }
   13908                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
   13909                         && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
   13910                     proc.notCachedSinceIdle = true;
   13911                     proc.initialIdlePss = 0;
   13912                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
   13913                             mTestPssMode, isSleepingLocked(), now);
   13914                 }
   13915             }
   13916 
   13917             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
   13918             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
   13919         }
   13920     }
   13921 
   13922     @Override
   13923     public void sendIdleJobTrigger() {
   13924         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   13925                 != PackageManager.PERMISSION_GRANTED) {
   13926             throw new SecurityException("Requires permission "
   13927                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   13928         }
   13929 
   13930         final long ident = Binder.clearCallingIdentity();
   13931         try {
   13932             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
   13933                     .setPackage("android")
   13934                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   13935             broadcastIntent(null, intent, null, null, 0, null, null, null,
   13936                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
   13937         } finally {
   13938             Binder.restoreCallingIdentity(ident);
   13939         }
   13940     }
   13941 
   13942     private void retrieveSettings() {
   13943         final ContentResolver resolver = mContext.getContentResolver();
   13944         final boolean freeformWindowManagement =
   13945                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
   13946                         || Settings.Global.getInt(
   13947                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
   13948         final boolean supportsPictureInPicture =
   13949                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
   13950 
   13951         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
   13952         final boolean supportsSplitScreenMultiWindow =
   13953                 ActivityManager.supportsSplitScreenMultiWindow(mContext);
   13954         final boolean supportsMultiDisplay = mContext.getPackageManager()
   13955                 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
   13956         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
   13957         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
   13958         final boolean alwaysFinishActivities =
   13959                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
   13960         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
   13961         final boolean forceResizable = Settings.Global.getInt(
   13962                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
   13963         final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
   13964                 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
   13965         final boolean supportsLeanbackOnly =
   13966                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
   13967 
   13968         // Transfer any global setting for forcing RTL layout, into a System Property
   13969         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
   13970 
   13971         final Configuration configuration = new Configuration();
   13972         Settings.System.getConfiguration(resolver, configuration);
   13973         if (forceRtl) {
   13974             // This will take care of setting the correct layout direction flags
   13975             configuration.setLayoutDirection(configuration.locale);
   13976         }
   13977 
   13978         synchronized (this) {
   13979             mDebugApp = mOrigDebugApp = debugApp;
   13980             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
   13981             mAlwaysFinishActivities = alwaysFinishActivities;
   13982             mSupportsLeanbackOnly = supportsLeanbackOnly;
   13983             mForceResizableActivities = forceResizable;
   13984             final boolean multiWindowFormEnabled = freeformWindowManagement
   13985                     || supportsSplitScreenMultiWindow
   13986                     || supportsPictureInPicture
   13987                     || supportsMultiDisplay;
   13988             if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
   13989                 mSupportsMultiWindow = true;
   13990                 mSupportsFreeformWindowManagement = freeformWindowManagement;
   13991                 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
   13992                 mSupportsPictureInPicture = supportsPictureInPicture;
   13993                 mSupportsMultiDisplay = supportsMultiDisplay;
   13994             } else {
   13995                 mSupportsMultiWindow = false;
   13996                 mSupportsFreeformWindowManagement = false;
   13997                 mSupportsSplitScreenMultiWindow = false;
   13998                 mSupportsPictureInPicture = false;
   13999                 mSupportsMultiDisplay = false;
   14000             }
   14001             mWindowManager.setForceResizableTasks(mForceResizableActivities);
   14002             mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
   14003             // This happens before any activities are started, so we can change global configuration
   14004             // in-place.
   14005             updateConfigurationLocked(configuration, null, true);
   14006             final Configuration globalConfig = getGlobalConfiguration();
   14007             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
   14008 
   14009             // Load resources only after the current configuration has been set.
   14010             final Resources res = mContext.getResources();
   14011             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
   14012             mThumbnailWidth = res.getDimensionPixelSize(
   14013                     com.android.internal.R.dimen.thumbnail_width);
   14014             mThumbnailHeight = res.getDimensionPixelSize(
   14015                     com.android.internal.R.dimen.thumbnail_height);
   14016             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
   14017                     com.android.internal.R.string.config_appsNotReportingCrashes));
   14018             mUserController.mUserSwitchUiEnabled = !res.getBoolean(
   14019                     com.android.internal.R.bool.config_customUserSwitchUi);
   14020             if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
   14021                 mFullscreenThumbnailScale = (float) res
   14022                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
   14023                     (float) globalConfig.screenWidthDp;
   14024             } else {
   14025                 mFullscreenThumbnailScale = res.getFraction(
   14026                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
   14027             }
   14028             mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
   14029         }
   14030     }
   14031 
   14032     public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
   14033         traceLog.traceBegin("PhaseActivityManagerReady");
   14034         synchronized(this) {
   14035             if (mSystemReady) {
   14036                 // If we're done calling all the receivers, run the next "boot phase" passed in
   14037                 // by the SystemServer
   14038                 if (goingCallback != null) {
   14039                     goingCallback.run();
   14040                 }
   14041                 return;
   14042             }
   14043 
   14044             mLocalDeviceIdleController
   14045                     = LocalServices.getService(DeviceIdleController.LocalService.class);
   14046             mAssistUtils = new AssistUtils(mContext);
   14047             mVrController.onSystemReady();
   14048             // Make sure we have the current profile info, since it is needed for security checks.
   14049             mUserController.onSystemReady();
   14050             mRecentTasks.onSystemReadyLocked();
   14051             mAppOpsService.systemReady();
   14052             mSystemReady = true;
   14053         }
   14054 
   14055         ArrayList<ProcessRecord> procsToKill = null;
   14056         synchronized(mPidsSelfLocked) {
   14057             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
   14058                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   14059                 if (!isAllowedWhileBooting(proc.info)){
   14060                     if (procsToKill == null) {
   14061                         procsToKill = new ArrayList<ProcessRecord>();
   14062                     }
   14063                     procsToKill.add(proc);
   14064                 }
   14065             }
   14066         }
   14067 
   14068         synchronized(this) {
   14069             if (procsToKill != null) {
   14070                 for (int i=procsToKill.size()-1; i>=0; i--) {
   14071                     ProcessRecord proc = procsToKill.get(i);
   14072                     Slog.i(TAG, "Removing system update proc: " + proc);
   14073                     removeProcessLocked(proc, true, false, "system update done");
   14074                 }
   14075             }
   14076 
   14077             // Now that we have cleaned up any update processes, we
   14078             // are ready to start launching real processes and know that
   14079             // we won't trample on them any more.
   14080             mProcessesReady = true;
   14081         }
   14082 
   14083         Slog.i(TAG, "System now ready");
   14084         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
   14085             SystemClock.uptimeMillis());
   14086 
   14087         synchronized(this) {
   14088             // Make sure we have no pre-ready processes sitting around.
   14089 
   14090             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   14091                 ResolveInfo ri = mContext.getPackageManager()
   14092                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
   14093                                 STOCK_PM_FLAGS);
   14094                 CharSequence errorMsg = null;
   14095                 if (ri != null) {
   14096                     ActivityInfo ai = ri.activityInfo;
   14097                     ApplicationInfo app = ai.applicationInfo;
   14098                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   14099                         mTopAction = Intent.ACTION_FACTORY_TEST;
   14100                         mTopData = null;
   14101                         mTopComponent = new ComponentName(app.packageName,
   14102                                 ai.name);
   14103                     } else {
   14104                         errorMsg = mContext.getResources().getText(
   14105                                 com.android.internal.R.string.factorytest_not_system);
   14106                     }
   14107                 } else {
   14108                     errorMsg = mContext.getResources().getText(
   14109                             com.android.internal.R.string.factorytest_no_action);
   14110                 }
   14111                 if (errorMsg != null) {
   14112                     mTopAction = null;
   14113                     mTopData = null;
   14114                     mTopComponent = null;
   14115                     Message msg = Message.obtain();
   14116                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
   14117                     msg.getData().putCharSequence("msg", errorMsg);
   14118                     mUiHandler.sendMessage(msg);
   14119                 }
   14120             }
   14121         }
   14122 
   14123         retrieveSettings();
   14124         final int currentUserId;
   14125         synchronized (this) {
   14126             currentUserId = mUserController.getCurrentUserIdLocked();
   14127             readGrantedUriPermissionsLocked();
   14128         }
   14129 
   14130         if (goingCallback != null) goingCallback.run();
   14131         traceLog.traceBegin("ActivityManagerStartApps");
   14132         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
   14133                 Integer.toString(currentUserId), currentUserId);
   14134         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
   14135                 Integer.toString(currentUserId), currentUserId);
   14136         mSystemServiceManager.startUser(currentUserId);
   14137 
   14138         synchronized (this) {
   14139             // Only start up encryption-aware persistent apps; once user is
   14140             // unlocked we'll come back around and start unaware apps
   14141             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
   14142 
   14143             // Start up initial activity.
   14144             mBooting = true;
   14145             // Enable home activity for system user, so that the system can always boot. We don't
   14146             // do this when the system user is not setup since the setup wizard should be the one
   14147             // to handle home activity in this case.
   14148             if (UserManager.isSplitSystemUser() &&
   14149                     Settings.Secure.getInt(mContext.getContentResolver(),
   14150                          Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
   14151                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
   14152                 try {
   14153                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
   14154                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
   14155                             UserHandle.USER_SYSTEM);
   14156                 } catch (RemoteException e) {
   14157                     throw e.rethrowAsRuntimeException();
   14158                 }
   14159             }
   14160             startHomeActivityLocked(currentUserId, "systemReady");
   14161 
   14162             try {
   14163                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
   14164                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
   14165                             + " data partition or your device will be unstable.");
   14166                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
   14167                 }
   14168             } catch (RemoteException e) {
   14169             }
   14170 
   14171             if (!Build.isBuildConsistent()) {
   14172                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
   14173                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
   14174             }
   14175 
   14176             long ident = Binder.clearCallingIdentity();
   14177             try {
   14178                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
   14179                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   14180                         | Intent.FLAG_RECEIVER_FOREGROUND);
   14181                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
   14182                 broadcastIntentLocked(null, null, intent,
   14183                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   14184                         null, false, false, MY_PID, SYSTEM_UID,
   14185                         currentUserId);
   14186                 intent = new Intent(Intent.ACTION_USER_STARTING);
   14187                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   14188                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
   14189                 broadcastIntentLocked(null, null, intent,
   14190                         null, new IIntentReceiver.Stub() {
   14191                             @Override
   14192                             public void performReceive(Intent intent, int resultCode, String data,
   14193                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
   14194                                     throws RemoteException {
   14195                             }
   14196                         }, 0, null, null,
   14197                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
   14198                         null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
   14199             } catch (Throwable t) {
   14200                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
   14201             } finally {
   14202                 Binder.restoreCallingIdentity(ident);
   14203             }
   14204             mStackSupervisor.resumeFocusedStackTopActivityLocked();
   14205             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
   14206             traceLog.traceEnd(); // ActivityManagerStartApps
   14207             traceLog.traceEnd(); // PhaseActivityManagerReady
   14208         }
   14209     }
   14210 
   14211     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
   14212         synchronized (this) {
   14213             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
   14214         }
   14215     }
   14216 
   14217     void skipCurrentReceiverLocked(ProcessRecord app) {
   14218         for (BroadcastQueue queue : mBroadcastQueues) {
   14219             queue.skipCurrentReceiverLocked(app);
   14220         }
   14221     }
   14222 
   14223     /**
   14224      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
   14225      * The application process will exit immediately after this call returns.
   14226      * @param app object of the crashing app, null for the system server
   14227      * @param crashInfo describing the exception
   14228      */
   14229     public void handleApplicationCrash(IBinder app,
   14230             ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
   14231         ProcessRecord r = findAppProcess(app, "Crash");
   14232         final String processName = app == null ? "system_server"
   14233                 : (r == null ? "unknown" : r.processName);
   14234 
   14235         handleApplicationCrashInner("crash", r, processName, crashInfo);
   14236     }
   14237 
   14238     /* Native crash reporting uses this inner version because it needs to be somewhat
   14239      * decoupled from the AM-managed cleanup lifecycle
   14240      */
   14241     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
   14242             ApplicationErrorReport.CrashInfo crashInfo) {
   14243         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
   14244                 UserHandle.getUserId(Binder.getCallingUid()), processName,
   14245                 r == null ? -1 : r.info.flags,
   14246                 crashInfo.exceptionClassName,
   14247                 crashInfo.exceptionMessage,
   14248                 crashInfo.throwFileName,
   14249                 crashInfo.throwLineNumber);
   14250 
   14251         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
   14252 
   14253         mAppErrors.crashApplication(r, crashInfo);
   14254     }
   14255 
   14256     public void handleApplicationStrictModeViolation(
   14257             IBinder app,
   14258             int violationMask,
   14259             StrictMode.ViolationInfo info) {
   14260         ProcessRecord r = findAppProcess(app, "StrictMode");
   14261         if (r == null) {
   14262             return;
   14263         }
   14264 
   14265         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
   14266             Integer stackFingerprint = info.hashCode();
   14267             boolean logIt = true;
   14268             synchronized (mAlreadyLoggedViolatedStacks) {
   14269                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
   14270                     logIt = false;
   14271                     // TODO: sub-sample into EventLog for these, with
   14272                     // the info.durationMillis?  Then we'd get
   14273                     // the relative pain numbers, without logging all
   14274                     // the stack traces repeatedly.  We'd want to do
   14275                     // likewise in the client code, which also does
   14276                     // dup suppression, before the Binder call.
   14277                 } else {
   14278                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
   14279                         mAlreadyLoggedViolatedStacks.clear();
   14280                     }
   14281                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
   14282                 }
   14283             }
   14284             if (logIt) {
   14285                 logStrictModeViolationToDropBox(r, info);
   14286             }
   14287         }
   14288 
   14289         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
   14290             AppErrorResult result = new AppErrorResult();
   14291             synchronized (this) {
   14292                 final long origId = Binder.clearCallingIdentity();
   14293 
   14294                 Message msg = Message.obtain();
   14295                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
   14296                 HashMap<String, Object> data = new HashMap<String, Object>();
   14297                 data.put("result", result);
   14298                 data.put("app", r);
   14299                 data.put("violationMask", violationMask);
   14300                 data.put("info", info);
   14301                 msg.obj = data;
   14302                 mUiHandler.sendMessage(msg);
   14303 
   14304                 Binder.restoreCallingIdentity(origId);
   14305             }
   14306             int res = result.get();
   14307             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
   14308         }
   14309     }
   14310 
   14311     // Depending on the policy in effect, there could be a bunch of
   14312     // these in quick succession so we try to batch these together to
   14313     // minimize disk writes, number of dropbox entries, and maximize
   14314     // compression, by having more fewer, larger records.
   14315     private void logStrictModeViolationToDropBox(
   14316             ProcessRecord process,
   14317             StrictMode.ViolationInfo info) {
   14318         if (info == null) {
   14319             return;
   14320         }
   14321         final boolean isSystemApp = process == null ||
   14322                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
   14323                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
   14324         final String processName = process == null ? "unknown" : process.processName;
   14325         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
   14326         final DropBoxManager dbox = (DropBoxManager)
   14327                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   14328 
   14329         // Exit early if the dropbox isn't configured to accept this report type.
   14330         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   14331 
   14332         boolean bufferWasEmpty;
   14333         boolean needsFlush;
   14334         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
   14335         synchronized (sb) {
   14336             bufferWasEmpty = sb.length() == 0;
   14337             appendDropBoxProcessHeaders(process, processName, sb);
   14338             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   14339             sb.append("System-App: ").append(isSystemApp).append("\n");
   14340             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
   14341             if (info.violationNumThisLoop != 0) {
   14342                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
   14343             }
   14344             if (info.numAnimationsRunning != 0) {
   14345                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
   14346             }
   14347             if (info.broadcastIntentAction != null) {
   14348                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
   14349             }
   14350             if (info.durationMillis != -1) {
   14351                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
   14352             }
   14353             if (info.numInstances != -1) {
   14354                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
   14355             }
   14356             if (info.tags != null) {
   14357                 for (String tag : info.tags) {
   14358                     sb.append("Span-Tag: ").append(tag).append("\n");
   14359                 }
   14360             }
   14361             sb.append("\n");
   14362             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
   14363                 sb.append(info.crashInfo.stackTrace);
   14364                 sb.append("\n");
   14365             }
   14366             if (info.message != null) {
   14367                 sb.append(info.message);
   14368                 sb.append("\n");
   14369             }
   14370 
   14371             // Only buffer up to ~64k.  Various logging bits truncate
   14372             // things at 128k.
   14373             needsFlush = (sb.length() > 64 * 1024);
   14374         }
   14375 
   14376         // Flush immediately if the buffer's grown too large, or this
   14377         // is a non-system app.  Non-system apps are isolated with a
   14378         // different tag & policy and not batched.
   14379         //
   14380         // Batching is useful during internal testing with
   14381         // StrictMode settings turned up high.  Without batching,
   14382         // thousands of separate files could be created on boot.
   14383         if (!isSystemApp || needsFlush) {
   14384             new Thread("Error dump: " + dropboxTag) {
   14385                 @Override
   14386                 public void run() {
   14387                     String report;
   14388                     synchronized (sb) {
   14389                         report = sb.toString();
   14390                         sb.delete(0, sb.length());
   14391                         sb.trimToSize();
   14392                     }
   14393                     if (report.length() != 0) {
   14394                         dbox.addText(dropboxTag, report);
   14395                     }
   14396                 }
   14397             }.start();
   14398             return;
   14399         }
   14400 
   14401         // System app batching:
   14402         if (!bufferWasEmpty) {
   14403             // An existing dropbox-writing thread is outstanding, so
   14404             // we don't need to start it up.  The existing thread will
   14405             // catch the buffer appends we just did.
   14406             return;
   14407         }
   14408 
   14409         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
   14410         // (After this point, we shouldn't access AMS internal data structures.)
   14411         new Thread("Error dump: " + dropboxTag) {
   14412             @Override
   14413             public void run() {
   14414                 // 5 second sleep to let stacks arrive and be batched together
   14415                 try {
   14416                     Thread.sleep(5000);  // 5 seconds
   14417                 } catch (InterruptedException e) {}
   14418 
   14419                 String errorReport;
   14420                 synchronized (mStrictModeBuffer) {
   14421                     errorReport = mStrictModeBuffer.toString();
   14422                     if (errorReport.length() == 0) {
   14423                         return;
   14424                     }
   14425                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
   14426                     mStrictModeBuffer.trimToSize();
   14427                 }
   14428                 dbox.addText(dropboxTag, errorReport);
   14429             }
   14430         }.start();
   14431     }
   14432 
   14433     /**
   14434      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
   14435      * @param app object of the crashing app, null for the system server
   14436      * @param tag reported by the caller
   14437      * @param system whether this wtf is coming from the system
   14438      * @param crashInfo describing the context of the error
   14439      * @return true if the process should exit immediately (WTF is fatal)
   14440      */
   14441     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
   14442             final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
   14443         final int callingUid = Binder.getCallingUid();
   14444         final int callingPid = Binder.getCallingPid();
   14445 
   14446         if (system) {
   14447             // If this is coming from the system, we could very well have low-level
   14448             // system locks held, so we want to do this all asynchronously.  And we
   14449             // never want this to become fatal, so there is that too.
   14450             mHandler.post(new Runnable() {
   14451                 @Override public void run() {
   14452                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
   14453                 }
   14454             });
   14455             return false;
   14456         }
   14457 
   14458         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
   14459                 crashInfo);
   14460 
   14461         final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
   14462                 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
   14463         final boolean isSystem = (r == null) || r.persistent;
   14464 
   14465         if (isFatal && !isSystem) {
   14466             mAppErrors.crashApplication(r, crashInfo);
   14467             return true;
   14468         } else {
   14469             return false;
   14470         }
   14471     }
   14472 
   14473     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
   14474             final ApplicationErrorReport.CrashInfo crashInfo) {
   14475         final ProcessRecord r = findAppProcess(app, "WTF");
   14476         final String processName = app == null ? "system_server"
   14477                 : (r == null ? "unknown" : r.processName);
   14478 
   14479         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
   14480                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
   14481 
   14482         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
   14483 
   14484         return r;
   14485     }
   14486 
   14487     /**
   14488      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
   14489      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
   14490      */
   14491     private ProcessRecord findAppProcess(IBinder app, String reason) {
   14492         if (app == null) {
   14493             return null;
   14494         }
   14495 
   14496         synchronized (this) {
   14497             final int NP = mProcessNames.getMap().size();
   14498             for (int ip=0; ip<NP; ip++) {
   14499                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   14500                 final int NA = apps.size();
   14501                 for (int ia=0; ia<NA; ia++) {
   14502                     ProcessRecord p = apps.valueAt(ia);
   14503                     if (p.thread != null && p.thread.asBinder() == app) {
   14504                         return p;
   14505                     }
   14506                 }
   14507             }
   14508 
   14509             Slog.w(TAG, "Can't find mystery application for " + reason
   14510                     + " from pid=" + Binder.getCallingPid()
   14511                     + " uid=" + Binder.getCallingUid() + ": " + app);
   14512             return null;
   14513         }
   14514     }
   14515 
   14516     /**
   14517      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
   14518      * to append various headers to the dropbox log text.
   14519      */
   14520     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
   14521             StringBuilder sb) {
   14522         // Watchdog thread ends up invoking this function (with
   14523         // a null ProcessRecord) to add the stack file to dropbox.
   14524         // Do not acquire a lock on this (am) in such cases, as it
   14525         // could cause a potential deadlock, if and when watchdog
   14526         // is invoked due to unavailability of lock on am and it
   14527         // would prevent watchdog from killing system_server.
   14528         if (process == null) {
   14529             sb.append("Process: ").append(processName).append("\n");
   14530             return;
   14531         }
   14532         // Note: ProcessRecord 'process' is guarded by the service
   14533         // instance.  (notably process.pkgList, which could otherwise change
   14534         // concurrently during execution of this method)
   14535         synchronized (this) {
   14536             sb.append("Process: ").append(processName).append("\n");
   14537             sb.append("PID: ").append(process.pid).append("\n");
   14538             int flags = process.info.flags;
   14539             IPackageManager pm = AppGlobals.getPackageManager();
   14540             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
   14541             for (int ip=0; ip<process.pkgList.size(); ip++) {
   14542                 String pkg = process.pkgList.keyAt(ip);
   14543                 sb.append("Package: ").append(pkg);
   14544                 try {
   14545                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
   14546                     if (pi != null) {
   14547                         sb.append(" v").append(pi.versionCode);
   14548                         if (pi.versionName != null) {
   14549                             sb.append(" (").append(pi.versionName).append(")");
   14550                         }
   14551                     }
   14552                 } catch (RemoteException e) {
   14553                     Slog.e(TAG, "Error getting package info: " + pkg, e);
   14554                 }
   14555                 sb.append("\n");
   14556             }
   14557         }
   14558     }
   14559 
   14560     private static String processClass(ProcessRecord process) {
   14561         if (process == null || process.pid == MY_PID) {
   14562             return "system_server";
   14563         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   14564             return "system_app";
   14565         } else {
   14566             return "data_app";
   14567         }
   14568     }
   14569 
   14570     private volatile long mWtfClusterStart;
   14571     private volatile int mWtfClusterCount;
   14572 
   14573     /**
   14574      * Write a description of an error (crash, WTF, ANR) to the drop box.
   14575      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
   14576      * @param process which caused the error, null means the system server
   14577      * @param activity which triggered the error, null if unknown
   14578      * @param parent activity related to the error, null if unknown
   14579      * @param subject line related to the error, null if absent
   14580      * @param report in long form describing the error, null if absent
   14581      * @param dataFile text file to include in the report, null if none
   14582      * @param crashInfo giving an application stack trace, null if absent
   14583      */
   14584     public void addErrorToDropBox(String eventType,
   14585             ProcessRecord process, String processName, ActivityRecord activity,
   14586             ActivityRecord parent, String subject,
   14587             final String report, final File dataFile,
   14588             final ApplicationErrorReport.CrashInfo crashInfo) {
   14589         // NOTE -- this must never acquire the ActivityManagerService lock,
   14590         // otherwise the watchdog may be prevented from resetting the system.
   14591 
   14592         // Bail early if not published yet
   14593         if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
   14594         final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
   14595 
   14596         // Exit early if the dropbox isn't configured to accept this report type.
   14597         final String dropboxTag = processClass(process) + "_" + eventType;
   14598         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   14599 
   14600         // Rate-limit how often we're willing to do the heavy lifting below to
   14601         // collect and record logs; currently 5 logs per 10 second period.
   14602         final long now = SystemClock.elapsedRealtime();
   14603         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
   14604             mWtfClusterStart = now;
   14605             mWtfClusterCount = 1;
   14606         } else {
   14607             if (mWtfClusterCount++ >= 5) return;
   14608         }
   14609 
   14610         final StringBuilder sb = new StringBuilder(1024);
   14611         appendDropBoxProcessHeaders(process, processName, sb);
   14612         if (process != null) {
   14613             sb.append("Foreground: ")
   14614                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
   14615                     .append("\n");
   14616         }
   14617         if (activity != null) {
   14618             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
   14619         }
   14620         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
   14621             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
   14622         }
   14623         if (parent != null && parent != activity) {
   14624             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
   14625         }
   14626         if (subject != null) {
   14627             sb.append("Subject: ").append(subject).append("\n");
   14628         }
   14629         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   14630         if (Debug.isDebuggerConnected()) {
   14631             sb.append("Debugger: Connected\n");
   14632         }
   14633         sb.append("\n");
   14634 
   14635         // Do the rest in a worker thread to avoid blocking the caller on I/O
   14636         // (After this point, we shouldn't access AMS internal data structures.)
   14637         Thread worker = new Thread("Error dump: " + dropboxTag) {
   14638             @Override
   14639             public void run() {
   14640                 if (report != null) {
   14641                     sb.append(report);
   14642                 }
   14643 
   14644                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
   14645                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
   14646                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
   14647                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
   14648 
   14649                 if (dataFile != null && maxDataFileSize > 0) {
   14650                     try {
   14651                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
   14652                                     "\n\n[[TRUNCATED]]"));
   14653                     } catch (IOException e) {
   14654                         Slog.e(TAG, "Error reading " + dataFile, e);
   14655                     }
   14656                 }
   14657                 if (crashInfo != null && crashInfo.stackTrace != null) {
   14658                     sb.append(crashInfo.stackTrace);
   14659                 }
   14660 
   14661                 if (lines > 0) {
   14662                     sb.append("\n");
   14663 
   14664                     // Merge several logcat streams, and take the last N lines
   14665                     InputStreamReader input = null;
   14666                     try {
   14667                         java.lang.Process logcat = new ProcessBuilder(
   14668                                 "/system/bin/timeout", "-k", "15s", "10s",
   14669                                 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
   14670                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
   14671                                         .redirectErrorStream(true).start();
   14672 
   14673                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
   14674                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
   14675                         input = new InputStreamReader(logcat.getInputStream());
   14676 
   14677                         int num;
   14678                         char[] buf = new char[8192];
   14679                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
   14680                     } catch (IOException e) {
   14681                         Slog.e(TAG, "Error running logcat", e);
   14682                     } finally {
   14683                         if (input != null) try { input.close(); } catch (IOException e) {}
   14684                     }
   14685                 }
   14686 
   14687                 dbox.addText(dropboxTag, sb.toString());
   14688             }
   14689         };
   14690 
   14691         if (process == null) {
   14692             // If process is null, we are being called from some internal code
   14693             // and may be about to die -- run this synchronously.
   14694             worker.run();
   14695         } else {
   14696             worker.start();
   14697         }
   14698     }
   14699 
   14700     @Override
   14701     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
   14702         enforceNotIsolatedCaller("getProcessesInErrorState");
   14703         // assume our apps are happy - lazy create the list
   14704         List<ActivityManager.ProcessErrorStateInfo> errList = null;
   14705 
   14706         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
   14707                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
   14708         int userId = UserHandle.getUserId(Binder.getCallingUid());
   14709 
   14710         synchronized (this) {
   14711 
   14712             // iterate across all processes
   14713             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   14714                 ProcessRecord app = mLruProcesses.get(i);
   14715                 if (!allUsers && app.userId != userId) {
   14716                     continue;
   14717                 }
   14718                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
   14719                     // This one's in trouble, so we'll generate a report for it
   14720                     // crashes are higher priority (in case there's a crash *and* an anr)
   14721                     ActivityManager.ProcessErrorStateInfo report = null;
   14722                     if (app.crashing) {
   14723                         report = app.crashingReport;
   14724                     } else if (app.notResponding) {
   14725                         report = app.notRespondingReport;
   14726                     }
   14727 
   14728                     if (report != null) {
   14729                         if (errList == null) {
   14730                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
   14731                         }
   14732                         errList.add(report);
   14733                     } else {
   14734                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
   14735                                 " crashing = " + app.crashing +
   14736                                 " notResponding = " + app.notResponding);
   14737                     }
   14738                 }
   14739             }
   14740         }
   14741 
   14742         return errList;
   14743     }
   14744 
   14745     static int procStateToImportance(int procState, int memAdj,
   14746             ActivityManager.RunningAppProcessInfo currApp,
   14747             int clientTargetSdk) {
   14748         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
   14749                 procState, clientTargetSdk);
   14750         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
   14751             currApp.lru = memAdj;
   14752         } else {
   14753             currApp.lru = 0;
   14754         }
   14755         return imp;
   14756     }
   14757 
   14758     private void fillInProcMemInfo(ProcessRecord app,
   14759             ActivityManager.RunningAppProcessInfo outInfo,
   14760             int clientTargetSdk) {
   14761         outInfo.pid = app.pid;
   14762         outInfo.uid = app.info.uid;
   14763         if (mHeavyWeightProcess == app) {
   14764             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
   14765         }
   14766         if (app.persistent) {
   14767             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
   14768         }
   14769         if (app.activities.size() > 0) {
   14770             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
   14771         }
   14772         outInfo.lastTrimLevel = app.trimMemoryLevel;
   14773         int adj = app.curAdj;
   14774         int procState = app.curProcState;
   14775         outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
   14776         outInfo.importanceReasonCode = app.adjTypeCode;
   14777         outInfo.processState = app.curProcState;
   14778     }
   14779 
   14780     @Override
   14781     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
   14782         enforceNotIsolatedCaller("getRunningAppProcesses");
   14783 
   14784         final int callingUid = Binder.getCallingUid();
   14785         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
   14786 
   14787         // Lazy instantiation of list
   14788         List<ActivityManager.RunningAppProcessInfo> runList = null;
   14789         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
   14790                 callingUid) == PackageManager.PERMISSION_GRANTED;
   14791         final int userId = UserHandle.getUserId(callingUid);
   14792         final boolean allUids = isGetTasksAllowed(
   14793                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
   14794 
   14795         synchronized (this) {
   14796             // Iterate across all processes
   14797             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   14798                 ProcessRecord app = mLruProcesses.get(i);
   14799                 if ((!allUsers && app.userId != userId)
   14800                         || (!allUids && app.uid != callingUid)) {
   14801                     continue;
   14802                 }
   14803                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
   14804                     // Generate process state info for running application
   14805                     ActivityManager.RunningAppProcessInfo currApp =
   14806                         new ActivityManager.RunningAppProcessInfo(app.processName,
   14807                                 app.pid, app.getPackageList());
   14808                     fillInProcMemInfo(app, currApp, clientTargetSdk);
   14809                     if (app.adjSource instanceof ProcessRecord) {
   14810                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
   14811                         currApp.importanceReasonImportance =
   14812                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
   14813                                         app.adjSourceProcState);
   14814                     } else if (app.adjSource instanceof ActivityRecord) {
   14815                         ActivityRecord r = (ActivityRecord)app.adjSource;
   14816                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
   14817                     }
   14818                     if (app.adjTarget instanceof ComponentName) {
   14819                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
   14820                     }
   14821                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
   14822                     //        + " lru=" + currApp.lru);
   14823                     if (runList == null) {
   14824                         runList = new ArrayList<>();
   14825                     }
   14826                     runList.add(currApp);
   14827                 }
   14828             }
   14829         }
   14830         return runList;
   14831     }
   14832 
   14833     @Override
   14834     public List<ApplicationInfo> getRunningExternalApplications() {
   14835         enforceNotIsolatedCaller("getRunningExternalApplications");
   14836         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
   14837         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
   14838         if (runningApps != null && runningApps.size() > 0) {
   14839             Set<String> extList = new HashSet<String>();
   14840             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
   14841                 if (app.pkgList != null) {
   14842                     for (String pkg : app.pkgList) {
   14843                         extList.add(pkg);
   14844                     }
   14845                 }
   14846             }
   14847             IPackageManager pm = AppGlobals.getPackageManager();
   14848             for (String pkg : extList) {
   14849                 try {
   14850                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
   14851                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
   14852                         retList.add(info);
   14853                     }
   14854                 } catch (RemoteException e) {
   14855                 }
   14856             }
   14857         }
   14858         return retList;
   14859     }
   14860 
   14861     @Override
   14862     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
   14863         enforceNotIsolatedCaller("getMyMemoryState");
   14864 
   14865         final int callingUid = Binder.getCallingUid();
   14866         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
   14867 
   14868         synchronized (this) {
   14869             ProcessRecord proc;
   14870             synchronized (mPidsSelfLocked) {
   14871                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   14872             }
   14873             fillInProcMemInfo(proc, outInfo, clientTargetSdk);
   14874         }
   14875     }
   14876 
   14877     @Override
   14878     public int getMemoryTrimLevel() {
   14879         enforceNotIsolatedCaller("getMyMemoryState");
   14880         synchronized (this) {
   14881             return mLastMemoryLevel;
   14882         }
   14883     }
   14884 
   14885     @Override
   14886     public void onShellCommand(FileDescriptor in, FileDescriptor out,
   14887             FileDescriptor err, String[] args, ShellCallback callback,
   14888             ResultReceiver resultReceiver) {
   14889         (new ActivityManagerShellCommand(this, false)).exec(
   14890                 this, in, out, err, args, callback, resultReceiver);
   14891     }
   14892 
   14893     @Override
   14894     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   14895         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
   14896 
   14897         boolean dumpAll = false;
   14898         boolean dumpClient = false;
   14899         boolean dumpCheckin = false;
   14900         boolean dumpCheckinFormat = false;
   14901         boolean dumpVisibleStacksOnly = false;
   14902         boolean dumpFocusedStackOnly = false;
   14903         String dumpPackage = null;
   14904 
   14905         int opti = 0;
   14906         while (opti < args.length) {
   14907             String opt = args[opti];
   14908             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   14909                 break;
   14910             }
   14911             opti++;
   14912             if ("-a".equals(opt)) {
   14913                 dumpAll = true;
   14914             } else if ("-c".equals(opt)) {
   14915                 dumpClient = true;
   14916             } else if ("-v".equals(opt)) {
   14917                 dumpVisibleStacksOnly = true;
   14918             } else if ("-f".equals(opt)) {
   14919                 dumpFocusedStackOnly = true;
   14920             } else if ("-p".equals(opt)) {
   14921                 if (opti < args.length) {
   14922                     dumpPackage = args[opti];
   14923                     opti++;
   14924                 } else {
   14925                     pw.println("Error: -p option requires package argument");
   14926                     return;
   14927                 }
   14928                 dumpClient = true;
   14929             } else if ("--checkin".equals(opt)) {
   14930                 dumpCheckin = dumpCheckinFormat = true;
   14931             } else if ("-C".equals(opt)) {
   14932                 dumpCheckinFormat = true;
   14933             } else if ("-h".equals(opt)) {
   14934                 ActivityManagerShellCommand.dumpHelp(pw, true);
   14935                 return;
   14936             } else {
   14937                 pw.println("Unknown argument: " + opt + "; use -h for help");
   14938             }
   14939         }
   14940 
   14941         long origId = Binder.clearCallingIdentity();
   14942         boolean more = false;
   14943         // Is the caller requesting to dump a particular piece of data?
   14944         if (opti < args.length) {
   14945             String cmd = args[opti];
   14946             opti++;
   14947             if ("activities".equals(cmd) || "a".equals(cmd)) {
   14948                 synchronized (this) {
   14949                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
   14950                 }
   14951             } else if ("lastanr".equals(cmd)) {
   14952                 synchronized (this) {
   14953                     dumpLastANRLocked(pw);
   14954                 }
   14955             } else if ("starter".equals(cmd)) {
   14956                 synchronized (this) {
   14957                     dumpActivityStarterLocked(pw);
   14958                 }
   14959             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
   14960                 synchronized (this) {
   14961                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
   14962                 }
   14963             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
   14964                 String[] newArgs;
   14965                 String name;
   14966                 if (opti >= args.length) {
   14967                     name = null;
   14968                     newArgs = EMPTY_STRING_ARRAY;
   14969                 } else {
   14970                     dumpPackage = args[opti];
   14971                     opti++;
   14972                     newArgs = new String[args.length - opti];
   14973                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   14974                             args.length - opti);
   14975                 }
   14976                 synchronized (this) {
   14977                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
   14978                 }
   14979             } else if ("broadcast-stats".equals(cmd)) {
   14980                 String[] newArgs;
   14981                 String name;
   14982                 if (opti >= args.length) {
   14983                     name = null;
   14984                     newArgs = EMPTY_STRING_ARRAY;
   14985                 } else {
   14986                     dumpPackage = args[opti];
   14987                     opti++;
   14988                     newArgs = new String[args.length - opti];
   14989                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   14990                             args.length - opti);
   14991                 }
   14992                 synchronized (this) {
   14993                     if (dumpCheckinFormat) {
   14994                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
   14995                                 dumpPackage);
   14996                     } else {
   14997                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
   14998                     }
   14999                 }
   15000             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
   15001                 String[] newArgs;
   15002                 String name;
   15003                 if (opti >= args.length) {
   15004                     name = null;
   15005                     newArgs = EMPTY_STRING_ARRAY;
   15006                 } else {
   15007                     dumpPackage = args[opti];
   15008                     opti++;
   15009                     newArgs = new String[args.length - opti];
   15010                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   15011                             args.length - opti);
   15012                 }
   15013                 synchronized (this) {
   15014                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
   15015                 }
   15016             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
   15017                 String[] newArgs;
   15018                 String name;
   15019                 if (opti >= args.length) {
   15020                     name = null;
   15021                     newArgs = EMPTY_STRING_ARRAY;
   15022                 } else {
   15023                     dumpPackage = args[opti];
   15024                     opti++;
   15025                     newArgs = new String[args.length - opti];
   15026                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   15027                             args.length - opti);
   15028                 }
   15029                 synchronized (this) {
   15030                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
   15031                 }
   15032             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
   15033                 synchronized (this) {
   15034                     dumpOomLocked(fd, pw, args, opti, true);
   15035                 }
   15036             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
   15037                 synchronized (this) {
   15038                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
   15039                 }
   15040             } else if ("provider".equals(cmd)) {
   15041                 String[] newArgs;
   15042                 String name;
   15043                 if (opti >= args.length) {
   15044                     name = null;
   15045                     newArgs = EMPTY_STRING_ARRAY;
   15046                 } else {
   15047                     name = args[opti];
   15048                     opti++;
   15049                     newArgs = new String[args.length - opti];
   15050                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   15051                 }
   15052                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
   15053                     pw.println("No providers match: " + name);
   15054                     pw.println("Use -h for help.");
   15055                 }
   15056             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
   15057                 synchronized (this) {
   15058                     dumpProvidersLocked(fd, pw, args, opti, true, null);
   15059                 }
   15060             } else if ("service".equals(cmd)) {
   15061                 String[] newArgs;
   15062                 String name;
   15063                 if (opti >= args.length) {
   15064                     name = null;
   15065                     newArgs = EMPTY_STRING_ARRAY;
   15066                 } else {
   15067                     name = args[opti];
   15068                     opti++;
   15069                     newArgs = new String[args.length - opti];
   15070                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   15071                             args.length - opti);
   15072                 }
   15073                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
   15074                     pw.println("No services match: " + name);
   15075                     pw.println("Use -h for help.");
   15076                 }
   15077             } else if ("package".equals(cmd)) {
   15078                 String[] newArgs;
   15079                 if (opti >= args.length) {
   15080                     pw.println("package: no package name specified");
   15081                     pw.println("Use -h for help.");
   15082                 } else {
   15083                     dumpPackage = args[opti];
   15084                     opti++;
   15085                     newArgs = new String[args.length - opti];
   15086                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   15087                             args.length - opti);
   15088                     args = newArgs;
   15089                     opti = 0;
   15090                     more = true;
   15091                 }
   15092             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
   15093                 synchronized (this) {
   15094                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
   15095                 }
   15096             } else if ("settings".equals(cmd)) {
   15097                 synchronized (this) {
   15098                     mConstants.dump(pw);
   15099                 }
   15100             } else if ("services".equals(cmd) || "s".equals(cmd)) {
   15101                 if (dumpClient) {
   15102                     ActiveServices.ServiceDumper dumper;
   15103                     synchronized (this) {
   15104                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
   15105                                 dumpPackage);
   15106                     }
   15107                     dumper.dumpWithClient();
   15108                 } else {
   15109                     synchronized (this) {
   15110                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
   15111                                 dumpPackage).dumpLocked();
   15112                     }
   15113                 }
   15114             } else if ("locks".equals(cmd)) {
   15115                 LockGuard.dump(fd, pw, args);
   15116             } else {
   15117                 // Dumping a single activity?
   15118                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
   15119                         dumpFocusedStackOnly)) {
   15120                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
   15121                     int res = shell.exec(this, null, fd, null, args, null,
   15122                             new ResultReceiver(null));
   15123                     if (res < 0) {
   15124                         pw.println("Bad activity command, or no activities match: " + cmd);
   15125                         pw.println("Use -h for help.");
   15126                     }
   15127                 }
   15128             }
   15129             if (!more) {
   15130                 Binder.restoreCallingIdentity(origId);
   15131                 return;
   15132             }
   15133         }
   15134 
   15135         // No piece of data specified, dump everything.
   15136         if (dumpCheckinFormat) {
   15137             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
   15138         } else if (dumpClient) {
   15139             ActiveServices.ServiceDumper sdumper;
   15140             synchronized (this) {
   15141                 mConstants.dump(pw);
   15142                 pw.println();
   15143                 if (dumpAll) {
   15144                     pw.println("-------------------------------------------------------------------------------");
   15145                 }
   15146                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   15147                 pw.println();
   15148                 if (dumpAll) {
   15149                     pw.println("-------------------------------------------------------------------------------");
   15150                 }
   15151                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   15152                 pw.println();
   15153                 if (dumpAll) {
   15154                     pw.println("-------------------------------------------------------------------------------");
   15155                 }
   15156                 if (dumpAll || dumpPackage != null) {
   15157                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   15158                     pw.println();
   15159                     if (dumpAll) {
   15160                         pw.println("-------------------------------------------------------------------------------");
   15161                     }
   15162                 }
   15163                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   15164                 pw.println();
   15165                 if (dumpAll) {
   15166                     pw.println("-------------------------------------------------------------------------------");
   15167                 }
   15168                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   15169                 pw.println();
   15170                 if (dumpAll) {
   15171                     pw.println("-------------------------------------------------------------------------------");
   15172                 }
   15173                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
   15174                         dumpPackage);
   15175             }
   15176             sdumper.dumpWithClient();
   15177             pw.println();
   15178             synchronized (this) {
   15179                 if (dumpAll) {
   15180                     pw.println("-------------------------------------------------------------------------------");
   15181                 }
   15182                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   15183                 pw.println();
   15184                 if (dumpAll) {
   15185                     pw.println("-------------------------------------------------------------------------------");
   15186                 }
   15187                 dumpLastANRLocked(pw);
   15188                 pw.println();
   15189                 if (dumpAll) {
   15190                     pw.println("-------------------------------------------------------------------------------");
   15191                 }
   15192                 dumpActivityStarterLocked(pw);
   15193                 pw.println();
   15194                 if (dumpAll) {
   15195                     pw.println("-------------------------------------------------------------------------------");
   15196                 }
   15197                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   15198                 if (mAssociations.size() > 0) {
   15199                     pw.println();
   15200                     if (dumpAll) {
   15201                         pw.println("-------------------------------------------------------------------------------");
   15202                     }
   15203                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   15204                 }
   15205                 pw.println();
   15206                 if (dumpAll) {
   15207                     pw.println("-------------------------------------------------------------------------------");
   15208                 }
   15209                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   15210             }
   15211 
   15212         } else {
   15213             synchronized (this) {
   15214                 mConstants.dump(pw);
   15215                 pw.println();
   15216                 if (dumpAll) {
   15217                     pw.println("-------------------------------------------------------------------------------");
   15218                 }
   15219                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   15220                 pw.println();
   15221                 if (dumpAll) {
   15222                     pw.println("-------------------------------------------------------------------------------");
   15223                 }
   15224                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   15225                 pw.println();
   15226                 if (dumpAll) {
   15227                     pw.println("-------------------------------------------------------------------------------");
   15228                 }
   15229                 if (dumpAll || dumpPackage != null) {
   15230                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   15231                     pw.println();
   15232                     if (dumpAll) {
   15233                         pw.println("-------------------------------------------------------------------------------");
   15234                     }
   15235                 }
   15236                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   15237                 pw.println();
   15238                 if (dumpAll) {
   15239                     pw.println("-------------------------------------------------------------------------------");
   15240                 }
   15241                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   15242                 pw.println();
   15243                 if (dumpAll) {
   15244                     pw.println("-------------------------------------------------------------------------------");
   15245                 }
   15246                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
   15247                         .dumpLocked();
   15248                 pw.println();
   15249                 if (dumpAll) {
   15250                     pw.println("-------------------------------------------------------------------------------");
   15251                 }
   15252                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   15253                 pw.println();
   15254                 if (dumpAll) {
   15255                     pw.println("-------------------------------------------------------------------------------");
   15256                 }
   15257                 dumpLastANRLocked(pw);
   15258                 pw.println();
   15259                 if (dumpAll) {
   15260                     pw.println("-------------------------------------------------------------------------------");
   15261                 }
   15262                 dumpActivityStarterLocked(pw);
   15263                 pw.println();
   15264                 if (dumpAll) {
   15265                     pw.println("-------------------------------------------------------------------------------");
   15266                 }
   15267                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   15268                 if (mAssociations.size() > 0) {
   15269                     pw.println();
   15270                     if (dumpAll) {
   15271                         pw.println("-------------------------------------------------------------------------------");
   15272                     }
   15273                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   15274                 }
   15275                 pw.println();
   15276                 if (dumpAll) {
   15277                     pw.println("-------------------------------------------------------------------------------");
   15278                 }
   15279                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   15280             }
   15281         }
   15282         Binder.restoreCallingIdentity(origId);
   15283     }
   15284 
   15285     private void dumpLastANRLocked(PrintWriter pw) {
   15286         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity lastanr)");
   15287         if (mLastANRState == null) {
   15288             pw.println("  <no ANR has occurred since boot>");
   15289         } else {
   15290             pw.println(mLastANRState);
   15291         }
   15292     }
   15293 
   15294     private void dumpActivityStarterLocked(PrintWriter pw) {
   15295         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity starter)");
   15296         mActivityStarter.dump(pw, "");
   15297     }
   15298 
   15299     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15300             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   15301         dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
   15302                 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
   15303     }
   15304 
   15305     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15306             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
   15307         pw.println(header);
   15308 
   15309         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
   15310                 dumpPackage);
   15311         boolean needSep = printedAnything;
   15312 
   15313         boolean printed = ActivityStackSupervisor.printThisActivity(pw,
   15314                 mStackSupervisor.getResumedActivityLocked(),
   15315                 dumpPackage, needSep, "  ResumedActivity: ");
   15316         if (printed) {
   15317             printedAnything = true;
   15318             needSep = false;
   15319         }
   15320 
   15321         if (dumpPackage == null) {
   15322             if (needSep) {
   15323                 pw.println();
   15324             }
   15325             printedAnything = true;
   15326             mStackSupervisor.dump(pw, "  ");
   15327         }
   15328 
   15329         if (!printedAnything) {
   15330             pw.println("  (nothing)");
   15331         }
   15332     }
   15333 
   15334     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15335             int opti, boolean dumpAll, String dumpPackage) {
   15336         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
   15337 
   15338         boolean printedAnything = false;
   15339 
   15340         if (mRecentTasks != null && mRecentTasks.size() > 0) {
   15341             boolean printedHeader = false;
   15342 
   15343             final int N = mRecentTasks.size();
   15344             for (int i=0; i<N; i++) {
   15345                 TaskRecord tr = mRecentTasks.get(i);
   15346                 if (dumpPackage != null) {
   15347                     if (tr.realActivity == null ||
   15348                             !dumpPackage.equals(tr.realActivity.getPackageName())) {
   15349                         continue;
   15350                     }
   15351                 }
   15352                 if (!printedHeader) {
   15353                     pw.println("  Recent tasks:");
   15354                     printedHeader = true;
   15355                     printedAnything = true;
   15356                 }
   15357                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
   15358                         pw.println(tr);
   15359                 if (dumpAll) {
   15360                     mRecentTasks.get(i).dump(pw, "    ");
   15361                 }
   15362             }
   15363         }
   15364 
   15365         if (!printedAnything) {
   15366             pw.println("  (nothing)");
   15367         }
   15368     }
   15369 
   15370     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15371             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   15372         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
   15373 
   15374         int dumpUid = 0;
   15375         if (dumpPackage != null) {
   15376             IPackageManager pm = AppGlobals.getPackageManager();
   15377             try {
   15378                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
   15379             } catch (RemoteException e) {
   15380             }
   15381         }
   15382 
   15383         boolean printedAnything = false;
   15384 
   15385         final long now = SystemClock.uptimeMillis();
   15386 
   15387         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
   15388             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
   15389                     = mAssociations.valueAt(i1);
   15390             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
   15391                 SparseArray<ArrayMap<String, Association>> sourceUids
   15392                         = targetComponents.valueAt(i2);
   15393                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
   15394                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
   15395                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
   15396                         Association ass = sourceProcesses.valueAt(i4);
   15397                         if (dumpPackage != null) {
   15398                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
   15399                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
   15400                                 continue;
   15401                             }
   15402                         }
   15403                         printedAnything = true;
   15404                         pw.print("  ");
   15405                         pw.print(ass.mTargetProcess);
   15406                         pw.print("/");
   15407                         UserHandle.formatUid(pw, ass.mTargetUid);
   15408                         pw.print(" <- ");
   15409                         pw.print(ass.mSourceProcess);
   15410                         pw.print("/");
   15411                         UserHandle.formatUid(pw, ass.mSourceUid);
   15412                         pw.println();
   15413                         pw.print("    via ");
   15414                         pw.print(ass.mTargetComponent.flattenToShortString());
   15415                         pw.println();
   15416                         pw.print("    ");
   15417                         long dur = ass.mTime;
   15418                         if (ass.mNesting > 0) {
   15419                             dur += now - ass.mStartTime;
   15420                         }
   15421                         TimeUtils.formatDuration(dur, pw);
   15422                         pw.print(" (");
   15423                         pw.print(ass.mCount);
   15424                         pw.print(" times)");
   15425                         pw.print("  ");
   15426                         for (int i=0; i<ass.mStateTimes.length; i++) {
   15427                             long amt = ass.mStateTimes[i];
   15428                             if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
   15429                                 amt += now - ass.mLastStateUptime;
   15430                             }
   15431                             if (amt != 0) {
   15432                                 pw.print(" ");
   15433                                 pw.print(ProcessList.makeProcStateString(
   15434                                             i + ActivityManager.MIN_PROCESS_STATE));
   15435                                 pw.print("=");
   15436                                 TimeUtils.formatDuration(amt, pw);
   15437                                 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
   15438                                     pw.print("*");
   15439                                 }
   15440                             }
   15441                         }
   15442                         pw.println();
   15443                         if (ass.mNesting > 0) {
   15444                             pw.print("    Currently active: ");
   15445                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
   15446                             pw.println();
   15447                         }
   15448                     }
   15449                 }
   15450             }
   15451 
   15452         }
   15453 
   15454         if (!printedAnything) {
   15455             pw.println("  (nothing)");
   15456         }
   15457     }
   15458 
   15459     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
   15460             String header, boolean needSep) {
   15461         boolean printed = false;
   15462         int whichAppId = -1;
   15463         if (dumpPackage != null) {
   15464             try {
   15465                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
   15466                         dumpPackage, 0);
   15467                 whichAppId = UserHandle.getAppId(info.uid);
   15468             } catch (NameNotFoundException e) {
   15469                 e.printStackTrace();
   15470             }
   15471         }
   15472         for (int i=0; i<uids.size(); i++) {
   15473             UidRecord uidRec = uids.valueAt(i);
   15474             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
   15475                 continue;
   15476             }
   15477             if (!printed) {
   15478                 printed = true;
   15479                 if (needSep) {
   15480                     pw.println();
   15481                 }
   15482                 pw.print("  ");
   15483                 pw.println(header);
   15484                 needSep = true;
   15485             }
   15486             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
   15487             pw.print(": "); pw.println(uidRec);
   15488         }
   15489         return printed;
   15490     }
   15491 
   15492     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15493             int opti, boolean dumpAll, String dumpPackage) {
   15494         boolean needSep = false;
   15495         boolean printedAnything = false;
   15496         int numPers = 0;
   15497 
   15498         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
   15499 
   15500         if (dumpAll) {
   15501             final int NP = mProcessNames.getMap().size();
   15502             for (int ip=0; ip<NP; ip++) {
   15503                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
   15504                 final int NA = procs.size();
   15505                 for (int ia=0; ia<NA; ia++) {
   15506                     ProcessRecord r = procs.valueAt(ia);
   15507                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   15508                         continue;
   15509                     }
   15510                     if (!needSep) {
   15511                         pw.println("  All known processes:");
   15512                         needSep = true;
   15513                         printedAnything = true;
   15514                     }
   15515                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
   15516                         pw.print(" UID "); pw.print(procs.keyAt(ia));
   15517                         pw.print(" "); pw.println(r);
   15518                     r.dump(pw, "    ");
   15519                     if (r.persistent) {
   15520                         numPers++;
   15521                     }
   15522                 }
   15523             }
   15524         }
   15525 
   15526         if (mIsolatedProcesses.size() > 0) {
   15527             boolean printed = false;
   15528             for (int i=0; i<mIsolatedProcesses.size(); i++) {
   15529                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
   15530                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   15531                     continue;
   15532                 }
   15533                 if (!printed) {
   15534                     if (needSep) {
   15535                         pw.println();
   15536                     }
   15537                     pw.println("  Isolated process list (sorted by uid):");
   15538                     printedAnything = true;
   15539                     printed = true;
   15540                     needSep = true;
   15541                 }
   15542                 pw.print("    Isolated #"); pw.print(i); pw.print(": ");
   15543                 pw.println(r);
   15544             }
   15545         }
   15546 
   15547         if (mActiveInstrumentation.size() > 0) {
   15548             boolean printed = false;
   15549             for (int i=0; i<mActiveInstrumentation.size(); i++) {
   15550                 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
   15551                 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
   15552                         && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
   15553                     continue;
   15554                 }
   15555                 if (!printed) {
   15556                     if (needSep) {
   15557                         pw.println();
   15558                     }
   15559                     pw.println("  Active instrumentation:");
   15560                     printedAnything = true;
   15561                     printed = true;
   15562                     needSep = true;
   15563                 }
   15564                 pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
   15565                 pw.println(ai);
   15566                 ai.dump(pw, "      ");
   15567             }
   15568         }
   15569 
   15570         if (mActiveUids.size() > 0) {
   15571             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
   15572                 printedAnything = needSep = true;
   15573             }
   15574         }
   15575         if (dumpAll) {
   15576             if (mValidateUids.size() > 0) {
   15577                 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
   15578                     printedAnything = needSep = true;
   15579                 }
   15580             }
   15581         }
   15582 
   15583         if (mLruProcesses.size() > 0) {
   15584             if (needSep) {
   15585                 pw.println();
   15586             }
   15587             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
   15588                     pw.print(" total, non-act at ");
   15589                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   15590                     pw.print(", non-svc at ");
   15591                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   15592                     pw.println("):");
   15593             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
   15594             needSep = true;
   15595             printedAnything = true;
   15596         }
   15597 
   15598         if (dumpAll || dumpPackage != null) {
   15599             synchronized (mPidsSelfLocked) {
   15600                 boolean printed = false;
   15601                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   15602                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
   15603                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   15604                         continue;
   15605                     }
   15606                     if (!printed) {
   15607                         if (needSep) pw.println();
   15608                         needSep = true;
   15609                         pw.println("  PID mappings:");
   15610                         printed = true;
   15611                         printedAnything = true;
   15612                     }
   15613                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
   15614                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
   15615                 }
   15616             }
   15617         }
   15618 
   15619         if (mImportantProcesses.size() > 0) {
   15620             synchronized (mPidsSelfLocked) {
   15621                 boolean printed = false;
   15622                 for (int i = 0; i< mImportantProcesses.size(); i++) {
   15623                     ProcessRecord r = mPidsSelfLocked.get(
   15624                             mImportantProcesses.valueAt(i).pid);
   15625                     if (dumpPackage != null && (r == null
   15626                             || !r.pkgList.containsKey(dumpPackage))) {
   15627                         continue;
   15628                     }
   15629                     if (!printed) {
   15630                         if (needSep) pw.println();
   15631                         needSep = true;
   15632                         pw.println("  Foreground Processes:");
   15633                         printed = true;
   15634                         printedAnything = true;
   15635                     }
   15636                     pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
   15637                             pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
   15638                 }
   15639             }
   15640         }
   15641 
   15642         if (mPersistentStartingProcesses.size() > 0) {
   15643             if (needSep) pw.println();
   15644             needSep = true;
   15645             printedAnything = true;
   15646             pw.println("  Persisent processes that are starting:");
   15647             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
   15648                     "Starting Norm", "Restarting PERS", dumpPackage);
   15649         }
   15650 
   15651         if (mRemovedProcesses.size() > 0) {
   15652             if (needSep) pw.println();
   15653             needSep = true;
   15654             printedAnything = true;
   15655             pw.println("  Processes that are being removed:");
   15656             dumpProcessList(pw, this, mRemovedProcesses, "    ",
   15657                     "Removed Norm", "Removed PERS", dumpPackage);
   15658         }
   15659 
   15660         if (mProcessesOnHold.size() > 0) {
   15661             if (needSep) pw.println();
   15662             needSep = true;
   15663             printedAnything = true;
   15664             pw.println("  Processes that are on old until the system is ready:");
   15665             dumpProcessList(pw, this, mProcessesOnHold, "    ",
   15666                     "OnHold Norm", "OnHold PERS", dumpPackage);
   15667         }
   15668 
   15669         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
   15670 
   15671         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
   15672         if (needSep) {
   15673             printedAnything = true;
   15674         }
   15675 
   15676         if (dumpPackage == null) {
   15677             pw.println();
   15678             needSep = false;
   15679             mUserController.dump(pw, dumpAll);
   15680         }
   15681         if (mHomeProcess != null && (dumpPackage == null
   15682                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
   15683             if (needSep) {
   15684                 pw.println();
   15685                 needSep = false;
   15686             }
   15687             pw.println("  mHomeProcess: " + mHomeProcess);
   15688         }
   15689         if (mPreviousProcess != null && (dumpPackage == null
   15690                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
   15691             if (needSep) {
   15692                 pw.println();
   15693                 needSep = false;
   15694             }
   15695             pw.println("  mPreviousProcess: " + mPreviousProcess);
   15696         }
   15697         if (dumpAll) {
   15698             StringBuilder sb = new StringBuilder(128);
   15699             sb.append("  mPreviousProcessVisibleTime: ");
   15700             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
   15701             pw.println(sb);
   15702         }
   15703         if (mHeavyWeightProcess != null && (dumpPackage == null
   15704                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
   15705             if (needSep) {
   15706                 pw.println();
   15707                 needSep = false;
   15708             }
   15709             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   15710         }
   15711         if (dumpPackage == null) {
   15712             pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
   15713             mStackSupervisor.dumpDisplayConfigs(pw, "  ");
   15714         }
   15715         if (dumpAll) {
   15716             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
   15717             if (mCompatModePackages.getPackages().size() > 0) {
   15718                 boolean printed = false;
   15719                 for (Map.Entry<String, Integer> entry
   15720                         : mCompatModePackages.getPackages().entrySet()) {
   15721                     String pkg = entry.getKey();
   15722                     int mode = entry.getValue();
   15723                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
   15724                         continue;
   15725                     }
   15726                     if (!printed) {
   15727                         pw.println("  mScreenCompatPackages:");
   15728                         printed = true;
   15729                     }
   15730                     pw.print("    "); pw.print(pkg); pw.print(": ");
   15731                             pw.print(mode); pw.println();
   15732                 }
   15733             }
   15734             final int NI = mUidObservers.getRegisteredCallbackCount();
   15735             boolean printed = false;
   15736             for (int i=0; i<NI; i++) {
   15737                 final UidObserverRegistration reg = (UidObserverRegistration)
   15738                         mUidObservers.getRegisteredCallbackCookie(i);
   15739                 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
   15740                     if (!printed) {
   15741                         pw.println("  mUidObservers:");
   15742                         printed = true;
   15743                     }
   15744                     pw.print("    "); UserHandle.formatUid(pw, reg.uid);
   15745                     pw.print(" "); pw.print(reg.pkg); pw.print(":");
   15746                     if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
   15747                         pw.print(" IDLE");
   15748                     }
   15749                     if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
   15750                         pw.print(" ACT" );
   15751                     }
   15752                     if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
   15753                         pw.print(" GONE");
   15754                     }
   15755                     if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
   15756                         pw.print(" STATE");
   15757                         pw.print(" (cut="); pw.print(reg.cutpoint);
   15758                         pw.print(")");
   15759                     }
   15760                     pw.println();
   15761                     if (reg.lastProcStates != null) {
   15762                         final int NJ = reg.lastProcStates.size();
   15763                         for (int j=0; j<NJ; j++) {
   15764                             pw.print("      Last ");
   15765                             UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
   15766                             pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
   15767                         }
   15768                     }
   15769                 }
   15770             }
   15771             pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
   15772             pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
   15773             if (mPendingTempWhitelist.size() > 0) {
   15774                 pw.println("  mPendingTempWhitelist:");
   15775                 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
   15776                     PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
   15777                     pw.print("    ");
   15778                     UserHandle.formatUid(pw, ptw.targetUid);
   15779                     pw.print(": ");
   15780                     TimeUtils.formatDuration(ptw.duration, pw);
   15781                     pw.print(" ");
   15782                     pw.println(ptw.tag);
   15783                 }
   15784             }
   15785         }
   15786         if (dumpPackage == null) {
   15787             pw.println("  mWakefulness="
   15788                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
   15789             pw.println("  mSleepTokens=" + mSleepTokens);
   15790             pw.println("  mSleeping=" + mSleeping);
   15791             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
   15792             if (mRunningVoice != null) {
   15793                 pw.println("  mRunningVoice=" + mRunningVoice);
   15794                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
   15795             }
   15796         }
   15797         pw.println("  mVrController=" + mVrController);
   15798         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
   15799                 || mOrigWaitForDebugger) {
   15800             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
   15801                     || dumpPackage.equals(mOrigDebugApp)) {
   15802                 if (needSep) {
   15803                     pw.println();
   15804                     needSep = false;
   15805                 }
   15806                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
   15807                         + " mDebugTransient=" + mDebugTransient
   15808                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
   15809             }
   15810         }
   15811         if (mCurAppTimeTracker != null) {
   15812             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
   15813         }
   15814         if (mMemWatchProcesses.getMap().size() > 0) {
   15815             pw.println("  Mem watch processes:");
   15816             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
   15817                     = mMemWatchProcesses.getMap();
   15818             for (int i=0; i<procs.size(); i++) {
   15819                 final String proc = procs.keyAt(i);
   15820                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
   15821                 for (int j=0; j<uids.size(); j++) {
   15822                     if (needSep) {
   15823                         pw.println();
   15824                         needSep = false;
   15825                     }
   15826                     StringBuilder sb = new StringBuilder();
   15827                     sb.append("    ").append(proc).append('/');
   15828                     UserHandle.formatUid(sb, uids.keyAt(j));
   15829                     Pair<Long, String> val = uids.valueAt(j);
   15830                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
   15831                     if (val.second != null) {
   15832                         sb.append(", report to ").append(val.second);
   15833                     }
   15834                     pw.println(sb.toString());
   15835                 }
   15836             }
   15837             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
   15838             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
   15839             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
   15840                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
   15841         }
   15842         if (mTrackAllocationApp != null) {
   15843             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
   15844                 if (needSep) {
   15845                     pw.println();
   15846                     needSep = false;
   15847                 }
   15848                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
   15849             }
   15850         }
   15851         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
   15852                 || mProfileFd != null) {
   15853             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
   15854                 if (needSep) {
   15855                     pw.println();
   15856                     needSep = false;
   15857                 }
   15858                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
   15859                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
   15860                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
   15861                         + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput);
   15862                 pw.println("  mProfileType=" + mProfileType);
   15863             }
   15864         }
   15865         if (mNativeDebuggingApp != null) {
   15866             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
   15867                 if (needSep) {
   15868                     pw.println();
   15869                     needSep = false;
   15870                 }
   15871                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
   15872             }
   15873         }
   15874         if (dumpPackage == null) {
   15875             if (mAlwaysFinishActivities) {
   15876                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
   15877             }
   15878             if (mController != null) {
   15879                 pw.println("  mController=" + mController
   15880                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
   15881             }
   15882             if (dumpAll) {
   15883                 pw.println("  Total persistent processes: " + numPers);
   15884                 pw.println("  mProcessesReady=" + mProcessesReady
   15885                         + " mSystemReady=" + mSystemReady
   15886                         + " mBooted=" + mBooted
   15887                         + " mFactoryTest=" + mFactoryTest);
   15888                 pw.println("  mBooting=" + mBooting
   15889                         + " mCallFinishBooting=" + mCallFinishBooting
   15890                         + " mBootAnimationComplete=" + mBootAnimationComplete);
   15891                 pw.print("  mLastPowerCheckRealtime=");
   15892                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
   15893                         pw.println("");
   15894                 pw.print("  mLastPowerCheckUptime=");
   15895                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
   15896                         pw.println("");
   15897                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
   15898                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
   15899                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
   15900                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
   15901                         + " (" + mLruProcesses.size() + " total)"
   15902                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
   15903                         + " mNumServiceProcs=" + mNumServiceProcs
   15904                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
   15905                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
   15906                         + " mLastMemoryLevel=" + mLastMemoryLevel
   15907                         + " mLastNumProcesses=" + mLastNumProcesses);
   15908                 long now = SystemClock.uptimeMillis();
   15909                 pw.print("  mLastIdleTime=");
   15910                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
   15911                         pw.print(" mLowRamSinceLastIdle=");
   15912                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
   15913                         pw.println();
   15914             }
   15915         }
   15916 
   15917         if (!printedAnything) {
   15918             pw.println("  (nothing)");
   15919         }
   15920     }
   15921 
   15922     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
   15923             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
   15924         if (mProcessesToGc.size() > 0) {
   15925             boolean printed = false;
   15926             long now = SystemClock.uptimeMillis();
   15927             for (int i=0; i<mProcessesToGc.size(); i++) {
   15928                 ProcessRecord proc = mProcessesToGc.get(i);
   15929                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
   15930                     continue;
   15931                 }
   15932                 if (!printed) {
   15933                     if (needSep) pw.println();
   15934                     needSep = true;
   15935                     pw.println("  Processes that are waiting to GC:");
   15936                     printed = true;
   15937                 }
   15938                 pw.print("    Process "); pw.println(proc);
   15939                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
   15940                         pw.print(", last gced=");
   15941                         pw.print(now-proc.lastRequestedGc);
   15942                         pw.print(" ms ago, last lowMem=");
   15943                         pw.print(now-proc.lastLowMemory);
   15944                         pw.println(" ms ago");
   15945 
   15946             }
   15947         }
   15948         return needSep;
   15949     }
   15950 
   15951     void printOomLevel(PrintWriter pw, String name, int adj) {
   15952         pw.print("    ");
   15953         if (adj >= 0) {
   15954             pw.print(' ');
   15955             if (adj < 10) pw.print(' ');
   15956         } else {
   15957             if (adj > -10) pw.print(' ');
   15958         }
   15959         pw.print(adj);
   15960         pw.print(": ");
   15961         pw.print(name);
   15962         pw.print(" (");
   15963         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
   15964         pw.println(")");
   15965     }
   15966 
   15967     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   15968             int opti, boolean dumpAll) {
   15969         boolean needSep = false;
   15970 
   15971         if (mLruProcesses.size() > 0) {
   15972             if (needSep) pw.println();
   15973             needSep = true;
   15974             pw.println("  OOM levels:");
   15975             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
   15976             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
   15977             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
   15978             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
   15979             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
   15980             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
   15981             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
   15982             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
   15983             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
   15984             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
   15985             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
   15986             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
   15987             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
   15988             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
   15989 
   15990             if (needSep) pw.println();
   15991             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
   15992                     pw.print(" total, non-act at ");
   15993                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   15994                     pw.print(", non-svc at ");
   15995                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   15996                     pw.println("):");
   15997             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
   15998             needSep = true;
   15999         }
   16000 
   16001         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
   16002 
   16003         pw.println();
   16004         pw.println("  mHomeProcess: " + mHomeProcess);
   16005         pw.println("  mPreviousProcess: " + mPreviousProcess);
   16006         if (mHeavyWeightProcess != null) {
   16007             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   16008         }
   16009 
   16010         return true;
   16011     }
   16012 
   16013     /**
   16014      * There are three ways to call this:
   16015      *  - no provider specified: dump all the providers
   16016      *  - a flattened component name that matched an existing provider was specified as the
   16017      *    first arg: dump that one provider
   16018      *  - the first arg isn't the flattened component name of an existing provider:
   16019      *    dump all providers whose component contains the first arg as a substring
   16020      */
   16021     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   16022             int opti, boolean dumpAll) {
   16023         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
   16024     }
   16025 
   16026     static class ItemMatcher {
   16027         ArrayList<ComponentName> components;
   16028         ArrayList<String> strings;
   16029         ArrayList<Integer> objects;
   16030         boolean all;
   16031 
   16032         ItemMatcher() {
   16033             all = true;
   16034         }
   16035 
   16036         void build(String name) {
   16037             ComponentName componentName = ComponentName.unflattenFromString(name);
   16038             if (componentName != null) {
   16039                 if (components == null) {
   16040                     components = new ArrayList<ComponentName>();
   16041                 }
   16042                 components.add(componentName);
   16043                 all = false;
   16044             } else {
   16045                 int objectId = 0;
   16046                 // Not a '/' separated full component name; maybe an object ID?
   16047                 try {
   16048                     objectId = Integer.parseInt(name, 16);
   16049                     if (objects == null) {
   16050                         objects = new ArrayList<Integer>();
   16051                     }
   16052                     objects.add(objectId);
   16053                     all = false;
   16054                 } catch (RuntimeException e) {
   16055                     // Not an integer; just do string match.
   16056                     if (strings == null) {
   16057                         strings = new ArrayList<String>();
   16058                     }
   16059                     strings.add(name);
   16060                     all = false;
   16061                 }
   16062             }
   16063         }
   16064 
   16065         int build(String[] args, int opti) {
   16066             for (; opti<args.length; opti++) {
   16067                 String name = args[opti];
   16068                 if ("--".equals(name)) {
   16069                     return opti+1;
   16070                 }
   16071                 build(name);
   16072             }
   16073             return opti;
   16074         }
   16075 
   16076         boolean match(Object object, ComponentName comp) {
   16077             if (all) {
   16078                 return true;
   16079             }
   16080             if (components != null) {
   16081                 for (int i=0; i<components.size(); i++) {
   16082                     if (components.get(i).equals(comp)) {
   16083                         return true;
   16084                     }
   16085                 }
   16086             }
   16087             if (objects != null) {
   16088                 for (int i=0; i<objects.size(); i++) {
   16089                     if (System.identityHashCode(object) == objects.get(i)) {
   16090                         return true;
   16091                     }
   16092                 }
   16093             }
   16094             if (strings != null) {
   16095                 String flat = comp.flattenToString();
   16096                 for (int i=0; i<strings.size(); i++) {
   16097                     if (flat.contains(strings.get(i))) {
   16098                         return true;
   16099                     }
   16100                 }
   16101             }
   16102             return false;
   16103         }
   16104     }
   16105 
   16106     /**
   16107      * There are three things that cmd can be:
   16108      *  - a flattened component name that matches an existing activity
   16109      *  - the cmd arg isn't the flattened component name of an existing activity:
   16110      *    dump all activity whose component contains the cmd as a substring
   16111      *  - A hex number of the ActivityRecord object instance.
   16112      *
   16113      *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
   16114      *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
   16115      */
   16116     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   16117             int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
   16118         ArrayList<ActivityRecord> activities;
   16119 
   16120         synchronized (this) {
   16121             activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
   16122                     dumpFocusedStackOnly);
   16123         }
   16124 
   16125         if (activities.size() <= 0) {
   16126             return false;
   16127         }
   16128 
   16129         String[] newArgs = new String[args.length - opti];
   16130         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   16131 
   16132         TaskRecord lastTask = null;
   16133         boolean needSep = false;
   16134         for (int i=activities.size()-1; i>=0; i--) {
   16135             ActivityRecord r = activities.get(i);
   16136             if (needSep) {
   16137                 pw.println();
   16138             }
   16139             needSep = true;
   16140             synchronized (this) {
   16141                 final TaskRecord task = r.getTask();
   16142                 if (lastTask != task) {
   16143                     lastTask = task;
   16144                     pw.print("TASK "); pw.print(lastTask.affinity);
   16145                             pw.print(" id="); pw.print(lastTask.taskId);
   16146                             pw.print(" userId="); pw.println(lastTask.userId);
   16147                     if (dumpAll) {
   16148                         lastTask.dump(pw, "  ");
   16149                     }
   16150                 }
   16151             }
   16152             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
   16153         }
   16154         return true;
   16155     }
   16156 
   16157     /**
   16158      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
   16159      * there is a thread associated with the activity.
   16160      */
   16161     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
   16162             final ActivityRecord r, String[] args, boolean dumpAll) {
   16163         String innerPrefix = prefix + "  ";
   16164         synchronized (this) {
   16165             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
   16166                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
   16167                     pw.print(" pid=");
   16168                     if (r.app != null) pw.println(r.app.pid);
   16169                     else pw.println("(not running)");
   16170             if (dumpAll) {
   16171                 r.dump(pw, innerPrefix);
   16172             }
   16173         }
   16174         if (r.app != null && r.app.thread != null) {
   16175             // flush anything that is already in the PrintWriter since the thread is going
   16176             // to write to the file descriptor directly
   16177             pw.flush();
   16178             try {
   16179                 TransferPipe tp = new TransferPipe();
   16180                 try {
   16181                     r.app.thread.dumpActivity(tp.getWriteFd(),
   16182                             r.appToken, innerPrefix, args);
   16183                     tp.go(fd);
   16184                 } finally {
   16185                     tp.kill();
   16186                 }
   16187             } catch (IOException e) {
   16188                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   16189             } catch (RemoteException e) {
   16190                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   16191             }
   16192         }
   16193     }
   16194 
   16195     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   16196             int opti, boolean dumpAll, String dumpPackage) {
   16197         boolean needSep = false;
   16198         boolean onlyHistory = false;
   16199         boolean printedAnything = false;
   16200 
   16201         if ("history".equals(dumpPackage)) {
   16202             if (opti < args.length && "-s".equals(args[opti])) {
   16203                 dumpAll = false;
   16204             }
   16205             onlyHistory = true;
   16206             dumpPackage = null;
   16207         }
   16208 
   16209         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
   16210         if (!onlyHistory && dumpAll) {
   16211             if (mRegisteredReceivers.size() > 0) {
   16212                 boolean printed = false;
   16213                 Iterator it = mRegisteredReceivers.values().iterator();
   16214                 while (it.hasNext()) {
   16215                     ReceiverList r = (ReceiverList)it.next();
   16216                     if (dumpPackage != null && (r.app == null ||
   16217                             !dumpPackage.equals(r.app.info.packageName))) {
   16218                         continue;
   16219                     }
   16220                     if (!printed) {
   16221                         pw.println("  Registered Receivers:");
   16222                         needSep = true;
   16223                         printed = true;
   16224                         printedAnything = true;
   16225                     }
   16226                     pw.print("  * "); pw.println(r);
   16227                     r.dump(pw, "    ");
   16228                 }
   16229             }
   16230 
   16231             if (mReceiverResolver.dump(pw, needSep ?
   16232                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
   16233                     "    ", dumpPackage, false, false)) {
   16234                 needSep = true;
   16235                 printedAnything = true;
   16236             }
   16237         }
   16238 
   16239         for (BroadcastQueue q : mBroadcastQueues) {
   16240             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
   16241             printedAnything |= needSep;
   16242         }
   16243 
   16244         needSep = true;
   16245 
   16246         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
   16247             for (int user=0; user<mStickyBroadcasts.size(); user++) {
   16248                 if (needSep) {
   16249                     pw.println();
   16250                 }
   16251                 needSep = true;
   16252                 printedAnything = true;
   16253                 pw.print("  Sticky broadcasts for user ");
   16254                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
   16255                 StringBuilder sb = new StringBuilder(128);
   16256                 for (Map.Entry<String, ArrayList<Intent>> ent
   16257                         : mStickyBroadcasts.valueAt(user).entrySet()) {
   16258                     pw.print("  * Sticky action "); pw.print(ent.getKey());
   16259                     if (dumpAll) {
   16260                         pw.println(":");
   16261                         ArrayList<Intent> intents = ent.getValue();
   16262                         final int N = intents.size();
   16263                         for (int i=0; i<N; i++) {
   16264                             sb.setLength(0);
   16265                             sb.append("    Intent: ");
   16266                             intents.get(i).toShortString(sb, false, true, false, false);
   16267                             pw.println(sb.toString());
   16268                             Bundle bundle = intents.get(i).getExtras();
   16269                             if (bundle != null) {
   16270                                 pw.print("      ");
   16271                                 pw.println(bundle.toString());
   16272                             }
   16273                         }
   16274                     } else {
   16275                         pw.println("");
   16276                     }
   16277                 }
   16278             }
   16279         }
   16280 
   16281         if (!onlyHistory && dumpAll) {
   16282             pw.println();
   16283             for (BroadcastQueue queue : mBroadcastQueues) {
   16284                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
   16285                         + queue.mBroadcastsScheduled);
   16286             }
   16287             pw.println("  mHandler:");
   16288             mHandler.dump(new PrintWriterPrinter(pw), "    ");
   16289             needSep = true;
   16290             printedAnything = true;
   16291         }
   16292 
   16293         if (!printedAnything) {
   16294             pw.println("  (nothing)");
   16295         }
   16296     }
   16297 
   16298     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   16299             int opti, boolean dumpAll, String dumpPackage) {
   16300         if (mCurBroadcastStats == null) {
   16301             return;
   16302         }
   16303 
   16304         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
   16305         final long now = SystemClock.elapsedRealtime();
   16306         if (mLastBroadcastStats != null) {
   16307             pw.print("  Last stats (from ");
   16308             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
   16309             pw.print(" to ");
   16310             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
   16311             pw.print(", ");
   16312             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
   16313                     - mLastBroadcastStats.mStartUptime, pw);
   16314             pw.println(" uptime):");
   16315             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
   16316                 pw.println("    (nothing)");
   16317             }
   16318             pw.println();
   16319         }
   16320         pw.print("  Current stats (from ");
   16321         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
   16322         pw.print(" to now, ");
   16323         TimeUtils.formatDuration(SystemClock.uptimeMillis()
   16324                 - mCurBroadcastStats.mStartUptime, pw);
   16325         pw.println(" uptime):");
   16326         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
   16327             pw.println("    (nothing)");
   16328         }
   16329     }
   16330 
   16331     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   16332             int opti, boolean fullCheckin, String dumpPackage) {
   16333         if (mCurBroadcastStats == null) {
   16334             return;
   16335         }
   16336 
   16337         if (mLastBroadcastStats != null) {
   16338             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
   16339             if (fullCheckin) {
   16340                 mLastBroadcastStats = null;
   16341                 return;
   16342             }
   16343         }
   16344         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
   16345         if (fullCheckin) {
   16346             mCurBroadcastStats = null;
   16347         }
   16348     }
   16349 
   16350     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   16351             int opti, boolean dumpAll, String dumpPackage) {
   16352         boolean needSep;
   16353         boolean printedAnything = false;
   16354 
   16355         ItemMatcher matcher = new ItemMatcher();
   16356         matcher.build(args, opti);
   16357 
   16358         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
   16359 
   16360         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
   16361         printedAnything |= needSep;
   16362 
   16363         if (mLaunchingProviders.size() > 0) {
   16364             boolean printed = false;
   16365             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
   16366                 ContentProviderRecord r = mLaunchingProviders.get(i);
   16367                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
   16368                     continue;
   16369                 }
   16370                 if (!printed) {
   16371                     if (needSep) pw.println();
   16372                     needSep = true;
   16373                     pw.println("  Launching content providers:");
   16374                     printed = true;
   16375                     printedAnything = true;
   16376                 }
   16377                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
   16378                         pw.println(r);
   16379             }
   16380         }
   16381 
   16382         if (!printedAnything) {
   16383             pw.println("  (nothing)");
   16384         }
   16385     }
   16386 
   16387     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   16388             int opti, boolean dumpAll, String dumpPackage) {
   16389         boolean needSep = false;
   16390         boolean printedAnything = false;
   16391 
   16392         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
   16393 
   16394         if (mGrantedUriPermissions.size() > 0) {
   16395             boolean printed = false;
   16396             int dumpUid = -2;
   16397             if (dumpPackage != null) {
   16398                 try {
   16399                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
   16400                             MATCH_ANY_USER, 0);
   16401                 } catch (NameNotFoundException e) {
   16402                     dumpUid = -1;
   16403                 }
   16404             }
   16405             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
   16406                 int uid = mGrantedUriPermissions.keyAt(i);
   16407                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
   16408                     continue;
   16409                 }
   16410                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   16411                 if (!printed) {
   16412                     if (needSep) pw.println();
   16413                     needSep = true;
   16414                     pw.println("  Granted Uri Permissions:");
   16415                     printed = true;
   16416                     printedAnything = true;
   16417                 }
   16418                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
   16419                 for (UriPermission perm : perms.values()) {
   16420                     pw.print("    "); pw.println(perm);
   16421                     if (dumpAll) {
   16422                         perm.dump(pw, "      ");
   16423                     }
   16424                 }
   16425             }
   16426         }
   16427 
   16428         if (!printedAnything) {
   16429             pw.println("  (nothing)");
   16430         }
   16431     }
   16432 
   16433     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   16434             int opti, boolean dumpAll, String dumpPackage) {
   16435         boolean printed = false;
   16436 
   16437         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
   16438 
   16439         if (mIntentSenderRecords.size() > 0) {
   16440             // Organize these by package name, so they are easier to read.
   16441             final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
   16442             final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
   16443             final Iterator<WeakReference<PendingIntentRecord>> it
   16444                     = mIntentSenderRecords.values().iterator();
   16445             while (it.hasNext()) {
   16446                 WeakReference<PendingIntentRecord> ref = it.next();
   16447                 PendingIntentRecord rec = ref != null ? ref.get() : null;
   16448                 if (rec == null) {
   16449                     weakRefs.add(ref);
   16450                     continue;
   16451                 }
   16452                 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
   16453                     continue;
   16454                 }
   16455                 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
   16456                 if (list == null) {
   16457                     list = new ArrayList<>();
   16458                     byPackage.put(rec.key.packageName, list);
   16459                 }
   16460                 list.add(rec);
   16461             }
   16462             for (int i = 0; i < byPackage.size(); i++) {
   16463                 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
   16464                 printed = true;
   16465                 pw.print("  * "); pw.print(byPackage.keyAt(i));
   16466                 pw.print(": "); pw.print(intents.size()); pw.println(" items");
   16467                 for (int j = 0; j < intents.size(); j++) {
   16468                     pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
   16469                     if (dumpAll) {
   16470                         intents.get(j).dump(pw, "      ");
   16471                     }
   16472                 }
   16473             }
   16474             if (weakRefs.size() > 0) {
   16475                 printed = true;
   16476                 pw.println("  * WEAK REFS:");
   16477                 for (int i = 0; i < weakRefs.size(); i++) {
   16478                     pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
   16479                 }
   16480             }
   16481         }
   16482 
   16483         if (!printed) {
   16484             pw.println("  (nothing)");
   16485         }
   16486     }
   16487 
   16488     private static final int dumpProcessList(PrintWriter pw,
   16489             ActivityManagerService service, List list,
   16490             String prefix, String normalLabel, String persistentLabel,
   16491             String dumpPackage) {
   16492         int numPers = 0;
   16493         final int N = list.size()-1;
   16494         for (int i=N; i>=0; i--) {
   16495             ProcessRecord r = (ProcessRecord)list.get(i);
   16496             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   16497                 continue;
   16498             }
   16499             pw.println(String.format("%s%s #%2d: %s",
   16500                     prefix, (r.persistent ? persistentLabel : normalLabel),
   16501                     i, r.toString()));
   16502             if (r.persistent) {
   16503                 numPers++;
   16504             }
   16505         }
   16506         return numPers;
   16507     }
   16508 
   16509     private static final boolean dumpProcessOomList(PrintWriter pw,
   16510             ActivityManagerService service, List<ProcessRecord> origList,
   16511             String prefix, String normalLabel, String persistentLabel,
   16512             boolean inclDetails, String dumpPackage) {
   16513 
   16514         ArrayList<Pair<ProcessRecord, Integer>> list
   16515                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
   16516         for (int i=0; i<origList.size(); i++) {
   16517             ProcessRecord r = origList.get(i);
   16518             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   16519                 continue;
   16520             }
   16521             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
   16522         }
   16523 
   16524         if (list.size() <= 0) {
   16525             return false;
   16526         }
   16527 
   16528         Comparator<Pair<ProcessRecord, Integer>> comparator
   16529                 = new Comparator<Pair<ProcessRecord, Integer>>() {
   16530             @Override
   16531             public int compare(Pair<ProcessRecord, Integer> object1,
   16532                     Pair<ProcessRecord, Integer> object2) {
   16533                 if (object1.first.setAdj != object2.first.setAdj) {
   16534                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
   16535                 }
   16536                 if (object1.first.setProcState != object2.first.setProcState) {
   16537                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
   16538                 }
   16539                 if (object1.second.intValue() != object2.second.intValue()) {
   16540                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
   16541                 }
   16542                 return 0;
   16543             }
   16544         };
   16545 
   16546         Collections.sort(list, comparator);
   16547 
   16548         final long curRealtime = SystemClock.elapsedRealtime();
   16549         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
   16550         final long curUptime = SystemClock.uptimeMillis();
   16551         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
   16552 
   16553         for (int i=list.size()-1; i>=0; i--) {
   16554             ProcessRecord r = list.get(i).first;
   16555             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
   16556             char schedGroup;
   16557             switch (r.setSchedGroup) {
   16558                 case ProcessList.SCHED_GROUP_BACKGROUND:
   16559                     schedGroup = 'B';
   16560                     break;
   16561                 case ProcessList.SCHED_GROUP_DEFAULT:
   16562                     schedGroup = 'F';
   16563                     break;
   16564                 case ProcessList.SCHED_GROUP_TOP_APP:
   16565                     schedGroup = 'T';
   16566                     break;
   16567                 default:
   16568                     schedGroup = '?';
   16569                     break;
   16570             }
   16571             char foreground;
   16572             if (r.foregroundActivities) {
   16573                 foreground = 'A';
   16574             } else if (r.foregroundServices) {
   16575                 foreground = 'S';
   16576             } else {
   16577                 foreground = ' ';
   16578             }
   16579             String procState = ProcessList.makeProcStateString(r.curProcState);
   16580             pw.print(prefix);
   16581             pw.print(r.persistent ? persistentLabel : normalLabel);
   16582             pw.print(" #");
   16583             int num = (origList.size()-1)-list.get(i).second;
   16584             if (num < 10) pw.print(' ');
   16585             pw.print(num);
   16586             pw.print(": ");
   16587             pw.print(oomAdj);
   16588             pw.print(' ');
   16589             pw.print(schedGroup);
   16590             pw.print('/');
   16591             pw.print(foreground);
   16592             pw.print('/');
   16593             pw.print(procState);
   16594             pw.print(" trm:");
   16595             if (r.trimMemoryLevel < 10) pw.print(' ');
   16596             pw.print(r.trimMemoryLevel);
   16597             pw.print(' ');
   16598             pw.print(r.toShortString());
   16599             pw.print(" (");
   16600             pw.print(r.adjType);
   16601             pw.println(')');
   16602             if (r.adjSource != null || r.adjTarget != null) {
   16603                 pw.print(prefix);
   16604                 pw.print("    ");
   16605                 if (r.adjTarget instanceof ComponentName) {
   16606                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
   16607                 } else if (r.adjTarget != null) {
   16608                     pw.print(r.adjTarget.toString());
   16609                 } else {
   16610                     pw.print("{null}");
   16611                 }
   16612                 pw.print("<=");
   16613                 if (r.adjSource instanceof ProcessRecord) {
   16614                     pw.print("Proc{");
   16615                     pw.print(((ProcessRecord)r.adjSource).toShortString());
   16616                     pw.println("}");
   16617                 } else if (r.adjSource != null) {
   16618                     pw.println(r.adjSource.toString());
   16619                 } else {
   16620                     pw.println("{null}");
   16621                 }
   16622             }
   16623             if (inclDetails) {
   16624                 pw.print(prefix);
   16625                 pw.print("    ");
   16626                 pw.print("oom: max="); pw.print(r.maxAdj);
   16627                 pw.print(" curRaw="); pw.print(r.curRawAdj);
   16628                 pw.print(" setRaw="); pw.print(r.setRawAdj);
   16629                 pw.print(" cur="); pw.print(r.curAdj);
   16630                 pw.print(" set="); pw.println(r.setAdj);
   16631                 pw.print(prefix);
   16632                 pw.print("    ");
   16633                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
   16634                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
   16635                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
   16636                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
   16637                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
   16638                 pw.println();
   16639                 pw.print(prefix);
   16640                 pw.print("    ");
   16641                 pw.print("cached="); pw.print(r.cached);
   16642                 pw.print(" empty="); pw.print(r.empty);
   16643                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
   16644 
   16645                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
   16646                     if (r.lastWakeTime != 0) {
   16647                         long wtime;
   16648                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
   16649                         synchronized (stats) {
   16650                             wtime = stats.getProcessWakeTime(r.info.uid,
   16651                                     r.pid, curRealtime);
   16652                         }
   16653                         long timeUsed = wtime - r.lastWakeTime;
   16654                         pw.print(prefix);
   16655                         pw.print("    ");
   16656                         pw.print("keep awake over ");
   16657                         TimeUtils.formatDuration(realtimeSince, pw);
   16658                         pw.print(" used ");
   16659                         TimeUtils.formatDuration(timeUsed, pw);
   16660                         pw.print(" (");
   16661                         pw.print((timeUsed*100)/realtimeSince);
   16662                         pw.println("%)");
   16663                     }
   16664                     if (r.lastCpuTime != 0) {
   16665                         long timeUsed = r.curCpuTime - r.lastCpuTime;
   16666                         pw.print(prefix);
   16667                         pw.print("    ");
   16668                         pw.print("run cpu over ");
   16669                         TimeUtils.formatDuration(uptimeSince, pw);
   16670                         pw.print(" used ");
   16671                         TimeUtils.formatDuration(timeUsed, pw);
   16672                         pw.print(" (");
   16673                         pw.print((timeUsed*100)/uptimeSince);
   16674                         pw.println("%)");
   16675                     }
   16676                 }
   16677             }
   16678         }
   16679         return true;
   16680     }
   16681 
   16682     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
   16683             String[] args) {
   16684         ArrayList<ProcessRecord> procs;
   16685         synchronized (this) {
   16686             if (args != null && args.length > start
   16687                     && args[start].charAt(0) != '-') {
   16688                 procs = new ArrayList<ProcessRecord>();
   16689                 int pid = -1;
   16690                 try {
   16691                     pid = Integer.parseInt(args[start]);
   16692                 } catch (NumberFormatException e) {
   16693                 }
   16694                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   16695                     ProcessRecord proc = mLruProcesses.get(i);
   16696                     if (proc.pid == pid) {
   16697                         procs.add(proc);
   16698                     } else if (allPkgs && proc.pkgList != null
   16699                             && proc.pkgList.containsKey(args[start])) {
   16700                         procs.add(proc);
   16701                     } else if (proc.processName.equals(args[start])) {
   16702                         procs.add(proc);
   16703                     }
   16704                 }
   16705                 if (procs.size() <= 0) {
   16706                     return null;
   16707                 }
   16708             } else {
   16709                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
   16710             }
   16711         }
   16712         return procs;
   16713     }
   16714 
   16715     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
   16716             PrintWriter pw, String[] args) {
   16717         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
   16718         if (procs == null) {
   16719             pw.println("No process found for: " + args[0]);
   16720             return;
   16721         }
   16722 
   16723         long uptime = SystemClock.uptimeMillis();
   16724         long realtime = SystemClock.elapsedRealtime();
   16725         pw.println("Applications Graphics Acceleration Info:");
   16726         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   16727 
   16728         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   16729             ProcessRecord r = procs.get(i);
   16730             if (r.thread != null) {
   16731                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
   16732                 pw.flush();
   16733                 try {
   16734                     TransferPipe tp = new TransferPipe();
   16735                     try {
   16736                         r.thread.dumpGfxInfo(tp.getWriteFd(), args);
   16737                         tp.go(fd);
   16738                     } finally {
   16739                         tp.kill();
   16740                     }
   16741                 } catch (IOException e) {
   16742                     pw.println("Failure while dumping the app: " + r);
   16743                     pw.flush();
   16744                 } catch (RemoteException e) {
   16745                     pw.println("Got a RemoteException while dumping the app " + r);
   16746                     pw.flush();
   16747                 }
   16748             }
   16749         }
   16750     }
   16751 
   16752     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
   16753         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
   16754         if (procs == null) {
   16755             pw.println("No process found for: " + args[0]);
   16756             return;
   16757         }
   16758 
   16759         pw.println("Applications Database Info:");
   16760 
   16761         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   16762             ProcessRecord r = procs.get(i);
   16763             if (r.thread != null) {
   16764                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
   16765                 pw.flush();
   16766                 try {
   16767                     TransferPipe tp = new TransferPipe();
   16768                     try {
   16769                         r.thread.dumpDbInfo(tp.getWriteFd(), args);
   16770                         tp.go(fd);
   16771                     } finally {
   16772                         tp.kill();
   16773                     }
   16774                 } catch (IOException e) {
   16775                     pw.println("Failure while dumping the app: " + r);
   16776                     pw.flush();
   16777                 } catch (RemoteException e) {
   16778                     pw.println("Got a RemoteException while dumping the app " + r);
   16779                     pw.flush();
   16780                 }
   16781             }
   16782         }
   16783     }
   16784 
   16785     final static class MemItem {
   16786         final boolean isProc;
   16787         final String label;
   16788         final String shortLabel;
   16789         final long pss;
   16790         final long swapPss;
   16791         final int id;
   16792         final boolean hasActivities;
   16793         ArrayList<MemItem> subitems;
   16794 
   16795         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
   16796                 boolean _hasActivities) {
   16797             isProc = true;
   16798             label = _label;
   16799             shortLabel = _shortLabel;
   16800             pss = _pss;
   16801             swapPss = _swapPss;
   16802             id = _id;
   16803             hasActivities = _hasActivities;
   16804         }
   16805 
   16806         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
   16807             isProc = false;
   16808             label = _label;
   16809             shortLabel = _shortLabel;
   16810             pss = _pss;
   16811             swapPss = _swapPss;
   16812             id = _id;
   16813             hasActivities = false;
   16814         }
   16815     }
   16816 
   16817     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
   16818             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
   16819         if (sort && !isCompact) {
   16820             Collections.sort(items, new Comparator<MemItem>() {
   16821                 @Override
   16822                 public int compare(MemItem lhs, MemItem rhs) {
   16823                     if (lhs.pss < rhs.pss) {
   16824                         return 1;
   16825                     } else if (lhs.pss > rhs.pss) {
   16826                         return -1;
   16827                     }
   16828                     return 0;
   16829                 }
   16830             });
   16831         }
   16832 
   16833         for (int i=0; i<items.size(); i++) {
   16834             MemItem mi = items.get(i);
   16835             if (!isCompact) {
   16836                 if (dumpSwapPss) {
   16837                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
   16838                             mi.label, stringifyKBSize(mi.swapPss));
   16839                 } else {
   16840                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
   16841                 }
   16842             } else if (mi.isProc) {
   16843                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
   16844                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
   16845                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
   16846                 pw.println(mi.hasActivities ? ",a" : ",e");
   16847             } else {
   16848                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
   16849                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
   16850             }
   16851             if (mi.subitems != null) {
   16852                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
   16853                         true, isCompact, dumpSwapPss);
   16854             }
   16855         }
   16856     }
   16857 
   16858     // These are in KB.
   16859     static final long[] DUMP_MEM_BUCKETS = new long[] {
   16860         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
   16861         120*1024, 160*1024, 200*1024,
   16862         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
   16863         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
   16864     };
   16865 
   16866     static final void appendMemBucket(StringBuilder out, long memKB, String label,
   16867             boolean stackLike) {
   16868         int start = label.lastIndexOf('.');
   16869         if (start >= 0) start++;
   16870         else start = 0;
   16871         int end = label.length();
   16872         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
   16873             if (DUMP_MEM_BUCKETS[i] >= memKB) {
   16874                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
   16875                 out.append(bucket);
   16876                 out.append(stackLike ? "MB." : "MB ");
   16877                 out.append(label, start, end);
   16878                 return;
   16879             }
   16880         }
   16881         out.append(memKB/1024);
   16882         out.append(stackLike ? "MB." : "MB ");
   16883         out.append(label, start, end);
   16884     }
   16885 
   16886     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
   16887             ProcessList.NATIVE_ADJ,
   16888             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
   16889             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
   16890             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
   16891             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
   16892             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
   16893             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
   16894     };
   16895     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
   16896             "Native",
   16897             "System", "Persistent", "Persistent Service", "Foreground",
   16898             "Visible", "Perceptible",
   16899             "Heavy Weight", "Backup",
   16900             "A Services", "Home",
   16901             "Previous", "B Services", "Cached"
   16902     };
   16903     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
   16904             "native",
   16905             "sys", "pers", "persvc", "fore",
   16906             "vis", "percept",
   16907             "heavy", "backup",
   16908             "servicea", "home",
   16909             "prev", "serviceb", "cached"
   16910     };
   16911 
   16912     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
   16913             long realtime, boolean isCheckinRequest, boolean isCompact) {
   16914         if (isCompact) {
   16915             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
   16916         }
   16917         if (isCheckinRequest || isCompact) {
   16918             // short checkin version
   16919             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
   16920         } else {
   16921             pw.println("Applications Memory Usage (in Kilobytes):");
   16922             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   16923         }
   16924     }
   16925 
   16926     private static final int KSM_SHARED = 0;
   16927     private static final int KSM_SHARING = 1;
   16928     private static final int KSM_UNSHARED = 2;
   16929     private static final int KSM_VOLATILE = 3;
   16930 
   16931     private final long[] getKsmInfo() {
   16932         long[] longOut = new long[4];
   16933         final int[] SINGLE_LONG_FORMAT = new int[] {
   16934             PROC_SPACE_TERM| PROC_OUT_LONG
   16935         };
   16936         long[] longTmp = new long[1];
   16937         readProcFile("/sys/kernel/mm/ksm/pages_shared",
   16938                 SINGLE_LONG_FORMAT, null, longTmp, null);
   16939         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   16940         longTmp[0] = 0;
   16941         readProcFile("/sys/kernel/mm/ksm/pages_sharing",
   16942                 SINGLE_LONG_FORMAT, null, longTmp, null);
   16943         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   16944         longTmp[0] = 0;
   16945         readProcFile("/sys/kernel/mm/ksm/pages_unshared",
   16946                 SINGLE_LONG_FORMAT, null, longTmp, null);
   16947         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   16948         longTmp[0] = 0;
   16949         readProcFile("/sys/kernel/mm/ksm/pages_volatile",
   16950                 SINGLE_LONG_FORMAT, null, longTmp, null);
   16951         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   16952         return longOut;
   16953     }
   16954 
   16955     private static String stringifySize(long size, int order) {
   16956         Locale locale = Locale.US;
   16957         switch (order) {
   16958             case 1:
   16959                 return String.format(locale, "%,13d", size);
   16960             case 1024:
   16961                 return String.format(locale, "%,9dK", size / 1024);
   16962             case 1024 * 1024:
   16963                 return String.format(locale, "%,5dM", size / 1024 / 1024);
   16964             case 1024 * 1024 * 1024:
   16965                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
   16966             default:
   16967                 throw new IllegalArgumentException("Invalid size order");
   16968         }
   16969     }
   16970 
   16971     private static String stringifyKBSize(long size) {
   16972         return stringifySize(size * 1024, 1024);
   16973     }
   16974 
   16975     // Update this version number in case you change the 'compact' format
   16976     private static final int MEMINFO_COMPACT_VERSION = 1;
   16977 
   16978     final void dumpApplicationMemoryUsage(FileDescriptor fd,
   16979             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
   16980         boolean dumpDetails = false;
   16981         boolean dumpFullDetails = false;
   16982         boolean dumpDalvik = false;
   16983         boolean dumpSummaryOnly = false;
   16984         boolean dumpUnreachable = false;
   16985         boolean oomOnly = false;
   16986         boolean isCompact = false;
   16987         boolean localOnly = false;
   16988         boolean packages = false;
   16989         boolean isCheckinRequest = false;
   16990         boolean dumpSwapPss = false;
   16991 
   16992         int opti = 0;
   16993         while (opti < args.length) {
   16994             String opt = args[opti];
   16995             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   16996                 break;
   16997             }
   16998             opti++;
   16999             if ("-a".equals(opt)) {
   17000                 dumpDetails = true;
   17001                 dumpFullDetails = true;
   17002                 dumpDalvik = true;
   17003                 dumpSwapPss = true;
   17004             } else if ("-d".equals(opt)) {
   17005                 dumpDalvik = true;
   17006             } else if ("-c".equals(opt)) {
   17007                 isCompact = true;
   17008             } else if ("-s".equals(opt)) {
   17009                 dumpDetails = true;
   17010                 dumpSummaryOnly = true;
   17011             } else if ("-S".equals(opt)) {
   17012                 dumpSwapPss = true;
   17013             } else if ("--unreachable".equals(opt)) {
   17014                 dumpUnreachable = true;
   17015             } else if ("--oom".equals(opt)) {
   17016                 oomOnly = true;
   17017             } else if ("--local".equals(opt)) {
   17018                 localOnly = true;
   17019             } else if ("--package".equals(opt)) {
   17020                 packages = true;
   17021             } else if ("--checkin".equals(opt)) {
   17022                 isCheckinRequest = true;
   17023 
   17024             } else if ("-h".equals(opt)) {
   17025                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
   17026                 pw.println("  -a: include all available information for each process.");
   17027                 pw.println("  -d: include dalvik details.");
   17028                 pw.println("  -c: dump in a compact machine-parseable representation.");
   17029                 pw.println("  -s: dump only summary of application memory usage.");
   17030                 pw.println("  -S: dump also SwapPss.");
   17031                 pw.println("  --oom: only show processes organized by oom adj.");
   17032                 pw.println("  --local: only collect details locally, don't call process.");
   17033                 pw.println("  --package: interpret process arg as package, dumping all");
   17034                 pw.println("             processes that have loaded that package.");
   17035                 pw.println("  --checkin: dump data for a checkin");
   17036                 pw.println("If [process] is specified it can be the name or ");
   17037                 pw.println("pid of a specific process to dump.");
   17038                 return;
   17039             } else {
   17040                 pw.println("Unknown argument: " + opt + "; use -h for help");
   17041             }
   17042         }
   17043 
   17044         long uptime = SystemClock.uptimeMillis();
   17045         long realtime = SystemClock.elapsedRealtime();
   17046         final long[] tmpLong = new long[1];
   17047 
   17048         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
   17049         if (procs == null) {
   17050             // No Java processes.  Maybe they want to print a native process.
   17051             if (args != null && args.length > opti
   17052                     && args[opti].charAt(0) != '-') {
   17053                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
   17054                         = new ArrayList<ProcessCpuTracker.Stats>();
   17055                 updateCpuStatsNow();
   17056                 int findPid = -1;
   17057                 try {
   17058                     findPid = Integer.parseInt(args[opti]);
   17059                 } catch (NumberFormatException e) {
   17060                 }
   17061                 synchronized (mProcessCpuTracker) {
   17062                     final int N = mProcessCpuTracker.countStats();
   17063                     for (int i=0; i<N; i++) {
   17064                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   17065                         if (st.pid == findPid || (st.baseName != null
   17066                                 && st.baseName.equals(args[opti]))) {
   17067                             nativeProcs.add(st);
   17068                         }
   17069                     }
   17070                 }
   17071                 if (nativeProcs.size() > 0) {
   17072                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
   17073                             isCompact);
   17074                     Debug.MemoryInfo mi = null;
   17075                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
   17076                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
   17077                         final int pid = r.pid;
   17078                         if (!isCheckinRequest && dumpDetails) {
   17079                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
   17080                         }
   17081                         if (mi == null) {
   17082                             mi = new Debug.MemoryInfo();
   17083                         }
   17084                         if (dumpDetails || (!brief && !oomOnly)) {
   17085                             Debug.getMemoryInfo(pid, mi);
   17086                         } else {
   17087                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
   17088                             mi.dalvikPrivateDirty = (int)tmpLong[0];
   17089                         }
   17090                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
   17091                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
   17092                         if (isCheckinRequest) {
   17093                             pw.println();
   17094                         }
   17095                     }
   17096                     return;
   17097                 }
   17098             }
   17099             pw.println("No process found for: " + args[opti]);
   17100             return;
   17101         }
   17102 
   17103         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
   17104             dumpDetails = true;
   17105         }
   17106 
   17107         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
   17108 
   17109         String[] innerArgs = new String[args.length-opti];
   17110         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
   17111 
   17112         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
   17113         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
   17114         long nativePss = 0;
   17115         long nativeSwapPss = 0;
   17116         long dalvikPss = 0;
   17117         long dalvikSwapPss = 0;
   17118         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
   17119                 EmptyArray.LONG;
   17120         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
   17121                 EmptyArray.LONG;
   17122         long otherPss = 0;
   17123         long otherSwapPss = 0;
   17124         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   17125         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   17126 
   17127         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   17128         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   17129         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
   17130                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
   17131 
   17132         long totalPss = 0;
   17133         long totalSwapPss = 0;
   17134         long cachedPss = 0;
   17135         long cachedSwapPss = 0;
   17136         boolean hasSwapPss = false;
   17137 
   17138         Debug.MemoryInfo mi = null;
   17139         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   17140             final ProcessRecord r = procs.get(i);
   17141             final IApplicationThread thread;
   17142             final int pid;
   17143             final int oomAdj;
   17144             final boolean hasActivities;
   17145             synchronized (this) {
   17146                 thread = r.thread;
   17147                 pid = r.pid;
   17148                 oomAdj = r.getSetAdjWithServices();
   17149                 hasActivities = r.activities.size() > 0;
   17150             }
   17151             if (thread != null) {
   17152                 if (!isCheckinRequest && dumpDetails) {
   17153                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
   17154                 }
   17155                 if (mi == null) {
   17156                     mi = new Debug.MemoryInfo();
   17157                 }
   17158                 if (dumpDetails || (!brief && !oomOnly)) {
   17159                     Debug.getMemoryInfo(pid, mi);
   17160                     hasSwapPss = mi.hasSwappedOutPss;
   17161                 } else {
   17162                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
   17163                     mi.dalvikPrivateDirty = (int)tmpLong[0];
   17164                 }
   17165                 if (dumpDetails) {
   17166                     if (localOnly) {
   17167                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
   17168                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
   17169                         if (isCheckinRequest) {
   17170                             pw.println();
   17171                         }
   17172                     } else {
   17173                         pw.flush();
   17174                         try {
   17175                             TransferPipe tp = new TransferPipe();
   17176                             try {
   17177                                 thread.dumpMemInfo(tp.getWriteFd(),
   17178                                         mi, isCheckinRequest, dumpFullDetails,
   17179                                         dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
   17180                                 tp.go(fd);
   17181                             } finally {
   17182                                 tp.kill();
   17183                             }
   17184                         } catch (IOException e) {
   17185                             if (!isCheckinRequest) {
   17186                                 pw.println("Got IoException!");
   17187                                 pw.flush();
   17188                             }
   17189                         } catch (RemoteException e) {
   17190                             if (!isCheckinRequest) {
   17191                                 pw.println("Got RemoteException!");
   17192                                 pw.flush();
   17193                             }
   17194                         }
   17195                     }
   17196                 }
   17197 
   17198                 final long myTotalPss = mi.getTotalPss();
   17199                 final long myTotalUss = mi.getTotalUss();
   17200                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
   17201 
   17202                 synchronized (this) {
   17203                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
   17204                         // Record this for posterity if the process has been stable.
   17205                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
   17206                     }
   17207                 }
   17208 
   17209                 if (!isCheckinRequest && mi != null) {
   17210                     totalPss += myTotalPss;
   17211                     totalSwapPss += myTotalSwapPss;
   17212                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
   17213                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
   17214                             myTotalSwapPss, pid, hasActivities);
   17215                     procMems.add(pssItem);
   17216                     procMemsMap.put(pid, pssItem);
   17217 
   17218                     nativePss += mi.nativePss;
   17219                     nativeSwapPss += mi.nativeSwappedOutPss;
   17220                     dalvikPss += mi.dalvikPss;
   17221                     dalvikSwapPss += mi.dalvikSwappedOutPss;
   17222                     for (int j=0; j<dalvikSubitemPss.length; j++) {
   17223                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   17224                         dalvikSubitemSwapPss[j] +=
   17225                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   17226                     }
   17227                     otherPss += mi.otherPss;
   17228                     otherSwapPss += mi.otherSwappedOutPss;
   17229                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   17230                         long mem = mi.getOtherPss(j);
   17231                         miscPss[j] += mem;
   17232                         otherPss -= mem;
   17233                         mem = mi.getOtherSwappedOutPss(j);
   17234                         miscSwapPss[j] += mem;
   17235                         otherSwapPss -= mem;
   17236                     }
   17237 
   17238                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   17239                         cachedPss += myTotalPss;
   17240                         cachedSwapPss += myTotalSwapPss;
   17241                     }
   17242 
   17243                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
   17244                         if (oomIndex == (oomPss.length - 1)
   17245                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
   17246                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
   17247                             oomPss[oomIndex] += myTotalPss;
   17248                             oomSwapPss[oomIndex] += myTotalSwapPss;
   17249                             if (oomProcs[oomIndex] == null) {
   17250                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
   17251                             }
   17252                             oomProcs[oomIndex].add(pssItem);
   17253                             break;
   17254                         }
   17255                     }
   17256                 }
   17257             }
   17258         }
   17259 
   17260         long nativeProcTotalPss = 0;
   17261 
   17262         if (!isCheckinRequest && procs.size() > 1 && !packages) {
   17263             // If we are showing aggregations, also look for native processes to
   17264             // include so that our aggregations are more accurate.
   17265             updateCpuStatsNow();
   17266             mi = null;
   17267             synchronized (mProcessCpuTracker) {
   17268                 final int N = mProcessCpuTracker.countStats();
   17269                 for (int i=0; i<N; i++) {
   17270                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   17271                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
   17272                         if (mi == null) {
   17273                             mi = new Debug.MemoryInfo();
   17274                         }
   17275                         if (!brief && !oomOnly) {
   17276                             Debug.getMemoryInfo(st.pid, mi);
   17277                         } else {
   17278                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
   17279                             mi.nativePrivateDirty = (int)tmpLong[0];
   17280                         }
   17281 
   17282                         final long myTotalPss = mi.getTotalPss();
   17283                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
   17284                         totalPss += myTotalPss;
   17285                         nativeProcTotalPss += myTotalPss;
   17286 
   17287                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
   17288                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
   17289                         procMems.add(pssItem);
   17290 
   17291                         nativePss += mi.nativePss;
   17292                         nativeSwapPss += mi.nativeSwappedOutPss;
   17293                         dalvikPss += mi.dalvikPss;
   17294                         dalvikSwapPss += mi.dalvikSwappedOutPss;
   17295                         for (int j=0; j<dalvikSubitemPss.length; j++) {
   17296                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   17297                             dalvikSubitemSwapPss[j] +=
   17298                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   17299                         }
   17300                         otherPss += mi.otherPss;
   17301                         otherSwapPss += mi.otherSwappedOutPss;
   17302                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   17303                             long mem = mi.getOtherPss(j);
   17304                             miscPss[j] += mem;
   17305                             otherPss -= mem;
   17306                             mem = mi.getOtherSwappedOutPss(j);
   17307                             miscSwapPss[j] += mem;
   17308                             otherSwapPss -= mem;
   17309                         }
   17310                         oomPss[0] += myTotalPss;
   17311                         oomSwapPss[0] += myTotalSwapPss;
   17312                         if (oomProcs[0] == null) {
   17313                             oomProcs[0] = new ArrayList<MemItem>();
   17314                         }
   17315                         oomProcs[0].add(pssItem);
   17316                     }
   17317                 }
   17318             }
   17319 
   17320             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
   17321 
   17322             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
   17323             final MemItem dalvikItem =
   17324                     new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
   17325             if (dalvikSubitemPss.length > 0) {
   17326                 dalvikItem.subitems = new ArrayList<MemItem>();
   17327                 for (int j=0; j<dalvikSubitemPss.length; j++) {
   17328                     final String name = Debug.MemoryInfo.getOtherLabel(
   17329                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
   17330                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
   17331                                     dalvikSubitemSwapPss[j], j));
   17332                 }
   17333             }
   17334             catMems.add(dalvikItem);
   17335             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
   17336             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   17337                 String label = Debug.MemoryInfo.getOtherLabel(j);
   17338                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
   17339             }
   17340 
   17341             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
   17342             for (int j=0; j<oomPss.length; j++) {
   17343                 if (oomPss[j] != 0) {
   17344                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
   17345                             : DUMP_MEM_OOM_LABEL[j];
   17346                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
   17347                             DUMP_MEM_OOM_ADJ[j]);
   17348                     item.subitems = oomProcs[j];
   17349                     oomMems.add(item);
   17350                 }
   17351             }
   17352 
   17353             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
   17354             if (!brief && !oomOnly && !isCompact) {
   17355                 pw.println();
   17356                 pw.println("Total PSS by process:");
   17357                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
   17358                 pw.println();
   17359             }
   17360             if (!isCompact) {
   17361                 pw.println("Total PSS by OOM adjustment:");
   17362             }
   17363             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
   17364             if (!brief && !oomOnly) {
   17365                 PrintWriter out = categoryPw != null ? categoryPw : pw;
   17366                 if (!isCompact) {
   17367                     out.println();
   17368                     out.println("Total PSS by category:");
   17369                 }
   17370                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
   17371             }
   17372             if (!isCompact) {
   17373                 pw.println();
   17374             }
   17375             MemInfoReader memInfo = new MemInfoReader();
   17376             memInfo.readMemInfo();
   17377             if (nativeProcTotalPss > 0) {
   17378                 synchronized (this) {
   17379                     final long cachedKb = memInfo.getCachedSizeKb();
   17380                     final long freeKb = memInfo.getFreeSizeKb();
   17381                     final long zramKb = memInfo.getZramTotalSizeKb();
   17382                     final long kernelKb = memInfo.getKernelUsedSizeKb();
   17383                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
   17384                             kernelKb*1024, nativeProcTotalPss*1024);
   17385                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
   17386                             nativeProcTotalPss);
   17387                 }
   17388             }
   17389             if (!brief) {
   17390                 if (!isCompact) {
   17391                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
   17392                     pw.print(" (status ");
   17393                     switch (mLastMemoryLevel) {
   17394                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
   17395                             pw.println("normal)");
   17396                             break;
   17397                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
   17398                             pw.println("moderate)");
   17399                             break;
   17400                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
   17401                             pw.println("low)");
   17402                             break;
   17403                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
   17404                             pw.println("critical)");
   17405                             break;
   17406                         default:
   17407                             pw.print(mLastMemoryLevel);
   17408                             pw.println(")");
   17409                             break;
   17410                     }
   17411                     pw.print(" Free RAM: ");
   17412                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
   17413                             + memInfo.getFreeSizeKb()));
   17414                     pw.print(" (");
   17415                     pw.print(stringifyKBSize(cachedPss));
   17416                     pw.print(" cached pss + ");
   17417                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
   17418                     pw.print(" cached kernel + ");
   17419                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
   17420                     pw.println(" free)");
   17421                 } else {
   17422                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
   17423                     pw.print(cachedPss + memInfo.getCachedSizeKb()
   17424                             + memInfo.getFreeSizeKb()); pw.print(",");
   17425                     pw.println(totalPss - cachedPss);
   17426                 }
   17427             }
   17428             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
   17429                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
   17430                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
   17431             if (!isCompact) {
   17432                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
   17433                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
   17434                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
   17435                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
   17436                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
   17437             } else {
   17438                 pw.print("lostram,"); pw.println(lostRAM);
   17439             }
   17440             if (!brief) {
   17441                 if (memInfo.getZramTotalSizeKb() != 0) {
   17442                     if (!isCompact) {
   17443                         pw.print("     ZRAM: ");
   17444                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
   17445                                 pw.print(" physical used for ");
   17446                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
   17447                                         - memInfo.getSwapFreeSizeKb()));
   17448                                 pw.print(" in swap (");
   17449                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
   17450                                 pw.println(" total swap)");
   17451                     } else {
   17452                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
   17453                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
   17454                                 pw.println(memInfo.getSwapFreeSizeKb());
   17455                     }
   17456                 }
   17457                 final long[] ksm = getKsmInfo();
   17458                 if (!isCompact) {
   17459                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
   17460                             || ksm[KSM_VOLATILE] != 0) {
   17461                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
   17462                                 pw.print(" saved from shared ");
   17463                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
   17464                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
   17465                                 pw.print(" unshared; ");
   17466                                 pw.print(stringifyKBSize(
   17467                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
   17468                     }
   17469                     pw.print("   Tuning: ");
   17470                     pw.print(ActivityManager.staticGetMemoryClass());
   17471                     pw.print(" (large ");
   17472                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   17473                     pw.print("), oom ");
   17474                     pw.print(stringifySize(
   17475                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
   17476                     pw.print(", restore limit ");
   17477                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
   17478                     if (ActivityManager.isLowRamDeviceStatic()) {
   17479                         pw.print(" (low-ram)");
   17480                     }
   17481                     if (ActivityManager.isHighEndGfx()) {
   17482                         pw.print(" (high-end-gfx)");
   17483                     }
   17484                     pw.println();
   17485                 } else {
   17486                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
   17487                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
   17488                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
   17489                     pw.print("tuning,");
   17490                     pw.print(ActivityManager.staticGetMemoryClass());
   17491                     pw.print(',');
   17492                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   17493                     pw.print(',');
   17494                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
   17495                     if (ActivityManager.isLowRamDeviceStatic()) {
   17496                         pw.print(",low-ram");
   17497                     }
   17498                     if (ActivityManager.isHighEndGfx()) {
   17499                         pw.print(",high-end-gfx");
   17500                     }
   17501                     pw.println();
   17502                 }
   17503             }
   17504         }
   17505     }
   17506 
   17507     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
   17508             long memtrack, String name) {
   17509         sb.append("  ");
   17510         sb.append(ProcessList.makeOomAdjString(oomAdj));
   17511         sb.append(' ');
   17512         sb.append(ProcessList.makeProcStateString(procState));
   17513         sb.append(' ');
   17514         ProcessList.appendRamKb(sb, pss);
   17515         sb.append(": ");
   17516         sb.append(name);
   17517         if (memtrack > 0) {
   17518             sb.append(" (");
   17519             sb.append(stringifyKBSize(memtrack));
   17520             sb.append(" memtrack)");
   17521         }
   17522     }
   17523 
   17524     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
   17525         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
   17526         sb.append(" (pid ");
   17527         sb.append(mi.pid);
   17528         sb.append(") ");
   17529         sb.append(mi.adjType);
   17530         sb.append('\n');
   17531         if (mi.adjReason != null) {
   17532             sb.append("                      ");
   17533             sb.append(mi.adjReason);
   17534             sb.append('\n');
   17535         }
   17536     }
   17537 
   17538     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
   17539         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
   17540         for (int i=0, N=memInfos.size(); i<N; i++) {
   17541             ProcessMemInfo mi = memInfos.get(i);
   17542             infoMap.put(mi.pid, mi);
   17543         }
   17544         updateCpuStatsNow();
   17545         long[] memtrackTmp = new long[1];
   17546         final List<ProcessCpuTracker.Stats> stats;
   17547         // Get a list of Stats that have vsize > 0
   17548         synchronized (mProcessCpuTracker) {
   17549             stats = mProcessCpuTracker.getStats((st) -> {
   17550                 return st.vsize > 0;
   17551             });
   17552         }
   17553         final int statsCount = stats.size();
   17554         for (int i = 0; i < statsCount; i++) {
   17555             ProcessCpuTracker.Stats st = stats.get(i);
   17556             long pss = Debug.getPss(st.pid, null, memtrackTmp);
   17557             if (pss > 0) {
   17558                 if (infoMap.indexOfKey(st.pid) < 0) {
   17559                     ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
   17560                             ProcessList.NATIVE_ADJ, -1, "native", null);
   17561                     mi.pss = pss;
   17562                     mi.memtrack = memtrackTmp[0];
   17563                     memInfos.add(mi);
   17564                 }
   17565             }
   17566         }
   17567 
   17568         long totalPss = 0;
   17569         long totalMemtrack = 0;
   17570         for (int i=0, N=memInfos.size(); i<N; i++) {
   17571             ProcessMemInfo mi = memInfos.get(i);
   17572             if (mi.pss == 0) {
   17573                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
   17574                 mi.memtrack = memtrackTmp[0];
   17575             }
   17576             totalPss += mi.pss;
   17577             totalMemtrack += mi.memtrack;
   17578         }
   17579         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
   17580             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
   17581                 if (lhs.oomAdj != rhs.oomAdj) {
   17582                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
   17583                 }
   17584                 if (lhs.pss != rhs.pss) {
   17585                     return lhs.pss < rhs.pss ? 1 : -1;
   17586                 }
   17587                 return 0;
   17588             }
   17589         });
   17590 
   17591         StringBuilder tag = new StringBuilder(128);
   17592         StringBuilder stack = new StringBuilder(128);
   17593         tag.append("Low on memory -- ");
   17594         appendMemBucket(tag, totalPss, "total", false);
   17595         appendMemBucket(stack, totalPss, "total", true);
   17596 
   17597         StringBuilder fullNativeBuilder = new StringBuilder(1024);
   17598         StringBuilder shortNativeBuilder = new StringBuilder(1024);
   17599         StringBuilder fullJavaBuilder = new StringBuilder(1024);
   17600 
   17601         boolean firstLine = true;
   17602         int lastOomAdj = Integer.MIN_VALUE;
   17603         long extraNativeRam = 0;
   17604         long extraNativeMemtrack = 0;
   17605         long cachedPss = 0;
   17606         for (int i=0, N=memInfos.size(); i<N; i++) {
   17607             ProcessMemInfo mi = memInfos.get(i);
   17608 
   17609             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   17610                 cachedPss += mi.pss;
   17611             }
   17612 
   17613             if (mi.oomAdj != ProcessList.NATIVE_ADJ
   17614                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
   17615                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
   17616                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
   17617                 if (lastOomAdj != mi.oomAdj) {
   17618                     lastOomAdj = mi.oomAdj;
   17619                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   17620                         tag.append(" / ");
   17621                     }
   17622                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
   17623                         if (firstLine) {
   17624                             stack.append(":");
   17625                             firstLine = false;
   17626                         }
   17627                         stack.append("\n\t at ");
   17628                     } else {
   17629                         stack.append("$");
   17630                     }
   17631                 } else {
   17632                     tag.append(" ");
   17633                     stack.append("$");
   17634                 }
   17635                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   17636                     appendMemBucket(tag, mi.pss, mi.name, false);
   17637                 }
   17638                 appendMemBucket(stack, mi.pss, mi.name, true);
   17639                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
   17640                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
   17641                     stack.append("(");
   17642                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
   17643                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
   17644                             stack.append(DUMP_MEM_OOM_LABEL[k]);
   17645                             stack.append(":");
   17646                             stack.append(DUMP_MEM_OOM_ADJ[k]);
   17647                         }
   17648                     }
   17649                     stack.append(")");
   17650                 }
   17651             }
   17652 
   17653             appendMemInfo(fullNativeBuilder, mi);
   17654             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
   17655                 // The short form only has native processes that are >= 512K.
   17656                 if (mi.pss >= 512) {
   17657                     appendMemInfo(shortNativeBuilder, mi);
   17658                 } else {
   17659                     extraNativeRam += mi.pss;
   17660                     extraNativeMemtrack += mi.memtrack;
   17661                 }
   17662             } else {
   17663                 // Short form has all other details, but if we have collected RAM
   17664                 // from smaller native processes let's dump a summary of that.
   17665                 if (extraNativeRam > 0) {
   17666                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
   17667                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
   17668                     shortNativeBuilder.append('\n');
   17669                     extraNativeRam = 0;
   17670                 }
   17671                 appendMemInfo(fullJavaBuilder, mi);
   17672             }
   17673         }
   17674 
   17675         fullJavaBuilder.append("           ");
   17676         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
   17677         fullJavaBuilder.append(": TOTAL");
   17678         if (totalMemtrack > 0) {
   17679             fullJavaBuilder.append(" (");
   17680             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
   17681             fullJavaBuilder.append(" memtrack)");
   17682         } else {
   17683         }
   17684         fullJavaBuilder.append("\n");
   17685 
   17686         MemInfoReader memInfo = new MemInfoReader();
   17687         memInfo.readMemInfo();
   17688         final long[] infos = memInfo.getRawInfo();
   17689 
   17690         StringBuilder memInfoBuilder = new StringBuilder(1024);
   17691         Debug.getMemInfo(infos);
   17692         memInfoBuilder.append("  MemInfo: ");
   17693         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
   17694         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
   17695         memInfoBuilder.append(stringifyKBSize(
   17696                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
   17697         memInfoBuilder.append(stringifyKBSize(
   17698                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
   17699         memInfoBuilder.append(stringifyKBSize(
   17700                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
   17701         memInfoBuilder.append("           ");
   17702         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
   17703         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
   17704         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
   17705         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
   17706         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
   17707             memInfoBuilder.append("  ZRAM: ");
   17708             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
   17709             memInfoBuilder.append(" RAM, ");
   17710             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
   17711             memInfoBuilder.append(" swap total, ");
   17712             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
   17713             memInfoBuilder.append(" swap free\n");
   17714         }
   17715         final long[] ksm = getKsmInfo();
   17716         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
   17717                 || ksm[KSM_VOLATILE] != 0) {
   17718             memInfoBuilder.append("  KSM: ");
   17719             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
   17720             memInfoBuilder.append(" saved from shared ");
   17721             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
   17722             memInfoBuilder.append("\n       ");
   17723             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
   17724             memInfoBuilder.append(" unshared; ");
   17725             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
   17726             memInfoBuilder.append(" volatile\n");
   17727         }
   17728         memInfoBuilder.append("  Free RAM: ");
   17729         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
   17730                 + memInfo.getFreeSizeKb()));
   17731         memInfoBuilder.append("\n");
   17732         memInfoBuilder.append("  Used RAM: ");
   17733         memInfoBuilder.append(stringifyKBSize(
   17734                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
   17735         memInfoBuilder.append("\n");
   17736         memInfoBuilder.append("  Lost RAM: ");
   17737         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
   17738                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
   17739                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
   17740         memInfoBuilder.append("\n");
   17741         Slog.i(TAG, "Low on memory:");
   17742         Slog.i(TAG, shortNativeBuilder.toString());
   17743         Slog.i(TAG, fullJavaBuilder.toString());
   17744         Slog.i(TAG, memInfoBuilder.toString());
   17745 
   17746         StringBuilder dropBuilder = new StringBuilder(1024);
   17747         /*
   17748         StringWriter oomSw = new StringWriter();
   17749         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
   17750         StringWriter catSw = new StringWriter();
   17751         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
   17752         String[] emptyArgs = new String[] { };
   17753         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
   17754         oomPw.flush();
   17755         String oomString = oomSw.toString();
   17756         */
   17757         dropBuilder.append("Low on memory:");
   17758         dropBuilder.append(stack);
   17759         dropBuilder.append('\n');
   17760         dropBuilder.append(fullNativeBuilder);
   17761         dropBuilder.append(fullJavaBuilder);
   17762         dropBuilder.append('\n');
   17763         dropBuilder.append(memInfoBuilder);
   17764         dropBuilder.append('\n');
   17765         /*
   17766         dropBuilder.append(oomString);
   17767         dropBuilder.append('\n');
   17768         */
   17769         StringWriter catSw = new StringWriter();
   17770         synchronized (ActivityManagerService.this) {
   17771             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
   17772             String[] emptyArgs = new String[] { };
   17773             catPw.println();
   17774             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
   17775             catPw.println();
   17776             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
   17777                     false, null).dumpLocked();
   17778             catPw.println();
   17779             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
   17780             catPw.flush();
   17781         }
   17782         dropBuilder.append(catSw.toString());
   17783         addErrorToDropBox("lowmem", null, "system_server", null,
   17784                 null, tag.toString(), dropBuilder.toString(), null, null);
   17785         //Slog.i(TAG, "Sent to dropbox:");
   17786         //Slog.i(TAG, dropBuilder.toString());
   17787         synchronized (ActivityManagerService.this) {
   17788             long now = SystemClock.uptimeMillis();
   17789             if (mLastMemUsageReportTime < now) {
   17790                 mLastMemUsageReportTime = now;
   17791             }
   17792         }
   17793     }
   17794 
   17795     /**
   17796      * Searches array of arguments for the specified string
   17797      * @param args array of argument strings
   17798      * @param value value to search for
   17799      * @return true if the value is contained in the array
   17800      */
   17801     private static boolean scanArgs(String[] args, String value) {
   17802         if (args != null) {
   17803             for (String arg : args) {
   17804                 if (value.equals(arg)) {
   17805                     return true;
   17806                 }
   17807             }
   17808         }
   17809         return false;
   17810     }
   17811 
   17812     private final boolean removeDyingProviderLocked(ProcessRecord proc,
   17813             ContentProviderRecord cpr, boolean always) {
   17814         final boolean inLaunching = mLaunchingProviders.contains(cpr);
   17815 
   17816         if (!inLaunching || always) {
   17817             synchronized (cpr) {
   17818                 cpr.launchingApp = null;
   17819                 cpr.notifyAll();
   17820             }
   17821             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
   17822             String names[] = cpr.info.authority.split(";");
   17823             for (int j = 0; j < names.length; j++) {
   17824                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
   17825             }
   17826         }
   17827 
   17828         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
   17829             ContentProviderConnection conn = cpr.connections.get(i);
   17830             if (conn.waiting) {
   17831                 // If this connection is waiting for the provider, then we don't
   17832                 // need to mess with its process unless we are always removing
   17833                 // or for some reason the provider is not currently launching.
   17834                 if (inLaunching && !always) {
   17835                     continue;
   17836                 }
   17837             }
   17838             ProcessRecord capp = conn.client;
   17839             conn.dead = true;
   17840             if (conn.stableCount > 0) {
   17841                 if (!capp.persistent && capp.thread != null
   17842                         && capp.pid != 0
   17843                         && capp.pid != MY_PID) {
   17844                     capp.kill("depends on provider "
   17845                             + cpr.name.flattenToShortString()
   17846                             + " in dying proc " + (proc != null ? proc.processName : "??")
   17847                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
   17848                 }
   17849             } else if (capp.thread != null && conn.provider.provider != null) {
   17850                 try {
   17851                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
   17852                 } catch (RemoteException e) {
   17853                 }
   17854                 // In the protocol here, we don't expect the client to correctly
   17855                 // clean up this connection, we'll just remove it.
   17856                 cpr.connections.remove(i);
   17857                 if (conn.client.conProviders.remove(conn)) {
   17858                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
   17859                 }
   17860             }
   17861         }
   17862 
   17863         if (inLaunching && always) {
   17864             mLaunchingProviders.remove(cpr);
   17865         }
   17866         return inLaunching;
   17867     }
   17868 
   17869     /**
   17870      * Main code for cleaning up a process when it has gone away.  This is
   17871      * called both as a result of the process dying, or directly when stopping
   17872      * a process when running in single process mode.
   17873      *
   17874      * @return Returns true if the given process has been restarted, so the
   17875      * app that was passed in must remain on the process lists.
   17876      */
   17877     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
   17878             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
   17879         if (index >= 0) {
   17880             removeLruProcessLocked(app);
   17881             ProcessList.remove(app.pid);
   17882         }
   17883 
   17884         mProcessesToGc.remove(app);
   17885         mPendingPssProcesses.remove(app);
   17886 
   17887         // Dismiss any open dialogs.
   17888         if (app.crashDialog != null && !app.forceCrashReport) {
   17889             app.crashDialog.dismiss();
   17890             app.crashDialog = null;
   17891         }
   17892         if (app.anrDialog != null) {
   17893             app.anrDialog.dismiss();
   17894             app.anrDialog = null;
   17895         }
   17896         if (app.waitDialog != null) {
   17897             app.waitDialog.dismiss();
   17898             app.waitDialog = null;
   17899         }
   17900 
   17901         app.crashing = false;
   17902         app.notResponding = false;
   17903 
   17904         app.resetPackageList(mProcessStats);
   17905         app.unlinkDeathRecipient();
   17906         app.makeInactive(mProcessStats);
   17907         app.waitingToKill = null;
   17908         app.forcingToImportant = null;
   17909         updateProcessForegroundLocked(app, false, false);
   17910         app.foregroundActivities = false;
   17911         app.hasShownUi = false;
   17912         app.treatLikeActivity = false;
   17913         app.hasAboveClient = false;
   17914         app.hasClientActivities = false;
   17915 
   17916         mServices.killServicesLocked(app, allowRestart);
   17917 
   17918         boolean restart = false;
   17919 
   17920         // Remove published content providers.
   17921         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
   17922             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
   17923             final boolean always = app.bad || !allowRestart;
   17924             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
   17925             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
   17926                 // We left the provider in the launching list, need to
   17927                 // restart it.
   17928                 restart = true;
   17929             }
   17930 
   17931             cpr.provider = null;
   17932             cpr.proc = null;
   17933         }
   17934         app.pubProviders.clear();
   17935 
   17936         // Take care of any launching providers waiting for this process.
   17937         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
   17938             restart = true;
   17939         }
   17940 
   17941         // Unregister from connected content providers.
   17942         if (!app.conProviders.isEmpty()) {
   17943             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
   17944                 ContentProviderConnection conn = app.conProviders.get(i);
   17945                 conn.provider.connections.remove(conn);
   17946                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
   17947                         conn.provider.name);
   17948             }
   17949             app.conProviders.clear();
   17950         }
   17951 
   17952         // At this point there may be remaining entries in mLaunchingProviders
   17953         // where we were the only one waiting, so they are no longer of use.
   17954         // Look for these and clean up if found.
   17955         // XXX Commented out for now.  Trying to figure out a way to reproduce
   17956         // the actual situation to identify what is actually going on.
   17957         if (false) {
   17958             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
   17959                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
   17960                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
   17961                     synchronized (cpr) {
   17962                         cpr.launchingApp = null;
   17963                         cpr.notifyAll();
   17964                     }
   17965                 }
   17966             }
   17967         }
   17968 
   17969         skipCurrentReceiverLocked(app);
   17970 
   17971         // Unregister any receivers.
   17972         for (int i = app.receivers.size() - 1; i >= 0; i--) {
   17973             removeReceiverLocked(app.receivers.valueAt(i));
   17974         }
   17975         app.receivers.clear();
   17976 
   17977         // If the app is undergoing backup, tell the backup manager about it
   17978         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
   17979             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
   17980                     + mBackupTarget.appInfo + " died during backup");
   17981             mHandler.post(new Runnable() {
   17982                 @Override
   17983                 public void run(){
   17984                     try {
   17985                         IBackupManager bm = IBackupManager.Stub.asInterface(
   17986                                 ServiceManager.getService(Context.BACKUP_SERVICE));
   17987                         bm.agentDisconnected(app.info.packageName);
   17988                     } catch (RemoteException e) {
   17989                         // can't happen; backup manager is local
   17990                     }
   17991                 }
   17992             });
   17993         }
   17994 
   17995         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
   17996             ProcessChangeItem item = mPendingProcessChanges.get(i);
   17997             if (item.pid == app.pid) {
   17998                 mPendingProcessChanges.remove(i);
   17999                 mAvailProcessChanges.add(item);
   18000             }
   18001         }
   18002         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
   18003                 null).sendToTarget();
   18004 
   18005         // If the caller is restarting this app, then leave it in its
   18006         // current lists and let the caller take care of it.
   18007         if (restarting) {
   18008             return false;
   18009         }
   18010 
   18011         if (!app.persistent || app.isolated) {
   18012             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
   18013                     "Removing non-persistent process during cleanup: " + app);
   18014             if (!replacingPid) {
   18015                 removeProcessNameLocked(app.processName, app.uid, app);
   18016             }
   18017             if (mHeavyWeightProcess == app) {
   18018                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   18019                         mHeavyWeightProcess.userId, 0));
   18020                 mHeavyWeightProcess = null;
   18021             }
   18022         } else if (!app.removed) {
   18023             // This app is persistent, so we need to keep its record around.
   18024             // If it is not already on the pending app list, add it there
   18025             // and start a new process for it.
   18026             if (mPersistentStartingProcesses.indexOf(app) < 0) {
   18027                 mPersistentStartingProcesses.add(app);
   18028                 restart = true;
   18029             }
   18030         }
   18031         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
   18032                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
   18033         mProcessesOnHold.remove(app);
   18034 
   18035         if (app == mHomeProcess) {
   18036             mHomeProcess = null;
   18037         }
   18038         if (app == mPreviousProcess) {
   18039             mPreviousProcess = null;
   18040         }
   18041 
   18042         if (restart && !app.isolated) {
   18043             // We have components that still need to be running in the
   18044             // process, so re-launch it.
   18045             if (index < 0) {
   18046                 ProcessList.remove(app.pid);
   18047             }
   18048             addProcessNameLocked(app);
   18049             startProcessLocked(app, "restart", app.processName);
   18050             return true;
   18051         } else if (app.pid > 0 && app.pid != MY_PID) {
   18052             // Goodbye!
   18053             boolean removed;
   18054             synchronized (mPidsSelfLocked) {
   18055                 mPidsSelfLocked.remove(app.pid);
   18056                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   18057             }
   18058             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   18059             if (app.isolated) {
   18060                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   18061             }
   18062             app.setPid(0);
   18063         }
   18064         return false;
   18065     }
   18066 
   18067     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
   18068         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
   18069             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   18070             if (cpr.launchingApp == app) {
   18071                 return true;
   18072             }
   18073         }
   18074         return false;
   18075     }
   18076 
   18077     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
   18078         // Look through the content providers we are waiting to have launched,
   18079         // and if any run in this process then either schedule a restart of
   18080         // the process or kill the client waiting for it if this process has
   18081         // gone bad.
   18082         boolean restart = false;
   18083         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
   18084             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   18085             if (cpr.launchingApp == app) {
   18086                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
   18087                     restart = true;
   18088                 } else {
   18089                     removeDyingProviderLocked(app, cpr, true);
   18090                 }
   18091             }
   18092         }
   18093         return restart;
   18094     }
   18095 
   18096     // =========================================================
   18097     // SERVICES
   18098     // =========================================================
   18099 
   18100     @Override
   18101     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
   18102             int flags) {
   18103         enforceNotIsolatedCaller("getServices");
   18104 
   18105         final int callingUid = Binder.getCallingUid();
   18106         final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
   18107             INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
   18108         final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
   18109             callingUid);
   18110         synchronized (this) {
   18111             return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
   18112                 allowed, canInteractAcrossUsers);
   18113         }
   18114     }
   18115 
   18116     @Override
   18117     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
   18118         enforceNotIsolatedCaller("getRunningServiceControlPanel");
   18119         synchronized (this) {
   18120             return mServices.getRunningServiceControlPanelLocked(name);
   18121         }
   18122     }
   18123 
   18124     @Override
   18125     public ComponentName startService(IApplicationThread caller, Intent service,
   18126             String resolvedType, boolean requireForeground, String callingPackage, int userId)
   18127             throws TransactionTooLargeException {
   18128         enforceNotIsolatedCaller("startService");
   18129         // Refuse possible leaked file descriptors
   18130         if (service != null && service.hasFileDescriptors() == true) {
   18131             throw new IllegalArgumentException("File descriptors passed in Intent");
   18132         }
   18133 
   18134         if (callingPackage == null) {
   18135             throw new IllegalArgumentException("callingPackage cannot be null");
   18136         }
   18137 
   18138         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
   18139                 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
   18140         synchronized(this) {
   18141             final int callingPid = Binder.getCallingPid();
   18142             final int callingUid = Binder.getCallingUid();
   18143             final long origId = Binder.clearCallingIdentity();
   18144             ComponentName res;
   18145             try {
   18146                 res = mServices.startServiceLocked(caller, service,
   18147                         resolvedType, callingPid, callingUid,
   18148                         requireForeground, callingPackage, userId);
   18149             } finally {
   18150                 Binder.restoreCallingIdentity(origId);
   18151             }
   18152             return res;
   18153         }
   18154     }
   18155 
   18156     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
   18157             boolean fgRequired, String callingPackage, int userId)
   18158             throws TransactionTooLargeException {
   18159         synchronized(this) {
   18160             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
   18161                     "startServiceInPackage: " + service + " type=" + resolvedType);
   18162             final long origId = Binder.clearCallingIdentity();
   18163             ComponentName res;
   18164             try {
   18165                 res = mServices.startServiceLocked(null, service,
   18166                         resolvedType, -1, uid, fgRequired, callingPackage, userId);
   18167             } finally {
   18168                 Binder.restoreCallingIdentity(origId);
   18169             }
   18170             return res;
   18171         }
   18172     }
   18173 
   18174     @Override
   18175     public int stopService(IApplicationThread caller, Intent service,
   18176             String resolvedType, int userId) {
   18177         enforceNotIsolatedCaller("stopService");
   18178         // Refuse possible leaked file descriptors
   18179         if (service != null && service.hasFileDescriptors() == true) {
   18180             throw new IllegalArgumentException("File descriptors passed in Intent");
   18181         }
   18182 
   18183         synchronized(this) {
   18184             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
   18185         }
   18186     }
   18187 
   18188     @Override
   18189     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
   18190         enforceNotIsolatedCaller("peekService");
   18191         // Refuse possible leaked file descriptors
   18192         if (service != null && service.hasFileDescriptors() == true) {
   18193             throw new IllegalArgumentException("File descriptors passed in Intent");
   18194         }
   18195 
   18196         if (callingPackage == null) {
   18197             throw new IllegalArgumentException("callingPackage cannot be null");
   18198         }
   18199 
   18200         synchronized(this) {
   18201             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
   18202         }
   18203     }
   18204 
   18205     @Override
   18206     public boolean stopServiceToken(ComponentName className, IBinder token,
   18207             int startId) {
   18208         synchronized(this) {
   18209             return mServices.stopServiceTokenLocked(className, token, startId);
   18210         }
   18211     }
   18212 
   18213     @Override
   18214     public void setServiceForeground(ComponentName className, IBinder token,
   18215             int id, Notification notification, int flags) {
   18216         synchronized(this) {
   18217             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
   18218         }
   18219     }
   18220 
   18221     @Override
   18222     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
   18223             boolean requireFull, String name, String callerPackage) {
   18224         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
   18225                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
   18226     }
   18227 
   18228     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
   18229             String className, int flags) {
   18230         boolean result = false;
   18231         // For apps that don't have pre-defined UIDs, check for permission
   18232         if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
   18233             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
   18234                 if (ActivityManager.checkUidPermission(
   18235                         INTERACT_ACROSS_USERS,
   18236                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
   18237                     ComponentName comp = new ComponentName(aInfo.packageName, className);
   18238                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
   18239                             + " requests FLAG_SINGLE_USER, but app does not hold "
   18240                             + INTERACT_ACROSS_USERS;
   18241                     Slog.w(TAG, msg);
   18242                     throw new SecurityException(msg);
   18243                 }
   18244                 // Permission passed
   18245                 result = true;
   18246             }
   18247         } else if ("system".equals(componentProcessName)) {
   18248             result = true;
   18249         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
   18250             // Phone app and persistent apps are allowed to export singleuser providers.
   18251             result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
   18252                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
   18253         }
   18254         if (DEBUG_MU) Slog.v(TAG_MU,
   18255                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
   18256                 + Integer.toHexString(flags) + ") = " + result);
   18257         return result;
   18258     }
   18259 
   18260     /**
   18261      * Checks to see if the caller is in the same app as the singleton
   18262      * component, or the component is in a special app. It allows special apps
   18263      * to export singleton components but prevents exporting singleton
   18264      * components for regular apps.
   18265      */
   18266     boolean isValidSingletonCall(int callingUid, int componentUid) {
   18267         int componentAppId = UserHandle.getAppId(componentUid);
   18268         return UserHandle.isSameApp(callingUid, componentUid)
   18269                 || componentAppId == SYSTEM_UID
   18270                 || componentAppId == PHONE_UID
   18271                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
   18272                         == PackageManager.PERMISSION_GRANTED;
   18273     }
   18274 
   18275     public int bindService(IApplicationThread caller, IBinder token, Intent service,
   18276             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
   18277             int userId) throws TransactionTooLargeException {
   18278         enforceNotIsolatedCaller("bindService");
   18279 
   18280         // Refuse possible leaked file descriptors
   18281         if (service != null && service.hasFileDescriptors() == true) {
   18282             throw new IllegalArgumentException("File descriptors passed in Intent");
   18283         }
   18284 
   18285         if (callingPackage == null) {
   18286             throw new IllegalArgumentException("callingPackage cannot be null");
   18287         }
   18288 
   18289         synchronized(this) {
   18290             return mServices.bindServiceLocked(caller, token, service,
   18291                     resolvedType, connection, flags, callingPackage, userId);
   18292         }
   18293     }
   18294 
   18295     public boolean unbindService(IServiceConnection connection) {
   18296         synchronized (this) {
   18297             return mServices.unbindServiceLocked(connection);
   18298         }
   18299     }
   18300 
   18301     public void publishService(IBinder token, Intent intent, IBinder service) {
   18302         // Refuse possible leaked file descriptors
   18303         if (intent != null && intent.hasFileDescriptors() == true) {
   18304             throw new IllegalArgumentException("File descriptors passed in Intent");
   18305         }
   18306 
   18307         synchronized(this) {
   18308             if (!(token instanceof ServiceRecord)) {
   18309                 throw new IllegalArgumentException("Invalid service token");
   18310             }
   18311             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
   18312         }
   18313     }
   18314 
   18315     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
   18316         // Refuse possible leaked file descriptors
   18317         if (intent != null && intent.hasFileDescriptors() == true) {
   18318             throw new IllegalArgumentException("File descriptors passed in Intent");
   18319         }
   18320 
   18321         synchronized(this) {
   18322             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
   18323         }
   18324     }
   18325 
   18326     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
   18327         synchronized(this) {
   18328             if (!(token instanceof ServiceRecord)) {
   18329                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
   18330                 throw new IllegalArgumentException("Invalid service token");
   18331             }
   18332             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
   18333         }
   18334     }
   18335 
   18336     // =========================================================
   18337     // BACKUP AND RESTORE
   18338     // =========================================================
   18339 
   18340     // Cause the target app to be launched if necessary and its backup agent
   18341     // instantiated.  The backup agent will invoke backupAgentCreated() on the
   18342     // activity manager to announce its creation.
   18343     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
   18344         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
   18345         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
   18346 
   18347         IPackageManager pm = AppGlobals.getPackageManager();
   18348         ApplicationInfo app = null;
   18349         try {
   18350             app = pm.getApplicationInfo(packageName, 0, userId);
   18351         } catch (RemoteException e) {
   18352             // can't happen; package manager is process-local
   18353         }
   18354         if (app == null) {
   18355             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
   18356             return false;
   18357         }
   18358 
   18359         int oldBackupUid;
   18360         int newBackupUid;
   18361 
   18362         synchronized(this) {
   18363             // !!! TODO: currently no check here that we're already bound
   18364             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   18365             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   18366             synchronized (stats) {
   18367                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
   18368             }
   18369 
   18370             // Backup agent is now in use, its package can't be stopped.
   18371             try {
   18372                 AppGlobals.getPackageManager().setPackageStoppedState(
   18373                         app.packageName, false, UserHandle.getUserId(app.uid));
   18374             } catch (RemoteException e) {
   18375             } catch (IllegalArgumentException e) {
   18376                 Slog.w(TAG, "Failed trying to unstop package "
   18377                         + app.packageName + ": " + e);
   18378             }
   18379 
   18380             BackupRecord r = new BackupRecord(ss, app, backupMode);
   18381             ComponentName hostingName =
   18382                     (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
   18383                             ? new ComponentName(app.packageName, app.backupAgentName)
   18384                             : new ComponentName("android", "FullBackupAgent");
   18385             // startProcessLocked() returns existing proc's record if it's already running
   18386             ProcessRecord proc = startProcessLocked(app.processName, app,
   18387                     false, 0, "backup", hostingName, false, false, false);
   18388             if (proc == null) {
   18389                 Slog.e(TAG, "Unable to start backup agent process " + r);
   18390                 return false;
   18391             }
   18392 
   18393             // If the app is a regular app (uid >= 10000) and not the system server or phone
   18394             // process, etc, then mark it as being in full backup so that certain calls to the
   18395             // process can be blocked. This is not reset to false anywhere because we kill the
   18396             // process after the full backup is done and the ProcessRecord will vaporize anyway.
   18397             if (UserHandle.isApp(app.uid) &&
   18398                     backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
   18399                 proc.inFullBackup = true;
   18400             }
   18401             r.app = proc;
   18402             oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
   18403             newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
   18404             mBackupTarget = r;
   18405             mBackupAppName = app.packageName;
   18406 
   18407             // Try not to kill the process during backup
   18408             updateOomAdjLocked(proc, true);
   18409 
   18410             // If the process is already attached, schedule the creation of the backup agent now.
   18411             // If it is not yet live, this will be done when it attaches to the framework.
   18412             if (proc.thread != null) {
   18413                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
   18414                 try {
   18415                     proc.thread.scheduleCreateBackupAgent(app,
   18416                             compatibilityInfoForPackageLocked(app), backupMode);
   18417                 } catch (RemoteException e) {
   18418                     // Will time out on the backup manager side
   18419                 }
   18420             } else {
   18421                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
   18422             }
   18423             // Invariants: at this point, the target app process exists and the application
   18424             // is either already running or in the process of coming up.  mBackupTarget and
   18425             // mBackupAppName describe the app, so that when it binds back to the AM we
   18426             // know that it's scheduled for a backup-agent operation.
   18427         }
   18428 
   18429         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
   18430         if (oldBackupUid != -1) {
   18431             js.removeBackingUpUid(oldBackupUid);
   18432         }
   18433         if (newBackupUid != -1) {
   18434             js.addBackingUpUid(newBackupUid);
   18435         }
   18436 
   18437         return true;
   18438     }
   18439 
   18440     @Override
   18441     public void clearPendingBackup() {
   18442         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
   18443         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
   18444 
   18445         synchronized (this) {
   18446             mBackupTarget = null;
   18447             mBackupAppName = null;
   18448         }
   18449 
   18450         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
   18451         js.clearAllBackingUpUids();
   18452     }
   18453 
   18454     // A backup agent has just come up
   18455     public void backupAgentCreated(String agentPackageName, IBinder agent) {
   18456         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
   18457                 + " = " + agent);
   18458 
   18459         synchronized(this) {
   18460             if (!agentPackageName.equals(mBackupAppName)) {
   18461                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
   18462                 return;
   18463             }
   18464         }
   18465 
   18466         long oldIdent = Binder.clearCallingIdentity();
   18467         try {
   18468             IBackupManager bm = IBackupManager.Stub.asInterface(
   18469                     ServiceManager.getService(Context.BACKUP_SERVICE));
   18470             bm.agentConnected(agentPackageName, agent);
   18471         } catch (RemoteException e) {
   18472             // can't happen; the backup manager service is local
   18473         } catch (Exception e) {
   18474             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
   18475             e.printStackTrace();
   18476         } finally {
   18477             Binder.restoreCallingIdentity(oldIdent);
   18478         }
   18479     }
   18480 
   18481     // done with this agent
   18482     public void unbindBackupAgent(ApplicationInfo appInfo) {
   18483         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
   18484         if (appInfo == null) {
   18485             Slog.w(TAG, "unbind backup agent for null app");
   18486             return;
   18487         }
   18488 
   18489         int oldBackupUid;
   18490 
   18491         synchronized(this) {
   18492             try {
   18493                 if (mBackupAppName == null) {
   18494                     Slog.w(TAG, "Unbinding backup agent with no active backup");
   18495                     return;
   18496                 }
   18497 
   18498                 if (!mBackupAppName.equals(appInfo.packageName)) {
   18499                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
   18500                     return;
   18501                 }
   18502 
   18503                 // Not backing this app up any more; reset its OOM adjustment
   18504                 final ProcessRecord proc = mBackupTarget.app;
   18505                 updateOomAdjLocked(proc, true);
   18506                 proc.inFullBackup = false;
   18507 
   18508                 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
   18509 
   18510                 // If the app crashed during backup, 'thread' will be null here
   18511                 if (proc.thread != null) {
   18512                     try {
   18513                         proc.thread.scheduleDestroyBackupAgent(appInfo,
   18514                                 compatibilityInfoForPackageLocked(appInfo));
   18515                     } catch (Exception e) {
   18516                         Slog.e(TAG, "Exception when unbinding backup agent:");
   18517                         e.printStackTrace();
   18518                     }
   18519                 }
   18520             } finally {
   18521                 mBackupTarget = null;
   18522                 mBackupAppName = null;
   18523             }
   18524         }
   18525 
   18526         if (oldBackupUid != -1) {
   18527             JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
   18528             js.removeBackingUpUid(oldBackupUid);
   18529         }
   18530     }
   18531 
   18532     // =========================================================
   18533     // BROADCASTS
   18534     // =========================================================
   18535 
   18536     private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
   18537         if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
   18538             return false;
   18539         }
   18540         // Easy case -- we have the app's ProcessRecord.
   18541         if (record != null) {
   18542             return record.info.isInstantApp();
   18543         }
   18544         // Otherwise check with PackageManager.
   18545         if (callerPackage == null) {
   18546             Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
   18547             throw new IllegalArgumentException("Calling application did not provide package name");
   18548         }
   18549         mAppOpsService.checkPackage(uid, callerPackage);
   18550         try {
   18551             IPackageManager pm = AppGlobals.getPackageManager();
   18552             return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
   18553         } catch (RemoteException e) {
   18554             Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
   18555             return true;
   18556         }
   18557     }
   18558 
   18559     boolean isPendingBroadcastProcessLocked(int pid) {
   18560         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
   18561                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
   18562     }
   18563 
   18564     void skipPendingBroadcastLocked(int pid) {
   18565             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   18566             for (BroadcastQueue queue : mBroadcastQueues) {
   18567                 queue.skipPendingBroadcastLocked(pid);
   18568             }
   18569     }
   18570 
   18571     // The app just attached; send any pending broadcasts that it should receive
   18572     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
   18573         boolean didSomething = false;
   18574         for (BroadcastQueue queue : mBroadcastQueues) {
   18575             didSomething |= queue.sendPendingBroadcastsLocked(app);
   18576         }
   18577         return didSomething;
   18578     }
   18579 
   18580     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
   18581             IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
   18582             int flags) {
   18583         enforceNotIsolatedCaller("registerReceiver");
   18584         ArrayList<Intent> stickyIntents = null;
   18585         ProcessRecord callerApp = null;
   18586         final boolean visibleToInstantApps
   18587                 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
   18588         int callingUid;
   18589         int callingPid;
   18590         boolean instantApp;
   18591         synchronized(this) {
   18592             if (caller != null) {
   18593                 callerApp = getRecordForAppLocked(caller);
   18594                 if (callerApp == null) {
   18595                     throw new SecurityException(
   18596                             "Unable to find app for caller " + caller
   18597                             + " (pid=" + Binder.getCallingPid()
   18598                             + ") when registering receiver " + receiver);
   18599                 }
   18600                 if (callerApp.info.uid != SYSTEM_UID &&
   18601                         !callerApp.pkgList.containsKey(callerPackage) &&
   18602                         !"android".equals(callerPackage)) {
   18603                     throw new SecurityException("Given caller package " + callerPackage
   18604                             + " is not running in process " + callerApp);
   18605                 }
   18606                 callingUid = callerApp.info.uid;
   18607                 callingPid = callerApp.pid;
   18608             } else {
   18609                 callerPackage = null;
   18610                 callingUid = Binder.getCallingUid();
   18611                 callingPid = Binder.getCallingPid();
   18612             }
   18613 
   18614             instantApp = isInstantApp(callerApp, callerPackage, callingUid);
   18615             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
   18616                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
   18617 
   18618             Iterator<String> actions = filter.actionsIterator();
   18619             if (actions == null) {
   18620                 ArrayList<String> noAction = new ArrayList<String>(1);
   18621                 noAction.add(null);
   18622                 actions = noAction.iterator();
   18623             }
   18624 
   18625             // Collect stickies of users
   18626             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
   18627             while (actions.hasNext()) {
   18628                 String action = actions.next();
   18629                 for (int id : userIds) {
   18630                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
   18631                     if (stickies != null) {
   18632                         ArrayList<Intent> intents = stickies.get(action);
   18633                         if (intents != null) {
   18634                             if (stickyIntents == null) {
   18635                                 stickyIntents = new ArrayList<Intent>();
   18636                             }
   18637                             stickyIntents.addAll(intents);
   18638                         }
   18639                     }
   18640                 }
   18641             }
   18642         }
   18643 
   18644         ArrayList<Intent> allSticky = null;
   18645         if (stickyIntents != null) {
   18646             final ContentResolver resolver = mContext.getContentResolver();
   18647             // Look for any matching sticky broadcasts...
   18648             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
   18649                 Intent intent = stickyIntents.get(i);
   18650                 // Don't provided intents that aren't available to instant apps.
   18651                 if (instantApp &&
   18652                         (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
   18653                     continue;
   18654                 }
   18655                 // If intent has scheme "content", it will need to acccess
   18656                 // provider that needs to lock mProviderMap in ActivityThread
   18657                 // and also it may need to wait application response, so we
   18658                 // cannot lock ActivityManagerService here.
   18659                 if (filter.match(resolver, intent, true, TAG) >= 0) {
   18660                     if (allSticky == null) {
   18661                         allSticky = new ArrayList<Intent>();
   18662                     }
   18663                     allSticky.add(intent);
   18664                 }
   18665             }
   18666         }
   18667 
   18668         // The first sticky in the list is returned directly back to the client.
   18669         Intent sticky = allSticky != null ? allSticky.get(0) : null;
   18670         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
   18671         if (receiver == null) {
   18672             return sticky;
   18673         }
   18674 
   18675         synchronized (this) {
   18676             if (callerApp != null && (callerApp.thread == null
   18677                     || callerApp.thread.asBinder() != caller.asBinder())) {
   18678                 // Original caller already died
   18679                 return null;
   18680             }
   18681             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
   18682             if (rl == null) {
   18683                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
   18684                         userId, receiver);
   18685                 if (rl.app != null) {
   18686                     rl.app.receivers.add(rl);
   18687                 } else {
   18688                     try {
   18689                         receiver.asBinder().linkToDeath(rl, 0);
   18690                     } catch (RemoteException e) {
   18691                         return sticky;
   18692                     }
   18693                     rl.linkedToDeath = true;
   18694                 }
   18695                 mRegisteredReceivers.put(receiver.asBinder(), rl);
   18696             } else if (rl.uid != callingUid) {
   18697                 throw new IllegalArgumentException(
   18698                         "Receiver requested to register for uid " + callingUid
   18699                         + " was previously registered for uid " + rl.uid
   18700                         + " callerPackage is " + callerPackage);
   18701             } else if (rl.pid != callingPid) {
   18702                 throw new IllegalArgumentException(
   18703                         "Receiver requested to register for pid " + callingPid
   18704                         + " was previously registered for pid " + rl.pid
   18705                         + " callerPackage is " + callerPackage);
   18706             } else if (rl.userId != userId) {
   18707                 throw new IllegalArgumentException(
   18708                         "Receiver requested to register for user " + userId
   18709                         + " was previously registered for user " + rl.userId
   18710                         + " callerPackage is " + callerPackage);
   18711             }
   18712             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
   18713                     permission, callingUid, userId, instantApp, visibleToInstantApps);
   18714             rl.add(bf);
   18715             if (!bf.debugCheck()) {
   18716                 Slog.w(TAG, "==> For Dynamic broadcast");
   18717             }
   18718             mReceiverResolver.addFilter(bf);
   18719 
   18720             // Enqueue broadcasts for all existing stickies that match
   18721             // this filter.
   18722             if (allSticky != null) {
   18723                 ArrayList receivers = new ArrayList();
   18724                 receivers.add(bf);
   18725 
   18726                 final int stickyCount = allSticky.size();
   18727                 for (int i = 0; i < stickyCount; i++) {
   18728                     Intent intent = allSticky.get(i);
   18729                     BroadcastQueue queue = broadcastQueueForIntent(intent);
   18730                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
   18731                             null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
   18732                             null, 0, null, null, false, true, true, -1);
   18733                     queue.enqueueParallelBroadcastLocked(r);
   18734                     queue.scheduleBroadcastsLocked();
   18735                 }
   18736             }
   18737 
   18738             return sticky;
   18739         }
   18740     }
   18741 
   18742     public void unregisterReceiver(IIntentReceiver receiver) {
   18743         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
   18744 
   18745         final long origId = Binder.clearCallingIdentity();
   18746         try {
   18747             boolean doTrim = false;
   18748 
   18749             synchronized(this) {
   18750                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
   18751                 if (rl != null) {
   18752                     final BroadcastRecord r = rl.curBroadcast;
   18753                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
   18754                         final boolean doNext = r.queue.finishReceiverLocked(
   18755                                 r, r.resultCode, r.resultData, r.resultExtras,
   18756                                 r.resultAbort, false);
   18757                         if (doNext) {
   18758                             doTrim = true;
   18759                             r.queue.processNextBroadcast(false);
   18760                         }
   18761                     }
   18762 
   18763                     if (rl.app != null) {
   18764                         rl.app.receivers.remove(rl);
   18765                     }
   18766                     removeReceiverLocked(rl);
   18767                     if (rl.linkedToDeath) {
   18768                         rl.linkedToDeath = false;
   18769                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
   18770                     }
   18771                 }
   18772             }
   18773 
   18774             // If we actually concluded any broadcasts, we might now be able
   18775             // to trim the recipients' apps from our working set
   18776             if (doTrim) {
   18777                 trimApplications();
   18778                 return;
   18779             }
   18780 
   18781         } finally {
   18782             Binder.restoreCallingIdentity(origId);
   18783         }
   18784     }
   18785 
   18786     void removeReceiverLocked(ReceiverList rl) {
   18787         mRegisteredReceivers.remove(rl.receiver.asBinder());
   18788         for (int i = rl.size() - 1; i >= 0; i--) {
   18789             mReceiverResolver.removeFilter(rl.get(i));
   18790         }
   18791     }
   18792 
   18793     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
   18794         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   18795             ProcessRecord r = mLruProcesses.get(i);
   18796             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
   18797                 try {
   18798                     r.thread.dispatchPackageBroadcast(cmd, packages);
   18799                 } catch (RemoteException ex) {
   18800                 }
   18801             }
   18802         }
   18803     }
   18804 
   18805     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
   18806             int callingUid, int[] users) {
   18807         // TODO: come back and remove this assumption to triage all broadcasts
   18808         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
   18809 
   18810         List<ResolveInfo> receivers = null;
   18811         try {
   18812             HashSet<ComponentName> singleUserReceivers = null;
   18813             boolean scannedFirstReceivers = false;
   18814             for (int user : users) {
   18815                 // Skip users that have Shell restrictions, with exception of always permitted
   18816                 // Shell broadcasts
   18817                 if (callingUid == SHELL_UID
   18818                         && mUserController.hasUserRestriction(
   18819                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
   18820                         && !isPermittedShellBroadcast(intent)) {
   18821                     continue;
   18822                 }
   18823                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
   18824                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
   18825                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
   18826                     // If this is not the system user, we need to check for
   18827                     // any receivers that should be filtered out.
   18828                     for (int i=0; i<newReceivers.size(); i++) {
   18829                         ResolveInfo ri = newReceivers.get(i);
   18830                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
   18831                             newReceivers.remove(i);
   18832                             i--;
   18833                         }
   18834                     }
   18835                 }
   18836                 if (newReceivers != null && newReceivers.size() == 0) {
   18837                     newReceivers = null;
   18838                 }
   18839                 if (receivers == null) {
   18840                     receivers = newReceivers;
   18841                 } else if (newReceivers != null) {
   18842                     // We need to concatenate the additional receivers
   18843                     // found with what we have do far.  This would be easy,
   18844                     // but we also need to de-dup any receivers that are
   18845                     // singleUser.
   18846                     if (!scannedFirstReceivers) {
   18847                         // Collect any single user receivers we had already retrieved.
   18848                         scannedFirstReceivers = true;
   18849                         for (int i=0; i<receivers.size(); i++) {
   18850                             ResolveInfo ri = receivers.get(i);
   18851                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   18852                                 ComponentName cn = new ComponentName(
   18853                                         ri.activityInfo.packageName, ri.activityInfo.name);
   18854                                 if (singleUserReceivers == null) {
   18855                                     singleUserReceivers = new HashSet<ComponentName>();
   18856                                 }
   18857                                 singleUserReceivers.add(cn);
   18858                             }
   18859                         }
   18860                     }
   18861                     // Add the new results to the existing results, tracking
   18862                     // and de-dupping single user receivers.
   18863                     for (int i=0; i<newReceivers.size(); i++) {
   18864                         ResolveInfo ri = newReceivers.get(i);
   18865                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   18866                             ComponentName cn = new ComponentName(
   18867                                     ri.activityInfo.packageName, ri.activityInfo.name);
   18868                             if (singleUserReceivers == null) {
   18869                                 singleUserReceivers = new HashSet<ComponentName>();
   18870                             }
   18871                             if (!singleUserReceivers.contains(cn)) {
   18872                                 singleUserReceivers.add(cn);
   18873                                 receivers.add(ri);
   18874                             }
   18875                         } else {
   18876                             receivers.add(ri);
   18877                         }
   18878                     }
   18879                 }
   18880             }
   18881         } catch (RemoteException ex) {
   18882             // pm is in same process, this will never happen.
   18883         }
   18884         return receivers;
   18885     }
   18886 
   18887     private boolean isPermittedShellBroadcast(Intent intent) {
   18888         // remote bugreport should always be allowed to be taken
   18889         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
   18890     }
   18891 
   18892     private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
   18893             String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
   18894         if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
   18895             // Don't yell about broadcasts sent via shell
   18896             return;
   18897         }
   18898 
   18899         final String action = intent.getAction();
   18900         if (isProtectedBroadcast
   18901                 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
   18902                 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
   18903                 || Intent.ACTION_MEDIA_BUTTON.equals(action)
   18904                 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
   18905                 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
   18906                 || Intent.ACTION_MASTER_CLEAR.equals(action)
   18907                 || Intent.ACTION_FACTORY_RESET.equals(action)
   18908                 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
   18909                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
   18910                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
   18911                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
   18912                 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
   18913                 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
   18914                 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
   18915             // Broadcast is either protected, or it's a public action that
   18916             // we've relaxed, so it's fine for system internals to send.
   18917             return;
   18918         }
   18919 
   18920         // This broadcast may be a problem...  but there are often system components that
   18921         // want to send an internal broadcast to themselves, which is annoying to have to
   18922         // explicitly list each action as a protected broadcast, so we will check for that
   18923         // one safe case and allow it: an explicit broadcast, only being received by something
   18924         // that has protected itself.
   18925         if (receivers != null && receivers.size() > 0
   18926                 && (intent.getPackage() != null || intent.getComponent() != null)) {
   18927             boolean allProtected = true;
   18928             for (int i = receivers.size()-1; i >= 0; i--) {
   18929                 Object target = receivers.get(i);
   18930                 if (target instanceof ResolveInfo) {
   18931                     ResolveInfo ri = (ResolveInfo)target;
   18932                     if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
   18933                         allProtected = false;
   18934                         break;
   18935                     }
   18936                 } else {
   18937                     BroadcastFilter bf = (BroadcastFilter)target;
   18938                     if (bf.requiredPermission == null) {
   18939                         allProtected = false;
   18940                         break;
   18941                     }
   18942                 }
   18943             }
   18944             if (allProtected) {
   18945                 // All safe!
   18946                 return;
   18947             }
   18948         }
   18949 
   18950         // The vast majority of broadcasts sent from system internals
   18951         // should be protected to avoid security holes, so yell loudly
   18952         // to ensure we examine these cases.
   18953         if (callerApp != null) {
   18954             Log.wtf(TAG, "Sending non-protected broadcast " + action
   18955                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
   18956                     new Throwable());
   18957         } else {
   18958             Log.wtf(TAG, "Sending non-protected broadcast " + action
   18959                             + " from system uid " + UserHandle.formatUid(callingUid)
   18960                             + " pkg " + callerPackage,
   18961                     new Throwable());
   18962         }
   18963     }
   18964 
   18965     final int broadcastIntentLocked(ProcessRecord callerApp,
   18966             String callerPackage, Intent intent, String resolvedType,
   18967             IIntentReceiver resultTo, int resultCode, String resultData,
   18968             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
   18969             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
   18970         intent = new Intent(intent);
   18971 
   18972         final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
   18973         // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
   18974         if (callerInstantApp) {
   18975             intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
   18976         }
   18977 
   18978         // By default broadcasts do not go to stopped apps.
   18979         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
   18980 
   18981         // If we have not finished booting, don't allow this to launch new processes.
   18982         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
   18983             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   18984         }
   18985 
   18986         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
   18987                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
   18988                 + " ordered=" + ordered + " userid=" + userId);
   18989         if ((resultTo != null) && !ordered) {
   18990             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
   18991         }
   18992 
   18993         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
   18994                 ALLOW_NON_FULL, "broadcast", callerPackage);
   18995 
   18996         // Make sure that the user who is receiving this broadcast is running.
   18997         // If not, we will just skip it. Make an exception for shutdown broadcasts
   18998         // and upgrade steps.
   18999 
   19000         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
   19001             if ((callingUid != SYSTEM_UID
   19002                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
   19003                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
   19004                 Slog.w(TAG, "Skipping broadcast of " + intent
   19005                         + ": user " + userId + " is stopped");
   19006                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
   19007             }
   19008         }
   19009 
   19010         BroadcastOptions brOptions = null;
   19011         if (bOptions != null) {
   19012             brOptions = new BroadcastOptions(bOptions);
   19013             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
   19014                 // See if the caller is allowed to do this.  Note we are checking against
   19015                 // the actual real caller (not whoever provided the operation as say a
   19016                 // PendingIntent), because that who is actually supplied the arguments.
   19017                 if (checkComponentPermission(
   19018                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
   19019                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
   19020                         != PackageManager.PERMISSION_GRANTED) {
   19021                     String msg = "Permission Denial: " + intent.getAction()
   19022                             + " broadcast from " + callerPackage + " (pid=" + callingPid
   19023                             + ", uid=" + callingUid + ")"
   19024                             + " requires "
   19025                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
   19026                     Slog.w(TAG, msg);
   19027                     throw new SecurityException(msg);
   19028                 }
   19029             }
   19030         }
   19031 
   19032         // Verify that protected broadcasts are only being sent by system code,
   19033         // and that system code is only sending protected broadcasts.
   19034         final String action = intent.getAction();
   19035         final boolean isProtectedBroadcast;
   19036         try {
   19037             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
   19038         } catch (RemoteException e) {
   19039             Slog.w(TAG, "Remote exception", e);
   19040             return ActivityManager.BROADCAST_SUCCESS;
   19041         }
   19042 
   19043         final boolean isCallerSystem;
   19044         switch (UserHandle.getAppId(callingUid)) {
   19045             case ROOT_UID:
   19046             case SYSTEM_UID:
   19047             case PHONE_UID:
   19048             case BLUETOOTH_UID:
   19049             case NFC_UID:
   19050                 isCallerSystem = true;
   19051                 break;
   19052             default:
   19053                 isCallerSystem = (callerApp != null) && callerApp.persistent;
   19054                 break;
   19055         }
   19056 
   19057         // First line security check before anything else: stop non-system apps from
   19058         // sending protected broadcasts.
   19059         if (!isCallerSystem) {
   19060             if (isProtectedBroadcast) {
   19061                 String msg = "Permission Denial: not allowed to send broadcast "
   19062                         + action + " from pid="
   19063                         + callingPid + ", uid=" + callingUid;
   19064                 Slog.w(TAG, msg);
   19065                 throw new SecurityException(msg);
   19066 
   19067             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
   19068                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
   19069                 // Special case for compatibility: we don't want apps to send this,
   19070                 // but historically it has not been protected and apps may be using it
   19071                 // to poke their own app widget.  So, instead of making it protected,
   19072                 // just limit it to the caller.
   19073                 if (callerPackage == null) {
   19074                     String msg = "Permission Denial: not allowed to send broadcast "
   19075                             + action + " from unknown caller.";
   19076                     Slog.w(TAG, msg);
   19077                     throw new SecurityException(msg);
   19078                 } else if (intent.getComponent() != null) {
   19079                     // They are good enough to send to an explicit component...  verify
   19080                     // it is being sent to the calling app.
   19081                     if (!intent.getComponent().getPackageName().equals(
   19082                             callerPackage)) {
   19083                         String msg = "Permission Denial: not allowed to send broadcast "
   19084                                 + action + " to "
   19085                                 + intent.getComponent().getPackageName() + " from "
   19086                                 + callerPackage;
   19087                         Slog.w(TAG, msg);
   19088                         throw new SecurityException(msg);
   19089                     }
   19090                 } else {
   19091                     // Limit broadcast to their own package.
   19092                     intent.setPackage(callerPackage);
   19093                 }
   19094             }
   19095         }
   19096 
   19097         if (action != null) {
   19098             if (getBackgroundLaunchBroadcasts().contains(action)) {
   19099                 if (DEBUG_BACKGROUND_CHECK) {
   19100                     Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
   19101                 }
   19102                 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
   19103             }
   19104 
   19105             switch (action) {
   19106                 case Intent.ACTION_UID_REMOVED:
   19107                 case Intent.ACTION_PACKAGE_REMOVED:
   19108                 case Intent.ACTION_PACKAGE_CHANGED:
   19109                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
   19110                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
   19111                 case Intent.ACTION_PACKAGES_SUSPENDED:
   19112                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
   19113                     // Handle special intents: if this broadcast is from the package
   19114                     // manager about a package being removed, we need to remove all of
   19115                     // its activities from the history stack.
   19116                     if (checkComponentPermission(
   19117                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
   19118                             callingPid, callingUid, -1, true)
   19119                             != PackageManager.PERMISSION_GRANTED) {
   19120                         String msg = "Permission Denial: " + intent.getAction()
   19121                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
   19122                                 + ", uid=" + callingUid + ")"
   19123                                 + " requires "
   19124                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
   19125                         Slog.w(TAG, msg);
   19126                         throw new SecurityException(msg);
   19127                     }
   19128                     switch (action) {
   19129                         case Intent.ACTION_UID_REMOVED:
   19130                             final int uid = getUidFromIntent(intent);
   19131                             if (uid >= 0) {
   19132                                 mBatteryStatsService.removeUid(uid);
   19133                                 mAppOpsService.uidRemoved(uid);
   19134                             }
   19135                             break;
   19136                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
   19137                             // If resources are unavailable just force stop all those packages
   19138                             // and flush the attribute cache as well.
   19139                             String list[] =
   19140                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   19141                             if (list != null && list.length > 0) {
   19142                                 for (int i = 0; i < list.length; i++) {
   19143                                     forceStopPackageLocked(list[i], -1, false, true, true,
   19144                                             false, false, userId, "storage unmount");
   19145                                 }
   19146                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
   19147                                 sendPackageBroadcastLocked(
   19148                                         ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
   19149                                         list, userId);
   19150                             }
   19151                             break;
   19152                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
   19153                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
   19154                             break;
   19155                         case Intent.ACTION_PACKAGE_REMOVED:
   19156                         case Intent.ACTION_PACKAGE_CHANGED:
   19157                             Uri data = intent.getData();
   19158                             String ssp;
   19159                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   19160                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
   19161                                 final boolean replacing =
   19162                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
   19163                                 final boolean killProcess =
   19164                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
   19165                                 final boolean fullUninstall = removed && !replacing;
   19166                                 if (removed) {
   19167                                     if (killProcess) {
   19168                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
   19169                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
   19170                                                 false, true, true, false, fullUninstall, userId,
   19171                                                 removed ? "pkg removed" : "pkg changed");
   19172                                     }
   19173                                     final int cmd = killProcess
   19174                                             ? ApplicationThreadConstants.PACKAGE_REMOVED
   19175                                             : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
   19176                                     sendPackageBroadcastLocked(cmd,
   19177                                             new String[] {ssp}, userId);
   19178                                     if (fullUninstall) {
   19179                                         mAppOpsService.packageRemoved(
   19180                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
   19181 
   19182                                         // Remove all permissions granted from/to this package
   19183                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
   19184 
   19185                                         removeTasksByPackageNameLocked(ssp, userId);
   19186 
   19187                                         mServices.forceStopPackageLocked(ssp, userId);
   19188 
   19189                                         // Hide the "unsupported display" dialog if necessary.
   19190                                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
   19191                                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
   19192                                             mUnsupportedDisplaySizeDialog.dismiss();
   19193                                             mUnsupportedDisplaySizeDialog = null;
   19194                                         }
   19195                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
   19196                                         mBatteryStatsService.notePackageUninstalled(ssp);
   19197                                     }
   19198                                 } else {
   19199                                     if (killProcess) {
   19200                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
   19201                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
   19202                                                 userId, ProcessList.INVALID_ADJ,
   19203                                                 false, true, true, false, "change " + ssp);
   19204                                     }
   19205                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
   19206                                             intent.getStringArrayExtra(
   19207                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
   19208                                 }
   19209                             }
   19210                             break;
   19211                         case Intent.ACTION_PACKAGES_SUSPENDED:
   19212                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
   19213                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
   19214                                     intent.getAction());
   19215                             final String[] packageNames = intent.getStringArrayExtra(
   19216                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
   19217                             final int userHandle = intent.getIntExtra(
   19218                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
   19219 
   19220                             synchronized(ActivityManagerService.this) {
   19221                                 mRecentTasks.onPackagesSuspendedChanged(
   19222                                         packageNames, suspended, userHandle);
   19223                             }
   19224                             break;
   19225                     }
   19226                     break;
   19227                 case Intent.ACTION_PACKAGE_REPLACED:
   19228                 {
   19229                     final Uri data = intent.getData();
   19230                     final String ssp;
   19231                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
   19232                         ApplicationInfo aInfo = null;
   19233                         try {
   19234                             aInfo = AppGlobals.getPackageManager()
   19235                                     .getApplicationInfo(ssp, 0 /*flags*/, userId);
   19236                         } catch (RemoteException ignore) {}
   19237                         if (aInfo == null) {
   19238                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
   19239                                     + " ssp=" + ssp + " data=" + data);
   19240                             return ActivityManager.BROADCAST_SUCCESS;
   19241                         }
   19242                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
   19243                         sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
   19244                                 new String[] {ssp}, userId);
   19245                     }
   19246                     break;
   19247                 }
   19248                 case Intent.ACTION_PACKAGE_ADDED:
   19249                 {
   19250                     // Special case for adding a package: by default turn on compatibility mode.
   19251                     Uri data = intent.getData();
   19252                     String ssp;
   19253                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
   19254                         final boolean replacing =
   19255                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
   19256                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
   19257 
   19258                         try {
   19259                             ApplicationInfo ai = AppGlobals.getPackageManager().
   19260                                     getApplicationInfo(ssp, 0, 0);
   19261                             mBatteryStatsService.notePackageInstalled(ssp,
   19262                                     ai != null ? ai.versionCode : 0);
   19263                         } catch (RemoteException e) {
   19264                         }
   19265                     }
   19266                     break;
   19267                 }
   19268                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
   19269                 {
   19270                     Uri data = intent.getData();
   19271                     String ssp;
   19272                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
   19273                         // Hide the "unsupported display" dialog if necessary.
   19274                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
   19275                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
   19276                             mUnsupportedDisplaySizeDialog.dismiss();
   19277                             mUnsupportedDisplaySizeDialog = null;
   19278                         }
   19279                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
   19280                     }
   19281                     break;
   19282                 }
   19283                 case Intent.ACTION_TIMEZONE_CHANGED:
   19284                     // If this is the time zone changed action, queue up a message that will reset
   19285                     // the timezone of all currently running processes. This message will get
   19286                     // queued up before the broadcast happens.
   19287                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
   19288                     break;
   19289                 case Intent.ACTION_TIME_CHANGED:
   19290                     // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
   19291                     // the tri-state value it may contain and "unknown".
   19292                     // For convenience we re-use the Intent extra values.
   19293                     final int NO_EXTRA_VALUE_FOUND = -1;
   19294                     final int timeFormatPreferenceMsgValue = intent.getIntExtra(
   19295                             Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
   19296                             NO_EXTRA_VALUE_FOUND /* defaultValue */);
   19297                     // Only send a message if the time preference is available.
   19298                     if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
   19299                         Message updateTimePreferenceMsg =
   19300                                 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
   19301                                         timeFormatPreferenceMsgValue, 0);
   19302                         mHandler.sendMessage(updateTimePreferenceMsg);
   19303                     }
   19304                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   19305                     synchronized (stats) {
   19306                         stats.noteCurrentTimeChangedLocked();
   19307                     }
   19308                     break;
   19309                 case Intent.ACTION_CLEAR_DNS_CACHE:
   19310                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
   19311                     break;
   19312                 case Proxy.PROXY_CHANGE_ACTION:
   19313                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
   19314                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
   19315                     break;
   19316                 case android.hardware.Camera.ACTION_NEW_PICTURE:
   19317                 case android.hardware.Camera.ACTION_NEW_VIDEO:
   19318                     // In N we just turned these off; in O we are turing them back on partly,
   19319                     // only for registered receivers.  This will still address the main problem
   19320                     // (a spam of apps waking up when a picture is taken putting significant
   19321                     // memory pressure on the system at a bad point), while still allowing apps
   19322                     // that are already actively running to know about this happening.
   19323                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   19324                     break;
   19325                 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
   19326                     mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
   19327                     break;
   19328                 case "com.android.launcher.action.INSTALL_SHORTCUT":
   19329                     // As of O, we no longer support this broadcasts, even for pre-O apps.
   19330                     // Apps should now be using ShortcutManager.pinRequestShortcut().
   19331                     Log.w(TAG, "Broadcast " + action
   19332                             + " no longer supported. It will not be delivered.");
   19333                     return ActivityManager.BROADCAST_SUCCESS;
   19334             }
   19335 
   19336             if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
   19337                     Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
   19338                     Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
   19339                 final int uid = getUidFromIntent(intent);
   19340                 if (uid != -1) {
   19341                     final UidRecord uidRec = mActiveUids.get(uid);
   19342                     if (uidRec != null) {
   19343                         uidRec.updateHasInternetPermission();
   19344                     }
   19345                 }
   19346             }
   19347         }
   19348 
   19349         // Add to the sticky list if requested.
   19350         if (sticky) {
   19351             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
   19352                     callingPid, callingUid)
   19353                     != PackageManager.PERMISSION_GRANTED) {
   19354                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
   19355                         + callingPid + ", uid=" + callingUid
   19356                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   19357                 Slog.w(TAG, msg);
   19358                 throw new SecurityException(msg);
   19359             }
   19360             if (requiredPermissions != null && requiredPermissions.length > 0) {
   19361                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
   19362                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
   19363                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
   19364             }
   19365             if (intent.getComponent() != null) {
   19366                 throw new SecurityException(
   19367                         "Sticky broadcasts can't target a specific component");
   19368             }
   19369             // We use userId directly here, since the "all" target is maintained
   19370             // as a separate set of sticky broadcasts.
   19371             if (userId != UserHandle.USER_ALL) {
   19372                 // But first, if this is not a broadcast to all users, then
   19373                 // make sure it doesn't conflict with an existing broadcast to
   19374                 // all users.
   19375                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
   19376                         UserHandle.USER_ALL);
   19377                 if (stickies != null) {
   19378                     ArrayList<Intent> list = stickies.get(intent.getAction());
   19379                     if (list != null) {
   19380                         int N = list.size();
   19381                         int i;
   19382                         for (i=0; i<N; i++) {
   19383                             if (intent.filterEquals(list.get(i))) {
   19384                                 throw new IllegalArgumentException(
   19385                                         "Sticky broadcast " + intent + " for user "
   19386                                         + userId + " conflicts with existing global broadcast");
   19387                             }
   19388                         }
   19389                     }
   19390                 }
   19391             }
   19392             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   19393             if (stickies == null) {
   19394                 stickies = new ArrayMap<>();
   19395                 mStickyBroadcasts.put(userId, stickies);
   19396             }
   19397             ArrayList<Intent> list = stickies.get(intent.getAction());
   19398             if (list == null) {
   19399                 list = new ArrayList<>();
   19400                 stickies.put(intent.getAction(), list);
   19401             }
   19402             final int stickiesCount = list.size();
   19403             int i;
   19404             for (i = 0; i < stickiesCount; i++) {
   19405                 if (intent.filterEquals(list.get(i))) {
   19406                     // This sticky already exists, replace it.
   19407                     list.set(i, new Intent(intent));
   19408                     break;
   19409                 }
   19410             }
   19411             if (i >= stickiesCount) {
   19412                 list.add(new Intent(intent));
   19413             }
   19414         }
   19415 
   19416         int[] users;
   19417         if (userId == UserHandle.USER_ALL) {
   19418             // Caller wants broadcast to go to all started users.
   19419             users = mUserController.getStartedUserArrayLocked();
   19420         } else {
   19421             // Caller wants broadcast to go to one specific user.
   19422             users = new int[] {userId};
   19423         }
   19424 
   19425         // Figure out who all will receive this broadcast.
   19426         List receivers = null;
   19427         List<BroadcastFilter> registeredReceivers = null;
   19428         // Need to resolve the intent to interested receivers...
   19429         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
   19430                  == 0) {
   19431             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
   19432         }
   19433         if (intent.getComponent() == null) {
   19434             if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
   19435                 // Query one target user at a time, excluding shell-restricted users
   19436                 for (int i = 0; i < users.length; i++) {
   19437                     if (mUserController.hasUserRestriction(
   19438                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
   19439                         continue;
   19440                     }
   19441                     List<BroadcastFilter> registeredReceiversForUser =
   19442                             mReceiverResolver.queryIntent(intent,
   19443                                     resolvedType, false /*defaultOnly*/, users[i]);
   19444                     if (registeredReceivers == null) {
   19445                         registeredReceivers = registeredReceiversForUser;
   19446                     } else if (registeredReceiversForUser != null) {
   19447                         registeredReceivers.addAll(registeredReceiversForUser);
   19448                     }
   19449                 }
   19450             } else {
   19451                 registeredReceivers = mReceiverResolver.queryIntent(intent,
   19452                         resolvedType, false /*defaultOnly*/, userId);
   19453             }
   19454         }
   19455 
   19456         final boolean replacePending =
   19457                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
   19458 
   19459         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
   19460                 + " replacePending=" + replacePending);
   19461 
   19462         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
   19463         if (!ordered && NR > 0) {
   19464             // If we are not serializing this broadcast, then send the
   19465             // registered receivers separately so they don't wait for the
   19466             // components to be launched.
   19467             if (isCallerSystem) {
   19468                 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
   19469                         isProtectedBroadcast, registeredReceivers);
   19470             }
   19471             final BroadcastQueue queue = broadcastQueueForIntent(intent);
   19472             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   19473                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
   19474                     requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
   19475                     resultCode, resultData, resultExtras, ordered, sticky, false, userId);
   19476             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
   19477             final boolean replaced = replacePending
   19478                     && (queue.replaceParallelBroadcastLocked(r) != null);
   19479             // Note: We assume resultTo is null for non-ordered broadcasts.
   19480             if (!replaced) {
   19481                 queue.enqueueParallelBroadcastLocked(r);
   19482                 queue.scheduleBroadcastsLocked();
   19483             }
   19484             registeredReceivers = null;
   19485             NR = 0;
   19486         }
   19487 
   19488         // Merge into one list.
   19489         int ir = 0;
   19490         if (receivers != null) {
   19491             // A special case for PACKAGE_ADDED: do not allow the package
   19492             // being added to see this broadcast.  This prevents them from
   19493             // using this as a back door to get run as soon as they are
   19494             // installed.  Maybe in the future we want to have a special install
   19495             // broadcast or such for apps, but we'd like to deliberately make
   19496             // this decision.
   19497             String skipPackages[] = null;
   19498             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
   19499                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
   19500                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
   19501                 Uri data = intent.getData();
   19502                 if (data != null) {
   19503                     String pkgName = data.getSchemeSpecificPart();
   19504                     if (pkgName != null) {
   19505                         skipPackages = new String[] { pkgName };
   19506                     }
   19507                 }
   19508             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
   19509                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   19510             }
   19511             if (skipPackages != null && (skipPackages.length > 0)) {
   19512                 for (String skipPackage : skipPackages) {
   19513                     if (skipPackage != null) {
   19514                         int NT = receivers.size();
   19515                         for (int it=0; it<NT; it++) {
   19516                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
   19517                             if (curt.activityInfo.packageName.equals(skipPackage)) {
   19518                                 receivers.remove(it);
   19519                                 it--;
   19520                                 NT--;
   19521                             }
   19522                         }
   19523                     }
   19524                 }
   19525             }
   19526 
   19527             int NT = receivers != null ? receivers.size() : 0;
   19528             int it = 0;
   19529             ResolveInfo curt = null;
   19530             BroadcastFilter curr = null;
   19531             while (it < NT && ir < NR) {
   19532                 if (curt == null) {
   19533                     curt = (ResolveInfo)receivers.get(it);
   19534                 }
   19535                 if (curr == null) {
   19536                     curr = registeredReceivers.get(ir);
   19537                 }
   19538                 if (curr.getPriority() >= curt.priority) {
   19539                     // Insert this broadcast record into the final list.
   19540                     receivers.add(it, curr);
   19541                     ir++;
   19542                     curr = null;
   19543                     it++;
   19544                     NT++;
   19545                 } else {
   19546                     // Skip to the next ResolveInfo in the final list.
   19547                     it++;
   19548                     curt = null;
   19549                 }
   19550             }
   19551         }
   19552         while (ir < NR) {
   19553             if (receivers == null) {
   19554                 receivers = new ArrayList();
   19555             }
   19556             receivers.add(registeredReceivers.get(ir));
   19557             ir++;
   19558         }
   19559 
   19560         if (isCallerSystem) {
   19561             checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
   19562                     isProtectedBroadcast, receivers);
   19563         }
   19564 
   19565         if ((receivers != null && receivers.size() > 0)
   19566                 || resultTo != null) {
   19567             BroadcastQueue queue = broadcastQueueForIntent(intent);
   19568             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   19569                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
   19570                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
   19571                     resultData, resultExtras, ordered, sticky, false, userId);
   19572 
   19573             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
   19574                     + ": prev had " + queue.mOrderedBroadcasts.size());
   19575             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
   19576                     "Enqueueing broadcast " + r.intent.getAction());
   19577 
   19578             final BroadcastRecord oldRecord =
   19579                     replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
   19580             if (oldRecord != null) {
   19581                 // Replaced, fire the result-to receiver.
   19582                 if (oldRecord.resultTo != null) {
   19583                     final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
   19584                     try {
   19585                         oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
   19586                                 oldRecord.intent,
   19587                                 Activity.RESULT_CANCELED, null, null,
   19588                                 false, false, oldRecord.userId);
   19589                     } catch (RemoteException e) {
   19590                         Slog.w(TAG, "Failure ["
   19591                                 + queue.mQueueName + "] sending broadcast result of "
   19592                                 + intent, e);
   19593 
   19594                     }
   19595                 }
   19596             } else {
   19597                 queue.enqueueOrderedBroadcastLocked(r);
   19598                 queue.scheduleBroadcastsLocked();
   19599             }
   19600         } else {
   19601             // There was nobody interested in the broadcast, but we still want to record
   19602             // that it happened.
   19603             if (intent.getComponent() == null && intent.getPackage() == null
   19604                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   19605                 // This was an implicit broadcast... let's record it for posterity.
   19606                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
   19607             }
   19608         }
   19609 
   19610         return ActivityManager.BROADCAST_SUCCESS;
   19611     }
   19612 
   19613     /**
   19614      * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
   19615      */
   19616     private int getUidFromIntent(Intent intent) {
   19617         if (intent == null) {
   19618             return -1;
   19619         }
   19620         final Bundle intentExtras = intent.getExtras();
   19621         return intent.hasExtra(Intent.EXTRA_UID)
   19622                 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
   19623     }
   19624 
   19625     final void rotateBroadcastStatsIfNeededLocked() {
   19626         final long now = SystemClock.elapsedRealtime();
   19627         if (mCurBroadcastStats == null ||
   19628                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
   19629             mLastBroadcastStats = mCurBroadcastStats;
   19630             if (mLastBroadcastStats != null) {
   19631                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
   19632                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
   19633             }
   19634             mCurBroadcastStats = new BroadcastStats();
   19635         }
   19636     }
   19637 
   19638     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
   19639             int skipCount, long dispatchTime) {
   19640         rotateBroadcastStatsIfNeededLocked();
   19641         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
   19642     }
   19643 
   19644     final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
   19645         rotateBroadcastStatsIfNeededLocked();
   19646         mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
   19647     }
   19648 
   19649     final Intent verifyBroadcastLocked(Intent intent) {
   19650         // Refuse possible leaked file descriptors
   19651         if (intent != null && intent.hasFileDescriptors() == true) {
   19652             throw new IllegalArgumentException("File descriptors passed in Intent");
   19653         }
   19654 
   19655         int flags = intent.getFlags();
   19656 
   19657         if (!mProcessesReady) {
   19658             // if the caller really truly claims to know what they're doing, go
   19659             // ahead and allow the broadcast without launching any receivers
   19660             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
   19661                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
   19662             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   19663                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
   19664                         + " before boot completion");
   19665                 throw new IllegalStateException("Cannot broadcast before boot completed");
   19666             }
   19667         }
   19668 
   19669         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   19670             throw new IllegalArgumentException(
   19671                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   19672         }
   19673 
   19674         if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
   19675             switch (Binder.getCallingUid()) {
   19676                 case ROOT_UID:
   19677                 case SHELL_UID:
   19678                     break;
   19679                 default:
   19680                     Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
   19681                             + Binder.getCallingUid());
   19682                     intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
   19683                     break;
   19684             }
   19685         }
   19686 
   19687         return intent;
   19688     }
   19689 
   19690     public final int broadcastIntent(IApplicationThread caller,
   19691             Intent intent, String resolvedType, IIntentReceiver resultTo,
   19692             int resultCode, String resultData, Bundle resultExtras,
   19693             String[] requiredPermissions, int appOp, Bundle bOptions,
   19694             boolean serialized, boolean sticky, int userId) {
   19695         enforceNotIsolatedCaller("broadcastIntent");
   19696         synchronized(this) {
   19697             intent = verifyBroadcastLocked(intent);
   19698 
   19699             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   19700             final int callingPid = Binder.getCallingPid();
   19701             final int callingUid = Binder.getCallingUid();
   19702             final long origId = Binder.clearCallingIdentity();
   19703             int res = broadcastIntentLocked(callerApp,
   19704                     callerApp != null ? callerApp.info.packageName : null,
   19705                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
   19706                     requiredPermissions, appOp, bOptions, serialized, sticky,
   19707                     callingPid, callingUid, userId);
   19708             Binder.restoreCallingIdentity(origId);
   19709             return res;
   19710         }
   19711     }
   19712 
   19713 
   19714     int broadcastIntentInPackage(String packageName, int uid,
   19715             Intent intent, String resolvedType, IIntentReceiver resultTo,
   19716             int resultCode, String resultData, Bundle resultExtras,
   19717             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
   19718             int userId) {
   19719         synchronized(this) {
   19720             intent = verifyBroadcastLocked(intent);
   19721 
   19722             final long origId = Binder.clearCallingIdentity();
   19723             String[] requiredPermissions = requiredPermission == null ? null
   19724                     : new String[] {requiredPermission};
   19725             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
   19726                     resultTo, resultCode, resultData, resultExtras,
   19727                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
   19728                     sticky, -1, uid, userId);
   19729             Binder.restoreCallingIdentity(origId);
   19730             return res;
   19731         }
   19732     }
   19733 
   19734     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
   19735         // Refuse possible leaked file descriptors
   19736         if (intent != null && intent.hasFileDescriptors() == true) {
   19737             throw new IllegalArgumentException("File descriptors passed in Intent");
   19738         }
   19739 
   19740         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   19741                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
   19742 
   19743         synchronized(this) {
   19744             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
   19745                     != PackageManager.PERMISSION_GRANTED) {
   19746                 String msg = "Permission Denial: unbroadcastIntent() from pid="
   19747                         + Binder.getCallingPid()
   19748                         + ", uid=" + Binder.getCallingUid()
   19749                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   19750                 Slog.w(TAG, msg);
   19751                 throw new SecurityException(msg);
   19752             }
   19753             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   19754             if (stickies != null) {
   19755                 ArrayList<Intent> list = stickies.get(intent.getAction());
   19756                 if (list != null) {
   19757                     int N = list.size();
   19758                     int i;
   19759                     for (i=0; i<N; i++) {
   19760                         if (intent.filterEquals(list.get(i))) {
   19761                             list.remove(i);
   19762                             break;
   19763                         }
   19764                     }
   19765                     if (list.size() <= 0) {
   19766                         stickies.remove(intent.getAction());
   19767                     }
   19768                 }
   19769                 if (stickies.size() <= 0) {
   19770                     mStickyBroadcasts.remove(userId);
   19771                 }
   19772             }
   19773         }
   19774     }
   19775 
   19776     void backgroundServicesFinishedLocked(int userId) {
   19777         for (BroadcastQueue queue : mBroadcastQueues) {
   19778             queue.backgroundServicesFinishedLocked(userId);
   19779         }
   19780     }
   19781 
   19782     public void finishReceiver(IBinder who, int resultCode, String resultData,
   19783             Bundle resultExtras, boolean resultAbort, int flags) {
   19784         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
   19785 
   19786         // Refuse possible leaked file descriptors
   19787         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
   19788             throw new IllegalArgumentException("File descriptors passed in Bundle");
   19789         }
   19790 
   19791         final long origId = Binder.clearCallingIdentity();
   19792         try {
   19793             boolean doNext = false;
   19794             BroadcastRecord r;
   19795 
   19796             synchronized(this) {
   19797                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
   19798                         ? mFgBroadcastQueue : mBgBroadcastQueue;
   19799                 r = queue.getMatchingOrderedReceiver(who);
   19800                 if (r != null) {
   19801                     doNext = r.queue.finishReceiverLocked(r, resultCode,
   19802                         resultData, resultExtras, resultAbort, true);
   19803                 }
   19804             }
   19805 
   19806             if (doNext) {
   19807                 r.queue.processNextBroadcast(false);
   19808             }
   19809             trimApplications();
   19810         } finally {
   19811             Binder.restoreCallingIdentity(origId);
   19812         }
   19813     }
   19814 
   19815     // =========================================================
   19816     // INSTRUMENTATION
   19817     // =========================================================
   19818 
   19819     public boolean startInstrumentation(ComponentName className,
   19820             String profileFile, int flags, Bundle arguments,
   19821             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
   19822             int userId, String abiOverride) {
   19823         enforceNotIsolatedCaller("startInstrumentation");
   19824         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   19825                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
   19826         // Refuse possible leaked file descriptors
   19827         if (arguments != null && arguments.hasFileDescriptors()) {
   19828             throw new IllegalArgumentException("File descriptors passed in Bundle");
   19829         }
   19830 
   19831         synchronized(this) {
   19832             InstrumentationInfo ii = null;
   19833             ApplicationInfo ai = null;
   19834             try {
   19835                 ii = mContext.getPackageManager().getInstrumentationInfo(
   19836                     className, STOCK_PM_FLAGS);
   19837                 ai = AppGlobals.getPackageManager().getApplicationInfo(
   19838                         ii.targetPackage, STOCK_PM_FLAGS, userId);
   19839             } catch (PackageManager.NameNotFoundException e) {
   19840             } catch (RemoteException e) {
   19841             }
   19842             if (ii == null) {
   19843                 reportStartInstrumentationFailureLocked(watcher, className,
   19844                         "Unable to find instrumentation info for: " + className);
   19845                 return false;
   19846             }
   19847             if (ai == null) {
   19848                 reportStartInstrumentationFailureLocked(watcher, className,
   19849                         "Unable to find instrumentation target package: " + ii.targetPackage);
   19850                 return false;
   19851             }
   19852             if (!ai.hasCode()) {
   19853                 reportStartInstrumentationFailureLocked(watcher, className,
   19854                         "Instrumentation target has no code: " + ii.targetPackage);
   19855                 return false;
   19856             }
   19857 
   19858             int match = mContext.getPackageManager().checkSignatures(
   19859                     ii.targetPackage, ii.packageName);
   19860             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
   19861                 String msg = "Permission Denial: starting instrumentation "
   19862                         + className + " from pid="
   19863                         + Binder.getCallingPid()
   19864                         + ", uid=" + Binder.getCallingPid()
   19865                         + " not allowed because package " + ii.packageName
   19866                         + " does not have a signature matching the target "
   19867                         + ii.targetPackage;
   19868                 reportStartInstrumentationFailureLocked(watcher, className, msg);
   19869                 throw new SecurityException(msg);
   19870             }
   19871 
   19872             ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
   19873             activeInstr.mClass = className;
   19874             String defProcess = ai.processName;;
   19875             if (ii.targetProcesses == null) {
   19876                 activeInstr.mTargetProcesses = new String[]{ai.processName};
   19877             } else if (ii.targetProcesses.equals("*")) {
   19878                 activeInstr.mTargetProcesses = new String[0];
   19879             } else {
   19880                 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
   19881                 defProcess = activeInstr.mTargetProcesses[0];
   19882             }
   19883             activeInstr.mTargetInfo = ai;
   19884             activeInstr.mProfileFile = profileFile;
   19885             activeInstr.mArguments = arguments;
   19886             activeInstr.mWatcher = watcher;
   19887             activeInstr.mUiAutomationConnection = uiAutomationConnection;
   19888             activeInstr.mResultClass = className;
   19889 
   19890             final long origId = Binder.clearCallingIdentity();
   19891             // Instrumentation can kill and relaunch even persistent processes
   19892             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
   19893                     "start instr");
   19894             ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
   19895             app.instr = activeInstr;
   19896             activeInstr.mFinished = false;
   19897             activeInstr.mRunningProcesses.add(app);
   19898             if (!mActiveInstrumentation.contains(activeInstr)) {
   19899                 mActiveInstrumentation.add(activeInstr);
   19900             }
   19901             Binder.restoreCallingIdentity(origId);
   19902         }
   19903 
   19904         return true;
   19905     }
   19906 
   19907     /**
   19908      * Report errors that occur while attempting to start Instrumentation.  Always writes the
   19909      * error to the logs, but if somebody is watching, send the report there too.  This enables
   19910      * the "am" command to report errors with more information.
   19911      *
   19912      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
   19913      * @param cn The component name of the instrumentation.
   19914      * @param report The error report.
   19915      */
   19916     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
   19917             ComponentName cn, String report) {
   19918         Slog.w(TAG, report);
   19919         if (watcher != null) {
   19920             Bundle results = new Bundle();
   19921             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
   19922             results.putString("Error", report);
   19923             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
   19924         }
   19925     }
   19926 
   19927     void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
   19928         if (app.instr == null) {
   19929             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
   19930             return;
   19931         }
   19932 
   19933         if (!app.instr.mFinished && results != null) {
   19934             if (app.instr.mCurResults == null) {
   19935                 app.instr.mCurResults = new Bundle(results);
   19936             } else {
   19937                 app.instr.mCurResults.putAll(results);
   19938             }
   19939         }
   19940     }
   19941 
   19942     public void addInstrumentationResults(IApplicationThread target, Bundle results) {
   19943         int userId = UserHandle.getCallingUserId();
   19944         // Refuse possible leaked file descriptors
   19945         if (results != null && results.hasFileDescriptors()) {
   19946             throw new IllegalArgumentException("File descriptors passed in Intent");
   19947         }
   19948 
   19949         synchronized(this) {
   19950             ProcessRecord app = getRecordForAppLocked(target);
   19951             if (app == null) {
   19952                 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
   19953                 return;
   19954             }
   19955             final long origId = Binder.clearCallingIdentity();
   19956             addInstrumentationResultsLocked(app, results);
   19957             Binder.restoreCallingIdentity(origId);
   19958         }
   19959     }
   19960 
   19961     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
   19962         if (app.instr == null) {
   19963             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
   19964             return;
   19965         }
   19966 
   19967         if (!app.instr.mFinished) {
   19968             if (app.instr.mWatcher != null) {
   19969                 Bundle finalResults = app.instr.mCurResults;
   19970                 if (finalResults != null) {
   19971                     if (app.instr.mCurResults != null && results != null) {
   19972                         finalResults.putAll(results);
   19973                     }
   19974                 } else {
   19975                     finalResults = results;
   19976                 }
   19977                 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
   19978                         app.instr.mClass, resultCode, finalResults);
   19979             }
   19980 
   19981             // Can't call out of the system process with a lock held, so post a message.
   19982             if (app.instr.mUiAutomationConnection != null) {
   19983                 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
   19984                         app.instr.mUiAutomationConnection).sendToTarget();
   19985             }
   19986             app.instr.mFinished = true;
   19987         }
   19988 
   19989         app.instr.removeProcess(app);
   19990         app.instr = null;
   19991 
   19992         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
   19993                 "finished inst");
   19994     }
   19995 
   19996     public void finishInstrumentation(IApplicationThread target,
   19997             int resultCode, Bundle results) {
   19998         int userId = UserHandle.getCallingUserId();
   19999         // Refuse possible leaked file descriptors
   20000         if (results != null && results.hasFileDescriptors()) {
   20001             throw new IllegalArgumentException("File descriptors passed in Intent");
   20002         }
   20003 
   20004         synchronized(this) {
   20005             ProcessRecord app = getRecordForAppLocked(target);
   20006             if (app == null) {
   20007                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
   20008                 return;
   20009             }
   20010             final long origId = Binder.clearCallingIdentity();
   20011             finishInstrumentationLocked(app, resultCode, results);
   20012             Binder.restoreCallingIdentity(origId);
   20013         }
   20014     }
   20015 
   20016     // =========================================================
   20017     // CONFIGURATION
   20018     // =========================================================
   20019 
   20020     public ConfigurationInfo getDeviceConfigurationInfo() {
   20021         ConfigurationInfo config = new ConfigurationInfo();
   20022         synchronized (this) {
   20023             final Configuration globalConfig = getGlobalConfiguration();
   20024             config.reqTouchScreen = globalConfig.touchscreen;
   20025             config.reqKeyboardType = globalConfig.keyboard;
   20026             config.reqNavigation = globalConfig.navigation;
   20027             if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
   20028                     || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
   20029                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
   20030             }
   20031             if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
   20032                     && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
   20033                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
   20034             }
   20035             config.reqGlEsVersion = GL_ES_VERSION;
   20036         }
   20037         return config;
   20038     }
   20039 
   20040     ActivityStack getFocusedStack() {
   20041         return mStackSupervisor.getFocusedStack();
   20042     }
   20043 
   20044     @Override
   20045     public int getFocusedStackId() throws RemoteException {
   20046         ActivityStack focusedStack = getFocusedStack();
   20047         if (focusedStack != null) {
   20048             return focusedStack.getStackId();
   20049         }
   20050         return -1;
   20051     }
   20052 
   20053     public Configuration getConfiguration() {
   20054         Configuration ci;
   20055         synchronized(this) {
   20056             ci = new Configuration(getGlobalConfiguration());
   20057             ci.userSetLocale = false;
   20058         }
   20059         return ci;
   20060     }
   20061 
   20062     @Override
   20063     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
   20064         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
   20065         synchronized (this) {
   20066             mSuppressResizeConfigChanges = suppress;
   20067         }
   20068     }
   20069 
   20070     /**
   20071      * NOTE: For the pinned stack, this method is usually called after the bounds animation has
   20072      *       animated the stack to the fullscreen, but can also be called if we are relaunching an
   20073      *       activity and clearing the task at the same time.
   20074      */
   20075     @Override
   20076     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
   20077         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
   20078         if (StackId.isHomeOrRecentsStack(fromStackId)) {
   20079             throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
   20080         }
   20081         synchronized (this) {
   20082             final long origId = Binder.clearCallingIdentity();
   20083             try {
   20084                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
   20085             } finally {
   20086                 Binder.restoreCallingIdentity(origId);
   20087             }
   20088         }
   20089     }
   20090 
   20091     @Override
   20092     public void updatePersistentConfiguration(Configuration values) {
   20093         enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
   20094         enforceWriteSettingsPermission("updatePersistentConfiguration()");
   20095         if (values == null) {
   20096             throw new NullPointerException("Configuration must not be null");
   20097         }
   20098 
   20099         int userId = UserHandle.getCallingUserId();
   20100 
   20101         synchronized(this) {
   20102             updatePersistentConfigurationLocked(values, userId);
   20103         }
   20104     }
   20105 
   20106     private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
   20107         final long origId = Binder.clearCallingIdentity();
   20108         try {
   20109             updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
   20110         } finally {
   20111             Binder.restoreCallingIdentity(origId);
   20112         }
   20113     }
   20114 
   20115     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
   20116         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
   20117                 FONT_SCALE, 1.0f, userId);
   20118 
   20119         synchronized (this) {
   20120             if (getGlobalConfiguration().fontScale == scaleFactor) {
   20121                 return;
   20122             }
   20123 
   20124             final Configuration configuration
   20125                     = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
   20126             configuration.fontScale = scaleFactor;
   20127             updatePersistentConfigurationLocked(configuration, userId);
   20128         }
   20129     }
   20130 
   20131     private void enforceWriteSettingsPermission(String func) {
   20132         int uid = Binder.getCallingUid();
   20133         if (uid == ROOT_UID) {
   20134             return;
   20135         }
   20136 
   20137         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
   20138                 Settings.getPackageNameForUid(mContext, uid), false)) {
   20139             return;
   20140         }
   20141 
   20142         String msg = "Permission Denial: " + func + " from pid="
   20143                 + Binder.getCallingPid()
   20144                 + ", uid=" + uid
   20145                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
   20146         Slog.w(TAG, msg);
   20147         throw new SecurityException(msg);
   20148     }
   20149 
   20150     @Override
   20151     public boolean updateConfiguration(Configuration values) {
   20152         enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
   20153 
   20154         synchronized(this) {
   20155             if (values == null && mWindowManager != null) {
   20156                 // sentinel: fetch the current configuration from the window manager
   20157                 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
   20158             }
   20159 
   20160             if (mWindowManager != null) {
   20161                 // Update OOM levels based on display size.
   20162                 mProcessList.applyDisplaySize(mWindowManager);
   20163             }
   20164 
   20165             final long origId = Binder.clearCallingIdentity();
   20166             try {
   20167                 if (values != null) {
   20168                     Settings.System.clearConfiguration(values);
   20169                 }
   20170                 updateConfigurationLocked(values, null, false, false /* persistent */,
   20171                         UserHandle.USER_NULL, false /* deferResume */,
   20172                         mTmpUpdateConfigurationResult);
   20173                 return mTmpUpdateConfigurationResult.changes != 0;
   20174             } finally {
   20175                 Binder.restoreCallingIdentity(origId);
   20176             }
   20177         }
   20178     }
   20179 
   20180     void updateUserConfigurationLocked() {
   20181         final Configuration configuration = new Configuration(getGlobalConfiguration());
   20182         final int currentUserId = mUserController.getCurrentUserIdLocked();
   20183         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
   20184                 currentUserId, Settings.System.canWrite(mContext));
   20185         updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
   20186                 false /* persistent */, currentUserId, false /* deferResume */);
   20187     }
   20188 
   20189     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
   20190             boolean initLocale) {
   20191         return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
   20192     }
   20193 
   20194     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
   20195             boolean initLocale, boolean deferResume) {
   20196         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
   20197         return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
   20198                 UserHandle.USER_NULL, deferResume);
   20199     }
   20200 
   20201     // To cache the list of supported system locales
   20202     private String[] mSupportedSystemLocales = null;
   20203 
   20204     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
   20205             boolean initLocale, boolean persistent, int userId, boolean deferResume) {
   20206         return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
   20207                 deferResume, null /* result */);
   20208     }
   20209 
   20210     /**
   20211      * Do either or both things: (1) change the current configuration, and (2)
   20212      * make sure the given activity is running with the (now) current
   20213      * configuration.  Returns true if the activity has been left running, or
   20214      * false if <var>starting</var> is being destroyed to match the new
   20215      * configuration.
   20216      *
   20217      * @param userId is only used when persistent parameter is set to true to persist configuration
   20218      *               for that particular user
   20219      */
   20220     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
   20221             boolean initLocale, boolean persistent, int userId, boolean deferResume,
   20222             UpdateConfigurationResult result) {
   20223         int changes = 0;
   20224         boolean kept = true;
   20225 
   20226         if (mWindowManager != null) {
   20227             mWindowManager.deferSurfaceLayout();
   20228         }
   20229         try {
   20230             if (values != null) {
   20231                 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
   20232                         deferResume);
   20233             }
   20234 
   20235             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
   20236         } finally {
   20237             if (mWindowManager != null) {
   20238                 mWindowManager.continueSurfaceLayout();
   20239             }
   20240         }
   20241 
   20242         if (result != null) {
   20243             result.changes = changes;
   20244             result.activityRelaunched = !kept;
   20245         }
   20246         return kept;
   20247     }
   20248 
   20249     /** Update default (global) configuration and notify listeners about changes. */
   20250     private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
   20251             boolean persistent, int userId, boolean deferResume) {
   20252         mTempConfig.setTo(getGlobalConfiguration());
   20253         final int changes = mTempConfig.updateFrom(values);
   20254         if (changes == 0) {
   20255             // Since calling to Activity.setRequestedOrientation leads to freezing the window with
   20256             // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
   20257             // performDisplayOverrideConfigUpdate in order to send the new display configuration
   20258             // (even if there are no actual changes) to unfreeze the window.
   20259             performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
   20260             return 0;
   20261         }
   20262 
   20263         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
   20264                 "Updating global configuration to: " + values);
   20265 
   20266         EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
   20267 
   20268         if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
   20269             final LocaleList locales = values.getLocales();
   20270             int bestLocaleIndex = 0;
   20271             if (locales.size() > 1) {
   20272                 if (mSupportedSystemLocales == null) {
   20273                     mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
   20274                 }
   20275                 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
   20276             }
   20277             SystemProperties.set("persist.sys.locale",
   20278                     locales.get(bestLocaleIndex).toLanguageTag());
   20279             LocaleList.setDefault(locales, bestLocaleIndex);
   20280             mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
   20281                     locales.get(bestLocaleIndex)));
   20282         }
   20283 
   20284         mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
   20285         mTempConfig.seq = mConfigurationSeq;
   20286 
   20287         // Update stored global config and notify everyone about the change.
   20288         mStackSupervisor.onConfigurationChanged(mTempConfig);
   20289 
   20290         Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
   20291         // TODO(multi-display): Update UsageEvents#Event to include displayId.
   20292         mUsageStatsService.reportConfigurationChange(mTempConfig,
   20293                 mUserController.getCurrentUserIdLocked());
   20294 
   20295         // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
   20296         mShowDialogs = shouldShowDialogs(mTempConfig);
   20297 
   20298         AttributeCache ac = AttributeCache.instance();
   20299         if (ac != null) {
   20300             ac.updateConfiguration(mTempConfig);
   20301         }
   20302 
   20303         // Make sure all resources in our process are updated right now, so that anyone who is going
   20304         // to retrieve resource values after we return will be sure to get the new ones. This is
   20305         // especially important during boot, where the first config change needs to guarantee all
   20306         // resources have that config before following boot code is executed.
   20307         mSystemThread.applyConfigurationToResources(mTempConfig);
   20308 
   20309         // We need another copy of global config because we're scheduling some calls instead of
   20310         // running them in place. We need to be sure that object we send will be handled unchanged.
   20311         final Configuration configCopy = new Configuration(mTempConfig);
   20312         if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
   20313             Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
   20314             msg.obj = configCopy;
   20315             msg.arg1 = userId;
   20316             mHandler.sendMessage(msg);
   20317         }
   20318 
   20319         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   20320             ProcessRecord app = mLruProcesses.get(i);
   20321             try {
   20322                 if (app.thread != null) {
   20323                     if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
   20324                             + app.processName + " new config " + configCopy);
   20325                     app.thread.scheduleConfigurationChanged(configCopy);
   20326                 }
   20327             } catch (Exception e) {
   20328             }
   20329         }
   20330 
   20331         Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
   20332         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
   20333                 | Intent.FLAG_RECEIVER_FOREGROUND
   20334                 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
   20335         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
   20336                 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
   20337                 UserHandle.USER_ALL);
   20338         if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
   20339             intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
   20340             intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
   20341                     | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
   20342                     | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
   20343             if (initLocale || !mProcessesReady) {
   20344                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   20345             }
   20346             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
   20347                     AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
   20348                     UserHandle.USER_ALL);
   20349         }
   20350 
   20351         // Override configuration of the default display duplicates global config, so we need to
   20352         // update it also. This will also notify WindowManager about changes.
   20353         performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
   20354                 DEFAULT_DISPLAY);
   20355 
   20356         return changes;
   20357     }
   20358 
   20359     @Override
   20360     public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
   20361         enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
   20362 
   20363         synchronized (this) {
   20364             // Check if display is initialized in AM.
   20365             if (!mStackSupervisor.isDisplayAdded(displayId)) {
   20366                 // Call might come when display is not yet added or has already been removed.
   20367                 if (DEBUG_CONFIGURATION) {
   20368                     Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
   20369                             + displayId);
   20370                 }
   20371                 return false;
   20372             }
   20373 
   20374             if (values == null && mWindowManager != null) {
   20375                 // sentinel: fetch the current configuration from the window manager
   20376                 values = mWindowManager.computeNewConfiguration(displayId);
   20377             }
   20378 
   20379             if (mWindowManager != null) {
   20380                 // Update OOM levels based on display size.
   20381                 mProcessList.applyDisplaySize(mWindowManager);
   20382             }
   20383 
   20384             final long origId = Binder.clearCallingIdentity();
   20385             try {
   20386                 if (values != null) {
   20387                     Settings.System.clearConfiguration(values);
   20388                 }
   20389                 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
   20390                         false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
   20391                 return mTmpUpdateConfigurationResult.changes != 0;
   20392             } finally {
   20393                 Binder.restoreCallingIdentity(origId);
   20394             }
   20395         }
   20396     }
   20397 
   20398     boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
   20399             boolean deferResume, int displayId) {
   20400         return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
   20401                 displayId, null /* result */);
   20402     }
   20403 
   20404     /**
   20405      * Updates override configuration specific for the selected display. If no config is provided,
   20406      * new one will be computed in WM based on current display info.
   20407      */
   20408     private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
   20409             ActivityRecord starting, boolean deferResume, int displayId,
   20410             UpdateConfigurationResult result) {
   20411         int changes = 0;
   20412         boolean kept = true;
   20413 
   20414         if (mWindowManager != null) {
   20415             mWindowManager.deferSurfaceLayout();
   20416         }
   20417         try {
   20418             if (values != null) {
   20419                 if (displayId == DEFAULT_DISPLAY) {
   20420                     // Override configuration of the default display duplicates global config, so
   20421                     // we're calling global config update instead for default display. It will also
   20422                     // apply the correct override config.
   20423                     changes = updateGlobalConfiguration(values, false /* initLocale */,
   20424                             false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
   20425                 } else {
   20426                     changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
   20427                 }
   20428             }
   20429 
   20430             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
   20431         } finally {
   20432             if (mWindowManager != null) {
   20433                 mWindowManager.continueSurfaceLayout();
   20434             }
   20435         }
   20436 
   20437         if (result != null) {
   20438             result.changes = changes;
   20439             result.activityRelaunched = !kept;
   20440         }
   20441         return kept;
   20442     }
   20443 
   20444     private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
   20445             int displayId) {
   20446         mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
   20447         final int changes = mTempConfig.updateFrom(values);
   20448         if (changes != 0) {
   20449             Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
   20450                     + mTempConfig + " for displayId=" + displayId);
   20451             mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
   20452 
   20453             final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
   20454             if (isDensityChange && displayId == DEFAULT_DISPLAY) {
   20455                 // Reset the unsupported display size dialog.
   20456                 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
   20457 
   20458                 killAllBackgroundProcessesExcept(N,
   20459                         ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
   20460             }
   20461         }
   20462 
   20463         // Update the configuration with WM first and check if any of the stacks need to be resized
   20464         // due to the configuration change. If so, resize the stacks now and do any relaunches if
   20465         // necessary. This way we don't need to relaunch again afterwards in
   20466         // ensureActivityConfigurationLocked().
   20467         if (mWindowManager != null) {
   20468             final int[] resizedStacks =
   20469                     mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
   20470             if (resizedStacks != null) {
   20471                 for (int stackId : resizedStacks) {
   20472                     resizeStackWithBoundsFromWindowManager(stackId, deferResume);
   20473                 }
   20474             }
   20475         }
   20476 
   20477         return changes;
   20478     }
   20479 
   20480     /** Applies latest configuration and/or visibility updates if needed. */
   20481     private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
   20482         boolean kept = true;
   20483         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
   20484         // mainStack is null during startup.
   20485         if (mainStack != null) {
   20486             if (changes != 0 && starting == null) {
   20487                 // If the configuration changed, and the caller is not already
   20488                 // in the process of starting an activity, then find the top
   20489                 // activity to check if its configuration needs to change.
   20490                 starting = mainStack.topRunningActivityLocked();
   20491             }
   20492 
   20493             if (starting != null) {
   20494                 kept = starting.ensureActivityConfigurationLocked(changes,
   20495                         false /* preserveWindow */);
   20496                 // And we need to make sure at this point that all other activities
   20497                 // are made visible with the correct configuration.
   20498                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
   20499                         !PRESERVE_WINDOWS);
   20500             }
   20501         }
   20502 
   20503         return kept;
   20504     }
   20505 
   20506     /** Helper method that requests bounds from WM and applies them to stack. */
   20507     private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
   20508         final Rect newStackBounds = new Rect();
   20509         mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
   20510         mStackSupervisor.resizeStackLocked(
   20511                 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
   20512                 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
   20513                 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
   20514     }
   20515 
   20516     /**
   20517      * Decide based on the configuration whether we should show the ANR,
   20518      * crash, etc dialogs.  The idea is that if there is no affordance to
   20519      * press the on-screen buttons, or the user experience would be more
   20520      * greatly impacted than the crash itself, we shouldn't show the dialog.
   20521      *
   20522      * A thought: SystemUI might also want to get told about this, the Power
   20523      * dialog / global actions also might want different behaviors.
   20524      */
   20525     private static boolean shouldShowDialogs(Configuration config) {
   20526         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
   20527                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
   20528                                    && config.navigation == Configuration.NAVIGATION_NONAV);
   20529         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
   20530         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
   20531                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE))
   20532                 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
   20533                 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
   20534         return inputMethodExists && uiModeSupportsDialogs;
   20535     }
   20536 
   20537     @Override
   20538     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
   20539         synchronized (this) {
   20540             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
   20541             if (srec != null) {
   20542                 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
   20543             }
   20544         }
   20545         return false;
   20546     }
   20547 
   20548     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
   20549             Intent resultData) {
   20550 
   20551         synchronized (this) {
   20552             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   20553             if (r != null) {
   20554                 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
   20555             }
   20556             return false;
   20557         }
   20558     }
   20559 
   20560     public int getLaunchedFromUid(IBinder activityToken) {
   20561         ActivityRecord srec;
   20562         synchronized (this) {
   20563             srec = ActivityRecord.forTokenLocked(activityToken);
   20564         }
   20565         if (srec == null) {
   20566             return -1;
   20567         }
   20568         return srec.launchedFromUid;
   20569     }
   20570 
   20571     public String getLaunchedFromPackage(IBinder activityToken) {
   20572         ActivityRecord srec;
   20573         synchronized (this) {
   20574             srec = ActivityRecord.forTokenLocked(activityToken);
   20575         }
   20576         if (srec == null) {
   20577             return null;
   20578         }
   20579         return srec.launchedFromPackage;
   20580     }
   20581 
   20582     // =========================================================
   20583     // LIFETIME MANAGEMENT
   20584     // =========================================================
   20585 
   20586     // Returns whether the app is receiving broadcast.
   20587     // If receiving, fetch all broadcast queues which the app is
   20588     // the current [or imminent] receiver on.
   20589     private boolean isReceivingBroadcastLocked(ProcessRecord app,
   20590             ArraySet<BroadcastQueue> receivingQueues) {
   20591         if (!app.curReceivers.isEmpty()) {
   20592             for (BroadcastRecord r : app.curReceivers) {
   20593                 receivingQueues.add(r.queue);
   20594             }
   20595             return true;
   20596         }
   20597 
   20598         // It's not the current receiver, but it might be starting up to become one
   20599         for (BroadcastQueue queue : mBroadcastQueues) {
   20600             final BroadcastRecord r = queue.mPendingBroadcast;
   20601             if (r != null && r.curApp == app) {
   20602                 // found it; report which queue it's in
   20603                 receivingQueues.add(queue);
   20604             }
   20605         }
   20606 
   20607         return !receivingQueues.isEmpty();
   20608     }
   20609 
   20610     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
   20611             int targetUid, ComponentName targetComponent, String targetProcess) {
   20612         if (!mTrackingAssociations) {
   20613             return null;
   20614         }
   20615         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
   20616                 = mAssociations.get(targetUid);
   20617         if (components == null) {
   20618             components = new ArrayMap<>();
   20619             mAssociations.put(targetUid, components);
   20620         }
   20621         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
   20622         if (sourceUids == null) {
   20623             sourceUids = new SparseArray<>();
   20624             components.put(targetComponent, sourceUids);
   20625         }
   20626         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
   20627         if (sourceProcesses == null) {
   20628             sourceProcesses = new ArrayMap<>();
   20629             sourceUids.put(sourceUid, sourceProcesses);
   20630         }
   20631         Association ass = sourceProcesses.get(sourceProcess);
   20632         if (ass == null) {
   20633             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
   20634                     targetProcess);
   20635             sourceProcesses.put(sourceProcess, ass);
   20636         }
   20637         ass.mCount++;
   20638         ass.mNesting++;
   20639         if (ass.mNesting == 1) {
   20640             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
   20641             ass.mLastState = sourceState;
   20642         }
   20643         return ass;
   20644     }
   20645 
   20646     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
   20647             ComponentName targetComponent) {
   20648         if (!mTrackingAssociations) {
   20649             return;
   20650         }
   20651         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
   20652                 = mAssociations.get(targetUid);
   20653         if (components == null) {
   20654             return;
   20655         }
   20656         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
   20657         if (sourceUids == null) {
   20658             return;
   20659         }
   20660         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
   20661         if (sourceProcesses == null) {
   20662             return;
   20663         }
   20664         Association ass = sourceProcesses.get(sourceProcess);
   20665         if (ass == null || ass.mNesting <= 0) {
   20666             return;
   20667         }
   20668         ass.mNesting--;
   20669         if (ass.mNesting == 0) {
   20670             long uptime = SystemClock.uptimeMillis();
   20671             ass.mTime += uptime - ass.mStartTime;
   20672             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
   20673                     += uptime - ass.mLastStateUptime;
   20674             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
   20675         }
   20676     }
   20677 
   20678     private void noteUidProcessState(final int uid, final int state) {
   20679         mBatteryStatsService.noteUidProcessState(uid, state);
   20680         if (mTrackingAssociations) {
   20681             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
   20682                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
   20683                         = mAssociations.valueAt(i1);
   20684                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
   20685                     SparseArray<ArrayMap<String, Association>> sourceUids
   20686                             = targetComponents.valueAt(i2);
   20687                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
   20688                     if (sourceProcesses != null) {
   20689                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
   20690                             Association ass = sourceProcesses.valueAt(i4);
   20691                             if (ass.mNesting >= 1) {
   20692                                 // currently associated
   20693                                 long uptime = SystemClock.uptimeMillis();
   20694                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
   20695                                         += uptime - ass.mLastStateUptime;
   20696                                 ass.mLastState = state;
   20697                                 ass.mLastStateUptime = uptime;
   20698                             }
   20699                         }
   20700                     }
   20701                 }
   20702             }
   20703         }
   20704     }
   20705 
   20706     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
   20707             boolean doingAll, long now) {
   20708         if (mAdjSeq == app.adjSeq) {
   20709             // This adjustment has already been computed.
   20710             return app.curRawAdj;
   20711         }
   20712 
   20713         if (app.thread == null) {
   20714             app.adjSeq = mAdjSeq;
   20715             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   20716             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   20717             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
   20718         }
   20719 
   20720         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
   20721         app.adjSource = null;
   20722         app.adjTarget = null;
   20723         app.empty = false;
   20724         app.cached = false;
   20725 
   20726         final int activitiesSize = app.activities.size();
   20727 
   20728         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   20729             // The max adjustment doesn't allow this app to be anything
   20730             // below foreground, so it is not worth doing work for it.
   20731             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
   20732             app.adjType = "fixed";
   20733             app.adjSeq = mAdjSeq;
   20734             app.curRawAdj = app.maxAdj;
   20735             app.foregroundActivities = false;
   20736             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   20737             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
   20738             // System processes can do UI, and when they do we want to have
   20739             // them trim their memory after the user leaves the UI.  To
   20740             // facilitate this, here we need to determine whether or not it
   20741             // is currently showing UI.
   20742             app.systemNoUi = true;
   20743             if (app == TOP_APP) {
   20744                 app.systemNoUi = false;
   20745                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
   20746                 app.adjType = "pers-top-activity";
   20747             } else if (app.hasTopUi) {
   20748                 app.systemNoUi = false;
   20749                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
   20750                 app.adjType = "pers-top-ui";
   20751             } else if (activitiesSize > 0) {
   20752                 for (int j = 0; j < activitiesSize; j++) {
   20753                     final ActivityRecord r = app.activities.get(j);
   20754                     if (r.visible) {
   20755                         app.systemNoUi = false;
   20756                     }
   20757                 }
   20758             }
   20759             if (!app.systemNoUi) {
   20760                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
   20761             }
   20762             return (app.curAdj=app.maxAdj);
   20763         }
   20764 
   20765         app.systemNoUi = false;
   20766 
   20767         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
   20768 
   20769         // Determine the importance of the process, starting with most
   20770         // important to least, and assign an appropriate OOM adjustment.
   20771         int adj;
   20772         int schedGroup;
   20773         int procState;
   20774         boolean foregroundActivities = false;
   20775         mTmpBroadcastQueue.clear();
   20776         if (app == TOP_APP) {
   20777             // The last app on the list is the foreground app.
   20778             adj = ProcessList.FOREGROUND_APP_ADJ;
   20779             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
   20780             app.adjType = "top-activity";
   20781             foregroundActivities = true;
   20782             procState = PROCESS_STATE_CUR_TOP;
   20783             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
   20784         } else if (app.instr != null) {
   20785             // Don't want to kill running instrumentation.
   20786             adj = ProcessList.FOREGROUND_APP_ADJ;
   20787             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   20788             app.adjType = "instrumentation";
   20789             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
   20790             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
   20791         } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
   20792             // An app that is currently receiving a broadcast also
   20793             // counts as being in the foreground for OOM killer purposes.
   20794             // It's placed in a sched group based on the nature of the
   20795             // broadcast as reflected by which queue it's active in.
   20796             adj = ProcessList.FOREGROUND_APP_ADJ;
   20797             schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
   20798                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
   20799             app.adjType = "broadcast";
   20800             procState = ActivityManager.PROCESS_STATE_RECEIVER;
   20801             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
   20802         } else if (app.executingServices.size() > 0) {
   20803             // An app that is currently executing a service callback also
   20804             // counts as being in the foreground.
   20805             adj = ProcessList.FOREGROUND_APP_ADJ;
   20806             schedGroup = app.execServicesFg ?
   20807                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
   20808             app.adjType = "exec-service";
   20809             procState = ActivityManager.PROCESS_STATE_SERVICE;
   20810             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
   20811             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
   20812         } else {
   20813             // As far as we know the process is empty.  We may change our mind later.
   20814             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   20815             // At this point we don't actually know the adjustment.  Use the cached adj
   20816             // value that the caller wants us to.
   20817             adj = cachedAdj;
   20818             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   20819             app.cached = true;
   20820             app.empty = true;
   20821             app.adjType = "cch-empty";
   20822             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
   20823         }
   20824 
   20825         // Examine all activities if not already foreground.
   20826         if (!foregroundActivities && activitiesSize > 0) {
   20827             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
   20828             for (int j = 0; j < activitiesSize; j++) {
   20829                 final ActivityRecord r = app.activities.get(j);
   20830                 if (r.app != app) {
   20831                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
   20832                             + " instead of expected " + app);
   20833                     if (r.app == null || (r.app.uid == app.uid)) {
   20834                         // Only fix things up when they look sane
   20835                         r.app = app;
   20836                     } else {
   20837                         continue;
   20838                     }
   20839                 }
   20840                 if (r.visible) {
   20841                     // App has a visible activity; only upgrade adjustment.
   20842                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   20843                         adj = ProcessList.VISIBLE_APP_ADJ;
   20844                         app.adjType = "vis-activity";
   20845                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
   20846                     }
   20847                     if (procState > PROCESS_STATE_CUR_TOP) {
   20848                         procState = PROCESS_STATE_CUR_TOP;
   20849                         app.adjType = "vis-activity";
   20850                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
   20851                     }
   20852                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   20853                     app.cached = false;
   20854                     app.empty = false;
   20855                     foregroundActivities = true;
   20856                     final TaskRecord task = r.getTask();
   20857                     if (task != null && minLayer > 0) {
   20858                         final int layer = task.mLayerRank;
   20859                         if (layer >= 0 && minLayer > layer) {
   20860                             minLayer = layer;
   20861                         }
   20862                     }
   20863                     break;
   20864                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
   20865                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   20866                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   20867                         app.adjType = "pause-activity";
   20868                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
   20869                     }
   20870                     if (procState > PROCESS_STATE_CUR_TOP) {
   20871                         procState = PROCESS_STATE_CUR_TOP;
   20872                         app.adjType = "pause-activity";
   20873                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
   20874                     }
   20875                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   20876                     app.cached = false;
   20877                     app.empty = false;
   20878                     foregroundActivities = true;
   20879                 } else if (r.state == ActivityState.STOPPING) {
   20880                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   20881                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   20882                         app.adjType = "stop-activity";
   20883                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
   20884                     }
   20885                     // For the process state, we will at this point consider the
   20886                     // process to be cached.  It will be cached either as an activity
   20887                     // or empty depending on whether the activity is finishing.  We do
   20888                     // this so that we can treat the process as cached for purposes of
   20889                     // memory trimming (determing current memory level, trim command to
   20890                     // send to process) since there can be an arbitrary number of stopping
   20891                     // processes and they should soon all go into the cached state.
   20892                     if (!r.finishing) {
   20893                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   20894                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   20895                             app.adjType = "stop-activity";
   20896                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
   20897                         }
   20898                     }
   20899                     app.cached = false;
   20900                     app.empty = false;
   20901                     foregroundActivities = true;
   20902                 } else {
   20903                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   20904                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   20905                         app.adjType = "cch-act";
   20906                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
   20907                     }
   20908                 }
   20909             }
   20910             if (adj == ProcessList.VISIBLE_APP_ADJ) {
   20911                 adj += minLayer;
   20912             }
   20913         }
   20914 
   20915         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
   20916                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
   20917             if (app.foregroundServices) {
   20918                 // The user is aware of this app, so make it visible.
   20919                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   20920                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
   20921                 app.cached = false;
   20922                 app.adjType = "fg-service";
   20923                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   20924                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
   20925             } else if (app.hasOverlayUi) {
   20926                 // The process is display an overlay UI.
   20927                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   20928                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   20929                 app.cached = false;
   20930                 app.adjType = "has-overlay-ui";
   20931                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   20932                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
   20933             }
   20934         }
   20935 
   20936         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
   20937                 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
   20938             if (app.forcingToImportant != null) {
   20939                 // This is currently used for toasts...  they are not interactive, and
   20940                 // we don't want them to cause the app to become fully foreground (and
   20941                 // thus out of background check), so we yes the best background level we can.
   20942                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   20943                 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
   20944                 app.cached = false;
   20945                 app.adjType = "force-imp";
   20946                 app.adjSource = app.forcingToImportant;
   20947                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   20948                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
   20949             }
   20950         }
   20951 
   20952         if (app == mHeavyWeightProcess) {
   20953             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   20954                 // We don't want to kill the current heavy-weight process.
   20955                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
   20956                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   20957                 app.cached = false;
   20958                 app.adjType = "heavy";
   20959                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
   20960             }
   20961             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
   20962                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
   20963                 app.adjType = "heavy";
   20964                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
   20965             }
   20966         }
   20967 
   20968         if (app == mHomeProcess) {
   20969             if (adj > ProcessList.HOME_APP_ADJ) {
   20970                 // This process is hosting what we currently consider to be the
   20971                 // home app, so we don't want to let it go into the background.
   20972                 adj = ProcessList.HOME_APP_ADJ;
   20973                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   20974                 app.cached = false;
   20975                 app.adjType = "home";
   20976                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
   20977             }
   20978             if (procState > ActivityManager.PROCESS_STATE_HOME) {
   20979                 procState = ActivityManager.PROCESS_STATE_HOME;
   20980                 app.adjType = "home";
   20981                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
   20982             }
   20983         }
   20984 
   20985         if (app == mPreviousProcess && app.activities.size() > 0) {
   20986             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
   20987                 // This was the previous process that showed UI to the user.
   20988                 // We want to try to keep it around more aggressively, to give
   20989                 // a good experience around switching between two apps.
   20990                 adj = ProcessList.PREVIOUS_APP_ADJ;
   20991                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   20992                 app.cached = false;
   20993                 app.adjType = "previous";
   20994                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
   20995             }
   20996             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   20997                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   20998                 app.adjType = "previous";
   20999                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
   21000             }
   21001         }
   21002 
   21003         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
   21004                 + " reason=" + app.adjType);
   21005 
   21006         // By default, we use the computed adjustment.  It may be changed if
   21007         // there are applications dependent on our services or providers, but
   21008         // this gives us a baseline and makes sure we don't get into an
   21009         // infinite recursion.
   21010         app.adjSeq = mAdjSeq;
   21011         app.curRawAdj = adj;
   21012         app.hasStartedServices = false;
   21013 
   21014         if (mBackupTarget != null && app == mBackupTarget.app) {
   21015             // If possible we want to avoid killing apps while they're being backed up
   21016             if (adj > ProcessList.BACKUP_APP_ADJ) {
   21017                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
   21018                 adj = ProcessList.BACKUP_APP_ADJ;
   21019                 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
   21020                     procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
   21021                 }
   21022                 app.adjType = "backup";
   21023                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
   21024                 app.cached = false;
   21025             }
   21026             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
   21027                 procState = ActivityManager.PROCESS_STATE_BACKUP;
   21028                 app.adjType = "backup";
   21029                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
   21030             }
   21031         }
   21032 
   21033         boolean mayBeTop = false;
   21034         String mayBeTopType = null;
   21035         Object mayBeTopSource = null;
   21036         Object mayBeTopTarget = null;
   21037 
   21038         for (int is = app.services.size()-1;
   21039                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   21040                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   21041                         || procState > ActivityManager.PROCESS_STATE_TOP);
   21042                 is--) {
   21043             ServiceRecord s = app.services.valueAt(is);
   21044             if (s.startRequested) {
   21045                 app.hasStartedServices = true;
   21046                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
   21047                     procState = ActivityManager.PROCESS_STATE_SERVICE;
   21048                     app.adjType = "started-services";
   21049                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
   21050                 }
   21051                 if (app.hasShownUi && app != mHomeProcess) {
   21052                     // If this process has shown some UI, let it immediately
   21053                     // go to the LRU list because it may be pretty heavy with
   21054                     // UI stuff.  We'll tag it with a label just to help
   21055                     // debug and understand what is going on.
   21056                     if (adj > ProcessList.SERVICE_ADJ) {
   21057                         app.adjType = "cch-started-ui-services";
   21058                     }
   21059                 } else {
   21060                     if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
   21061                         // This service has seen some activity within
   21062                         // recent memory, so we will keep its process ahead
   21063                         // of the background processes.
   21064                         if (adj > ProcessList.SERVICE_ADJ) {
   21065                             adj = ProcessList.SERVICE_ADJ;
   21066                             app.adjType = "started-services";
   21067                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
   21068                             app.cached = false;
   21069                         }
   21070                     }
   21071                     // If we have let the service slide into the background
   21072                     // state, still have some text describing what it is doing
   21073                     // even though the service no longer has an impact.
   21074                     if (adj > ProcessList.SERVICE_ADJ) {
   21075                         app.adjType = "cch-started-services";
   21076                     }
   21077                 }
   21078             }
   21079 
   21080             for (int conni = s.connections.size()-1;
   21081                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   21082                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   21083                             || procState > ActivityManager.PROCESS_STATE_TOP);
   21084                     conni--) {
   21085                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
   21086                 for (int i = 0;
   21087                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
   21088                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   21089                                 || procState > ActivityManager.PROCESS_STATE_TOP);
   21090                         i++) {
   21091                     // XXX should compute this based on the max of
   21092                     // all connected clients.
   21093                     ConnectionRecord cr = clist.get(i);
   21094                     if (cr.binding.client == app) {
   21095                         // Binding to ourself is not interesting.
   21096                         continue;
   21097                     }
   21098 
   21099                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
   21100                         ProcessRecord client = cr.binding.client;
   21101                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
   21102                                 TOP_APP, doingAll, now);
   21103                         int clientProcState = client.curProcState;
   21104                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   21105                             // If the other app is cached for any reason, for purposes here
   21106                             // we are going to consider it empty.  The specific cached state
   21107                             // doesn't propagate except under certain conditions.
   21108                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   21109                         }
   21110                         String adjType = null;
   21111                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
   21112                             // Not doing bind OOM management, so treat
   21113                             // this guy more like a started service.
   21114                             if (app.hasShownUi && app != mHomeProcess) {
   21115                                 // If this process has shown some UI, let it immediately
   21116                                 // go to the LRU list because it may be pretty heavy with
   21117                                 // UI stuff.  We'll tag it with a label just to help
   21118                                 // debug and understand what is going on.
   21119                                 if (adj > clientAdj) {
   21120                                     adjType = "cch-bound-ui-services";
   21121                                 }
   21122                                 app.cached = false;
   21123                                 clientAdj = adj;
   21124                                 clientProcState = procState;
   21125                             } else {
   21126                                 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
   21127                                     // This service has not seen activity within
   21128                                     // recent memory, so allow it to drop to the
   21129                                     // LRU list if there is no other reason to keep
   21130                                     // it around.  We'll also tag it with a label just
   21131                                     // to help debug and undertand what is going on.
   21132                                     if (adj > clientAdj) {
   21133                                         adjType = "cch-bound-services";
   21134                                     }
   21135                                     clientAdj = adj;
   21136                                 }
   21137                             }
   21138                         }
   21139                         if (adj > clientAdj) {
   21140                             // If this process has recently shown UI, and
   21141                             // the process that is binding to it is less
   21142                             // important than being visible, then we don't
   21143                             // care about the binding as much as we care
   21144                             // about letting this process get into the LRU
   21145                             // list to be killed and restarted if needed for
   21146                             // memory.
   21147                             if (app.hasShownUi && app != mHomeProcess
   21148                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   21149                                 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
   21150                                     adjType = "cch-bound-ui-services";
   21151                                 }
   21152                             } else {
   21153                                 int newAdj;
   21154                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
   21155                                         |Context.BIND_IMPORTANT)) != 0) {
   21156                                     newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
   21157                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
   21158                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
   21159                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
   21160                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   21161                                     newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
   21162                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   21163                                     newAdj = clientAdj;
   21164                                 } else {
   21165                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   21166                                         newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
   21167                                     } else {
   21168                                         newAdj = adj;
   21169                                     }
   21170                                 }
   21171                                 if (!client.cached) {
   21172                                     app.cached = false;
   21173                                 }
   21174                                 if (adj >  newAdj) {
   21175                                     adj = newAdj;
   21176                                     adjType = "service";
   21177                                 }
   21178                             }
   21179                         }
   21180                         if ((cr.flags & (Context.BIND_NOT_FOREGROUND
   21181                                 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
   21182                             // This will treat important bound services identically to
   21183                             // the top app, which may behave differently than generic
   21184                             // foreground work.
   21185                             if (client.curSchedGroup > schedGroup) {
   21186                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
   21187                                     schedGroup = client.curSchedGroup;
   21188                                 } else {
   21189                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   21190                                 }
   21191                             }
   21192                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   21193                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   21194                                     // Special handling of clients who are in the top state.
   21195                                     // We *may* want to consider this process to be in the
   21196                                     // top state as well, but only if there is not another
   21197                                     // reason for it to be running.  Being on the top is a
   21198                                     // special state, meaning you are specifically running
   21199                                     // for the current top app.  If the process is already
   21200                                     // running in the background for some other reason, it
   21201                                     // is more important to continue considering it to be
   21202                                     // in the background state.
   21203                                     mayBeTop = true;
   21204                                     mayBeTopType = "service";
   21205                                     mayBeTopSource = cr.binding.client;
   21206                                     mayBeTopTarget = s.name;
   21207                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   21208                                 } else {
   21209                                     // Special handling for above-top states (persistent
   21210                                     // processes).  These should not bring the current process
   21211                                     // into the top state, since they are not on top.  Instead
   21212                                     // give them the best state after that.
   21213                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
   21214                                         clientProcState =
   21215                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
   21216                                     } else if (mWakefulness
   21217                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
   21218                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
   21219                                                     != 0) {
   21220                                         clientProcState =
   21221                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
   21222                                     } else {
   21223                                         clientProcState =
   21224                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   21225                                     }
   21226                                 }
   21227                             }
   21228                         } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
   21229                             if (clientProcState <
   21230                                     ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
   21231                                 clientProcState =
   21232                                         ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
   21233                             }
   21234                         } else {
   21235                             if (clientProcState <
   21236                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   21237                                 clientProcState =
   21238                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
   21239                             }
   21240                         }
   21241                         if (procState > clientProcState) {
   21242                             procState = clientProcState;
   21243                             if (adjType == null) {
   21244                                 adjType = "service";
   21245                             }
   21246                         }
   21247                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   21248                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
   21249                             app.pendingUiClean = true;
   21250                         }
   21251                         if (adjType != null) {
   21252                             app.adjType = adjType;
   21253                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   21254                                     .REASON_SERVICE_IN_USE;
   21255                             app.adjSource = cr.binding.client;
   21256                             app.adjSourceProcState = clientProcState;
   21257                             app.adjTarget = s.name;
   21258                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
   21259                                     + ": " + app + ", due to " + cr.binding.client
   21260                                     + " adj=" + adj + " procState=" + procState);
   21261                         }
   21262                     }
   21263                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
   21264                         app.treatLikeActivity = true;
   21265                     }
   21266                     final ActivityRecord a = cr.activity;
   21267                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
   21268                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
   21269                             (a.visible || a.state == ActivityState.RESUMED ||
   21270                              a.state == ActivityState.PAUSING)) {
   21271                             adj = ProcessList.FOREGROUND_APP_ADJ;
   21272                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   21273                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
   21274                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
   21275                                 } else {
   21276                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   21277                                 }
   21278                             }
   21279                             app.cached = false;
   21280                             app.adjType = "service";
   21281                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   21282                                     .REASON_SERVICE_IN_USE;
   21283                             app.adjSource = a;
   21284                             app.adjSourceProcState = procState;
   21285                             app.adjTarget = s.name;
   21286                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
   21287                                     + app);
   21288                         }
   21289                     }
   21290                 }
   21291             }
   21292         }
   21293 
   21294         for (int provi = app.pubProviders.size()-1;
   21295                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   21296                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   21297                         || procState > ActivityManager.PROCESS_STATE_TOP);
   21298                 provi--) {
   21299             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
   21300             for (int i = cpr.connections.size()-1;
   21301                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   21302                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   21303                             || procState > ActivityManager.PROCESS_STATE_TOP);
   21304                     i--) {
   21305                 ContentProviderConnection conn = cpr.connections.get(i);
   21306                 ProcessRecord client = conn.client;
   21307                 if (client == app) {
   21308                     // Being our own client is not interesting.
   21309                     continue;
   21310                 }
   21311                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
   21312                 int clientProcState = client.curProcState;
   21313                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   21314                     // If the other app is cached for any reason, for purposes here
   21315                     // we are going to consider it empty.
   21316                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   21317                 }
   21318                 String adjType = null;
   21319                 if (adj > clientAdj) {
   21320                     if (app.hasShownUi && app != mHomeProcess
   21321                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   21322                         adjType = "cch-ui-provider";
   21323                     } else {
   21324                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
   21325                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
   21326                         adjType = "provider";
   21327                     }
   21328                     app.cached &= client.cached;
   21329                 }
   21330                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   21331                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   21332                         // Special handling of clients who are in the top state.
   21333                         // We *may* want to consider this process to be in the
   21334                         // top state as well, but only if there is not another
   21335                         // reason for it to be running.  Being on the top is a
   21336                         // special state, meaning you are specifically running
   21337                         // for the current top app.  If the process is already
   21338                         // running in the background for some other reason, it
   21339                         // is more important to continue considering it to be
   21340                         // in the background state.
   21341                         mayBeTop = true;
   21342                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   21343                         mayBeTopType = adjType = "provider-top";
   21344                         mayBeTopSource = client;
   21345                         mayBeTopTarget = cpr.name;
   21346                     } else {
   21347                         // Special handling for above-top states (persistent
   21348                         // processes).  These should not bring the current process
   21349                         // into the top state, since they are not on top.  Instead
   21350                         // give them the best state after that.
   21351                         clientProcState =
   21352                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
   21353                         if (adjType == null) {
   21354                             adjType = "provider";
   21355                         }
   21356                     }
   21357                 }
   21358                 if (procState > clientProcState) {
   21359                     procState = clientProcState;
   21360                 }
   21361                 if (client.curSchedGroup > schedGroup) {
   21362                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   21363                 }
   21364                 if (adjType != null) {
   21365                     app.adjType = adjType;
   21366                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   21367                             .REASON_PROVIDER_IN_USE;
   21368                     app.adjSource = client;
   21369                     app.adjSourceProcState = clientProcState;
   21370                     app.adjTarget = cpr.name;
   21371                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
   21372                             + ": " + app + ", due to " + client
   21373                             + " adj=" + adj + " procState=" + procState);
   21374                 }
   21375             }
   21376             // If the provider has external (non-framework) process
   21377             // dependencies, ensure that its adjustment is at least
   21378             // FOREGROUND_APP_ADJ.
   21379             if (cpr.hasExternalProcessHandles()) {
   21380                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
   21381                     adj = ProcessList.FOREGROUND_APP_ADJ;
   21382                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   21383                     app.cached = false;
   21384                     app.adjType = "ext-provider";
   21385                     app.adjTarget = cpr.name;
   21386                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
   21387                 }
   21388                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
   21389                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   21390                 }
   21391             }
   21392         }
   21393 
   21394         if (app.lastProviderTime > 0 &&
   21395                 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
   21396             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
   21397                 adj = ProcessList.PREVIOUS_APP_ADJ;
   21398                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   21399                 app.cached = false;
   21400                 app.adjType = "recent-provider";
   21401                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
   21402             }
   21403             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   21404                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   21405                 app.adjType = "recent-provider";
   21406                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
   21407             }
   21408         }
   21409 
   21410         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
   21411             // A client of one of our services or providers is in the top state.  We
   21412             // *may* want to be in the top state, but not if we are already running in
   21413             // the background for some other reason.  For the decision here, we are going
   21414             // to pick out a few specific states that we want to remain in when a client
   21415             // is top (states that tend to be longer-term) and otherwise allow it to go
   21416             // to the top state.
   21417             switch (procState) {
   21418                 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
   21419                     // Something else is keeping it at this level, just leave it.
   21420                     break;
   21421                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
   21422                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
   21423                 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
   21424                 case ActivityManager.PROCESS_STATE_SERVICE:
   21425                     // These all are longer-term states, so pull them up to the top
   21426                     // of the background states, but not all the way to the top state.
   21427                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
   21428                     app.adjType = mayBeTopType;
   21429                     app.adjSource = mayBeTopSource;
   21430                     app.adjTarget = mayBeTopTarget;
   21431                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
   21432                             + ": " + app + ", due to " + mayBeTopSource
   21433                             + " adj=" + adj + " procState=" + procState);
   21434                     break;
   21435                 default:
   21436                     // Otherwise, top is a better choice, so take it.
   21437                     procState = ActivityManager.PROCESS_STATE_TOP;
   21438                     app.adjType = mayBeTopType;
   21439                     app.adjSource = mayBeTopSource;
   21440                     app.adjTarget = mayBeTopTarget;
   21441                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
   21442                             + ": " + app + ", due to " + mayBeTopSource
   21443                             + " adj=" + adj + " procState=" + procState);
   21444                     break;
   21445             }
   21446         }
   21447 
   21448         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
   21449             if (app.hasClientActivities) {
   21450                 // This is a cached process, but with client activities.  Mark it so.
   21451                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
   21452                 app.adjType = "cch-client-act";
   21453             } else if (app.treatLikeActivity) {
   21454                 // This is a cached process, but somebody wants us to treat it like it has
   21455                 // an activity, okay!
   21456                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   21457                 app.adjType = "cch-as-act";
   21458             }
   21459         }
   21460 
   21461         if (adj == ProcessList.SERVICE_ADJ) {
   21462             if (doingAll) {
   21463                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
   21464                 mNewNumServiceProcs++;
   21465                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
   21466                 if (!app.serviceb) {
   21467                     // This service isn't far enough down on the LRU list to
   21468                     // normally be a B service, but if we are low on RAM and it
   21469                     // is large we want to force it down since we would prefer to
   21470                     // keep launcher over it.
   21471                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
   21472                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
   21473                         app.serviceHighRam = true;
   21474                         app.serviceb = true;
   21475                         //Slog.i(TAG, "ADJ " + app + " high ram!");
   21476                     } else {
   21477                         mNewNumAServiceProcs++;
   21478                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
   21479                     }
   21480                 } else {
   21481                     app.serviceHighRam = false;
   21482                 }
   21483             }
   21484             if (app.serviceb) {
   21485                 adj = ProcessList.SERVICE_B_ADJ;
   21486             }
   21487         }
   21488 
   21489         app.curRawAdj = adj;
   21490 
   21491         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
   21492         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
   21493         if (adj > app.maxAdj) {
   21494             adj = app.maxAdj;
   21495             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   21496                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   21497             }
   21498         }
   21499 
   21500         // Do final modification to adj.  Everything we do between here and applying
   21501         // the final setAdj must be done in this function, because we will also use
   21502         // it when computing the final cached adj later.  Note that we don't need to
   21503         // worry about this for max adj above, since max adj will always be used to
   21504         // keep it out of the cached vaues.
   21505         app.curAdj = app.modifyRawOomAdj(adj);
   21506         app.curSchedGroup = schedGroup;
   21507         app.curProcState = procState;
   21508         app.foregroundActivities = foregroundActivities;
   21509 
   21510         return app.curRawAdj;
   21511     }
   21512 
   21513     /**
   21514      * Record new PSS sample for a process.
   21515      */
   21516     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
   21517             long now) {
   21518         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
   21519                 swapPss * 1024);
   21520         proc.lastPssTime = now;
   21521         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
   21522         if (DEBUG_PSS) Slog.d(TAG_PSS,
   21523                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
   21524                 + " state=" + ProcessList.makeProcStateString(procState));
   21525         if (proc.initialIdlePss == 0) {
   21526             proc.initialIdlePss = pss;
   21527         }
   21528         proc.lastPss = pss;
   21529         proc.lastSwapPss = swapPss;
   21530         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
   21531             proc.lastCachedPss = pss;
   21532             proc.lastCachedSwapPss = swapPss;
   21533         }
   21534 
   21535         final SparseArray<Pair<Long, String>> watchUids
   21536                 = mMemWatchProcesses.getMap().get(proc.processName);
   21537         Long check = null;
   21538         if (watchUids != null) {
   21539             Pair<Long, String> val = watchUids.get(proc.uid);
   21540             if (val == null) {
   21541                 val = watchUids.get(0);
   21542             }
   21543             if (val != null) {
   21544                 check = val.first;
   21545             }
   21546         }
   21547         if (check != null) {
   21548             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
   21549                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   21550                 if (!isDebuggable) {
   21551                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   21552                         isDebuggable = true;
   21553                     }
   21554                 }
   21555                 if (isDebuggable) {
   21556                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
   21557                     final ProcessRecord myProc = proc;
   21558                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
   21559                     mMemWatchDumpProcName = proc.processName;
   21560                     mMemWatchDumpFile = heapdumpFile.toString();
   21561                     mMemWatchDumpPid = proc.pid;
   21562                     mMemWatchDumpUid = proc.uid;
   21563                     BackgroundThread.getHandler().post(new Runnable() {
   21564                         @Override
   21565                         public void run() {
   21566                             revokeUriPermission(ActivityThread.currentActivityThread()
   21567                                             .getApplicationThread(),
   21568                                     null, DumpHeapActivity.JAVA_URI,
   21569                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
   21570                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
   21571                                     UserHandle.myUserId());
   21572                             ParcelFileDescriptor fd = null;
   21573                             try {
   21574                                 heapdumpFile.delete();
   21575                                 fd = ParcelFileDescriptor.open(heapdumpFile,
   21576                                         ParcelFileDescriptor.MODE_CREATE |
   21577                                                 ParcelFileDescriptor.MODE_TRUNCATE |
   21578                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
   21579                                                 ParcelFileDescriptor.MODE_APPEND);
   21580                                 IApplicationThread thread = myProc.thread;
   21581                                 if (thread != null) {
   21582                                     try {
   21583                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
   21584                                                 "Requesting dump heap from "
   21585                                                 + myProc + " to " + heapdumpFile);
   21586                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
   21587                                     } catch (RemoteException e) {
   21588                                     }
   21589                                 }
   21590                             } catch (FileNotFoundException e) {
   21591                                 e.printStackTrace();
   21592                             } finally {
   21593                                 if (fd != null) {
   21594                                     try {
   21595                                         fd.close();
   21596                                     } catch (IOException e) {
   21597                                     }
   21598                                 }
   21599                             }
   21600                         }
   21601                     });
   21602                 } else {
   21603                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
   21604                             + ", but debugging not enabled");
   21605                 }
   21606             }
   21607         }
   21608     }
   21609 
   21610     /**
   21611      * Schedule PSS collection of a process.
   21612      */
   21613     void requestPssLocked(ProcessRecord proc, int procState) {
   21614         if (mPendingPssProcesses.contains(proc)) {
   21615             return;
   21616         }
   21617         if (mPendingPssProcesses.size() == 0) {
   21618             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   21619         }
   21620         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
   21621         proc.pssProcState = procState;
   21622         mPendingPssProcesses.add(proc);
   21623     }
   21624 
   21625     /**
   21626      * Schedule PSS collection of all processes.
   21627      */
   21628     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
   21629         if (!always) {
   21630             if (now < (mLastFullPssTime +
   21631                     (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
   21632                             : mConstants.FULL_PSS_MIN_INTERVAL))) {
   21633                 return;
   21634             }
   21635         }
   21636         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
   21637         mLastFullPssTime = now;
   21638         mFullPssPending = true;
   21639         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
   21640         mPendingPssProcesses.clear();
   21641         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   21642             ProcessRecord app = mLruProcesses.get(i);
   21643             if (app.thread == null
   21644                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
   21645                 continue;
   21646             }
   21647             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
   21648                 app.pssProcState = app.setProcState;
   21649                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
   21650                         mTestPssMode, isSleepingLocked(), now);
   21651                 mPendingPssProcesses.add(app);
   21652             }
   21653         }
   21654         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   21655     }
   21656 
   21657     public void setTestPssMode(boolean enabled) {
   21658         synchronized (this) {
   21659             mTestPssMode = enabled;
   21660             if (enabled) {
   21661                 // Whenever we enable the mode, we want to take a snapshot all of current
   21662                 // process mem use.
   21663                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
   21664             }
   21665         }
   21666     }
   21667 
   21668     /**
   21669      * Ask a given process to GC right now.
   21670      */
   21671     final void performAppGcLocked(ProcessRecord app) {
   21672         try {
   21673             app.lastRequestedGc = SystemClock.uptimeMillis();
   21674             if (app.thread != null) {
   21675                 if (app.reportLowMemory) {
   21676                     app.reportLowMemory = false;
   21677                     app.thread.scheduleLowMemory();
   21678                 } else {
   21679                     app.thread.processInBackground();
   21680                 }
   21681             }
   21682         } catch (Exception e) {
   21683             // whatever.
   21684         }
   21685     }
   21686 
   21687     /**
   21688      * Returns true if things are idle enough to perform GCs.
   21689      */
   21690     private final boolean canGcNowLocked() {
   21691         boolean processingBroadcasts = false;
   21692         for (BroadcastQueue q : mBroadcastQueues) {
   21693             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
   21694                 processingBroadcasts = true;
   21695             }
   21696         }
   21697         return !processingBroadcasts
   21698                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
   21699     }
   21700 
   21701     /**
   21702      * Perform GCs on all processes that are waiting for it, but only
   21703      * if things are idle.
   21704      */
   21705     final void performAppGcsLocked() {
   21706         final int N = mProcessesToGc.size();
   21707         if (N <= 0) {
   21708             return;
   21709         }
   21710         if (canGcNowLocked()) {
   21711             while (mProcessesToGc.size() > 0) {
   21712                 ProcessRecord proc = mProcessesToGc.remove(0);
   21713                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
   21714                     if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
   21715                             <= SystemClock.uptimeMillis()) {
   21716                         // To avoid spamming the system, we will GC processes one
   21717                         // at a time, waiting a few seconds between each.
   21718                         performAppGcLocked(proc);
   21719                         scheduleAppGcsLocked();
   21720                         return;
   21721                     } else {
   21722                         // It hasn't been long enough since we last GCed this
   21723                         // process...  put it in the list to wait for its time.
   21724                         addProcessToGcListLocked(proc);
   21725                         break;
   21726                     }
   21727                 }
   21728             }
   21729 
   21730             scheduleAppGcsLocked();
   21731         }
   21732     }
   21733 
   21734     /**
   21735      * If all looks good, perform GCs on all processes waiting for them.
   21736      */
   21737     final void performAppGcsIfAppropriateLocked() {
   21738         if (canGcNowLocked()) {
   21739             performAppGcsLocked();
   21740             return;
   21741         }
   21742         // Still not idle, wait some more.
   21743         scheduleAppGcsLocked();
   21744     }
   21745 
   21746     /**
   21747      * Schedule the execution of all pending app GCs.
   21748      */
   21749     final void scheduleAppGcsLocked() {
   21750         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
   21751 
   21752         if (mProcessesToGc.size() > 0) {
   21753             // Schedule a GC for the time to the next process.
   21754             ProcessRecord proc = mProcessesToGc.get(0);
   21755             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
   21756 
   21757             long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
   21758             long now = SystemClock.uptimeMillis();
   21759             if (when < (now+mConstants.GC_TIMEOUT)) {
   21760                 when = now + mConstants.GC_TIMEOUT;
   21761             }
   21762             mHandler.sendMessageAtTime(msg, when);
   21763         }
   21764     }
   21765 
   21766     /**
   21767      * Add a process to the array of processes waiting to be GCed.  Keeps the
   21768      * list in sorted order by the last GC time.  The process can't already be
   21769      * on the list.
   21770      */
   21771     final void addProcessToGcListLocked(ProcessRecord proc) {
   21772         boolean added = false;
   21773         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
   21774             if (mProcessesToGc.get(i).lastRequestedGc <
   21775                     proc.lastRequestedGc) {
   21776                 added = true;
   21777                 mProcessesToGc.add(i+1, proc);
   21778                 break;
   21779             }
   21780         }
   21781         if (!added) {
   21782             mProcessesToGc.add(0, proc);
   21783         }
   21784     }
   21785 
   21786     /**
   21787      * Set up to ask a process to GC itself.  This will either do it
   21788      * immediately, or put it on the list of processes to gc the next
   21789      * time things are idle.
   21790      */
   21791     final void scheduleAppGcLocked(ProcessRecord app) {
   21792         long now = SystemClock.uptimeMillis();
   21793         if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
   21794             return;
   21795         }
   21796         if (!mProcessesToGc.contains(app)) {
   21797             addProcessToGcListLocked(app);
   21798             scheduleAppGcsLocked();
   21799         }
   21800     }
   21801 
   21802     final void checkExcessivePowerUsageLocked(boolean doKills) {
   21803         updateCpuStatsNow();
   21804 
   21805         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   21806         boolean doWakeKills = doKills;
   21807         boolean doCpuKills = doKills;
   21808         if (mLastPowerCheckRealtime == 0) {
   21809             doWakeKills = false;
   21810         }
   21811         if (mLastPowerCheckUptime == 0) {
   21812             doCpuKills = false;
   21813         }
   21814         if (stats.isScreenOn()) {
   21815             doWakeKills = false;
   21816         }
   21817         final long curRealtime = SystemClock.elapsedRealtime();
   21818         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
   21819         final long curUptime = SystemClock.uptimeMillis();
   21820         final long uptimeSince = curUptime - mLastPowerCheckUptime;
   21821         mLastPowerCheckRealtime = curRealtime;
   21822         mLastPowerCheckUptime = curUptime;
   21823         if (realtimeSince < mConstants.WAKE_LOCK_MIN_CHECK_DURATION) {
   21824             doWakeKills = false;
   21825         }
   21826         if (uptimeSince < mConstants.CPU_MIN_CHECK_DURATION) {
   21827             doCpuKills = false;
   21828         }
   21829         int i = mLruProcesses.size();
   21830         while (i > 0) {
   21831             i--;
   21832             ProcessRecord app = mLruProcesses.get(i);
   21833             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
   21834                 long wtime;
   21835                 synchronized (stats) {
   21836                     wtime = stats.getProcessWakeTime(app.info.uid,
   21837                             app.pid, curRealtime);
   21838                 }
   21839                 long wtimeUsed = wtime - app.lastWakeTime;
   21840                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
   21841                 if (DEBUG_POWER) {
   21842                     StringBuilder sb = new StringBuilder(128);
   21843                     sb.append("Wake for ");
   21844                     app.toShortString(sb);
   21845                     sb.append(": over ");
   21846                     TimeUtils.formatDuration(realtimeSince, sb);
   21847                     sb.append(" used ");
   21848                     TimeUtils.formatDuration(wtimeUsed, sb);
   21849                     sb.append(" (");
   21850                     sb.append((wtimeUsed*100)/realtimeSince);
   21851                     sb.append("%)");
   21852                     Slog.i(TAG_POWER, sb.toString());
   21853                     sb.setLength(0);
   21854                     sb.append("CPU for ");
   21855                     app.toShortString(sb);
   21856                     sb.append(": over ");
   21857                     TimeUtils.formatDuration(uptimeSince, sb);
   21858                     sb.append(" used ");
   21859                     TimeUtils.formatDuration(cputimeUsed, sb);
   21860                     sb.append(" (");
   21861                     sb.append((cputimeUsed*100)/uptimeSince);
   21862                     sb.append("%)");
   21863                     Slog.i(TAG_POWER, sb.toString());
   21864                 }
   21865                 // If a process has held a wake lock for more
   21866                 // than 50% of the time during this period,
   21867                 // that sounds bad.  Kill!
   21868                 if (doWakeKills && realtimeSince > 0
   21869                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
   21870                     synchronized (stats) {
   21871                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
   21872                                 realtimeSince, wtimeUsed);
   21873                     }
   21874                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
   21875                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
   21876                 } else if (doCpuKills && uptimeSince > 0
   21877                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
   21878                     synchronized (stats) {
   21879                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
   21880                                 uptimeSince, cputimeUsed);
   21881                     }
   21882                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
   21883                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
   21884                 } else {
   21885                     app.lastWakeTime = wtime;
   21886                     app.lastCpuTime = app.curCpuTime;
   21887                 }
   21888             }
   21889         }
   21890     }
   21891 
   21892     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
   21893             long nowElapsed) {
   21894         boolean success = true;
   21895 
   21896         if (app.curRawAdj != app.setRawAdj) {
   21897             app.setRawAdj = app.curRawAdj;
   21898         }
   21899 
   21900         int changes = 0;
   21901 
   21902         if (app.curAdj != app.setAdj) {
   21903             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
   21904             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   21905                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
   21906                     + app.adjType);
   21907             app.setAdj = app.curAdj;
   21908             app.verifiedAdj = ProcessList.INVALID_ADJ;
   21909         }
   21910 
   21911         if (app.setSchedGroup != app.curSchedGroup) {
   21912             int oldSchedGroup = app.setSchedGroup;
   21913             app.setSchedGroup = app.curSchedGroup;
   21914             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   21915                     "Setting sched group of " + app.processName
   21916                     + " to " + app.curSchedGroup);
   21917             if (app.waitingToKill != null && app.curReceivers.isEmpty()
   21918                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
   21919                 app.kill(app.waitingToKill, true);
   21920                 success = false;
   21921             } else {
   21922                 int processGroup;
   21923                 switch (app.curSchedGroup) {
   21924                     case ProcessList.SCHED_GROUP_BACKGROUND:
   21925                         processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
   21926                         break;
   21927                     case ProcessList.SCHED_GROUP_TOP_APP:
   21928                     case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
   21929                         processGroup = THREAD_GROUP_TOP_APP;
   21930                         break;
   21931                     default:
   21932                         processGroup = THREAD_GROUP_DEFAULT;
   21933                         break;
   21934                 }
   21935                 long oldId = Binder.clearCallingIdentity();
   21936                 try {
   21937                     setProcessGroup(app.pid, processGroup);
   21938                     if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
   21939                         // do nothing if we already switched to RT
   21940                         if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
   21941                             mVrController.onTopProcChangedLocked(app);
   21942                             if (mUseFifoUiScheduling) {
   21943                                 // Switch UI pipeline for app to SCHED_FIFO
   21944                                 app.savedPriority = Process.getThreadPriority(app.pid);
   21945                                 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
   21946                                 if (app.renderThreadTid != 0) {
   21947                                     scheduleAsFifoPriority(app.renderThreadTid,
   21948                                         /* suppressLogs */true);
   21949                                     if (DEBUG_OOM_ADJ) {
   21950                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
   21951                                             app.renderThreadTid + ") to FIFO");
   21952                                     }
   21953                                 } else {
   21954                                     if (DEBUG_OOM_ADJ) {
   21955                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
   21956                                     }
   21957                                 }
   21958                             } else {
   21959                                 // Boost priority for top app UI and render threads
   21960                                 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
   21961                                 if (app.renderThreadTid != 0) {
   21962                                     try {
   21963                                         setThreadPriority(app.renderThreadTid,
   21964                                                 TOP_APP_PRIORITY_BOOST);
   21965                                     } catch (IllegalArgumentException e) {
   21966                                         // thread died, ignore
   21967                                     }
   21968                                 }
   21969                             }
   21970                         }
   21971                     } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
   21972                                app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
   21973                         mVrController.onTopProcChangedLocked(app);
   21974                         if (mUseFifoUiScheduling) {
   21975                             // Reset UI pipeline to SCHED_OTHER
   21976                             setThreadScheduler(app.pid, SCHED_OTHER, 0);
   21977                             setThreadPriority(app.pid, app.savedPriority);
   21978                             if (app.renderThreadTid != 0) {
   21979                                 setThreadScheduler(app.renderThreadTid,
   21980                                     SCHED_OTHER, 0);
   21981                                 setThreadPriority(app.renderThreadTid, -4);
   21982                             }
   21983                         } else {
   21984                             // Reset priority for top app UI and render threads
   21985                             setThreadPriority(app.pid, 0);
   21986                             if (app.renderThreadTid != 0) {
   21987                                 setThreadPriority(app.renderThreadTid, 0);
   21988                             }
   21989                         }
   21990                     }
   21991                 } catch (Exception e) {
   21992                     if (false) {
   21993                         Slog.w(TAG, "Failed setting process group of " + app.pid
   21994                                 + " to " + app.curSchedGroup);
   21995                         Slog.w(TAG, "at location", e);
   21996                     }
   21997                 } finally {
   21998                     Binder.restoreCallingIdentity(oldId);
   21999                 }
   22000             }
   22001         }
   22002         if (app.repForegroundActivities != app.foregroundActivities) {
   22003             app.repForegroundActivities = app.foregroundActivities;
   22004             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
   22005         }
   22006         if (app.repProcState != app.curProcState) {
   22007             app.repProcState = app.curProcState;
   22008             if (app.thread != null) {
   22009                 try {
   22010                     if (false) {
   22011                         //RuntimeException h = new RuntimeException("here");
   22012                         Slog.i(TAG, "Sending new process state " + app.repProcState
   22013                                 + " to " + app /*, h*/);
   22014                     }
   22015                     app.thread.setProcessState(app.repProcState);
   22016                 } catch (RemoteException e) {
   22017                 }
   22018             }
   22019         }
   22020         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
   22021                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
   22022             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
   22023                 // Experimental code to more aggressively collect pss while
   22024                 // running test...  the problem is that this tends to collect
   22025                 // the data right when a process is transitioning between process
   22026                 // states, which well tend to give noisy data.
   22027                 long start = SystemClock.uptimeMillis();
   22028                 long pss = Debug.getPss(app.pid, mTmpLong, null);
   22029                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
   22030                 mPendingPssProcesses.remove(app);
   22031                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
   22032                         + " to " + app.curProcState + ": "
   22033                         + (SystemClock.uptimeMillis()-start) + "ms");
   22034             }
   22035             app.lastStateTime = now;
   22036             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
   22037                     mTestPssMode, isSleepingLocked(), now);
   22038             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
   22039                     + ProcessList.makeProcStateString(app.setProcState) + " to "
   22040                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
   22041                     + (app.nextPssTime-now) + ": " + app);
   22042         } else {
   22043             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
   22044                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
   22045                     mTestPssMode)))) {
   22046                 requestPssLocked(app, app.setProcState);
   22047                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
   22048                         mTestPssMode, isSleepingLocked(), now);
   22049             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
   22050                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
   22051         }
   22052         if (app.setProcState != app.curProcState) {
   22053             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   22054                     "Proc state change of " + app.processName
   22055                             + " to " + app.curProcState);
   22056             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
   22057             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
   22058             if (setImportant && !curImportant) {
   22059                 // This app is no longer something we consider important enough to allow to
   22060                 // use arbitrary amounts of battery power.  Note
   22061                 // its current wake lock time to later know to kill it if
   22062                 // it is not behaving well.
   22063                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   22064                 synchronized (stats) {
   22065                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
   22066                             app.pid, nowElapsed);
   22067                 }
   22068                 app.lastCpuTime = app.curCpuTime;
   22069 
   22070             }
   22071             // Inform UsageStats of important process state change
   22072             // Must be called before updating setProcState
   22073             maybeUpdateUsageStatsLocked(app, nowElapsed);
   22074 
   22075             app.setProcState = app.curProcState;
   22076             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
   22077                 app.notCachedSinceIdle = false;
   22078             }
   22079             if (!doingAll) {
   22080                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
   22081             } else {
   22082                 app.procStateChanged = true;
   22083             }
   22084         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
   22085                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
   22086             // For apps that sit around for a long time in the interactive state, we need
   22087             // to report this at least once a day so they don't go idle.
   22088             maybeUpdateUsageStatsLocked(app, nowElapsed);
   22089         }
   22090 
   22091         if (changes != 0) {
   22092             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   22093                     "Changes in " + app + ": " + changes);
   22094             int i = mPendingProcessChanges.size()-1;
   22095             ProcessChangeItem item = null;
   22096             while (i >= 0) {
   22097                 item = mPendingProcessChanges.get(i);
   22098                 if (item.pid == app.pid) {
   22099                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   22100                             "Re-using existing item: " + item);
   22101                     break;
   22102                 }
   22103                 i--;
   22104             }
   22105             if (i < 0) {
   22106                 // No existing item in pending changes; need a new one.
   22107                 final int NA = mAvailProcessChanges.size();
   22108                 if (NA > 0) {
   22109                     item = mAvailProcessChanges.remove(NA-1);
   22110                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   22111                             "Retrieving available item: " + item);
   22112                 } else {
   22113                     item = new ProcessChangeItem();
   22114                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   22115                             "Allocating new item: " + item);
   22116                 }
   22117                 item.changes = 0;
   22118                 item.pid = app.pid;
   22119                 item.uid = app.info.uid;
   22120                 if (mPendingProcessChanges.size() == 0) {
   22121                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   22122                             "*** Enqueueing dispatch processes changed!");
   22123                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
   22124                 }
   22125                 mPendingProcessChanges.add(item);
   22126             }
   22127             item.changes |= changes;
   22128             item.foregroundActivities = app.repForegroundActivities;
   22129             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   22130                     "Item " + Integer.toHexString(System.identityHashCode(item))
   22131                     + " " + app.toShortString() + ": changes=" + item.changes
   22132                     + " foreground=" + item.foregroundActivities
   22133                     + " type=" + app.adjType + " source=" + app.adjSource
   22134                     + " target=" + app.adjTarget);
   22135         }
   22136 
   22137         return success;
   22138     }
   22139 
   22140     private boolean isEphemeralLocked(int uid) {
   22141         String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
   22142         if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
   22143             return false;
   22144         }
   22145         return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
   22146                 packages[0]);
   22147     }
   22148 
   22149     @VisibleForTesting
   22150     final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
   22151         final UidRecord.ChangeItem pendingChange;
   22152         if (uidRec == null || uidRec.pendingChange == null) {
   22153             if (mPendingUidChanges.size() == 0) {
   22154                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   22155                         "*** Enqueueing dispatch uid changed!");
   22156                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
   22157             }
   22158             final int NA = mAvailUidChanges.size();
   22159             if (NA > 0) {
   22160                 pendingChange = mAvailUidChanges.remove(NA-1);
   22161                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   22162                         "Retrieving available item: " + pendingChange);
   22163             } else {
   22164                 pendingChange = new UidRecord.ChangeItem();
   22165                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   22166                         "Allocating new item: " + pendingChange);
   22167             }
   22168             if (uidRec != null) {
   22169                 uidRec.pendingChange = pendingChange;
   22170                 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
   22171                     // If this uid is going away, and we haven't yet reported it is gone,
   22172                     // then do so now.
   22173                     change = UidRecord.CHANGE_GONE_IDLE;
   22174                 }
   22175             } else if (uid < 0) {
   22176                 throw new IllegalArgumentException("No UidRecord or uid");
   22177             }
   22178             pendingChange.uidRecord = uidRec;
   22179             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
   22180             mPendingUidChanges.add(pendingChange);
   22181         } else {
   22182             pendingChange = uidRec.pendingChange;
   22183             if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
   22184                 change = UidRecord.CHANGE_GONE_IDLE;
   22185             }
   22186         }
   22187         pendingChange.change = change;
   22188         pendingChange.processState = uidRec != null
   22189                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
   22190         pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
   22191         pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
   22192         if (uidRec != null) {
   22193             uidRec.updateLastDispatchedProcStateSeq(change);
   22194         }
   22195 
   22196         // Directly update the power manager, since we sit on top of it and it is critical
   22197         // it be kept in sync (so wake locks will be held as soon as appropriate).
   22198         if (mLocalPowerManager != null) {
   22199             switch (change) {
   22200                 case UidRecord.CHANGE_GONE:
   22201                 case UidRecord.CHANGE_GONE_IDLE:
   22202                     mLocalPowerManager.uidGone(pendingChange.uid);
   22203                     break;
   22204                 case UidRecord.CHANGE_IDLE:
   22205                     mLocalPowerManager.uidIdle(pendingChange.uid);
   22206                     break;
   22207                 case UidRecord.CHANGE_ACTIVE:
   22208                     mLocalPowerManager.uidActive(pendingChange.uid);
   22209                     break;
   22210                 default:
   22211                     mLocalPowerManager.updateUidProcState(pendingChange.uid,
   22212                             pendingChange.processState);
   22213                     break;
   22214             }
   22215         }
   22216     }
   22217 
   22218     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
   22219             String authority) {
   22220         if (app == null) return;
   22221         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
   22222             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
   22223             if (userState == null) return;
   22224             final long now = SystemClock.elapsedRealtime();
   22225             Long lastReported = userState.mProviderLastReportedFg.get(authority);
   22226             if (lastReported == null || lastReported < now - 60 * 1000L) {
   22227                 if (mSystemReady) {
   22228                     // Cannot touch the user stats if not system ready
   22229                     mUsageStatsService.reportContentProviderUsage(
   22230                             authority, providerPkgName, app.userId);
   22231                 }
   22232                 userState.mProviderLastReportedFg.put(authority, now);
   22233             }
   22234         }
   22235     }
   22236 
   22237     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
   22238         if (DEBUG_USAGE_STATS) {
   22239             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
   22240                     + "] state changes: old = " + app.setProcState + ", new = "
   22241                     + app.curProcState);
   22242         }
   22243         if (mUsageStatsService == null) {
   22244             return;
   22245         }
   22246         boolean isInteraction;
   22247         // To avoid some abuse patterns, we are going to be careful about what we consider
   22248         // to be an app interaction.  Being the top activity doesn't count while the display
   22249         // is sleeping, nor do short foreground services.
   22250         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
   22251             isInteraction = true;
   22252             app.fgInteractionTime = 0;
   22253         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
   22254             if (app.fgInteractionTime == 0) {
   22255                 app.fgInteractionTime = nowElapsed;
   22256                 isInteraction = false;
   22257             } else {
   22258                 isInteraction = nowElapsed > app.fgInteractionTime
   22259                         + mConstants.SERVICE_USAGE_INTERACTION_TIME;
   22260             }
   22261         } else {
   22262             isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   22263             app.fgInteractionTime = 0;
   22264         }
   22265         if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
   22266                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
   22267             app.interactionEventTime = nowElapsed;
   22268             String[] packages = app.getPackageList();
   22269             if (packages != null) {
   22270                 for (int i = 0; i < packages.length; i++) {
   22271                     mUsageStatsService.reportEvent(packages[i], app.userId,
   22272                             UsageEvents.Event.SYSTEM_INTERACTION);
   22273                 }
   22274             }
   22275         }
   22276         app.reportedInteraction = isInteraction;
   22277         if (!isInteraction) {
   22278             app.interactionEventTime = 0;
   22279         }
   22280     }
   22281 
   22282     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
   22283         if (proc.thread != null) {
   22284             if (proc.baseProcessTracker != null) {
   22285                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
   22286             }
   22287         }
   22288     }
   22289 
   22290     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
   22291             ProcessRecord TOP_APP, boolean doingAll, long now) {
   22292         if (app.thread == null) {
   22293             return false;
   22294         }
   22295 
   22296         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
   22297 
   22298         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
   22299     }
   22300 
   22301     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
   22302             boolean oomAdj) {
   22303         if (isForeground != proc.foregroundServices) {
   22304             proc.foregroundServices = isForeground;
   22305             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
   22306                     proc.info.uid);
   22307             if (isForeground) {
   22308                 if (curProcs == null) {
   22309                     curProcs = new ArrayList<ProcessRecord>();
   22310                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
   22311                 }
   22312                 if (!curProcs.contains(proc)) {
   22313                     curProcs.add(proc);
   22314                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
   22315                             proc.info.packageName, proc.info.uid);
   22316                 }
   22317             } else {
   22318                 if (curProcs != null) {
   22319                     if (curProcs.remove(proc)) {
   22320                         mBatteryStatsService.noteEvent(
   22321                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
   22322                                 proc.info.packageName, proc.info.uid);
   22323                         if (curProcs.size() <= 0) {
   22324                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
   22325                         }
   22326                     }
   22327                 }
   22328             }
   22329             if (oomAdj) {
   22330                 updateOomAdjLocked();
   22331             }
   22332         }
   22333     }
   22334 
   22335     private final ActivityRecord resumedAppLocked() {
   22336         ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
   22337         String pkg;
   22338         int uid;
   22339         if (act != null) {
   22340             pkg = act.packageName;
   22341             uid = act.info.applicationInfo.uid;
   22342         } else {
   22343             pkg = null;
   22344             uid = -1;
   22345         }
   22346         // Has the UID or resumed package name changed?
   22347         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
   22348                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
   22349             if (mCurResumedPackage != null) {
   22350                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
   22351                         mCurResumedPackage, mCurResumedUid);
   22352             }
   22353             mCurResumedPackage = pkg;
   22354             mCurResumedUid = uid;
   22355             if (mCurResumedPackage != null) {
   22356                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
   22357                         mCurResumedPackage, mCurResumedUid);
   22358             }
   22359         }
   22360         return act;
   22361     }
   22362 
   22363     /**
   22364      * Update OomAdj for a specific process.
   22365      * @param app The process to update
   22366      * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
   22367      *                  if necessary, or skip.
   22368      * @return whether updateOomAdjLocked(app) was successful.
   22369      */
   22370     final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
   22371         final ActivityRecord TOP_ACT = resumedAppLocked();
   22372         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   22373         final boolean wasCached = app.cached;
   22374 
   22375         mAdjSeq++;
   22376 
   22377         // This is the desired cached adjusment we want to tell it to use.
   22378         // If our app is currently cached, we know it, and that is it.  Otherwise,
   22379         // we don't know it yet, and it needs to now be cached we will then
   22380         // need to do a complete oom adj.
   22381         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
   22382                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
   22383         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
   22384                 SystemClock.uptimeMillis());
   22385         if (oomAdjAll
   22386                 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
   22387             // Changed to/from cached state, so apps after it in the LRU
   22388             // list may also be changed.
   22389             updateOomAdjLocked();
   22390         }
   22391         return success;
   22392     }
   22393 
   22394     final void updateOomAdjLocked() {
   22395         final ActivityRecord TOP_ACT = resumedAppLocked();
   22396         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   22397         final long now = SystemClock.uptimeMillis();
   22398         final long nowElapsed = SystemClock.elapsedRealtime();
   22399         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
   22400         final int N = mLruProcesses.size();
   22401 
   22402         if (false) {
   22403             RuntimeException e = new RuntimeException();
   22404             e.fillInStackTrace();
   22405             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
   22406         }
   22407 
   22408         // Reset state in all uid records.
   22409         for (int i=mActiveUids.size()-1; i>=0; i--) {
   22410             final UidRecord uidRec = mActiveUids.valueAt(i);
   22411             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   22412                     "Starting update of " + uidRec);
   22413             uidRec.reset();
   22414         }
   22415 
   22416         mStackSupervisor.rankTaskLayersIfNeeded();
   22417 
   22418         mAdjSeq++;
   22419         mNewNumServiceProcs = 0;
   22420         mNewNumAServiceProcs = 0;
   22421 
   22422         final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
   22423         final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
   22424 
   22425         // Let's determine how many processes we have running vs.
   22426         // how many slots we have for background processes; we may want
   22427         // to put multiple processes in a slot of there are enough of
   22428         // them.
   22429         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
   22430                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
   22431         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
   22432         if (numEmptyProcs > cachedProcessLimit) {
   22433             // If there are more empty processes than our limit on cached
   22434             // processes, then use the cached process limit for the factor.
   22435             // This ensures that the really old empty processes get pushed
   22436             // down to the bottom, so if we are running low on memory we will
   22437             // have a better chance at keeping around more cached processes
   22438             // instead of a gazillion empty processes.
   22439             numEmptyProcs = cachedProcessLimit;
   22440         }
   22441         int emptyFactor = numEmptyProcs/numSlots;
   22442         if (emptyFactor < 1) emptyFactor = 1;
   22443         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
   22444         if (cachedFactor < 1) cachedFactor = 1;
   22445         int stepCached = 0;
   22446         int stepEmpty = 0;
   22447         int numCached = 0;
   22448         int numEmpty = 0;
   22449         int numTrimming = 0;
   22450 
   22451         mNumNonCachedProcs = 0;
   22452         mNumCachedHiddenProcs = 0;
   22453 
   22454         // First update the OOM adjustment for each of the
   22455         // application processes based on their current state.
   22456         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
   22457         int nextCachedAdj = curCachedAdj+1;
   22458         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
   22459         int nextEmptyAdj = curEmptyAdj+2;
   22460         for (int i=N-1; i>=0; i--) {
   22461             ProcessRecord app = mLruProcesses.get(i);
   22462             if (!app.killedByAm && app.thread != null) {
   22463                 app.procStateChanged = false;
   22464                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
   22465 
   22466                 // If we haven't yet assigned the final cached adj
   22467                 // to the process, do that now.
   22468                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
   22469                     switch (app.curProcState) {
   22470                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   22471                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   22472                             // This process is a cached process holding activities...
   22473                             // assign it the next cached value for that type, and then
   22474                             // step that cached level.
   22475                             app.curRawAdj = curCachedAdj;
   22476                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
   22477                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
   22478                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
   22479                                     + ")");
   22480                             if (curCachedAdj != nextCachedAdj) {
   22481                                 stepCached++;
   22482                                 if (stepCached >= cachedFactor) {
   22483                                     stepCached = 0;
   22484                                     curCachedAdj = nextCachedAdj;
   22485                                     nextCachedAdj += 2;
   22486                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   22487                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
   22488                                     }
   22489                                 }
   22490                             }
   22491                             break;
   22492                         default:
   22493                             // For everything else, assign next empty cached process
   22494                             // level and bump that up.  Note that this means that
   22495                             // long-running services that have dropped down to the
   22496                             // cached level will be treated as empty (since their process
   22497                             // state is still as a service), which is what we want.
   22498                             app.curRawAdj = curEmptyAdj;
   22499                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
   22500                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
   22501                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
   22502                                     + ")");
   22503                             if (curEmptyAdj != nextEmptyAdj) {
   22504                                 stepEmpty++;
   22505                                 if (stepEmpty >= emptyFactor) {
   22506                                     stepEmpty = 0;
   22507                                     curEmptyAdj = nextEmptyAdj;
   22508                                     nextEmptyAdj += 2;
   22509                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   22510                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
   22511                                     }
   22512                                 }
   22513                             }
   22514                             break;
   22515                     }
   22516                 }
   22517 
   22518                 applyOomAdjLocked(app, true, now, nowElapsed);
   22519 
   22520                 // Count the number of process types.
   22521                 switch (app.curProcState) {
   22522                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   22523                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   22524                         mNumCachedHiddenProcs++;
   22525                         numCached++;
   22526                         if (numCached > cachedProcessLimit) {
   22527                             app.kill("cached #" + numCached, true);
   22528                         }
   22529                         break;
   22530                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
   22531                         if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
   22532                                 && app.lastActivityTime < oldTime) {
   22533                             app.kill("empty for "
   22534                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
   22535                                     / 1000) + "s", true);
   22536                         } else {
   22537                             numEmpty++;
   22538                             if (numEmpty > emptyProcessLimit) {
   22539                                 app.kill("empty #" + numEmpty, true);
   22540                             }
   22541                         }
   22542                         break;
   22543                     default:
   22544                         mNumNonCachedProcs++;
   22545                         break;
   22546                 }
   22547 
   22548                 if (app.isolated && app.services.size() <= 0) {
   22549                     // If this is an isolated process, and there are no
   22550                     // services running in it, then the process is no longer
   22551                     // needed.  We agressively kill these because we can by
   22552                     // definition not re-use the same process again, and it is
   22553                     // good to avoid having whatever code was running in them
   22554                     // left sitting around after no longer needed.
   22555                     app.kill("isolated not needed", true);
   22556                 } else {
   22557                     // Keeping this process, update its uid.
   22558                     final UidRecord uidRec = app.uidRecord;
   22559                     if (uidRec != null) {
   22560                         uidRec.ephemeral = app.info.isInstantApp();
   22561                         if (uidRec.curProcState > app.curProcState) {
   22562                             uidRec.curProcState = app.curProcState;
   22563                         }
   22564                         if (app.foregroundServices) {
   22565                             uidRec.foregroundServices = true;
   22566                         }
   22567                     }
   22568                 }
   22569 
   22570                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   22571                         && !app.killedByAm) {
   22572                     numTrimming++;
   22573                 }
   22574             }
   22575         }
   22576 
   22577         incrementProcStateSeqAndNotifyAppsLocked();
   22578 
   22579         mNumServiceProcs = mNewNumServiceProcs;
   22580 
   22581         // Now determine the memory trimming level of background processes.
   22582         // Unfortunately we need to start at the back of the list to do this
   22583         // properly.  We only do this if the number of background apps we
   22584         // are managing to keep around is less than half the maximum we desire;
   22585         // if we are keeping a good number around, we'll let them use whatever
   22586         // memory they want.
   22587         final int numCachedAndEmpty = numCached + numEmpty;
   22588         int memFactor;
   22589         if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
   22590                 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
   22591             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
   22592                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
   22593             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
   22594                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
   22595             } else {
   22596                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
   22597             }
   22598         } else {
   22599             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
   22600         }
   22601         // We always allow the memory level to go up (better).  We only allow it to go
   22602         // down if we are in a state where that is allowed, *and* the total number of processes
   22603         // has gone down since last time.
   22604         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
   22605                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
   22606                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
   22607         if (memFactor > mLastMemoryLevel) {
   22608             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
   22609                 memFactor = mLastMemoryLevel;
   22610                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
   22611             }
   22612         }
   22613         if (memFactor != mLastMemoryLevel) {
   22614             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
   22615         }
   22616         mLastMemoryLevel = memFactor;
   22617         mLastNumProcesses = mLruProcesses.size();
   22618         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
   22619         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
   22620         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
   22621             if (mLowRamStartTime == 0) {
   22622                 mLowRamStartTime = now;
   22623             }
   22624             int step = 0;
   22625             int fgTrimLevel;
   22626             switch (memFactor) {
   22627                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
   22628                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
   22629                     break;
   22630                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
   22631                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
   22632                     break;
   22633                 default:
   22634                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
   22635                     break;
   22636             }
   22637             int factor = numTrimming/3;
   22638             int minFactor = 2;
   22639             if (mHomeProcess != null) minFactor++;
   22640             if (mPreviousProcess != null) minFactor++;
   22641             if (factor < minFactor) factor = minFactor;
   22642             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
   22643             for (int i=N-1; i>=0; i--) {
   22644                 ProcessRecord app = mLruProcesses.get(i);
   22645                 if (allChanged || app.procStateChanged) {
   22646                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
   22647                     app.procStateChanged = false;
   22648                 }
   22649                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   22650                         && !app.killedByAm) {
   22651                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
   22652                         try {
   22653                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   22654                                     "Trimming memory of " + app.processName + " to " + curLevel);
   22655                             app.thread.scheduleTrimMemory(curLevel);
   22656                         } catch (RemoteException e) {
   22657                         }
   22658                         if (false) {
   22659                             // For now we won't do this; our memory trimming seems
   22660                             // to be good enough at this point that destroying
   22661                             // activities causes more harm than good.
   22662                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
   22663                                     && app != mHomeProcess && app != mPreviousProcess) {
   22664                                 // Need to do this on its own message because the stack may not
   22665                                 // be in a consistent state at this point.
   22666                                 // For these apps we will also finish their activities
   22667                                 // to help them free memory.
   22668                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
   22669                             }
   22670                         }
   22671                     }
   22672                     app.trimMemoryLevel = curLevel;
   22673                     step++;
   22674                     if (step >= factor) {
   22675                         step = 0;
   22676                         switch (curLevel) {
   22677                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
   22678                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
   22679                                 break;
   22680                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
   22681                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   22682                                 break;
   22683                         }
   22684                     }
   22685                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
   22686                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
   22687                             && app.thread != null) {
   22688                         try {
   22689                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   22690                                     "Trimming memory of heavy-weight " + app.processName
   22691                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   22692                             app.thread.scheduleTrimMemory(
   22693                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   22694                         } catch (RemoteException e) {
   22695                         }
   22696                     }
   22697                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   22698                 } else {
   22699                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   22700                             || app.systemNoUi) && app.pendingUiClean) {
   22701                         // If this application is now in the background and it
   22702                         // had done UI, then give it the special trim level to
   22703                         // have it free UI resources.
   22704                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
   22705                         if (app.trimMemoryLevel < level && app.thread != null) {
   22706                             try {
   22707                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   22708                                         "Trimming memory of bg-ui " + app.processName
   22709                                         + " to " + level);
   22710                                 app.thread.scheduleTrimMemory(level);
   22711                             } catch (RemoteException e) {
   22712                             }
   22713                         }
   22714                         app.pendingUiClean = false;
   22715                     }
   22716                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
   22717                         try {
   22718                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   22719                                     "Trimming memory of fg " + app.processName
   22720                                     + " to " + fgTrimLevel);
   22721                             app.thread.scheduleTrimMemory(fgTrimLevel);
   22722                         } catch (RemoteException e) {
   22723                         }
   22724                     }
   22725                     app.trimMemoryLevel = fgTrimLevel;
   22726                 }
   22727             }
   22728         } else {
   22729             if (mLowRamStartTime != 0) {
   22730                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
   22731                 mLowRamStartTime = 0;
   22732             }
   22733             for (int i=N-1; i>=0; i--) {
   22734                 ProcessRecord app = mLruProcesses.get(i);
   22735                 if (allChanged || app.procStateChanged) {
   22736                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
   22737                     app.procStateChanged = false;
   22738                 }
   22739                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   22740                         || app.systemNoUi) && app.pendingUiClean) {
   22741                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
   22742                             && app.thread != null) {
   22743                         try {
   22744                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   22745                                     "Trimming memory of ui hidden " + app.processName
   22746                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   22747                             app.thread.scheduleTrimMemory(
   22748                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   22749                         } catch (RemoteException e) {
   22750                         }
   22751                     }
   22752                     app.pendingUiClean = false;
   22753                 }
   22754                 app.trimMemoryLevel = 0;
   22755             }
   22756         }
   22757 
   22758         if (mAlwaysFinishActivities) {
   22759             // Need to do this on its own message because the stack may not
   22760             // be in a consistent state at this point.
   22761             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
   22762         }
   22763 
   22764         if (allChanged) {
   22765             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
   22766         }
   22767 
   22768         // Update from any uid changes.
   22769         if (mLocalPowerManager != null) {
   22770             mLocalPowerManager.startUidChanges();
   22771         }
   22772         for (int i=mActiveUids.size()-1; i>=0; i--) {
   22773             final UidRecord uidRec = mActiveUids.valueAt(i);
   22774             int uidChange = UidRecord.CHANGE_PROCSTATE;
   22775             if (uidRec.setProcState != uidRec.curProcState
   22776                     || uidRec.setWhitelist != uidRec.curWhitelist) {
   22777                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   22778                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
   22779                         + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
   22780                         + " to " + uidRec.curWhitelist);
   22781                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
   22782                         && !uidRec.curWhitelist) {
   22783                     // UID is now in the background (and not on the temp whitelist).  Was it
   22784                     // previously in the foreground (or on the temp whitelist)?
   22785                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
   22786                             || uidRec.setWhitelist) {
   22787                         uidRec.lastBackgroundTime = nowElapsed;
   22788                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
   22789                             // Note: the background settle time is in elapsed realtime, while
   22790                             // the handler time base is uptime.  All this means is that we may
   22791                             // stop background uids later than we had intended, but that only
   22792                             // happens because the device was sleeping so we are okay anyway.
   22793                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
   22794                                     mConstants.BACKGROUND_SETTLE_TIME);
   22795                         }
   22796                     }
   22797                 } else {
   22798                     if (uidRec.idle) {
   22799                         uidChange = UidRecord.CHANGE_ACTIVE;
   22800                         EventLogTags.writeAmUidActive(uidRec.uid);
   22801                         uidRec.idle = false;
   22802                     }
   22803                     uidRec.lastBackgroundTime = 0;
   22804                 }
   22805                 uidRec.setProcState = uidRec.curProcState;
   22806                 uidRec.setWhitelist = uidRec.curWhitelist;
   22807                 enqueueUidChangeLocked(uidRec, -1, uidChange);
   22808                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
   22809                 if (uidRec.foregroundServices) {
   22810                     mServices.foregroundServiceProcStateChangedLocked(uidRec);
   22811                 }
   22812             }
   22813         }
   22814         if (mLocalPowerManager != null) {
   22815             mLocalPowerManager.finishUidChanges();
   22816         }
   22817 
   22818         if (mProcessStats.shouldWriteNowLocked(now)) {
   22819             mHandler.post(new Runnable() {
   22820                 @Override public void run() {
   22821                     synchronized (ActivityManagerService.this) {
   22822                         mProcessStats.writeStateAsyncLocked();
   22823                     }
   22824                 }
   22825             });
   22826         }
   22827 
   22828         if (DEBUG_OOM_ADJ) {
   22829             final long duration = SystemClock.uptimeMillis() - now;
   22830             if (false) {
   22831                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
   22832                         new RuntimeException("here").fillInStackTrace());
   22833             } else {
   22834                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
   22835             }
   22836         }
   22837     }
   22838 
   22839     @Override
   22840     public void makePackageIdle(String packageName, int userId) {
   22841         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   22842                 != PackageManager.PERMISSION_GRANTED) {
   22843             String msg = "Permission Denial: makePackageIdle() from pid="
   22844                     + Binder.getCallingPid()
   22845                     + ", uid=" + Binder.getCallingUid()
   22846                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   22847             Slog.w(TAG, msg);
   22848             throw new SecurityException(msg);
   22849         }
   22850         final int callingPid = Binder.getCallingPid();
   22851         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
   22852                 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
   22853         long callingId = Binder.clearCallingIdentity();
   22854         synchronized(this) {
   22855             try {
   22856                 IPackageManager pm = AppGlobals.getPackageManager();
   22857                 int pkgUid = -1;
   22858                 try {
   22859                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
   22860                             | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
   22861                 } catch (RemoteException e) {
   22862                 }
   22863                 if (pkgUid == -1) {
   22864                     throw new IllegalArgumentException("Unknown package name " + packageName);
   22865                 }
   22866 
   22867                 if (mLocalPowerManager != null) {
   22868                     mLocalPowerManager.startUidChanges();
   22869                 }
   22870                 final int appId = UserHandle.getAppId(pkgUid);
   22871                 final int N = mActiveUids.size();
   22872                 for (int i=N-1; i>=0; i--) {
   22873                     final UidRecord uidRec = mActiveUids.valueAt(i);
   22874                     final long bgTime = uidRec.lastBackgroundTime;
   22875                     if (bgTime > 0 && !uidRec.idle) {
   22876                         if (UserHandle.getAppId(uidRec.uid) == appId) {
   22877                             if (userId == UserHandle.USER_ALL ||
   22878                                     userId == UserHandle.getUserId(uidRec.uid)) {
   22879                                 EventLogTags.writeAmUidIdle(uidRec.uid);
   22880                                 uidRec.idle = true;
   22881                                 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
   22882                                         + " from package " + packageName + " user " + userId);
   22883                                 doStopUidLocked(uidRec.uid, uidRec);
   22884                             }
   22885                         }
   22886                     }
   22887                 }
   22888             } finally {
   22889                 if (mLocalPowerManager != null) {
   22890                     mLocalPowerManager.finishUidChanges();
   22891                 }
   22892                 Binder.restoreCallingIdentity(callingId);
   22893             }
   22894         }
   22895     }
   22896 
   22897     final void idleUids() {
   22898         synchronized (this) {
   22899             final int N = mActiveUids.size();
   22900             if (N <= 0) {
   22901                 return;
   22902             }
   22903             final long nowElapsed = SystemClock.elapsedRealtime();
   22904             final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
   22905             long nextTime = 0;
   22906             if (mLocalPowerManager != null) {
   22907                 mLocalPowerManager.startUidChanges();
   22908             }
   22909             for (int i=N-1; i>=0; i--) {
   22910                 final UidRecord uidRec = mActiveUids.valueAt(i);
   22911                 final long bgTime = uidRec.lastBackgroundTime;
   22912                 if (bgTime > 0 && !uidRec.idle) {
   22913                     if (bgTime <= maxBgTime) {
   22914                         EventLogTags.writeAmUidIdle(uidRec.uid);
   22915                         uidRec.idle = true;
   22916                         doStopUidLocked(uidRec.uid, uidRec);
   22917                     } else {
   22918                         if (nextTime == 0 || nextTime > bgTime) {
   22919                             nextTime = bgTime;
   22920                         }
   22921                     }
   22922                 }
   22923             }
   22924             if (mLocalPowerManager != null) {
   22925                 mLocalPowerManager.finishUidChanges();
   22926             }
   22927             if (nextTime > 0) {
   22928                 mHandler.removeMessages(IDLE_UIDS_MSG);
   22929                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
   22930                         nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
   22931             }
   22932         }
   22933     }
   22934 
   22935     /**
   22936      * Checks if any uid is coming from background to foreground or vice versa and if so, increments
   22937      * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
   22938      * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
   22939      */
   22940     @VisibleForTesting
   22941     @GuardedBy("this")
   22942     void incrementProcStateSeqAndNotifyAppsLocked() {
   22943         if (mWaitForNetworkTimeoutMs <= 0) {
   22944             return;
   22945         }
   22946         // Used for identifying which uids need to block for network.
   22947         ArrayList<Integer> blockingUids = null;
   22948         for (int i = mActiveUids.size() - 1; i >= 0; --i) {
   22949             final UidRecord uidRec = mActiveUids.valueAt(i);
   22950             // If the network is not restricted for uid, then nothing to do here.
   22951             if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
   22952                 continue;
   22953             }
   22954             if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
   22955                 continue;
   22956             }
   22957             // If process state is not changed, then there's nothing to do.
   22958             if (uidRec.setProcState == uidRec.curProcState) {
   22959                 continue;
   22960             }
   22961             final int blockState = getBlockStateForUid(uidRec);
   22962             // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
   22963             // there's nothing the app needs to do in this scenario.
   22964             if (blockState == NETWORK_STATE_NO_CHANGE) {
   22965                 continue;
   22966             }
   22967             synchronized (uidRec.networkStateLock) {
   22968                 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
   22969                 if (blockState == NETWORK_STATE_BLOCK) {
   22970                     if (blockingUids == null) {
   22971                         blockingUids = new ArrayList<>();
   22972                     }
   22973                     blockingUids.add(uidRec.uid);
   22974                 } else {
   22975                     if (DEBUG_NETWORK) {
   22976                         Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
   22977                                 + " threads for uid: " + uidRec);
   22978                     }
   22979                     if (uidRec.waitingForNetwork) {
   22980                         uidRec.networkStateLock.notifyAll();
   22981                     }
   22982                 }
   22983             }
   22984         }
   22985 
   22986         // There are no uids that need to block, so nothing more to do.
   22987         if (blockingUids == null) {
   22988             return;
   22989         }
   22990 
   22991         for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
   22992             final ProcessRecord app = mLruProcesses.get(i);
   22993             if (!blockingUids.contains(app.uid)) {
   22994                 continue;
   22995             }
   22996             if (!app.killedByAm && app.thread != null) {
   22997                 final UidRecord uidRec = mActiveUids.get(app.uid);
   22998                 try {
   22999                     if (DEBUG_NETWORK) {
   23000                         Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
   23001                                 + uidRec);
   23002                     }
   23003                     app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
   23004                 } catch (RemoteException ignored) {
   23005                 }
   23006             }
   23007         }
   23008     }
   23009 
   23010     /**
   23011      * Checks if the uid is coming from background to foreground or vice versa and returns
   23012      * appropriate block state based on this.
   23013      *
   23014      * @return blockState based on whether the uid is coming from background to foreground or
   23015      *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
   23016      *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
   23017      *         {@link #NETWORK_STATE_NO_CHANGE}.
   23018      */
   23019     @VisibleForTesting
   23020     int getBlockStateForUid(UidRecord uidRec) {
   23021         // Denotes whether uid's process state is currently allowed network access.
   23022         final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
   23023                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
   23024         // Denotes whether uid's process state was previously allowed network access.
   23025         final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
   23026                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
   23027 
   23028         // When the uid is coming to foreground, AMS should inform the app thread that it should
   23029         // block for the network rules to get updated before launching an activity.
   23030         if (!wasAllowed && isAllowed) {
   23031             return NETWORK_STATE_BLOCK;
   23032         }
   23033         // When the uid is going to background, AMS should inform the app thread that if an
   23034         // activity launch is blocked for the network rules to get updated, it should be unblocked.
   23035         if (wasAllowed && !isAllowed) {
   23036             return NETWORK_STATE_UNBLOCK;
   23037         }
   23038         return NETWORK_STATE_NO_CHANGE;
   23039     }
   23040 
   23041     final void runInBackgroundDisabled(int uid) {
   23042         synchronized (this) {
   23043             UidRecord uidRec = mActiveUids.get(uid);
   23044             if (uidRec != null) {
   23045                 // This uid is actually running...  should it be considered background now?
   23046                 if (uidRec.idle) {
   23047                     doStopUidLocked(uidRec.uid, uidRec);
   23048                 }
   23049             } else {
   23050                 // This uid isn't actually running...  still send a report about it being "stopped".
   23051                 doStopUidLocked(uid, null);
   23052             }
   23053         }
   23054     }
   23055 
   23056     final void doStopUidLocked(int uid, final UidRecord uidRec) {
   23057         mServices.stopInBackgroundLocked(uid);
   23058         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
   23059     }
   23060 
   23061     /**
   23062      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
   23063      */
   23064     void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
   23065             long duration, String tag) {
   23066         if (DEBUG_WHITELISTS) {
   23067             Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
   23068                     + targetUid + ", " + duration + ")");
   23069         }
   23070 
   23071         synchronized (mPidsSelfLocked) {
   23072             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
   23073             if (pr == null) {
   23074                 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
   23075                         + callerPid);
   23076                 return;
   23077             }
   23078             if (!pr.whitelistManager) {
   23079                 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
   23080                         != PackageManager.PERMISSION_GRANTED) {
   23081                     if (DEBUG_WHITELISTS) {
   23082                         Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
   23083                                 + ": pid " + callerPid + " is not allowed");
   23084                     }
   23085                     return;
   23086                 }
   23087             }
   23088         }
   23089 
   23090         tempWhitelistUidLocked(targetUid, duration, tag);
   23091     }
   23092 
   23093     /**
   23094      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
   23095      */
   23096     void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
   23097         mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
   23098         setUidTempWhitelistStateLocked(targetUid, true);
   23099         mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
   23100     }
   23101 
   23102     void pushTempWhitelist() {
   23103         final int N;
   23104         final PendingTempWhitelist[] list;
   23105 
   23106         // First copy out the pending changes...  we need to leave them in the map for now,
   23107         // in case someone needs to check what is coming up while we don't have the lock held.
   23108         synchronized(this) {
   23109             N = mPendingTempWhitelist.size();
   23110             list = new PendingTempWhitelist[N];
   23111             for (int i = 0; i < N; i++) {
   23112                 list[i] = mPendingTempWhitelist.valueAt(i);
   23113             }
   23114         }
   23115 
   23116         // Now safely dispatch changes to device idle controller.
   23117         for (int i = 0; i < N; i++) {
   23118             PendingTempWhitelist ptw = list[i];
   23119             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
   23120                     ptw.duration, true, ptw.tag);
   23121         }
   23122 
   23123         // And now we can safely remove them from the map.
   23124         synchronized(this) {
   23125             for (int i = 0; i < N; i++) {
   23126                 PendingTempWhitelist ptw = list[i];
   23127                 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
   23128                 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
   23129                     mPendingTempWhitelist.removeAt(index);
   23130                 }
   23131             }
   23132         }
   23133     }
   23134 
   23135     final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
   23136         boolean changed = false;
   23137         for (int i=mActiveUids.size()-1; i>=0; i--) {
   23138             final UidRecord uidRec = mActiveUids.valueAt(i);
   23139             if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
   23140                 uidRec.curWhitelist = onWhitelist;
   23141                 changed = true;
   23142             }
   23143         }
   23144         if (changed) {
   23145             updateOomAdjLocked();
   23146         }
   23147     }
   23148 
   23149     final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
   23150         boolean changed = false;
   23151         final UidRecord uidRec = mActiveUids.get(uid);
   23152         if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
   23153             uidRec.curWhitelist = onWhitelist;
   23154             updateOomAdjLocked();
   23155         }
   23156     }
   23157 
   23158     final void trimApplications() {
   23159         synchronized (this) {
   23160             int i;
   23161 
   23162             // First remove any unused application processes whose package
   23163             // has been removed.
   23164             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
   23165                 final ProcessRecord app = mRemovedProcesses.get(i);
   23166                 if (app.activities.size() == 0
   23167                         && app.curReceivers.isEmpty() && app.services.size() == 0) {
   23168                     Slog.i(
   23169                         TAG, "Exiting empty application process "
   23170                         + app.toShortString() + " ("
   23171                         + (app.thread != null ? app.thread.asBinder() : null)
   23172                         + ")\n");
   23173                     if (app.pid > 0 && app.pid != MY_PID) {
   23174                         app.kill("empty", false);
   23175                     } else {
   23176                         try {
   23177                             app.thread.scheduleExit();
   23178                         } catch (Exception e) {
   23179                             // Ignore exceptions.
   23180                         }
   23181                     }
   23182                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
   23183                     mRemovedProcesses.remove(i);
   23184 
   23185                     if (app.persistent) {
   23186                         addAppLocked(app.info, null, false, null /* ABI override */);
   23187                     }
   23188                 }
   23189             }
   23190 
   23191             // Now update the oom adj for all processes.
   23192             updateOomAdjLocked();
   23193         }
   23194     }
   23195 
   23196     /** This method sends the specified signal to each of the persistent apps */
   23197     public void signalPersistentProcesses(int sig) throws RemoteException {
   23198         if (sig != SIGNAL_USR1) {
   23199             throw new SecurityException("Only SIGNAL_USR1 is allowed");
   23200         }
   23201 
   23202         synchronized (this) {
   23203             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
   23204                     != PackageManager.PERMISSION_GRANTED) {
   23205                 throw new SecurityException("Requires permission "
   23206                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
   23207             }
   23208 
   23209             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   23210                 ProcessRecord r = mLruProcesses.get(i);
   23211                 if (r.thread != null && r.persistent) {
   23212                     sendSignal(r.pid, sig);
   23213                 }
   23214             }
   23215         }
   23216     }
   23217 
   23218     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
   23219         if (proc == null || proc == mProfileProc) {
   23220             proc = mProfileProc;
   23221             profileType = mProfileType;
   23222             clearProfilerLocked();
   23223         }
   23224         if (proc == null) {
   23225             return;
   23226         }
   23227         try {
   23228             proc.thread.profilerControl(false, null, profileType);
   23229         } catch (RemoteException e) {
   23230             throw new IllegalStateException("Process disappeared");
   23231         }
   23232     }
   23233 
   23234     private void clearProfilerLocked() {
   23235         if (mProfileFd != null) {
   23236             try {
   23237                 mProfileFd.close();
   23238             } catch (IOException e) {
   23239             }
   23240         }
   23241         mProfileApp = null;
   23242         mProfileProc = null;
   23243         mProfileFile = null;
   23244         mProfileType = 0;
   23245         mAutoStopProfiler = false;
   23246         mStreamingOutput = false;
   23247         mSamplingInterval = 0;
   23248     }
   23249 
   23250     public boolean profileControl(String process, int userId, boolean start,
   23251             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
   23252 
   23253         try {
   23254             synchronized (this) {
   23255                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   23256                 // its own permission.
   23257                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   23258                         != PackageManager.PERMISSION_GRANTED) {
   23259                     throw new SecurityException("Requires permission "
   23260                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   23261                 }
   23262 
   23263                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
   23264                     throw new IllegalArgumentException("null profile info or fd");
   23265                 }
   23266 
   23267                 ProcessRecord proc = null;
   23268                 if (process != null) {
   23269                     proc = findProcessLocked(process, userId, "profileControl");
   23270                 }
   23271 
   23272                 if (start && (proc == null || proc.thread == null)) {
   23273                     throw new IllegalArgumentException("Unknown process: " + process);
   23274                 }
   23275 
   23276                 if (start) {
   23277                     stopProfilerLocked(null, 0);
   23278                     setProfileApp(proc.info, proc.processName, profilerInfo);
   23279                     mProfileProc = proc;
   23280                     mProfileType = profileType;
   23281                     ParcelFileDescriptor fd = profilerInfo.profileFd;
   23282                     try {
   23283                         fd = fd.dup();
   23284                     } catch (IOException e) {
   23285                         fd = null;
   23286                     }
   23287                     profilerInfo.profileFd = fd;
   23288                     proc.thread.profilerControl(start, profilerInfo, profileType);
   23289                     fd = null;
   23290                     try {
   23291                         mProfileFd.close();
   23292                     } catch (IOException e) {
   23293                     }
   23294                     mProfileFd = null;
   23295                 } else {
   23296                     stopProfilerLocked(proc, profileType);
   23297                     if (profilerInfo != null && profilerInfo.profileFd != null) {
   23298                         try {
   23299                             profilerInfo.profileFd.close();
   23300                         } catch (IOException e) {
   23301                         }
   23302                     }
   23303                 }
   23304 
   23305                 return true;
   23306             }
   23307         } catch (RemoteException e) {
   23308             throw new IllegalStateException("Process disappeared");
   23309         } finally {
   23310             if (profilerInfo != null && profilerInfo.profileFd != null) {
   23311                 try {
   23312                     profilerInfo.profileFd.close();
   23313                 } catch (IOException e) {
   23314                 }
   23315             }
   23316         }
   23317     }
   23318 
   23319     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
   23320         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   23321                 userId, true, ALLOW_FULL_ONLY, callName, null);
   23322         ProcessRecord proc = null;
   23323         try {
   23324             int pid = Integer.parseInt(process);
   23325             synchronized (mPidsSelfLocked) {
   23326                 proc = mPidsSelfLocked.get(pid);
   23327             }
   23328         } catch (NumberFormatException e) {
   23329         }
   23330 
   23331         if (proc == null) {
   23332             ArrayMap<String, SparseArray<ProcessRecord>> all
   23333                     = mProcessNames.getMap();
   23334             SparseArray<ProcessRecord> procs = all.get(process);
   23335             if (procs != null && procs.size() > 0) {
   23336                 proc = procs.valueAt(0);
   23337                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
   23338                     for (int i=1; i<procs.size(); i++) {
   23339                         ProcessRecord thisProc = procs.valueAt(i);
   23340                         if (thisProc.userId == userId) {
   23341                             proc = thisProc;
   23342                             break;
   23343                         }
   23344                     }
   23345                 }
   23346             }
   23347         }
   23348 
   23349         return proc;
   23350     }
   23351 
   23352     public boolean dumpHeap(String process, int userId, boolean managed,
   23353             String path, ParcelFileDescriptor fd) throws RemoteException {
   23354 
   23355         try {
   23356             synchronized (this) {
   23357                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   23358                 // its own permission (same as profileControl).
   23359                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   23360                         != PackageManager.PERMISSION_GRANTED) {
   23361                     throw new SecurityException("Requires permission "
   23362                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   23363                 }
   23364 
   23365                 if (fd == null) {
   23366                     throw new IllegalArgumentException("null fd");
   23367                 }
   23368 
   23369                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
   23370                 if (proc == null || proc.thread == null) {
   23371                     throw new IllegalArgumentException("Unknown process: " + process);
   23372                 }
   23373 
   23374                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   23375                 if (!isDebuggable) {
   23376                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   23377                         throw new SecurityException("Process not debuggable: " + proc);
   23378                     }
   23379                 }
   23380 
   23381                 proc.thread.dumpHeap(managed, path, fd);
   23382                 fd = null;
   23383                 return true;
   23384             }
   23385         } catch (RemoteException e) {
   23386             throw new IllegalStateException("Process disappeared");
   23387         } finally {
   23388             if (fd != null) {
   23389                 try {
   23390                     fd.close();
   23391                 } catch (IOException e) {
   23392                 }
   23393             }
   23394         }
   23395     }
   23396 
   23397     @Override
   23398     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
   23399             String reportPackage) {
   23400         if (processName != null) {
   23401             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   23402                     "setDumpHeapDebugLimit()");
   23403         } else {
   23404             synchronized (mPidsSelfLocked) {
   23405                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
   23406                 if (proc == null) {
   23407                     throw new SecurityException("No process found for calling pid "
   23408                             + Binder.getCallingPid());
   23409                 }
   23410                 if (!Build.IS_DEBUGGABLE
   23411                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   23412                     throw new SecurityException("Not running a debuggable build");
   23413                 }
   23414                 processName = proc.processName;
   23415                 uid = proc.uid;
   23416                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
   23417                     throw new SecurityException("Package " + reportPackage + " is not running in "
   23418                             + proc);
   23419                 }
   23420             }
   23421         }
   23422         synchronized (this) {
   23423             if (maxMemSize > 0) {
   23424                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
   23425             } else {
   23426                 if (uid != 0) {
   23427                     mMemWatchProcesses.remove(processName, uid);
   23428                 } else {
   23429                     mMemWatchProcesses.getMap().remove(processName);
   23430                 }
   23431             }
   23432         }
   23433     }
   23434 
   23435     @Override
   23436     public void dumpHeapFinished(String path) {
   23437         synchronized (this) {
   23438             if (Binder.getCallingPid() != mMemWatchDumpPid) {
   23439                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
   23440                         + " does not match last pid " + mMemWatchDumpPid);
   23441                 return;
   23442             }
   23443             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
   23444                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
   23445                         + " does not match last path " + mMemWatchDumpFile);
   23446                 return;
   23447             }
   23448             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
   23449             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
   23450         }
   23451     }
   23452 
   23453     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
   23454     public void monitor() {
   23455         synchronized (this) { }
   23456     }
   23457 
   23458     void onCoreSettingsChange(Bundle settings) {
   23459         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   23460             ProcessRecord processRecord = mLruProcesses.get(i);
   23461             try {
   23462                 if (processRecord.thread != null) {
   23463                     processRecord.thread.setCoreSettings(settings);
   23464                 }
   23465             } catch (RemoteException re) {
   23466                 /* ignore */
   23467             }
   23468         }
   23469     }
   23470 
   23471     // Multi-user methods
   23472 
   23473     /**
   23474      * Start user, if its not already running, but don't bring it to foreground.
   23475      */
   23476     @Override
   23477     public boolean startUserInBackground(final int userId) {
   23478         return mUserController.startUser(userId, /* foreground */ false);
   23479     }
   23480 
   23481     @Override
   23482     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
   23483         return mUserController.unlockUser(userId, token, secret, listener);
   23484     }
   23485 
   23486     @Override
   23487     public boolean switchUser(final int targetUserId) {
   23488         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
   23489         int currentUserId;
   23490         UserInfo targetUserInfo;
   23491         synchronized (this) {
   23492             currentUserId = mUserController.getCurrentUserIdLocked();
   23493             targetUserInfo = mUserController.getUserInfo(targetUserId);
   23494             if (targetUserId == currentUserId) {
   23495                 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
   23496                 return true;
   23497             }
   23498             if (targetUserInfo == null) {
   23499                 Slog.w(TAG, "No user info for user #" + targetUserId);
   23500                 return false;
   23501             }
   23502             if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
   23503                 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
   23504                         + " when device is in demo mode");
   23505                 return false;
   23506             }
   23507             if (!targetUserInfo.supportsSwitchTo()) {
   23508                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
   23509                 return false;
   23510             }
   23511             if (targetUserInfo.isManagedProfile()) {
   23512                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
   23513                 return false;
   23514             }
   23515             mUserController.setTargetUserIdLocked(targetUserId);
   23516         }
   23517         if (mUserController.mUserSwitchUiEnabled) {
   23518             UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
   23519             Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
   23520             mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
   23521             mUiHandler.sendMessage(mHandler.obtainMessage(
   23522                     START_USER_SWITCH_UI_MSG, userNames));
   23523         } else {
   23524             mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
   23525             mHandler.sendMessage(mHandler.obtainMessage(
   23526                     START_USER_SWITCH_FG_MSG, targetUserId, 0));
   23527         }
   23528         return true;
   23529     }
   23530 
   23531     void scheduleStartProfilesLocked() {
   23532         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
   23533             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
   23534                     DateUtils.SECOND_IN_MILLIS);
   23535         }
   23536     }
   23537 
   23538     @Override
   23539     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
   23540         return mUserController.stopUser(userId, force, callback);
   23541     }
   23542 
   23543     @Override
   23544     public UserInfo getCurrentUser() {
   23545         return mUserController.getCurrentUser();
   23546     }
   23547 
   23548     String getStartedUserState(int userId) {
   23549         synchronized (this) {
   23550             final UserState userState = mUserController.getStartedUserStateLocked(userId);
   23551             return UserState.stateToString(userState.state);
   23552         }
   23553     }
   23554 
   23555     @Override
   23556     public boolean isUserRunning(int userId, int flags) {
   23557         if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
   23558                 && checkCallingPermission(INTERACT_ACROSS_USERS)
   23559                     != PackageManager.PERMISSION_GRANTED) {
   23560             String msg = "Permission Denial: isUserRunning() from pid="
   23561                     + Binder.getCallingPid()
   23562                     + ", uid=" + Binder.getCallingUid()
   23563                     + " requires " + INTERACT_ACROSS_USERS;
   23564             Slog.w(TAG, msg);
   23565             throw new SecurityException(msg);
   23566         }
   23567         synchronized (this) {
   23568             return mUserController.isUserRunningLocked(userId, flags);
   23569         }
   23570     }
   23571 
   23572     @Override
   23573     public int[] getRunningUserIds() {
   23574         if (checkCallingPermission(INTERACT_ACROSS_USERS)
   23575                 != PackageManager.PERMISSION_GRANTED) {
   23576             String msg = "Permission Denial: isUserRunning() from pid="
   23577                     + Binder.getCallingPid()
   23578                     + ", uid=" + Binder.getCallingUid()
   23579                     + " requires " + INTERACT_ACROSS_USERS;
   23580             Slog.w(TAG, msg);
   23581             throw new SecurityException(msg);
   23582         }
   23583         synchronized (this) {
   23584             return mUserController.getStartedUserArrayLocked();
   23585         }
   23586     }
   23587 
   23588     @Override
   23589     public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
   23590         mUserController.registerUserSwitchObserver(observer, name);
   23591     }
   23592 
   23593     @Override
   23594     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
   23595         mUserController.unregisterUserSwitchObserver(observer);
   23596     }
   23597 
   23598     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
   23599         if (info == null) return null;
   23600         ApplicationInfo newInfo = new ApplicationInfo(info);
   23601         newInfo.initForUser(userId);
   23602         return newInfo;
   23603     }
   23604 
   23605     public boolean isUserStopped(int userId) {
   23606         synchronized (this) {
   23607             return mUserController.getStartedUserStateLocked(userId) == null;
   23608         }
   23609     }
   23610 
   23611     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
   23612         if (aInfo == null
   23613                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
   23614             return aInfo;
   23615         }
   23616 
   23617         ActivityInfo info = new ActivityInfo(aInfo);
   23618         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
   23619         return info;
   23620     }
   23621 
   23622     private boolean processSanityChecksLocked(ProcessRecord process) {
   23623         if (process == null || process.thread == null) {
   23624             return false;
   23625         }
   23626 
   23627         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   23628         if (!isDebuggable) {
   23629             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   23630                 return false;
   23631             }
   23632         }
   23633 
   23634         return true;
   23635     }
   23636 
   23637     public boolean startBinderTracking() throws RemoteException {
   23638         synchronized (this) {
   23639             mBinderTransactionTrackingEnabled = true;
   23640             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
   23641             // permission (same as profileControl).
   23642             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   23643                     != PackageManager.PERMISSION_GRANTED) {
   23644                 throw new SecurityException("Requires permission "
   23645                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   23646             }
   23647 
   23648             for (int i = 0; i < mLruProcesses.size(); i++) {
   23649                 ProcessRecord process = mLruProcesses.get(i);
   23650                 if (!processSanityChecksLocked(process)) {
   23651                     continue;
   23652                 }
   23653                 try {
   23654                     process.thread.startBinderTracking();
   23655                 } catch (RemoteException e) {
   23656                     Log.v(TAG, "Process disappared");
   23657                 }
   23658             }
   23659             return true;
   23660         }
   23661     }
   23662 
   23663     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
   23664         try {
   23665             synchronized (this) {
   23666                 mBinderTransactionTrackingEnabled = false;
   23667                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
   23668                 // permission (same as profileControl).
   23669                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   23670                         != PackageManager.PERMISSION_GRANTED) {
   23671                     throw new SecurityException("Requires permission "
   23672                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   23673                 }
   23674 
   23675                 if (fd == null) {
   23676                     throw new IllegalArgumentException("null fd");
   23677                 }
   23678 
   23679                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
   23680                 pw.println("Binder transaction traces for all processes.\n");
   23681                 for (ProcessRecord process : mLruProcesses) {
   23682                     if (!processSanityChecksLocked(process)) {
   23683                         continue;
   23684                     }
   23685 
   23686                     pw.println("Traces for process: " + process.processName);
   23687                     pw.flush();
   23688                     try {
   23689                         TransferPipe tp = new TransferPipe();
   23690                         try {
   23691                             process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
   23692                             tp.go(fd.getFileDescriptor());
   23693                         } finally {
   23694                             tp.kill();
   23695                         }
   23696                     } catch (IOException e) {
   23697                         pw.println("Failure while dumping IPC traces from " + process +
   23698                                 ".  Exception: " + e);
   23699                         pw.flush();
   23700                     } catch (RemoteException e) {
   23701                         pw.println("Got a RemoteException while dumping IPC traces from " +
   23702                                 process + ".  Exception: " + e);
   23703                         pw.flush();
   23704                     }
   23705                 }
   23706                 fd = null;
   23707                 return true;
   23708             }
   23709         } finally {
   23710             if (fd != null) {
   23711                 try {
   23712                     fd.close();
   23713                 } catch (IOException e) {
   23714                 }
   23715             }
   23716         }
   23717     }
   23718 
   23719     @VisibleForTesting
   23720     final class LocalService extends ActivityManagerInternal {
   23721         @Override
   23722         public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
   23723                 int targetUserId) {
   23724             synchronized (ActivityManagerService.this) {
   23725                 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
   23726                         targetPkg, intent, null, targetUserId);
   23727             }
   23728         }
   23729 
   23730         @Override
   23731         public String checkContentProviderAccess(String authority, int userId) {
   23732             return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
   23733         }
   23734 
   23735         @Override
   23736         public void onWakefulnessChanged(int wakefulness) {
   23737             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
   23738         }
   23739 
   23740         @Override
   23741         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
   23742                 String processName, String abiOverride, int uid, Runnable crashHandler) {
   23743             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
   23744                     processName, abiOverride, uid, crashHandler);
   23745         }
   23746 
   23747         @Override
   23748         public SleepToken acquireSleepToken(String tag) {
   23749             Preconditions.checkNotNull(tag);
   23750 
   23751             synchronized (ActivityManagerService.this) {
   23752                 SleepTokenImpl token = new SleepTokenImpl(tag);
   23753                 mSleepTokens.add(token);
   23754                 updateSleepIfNeededLocked();
   23755                 return token;
   23756             }
   23757         }
   23758 
   23759         @Override
   23760         public ComponentName getHomeActivityForUser(int userId) {
   23761             synchronized (ActivityManagerService.this) {
   23762                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
   23763                 return homeActivity == null ? null : homeActivity.realActivity;
   23764             }
   23765         }
   23766 
   23767         @Override
   23768         public void onUserRemoved(int userId) {
   23769             synchronized (ActivityManagerService.this) {
   23770                 ActivityManagerService.this.onUserStoppedLocked(userId);
   23771             }
   23772         }
   23773 
   23774         @Override
   23775         public void onLocalVoiceInteractionStarted(IBinder activity,
   23776                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
   23777             synchronized (ActivityManagerService.this) {
   23778                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
   23779                         voiceSession, voiceInteractor);
   23780             }
   23781         }
   23782 
   23783         @Override
   23784         public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
   23785             synchronized (ActivityManagerService.this) {
   23786                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
   23787                         reasons, timestamp);
   23788             }
   23789         }
   23790 
   23791         @Override
   23792         public void notifyAppTransitionFinished() {
   23793             synchronized (ActivityManagerService.this) {
   23794                 mStackSupervisor.notifyAppTransitionDone();
   23795             }
   23796         }
   23797 
   23798         @Override
   23799         public void notifyAppTransitionCancelled() {
   23800             synchronized (ActivityManagerService.this) {
   23801                 mStackSupervisor.notifyAppTransitionDone();
   23802             }
   23803         }
   23804 
   23805         @Override
   23806         public List<IBinder> getTopVisibleActivities() {
   23807             synchronized (ActivityManagerService.this) {
   23808                 return mStackSupervisor.getTopVisibleActivities();
   23809             }
   23810         }
   23811 
   23812         @Override
   23813         public void notifyDockedStackMinimizedChanged(boolean minimized) {
   23814             synchronized (ActivityManagerService.this) {
   23815                 mStackSupervisor.setDockedStackMinimized(minimized);
   23816             }
   23817         }
   23818 
   23819         @Override
   23820         public void killForegroundAppsForUser(int userHandle) {
   23821             synchronized (ActivityManagerService.this) {
   23822                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
   23823                 final int NP = mProcessNames.getMap().size();
   23824                 for (int ip = 0; ip < NP; ip++) {
   23825                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   23826                     final int NA = apps.size();
   23827                     for (int ia = 0; ia < NA; ia++) {
   23828                         final ProcessRecord app = apps.valueAt(ia);
   23829                         if (app.persistent) {
   23830                             // We don't kill persistent processes.
   23831                             continue;
   23832                         }
   23833                         if (app.removed) {
   23834                             procs.add(app);
   23835                         } else if (app.userId == userHandle && app.foregroundActivities) {
   23836                             app.removed = true;
   23837                             procs.add(app);
   23838                         }
   23839                     }
   23840                 }
   23841 
   23842                 final int N = procs.size();
   23843                 for (int i = 0; i < N; i++) {
   23844                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
   23845                 }
   23846             }
   23847         }
   23848 
   23849         @Override
   23850         public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
   23851                 long duration) {
   23852             if (!(target instanceof PendingIntentRecord)) {
   23853                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
   23854                 return;
   23855             }
   23856             ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
   23857         }
   23858 
   23859         @Override
   23860         public void setDeviceIdleWhitelist(int[] appids) {
   23861             synchronized (ActivityManagerService.this) {
   23862                 mDeviceIdleWhitelist = appids;
   23863             }
   23864         }
   23865 
   23866         @Override
   23867         public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
   23868             synchronized (ActivityManagerService.this) {
   23869                 mDeviceIdleTempWhitelist = appids;
   23870                 setAppIdTempWhitelistStateLocked(changingAppId, adding);
   23871             }
   23872         }
   23873 
   23874         @Override
   23875         public void updatePersistentConfigurationForUser(@NonNull Configuration values,
   23876                 int userId) {
   23877             Preconditions.checkNotNull(values, "Configuration must not be null");
   23878             Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
   23879             synchronized (ActivityManagerService.this) {
   23880                 updateConfigurationLocked(values, null, false, true, userId,
   23881                         false /* deferResume */);
   23882             }
   23883         }
   23884 
   23885         @Override
   23886         public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
   23887                 Bundle bOptions) {
   23888             Preconditions.checkNotNull(intents, "intents");
   23889             final String[] resolvedTypes = new String[intents.length];
   23890             for (int i = 0; i < intents.length; i++) {
   23891                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
   23892             }
   23893 
   23894             // UID of the package on user userId.
   23895             // "= 0" is needed because otherwise catch(RemoteException) would make it look like
   23896             // packageUid may not be initialized.
   23897             int packageUid = 0;
   23898             try {
   23899                 packageUid = AppGlobals.getPackageManager().getPackageUid(
   23900                         packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
   23901             } catch (RemoteException e) {
   23902                 // Shouldn't happen.
   23903             }
   23904 
   23905             synchronized (ActivityManagerService.this) {
   23906                 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
   23907                         /*resultTo*/ null, bOptions, userId);
   23908             }
   23909         }
   23910 
   23911         @Override
   23912         public int getUidProcessState(int uid) {
   23913             return getUidState(uid);
   23914         }
   23915 
   23916         @Override
   23917         public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
   23918             synchronized (ActivityManagerService.this) {
   23919 
   23920                 // We might change the visibilities here, so prepare an empty app transition which
   23921                 // might be overridden later if we actually change visibilities.
   23922                 mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
   23923                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   23924                 mWindowManager.executeAppTransition();
   23925             }
   23926             if (callback != null) {
   23927                 callback.run();
   23928             }
   23929         }
   23930 
   23931         @Override
   23932         public boolean isSystemReady() {
   23933             // no need to synchronize(this) just to read & return the value
   23934             return mSystemReady;
   23935         }
   23936 
   23937         @Override
   23938         public void notifyKeyguardTrustedChanged() {
   23939             synchronized (ActivityManagerService.this) {
   23940                 if (mKeyguardController.isKeyguardShowing()) {
   23941                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   23942                 }
   23943             }
   23944         }
   23945 
   23946         /**
   23947          * Sets if the given pid has an overlay UI or not.
   23948          *
   23949          * @param pid The pid we are setting overlay UI for.
   23950          * @param hasOverlayUi True if the process has overlay UI.
   23951          * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
   23952          */
   23953         @Override
   23954         public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
   23955             synchronized (ActivityManagerService.this) {
   23956                 final ProcessRecord pr;
   23957                 synchronized (mPidsSelfLocked) {
   23958                     pr = mPidsSelfLocked.get(pid);
   23959                     if (pr == null) {
   23960                         Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
   23961                         return;
   23962                     }
   23963                 }
   23964                 if (pr.hasOverlayUi == hasOverlayUi) {
   23965                     return;
   23966                 }
   23967                 pr.hasOverlayUi = hasOverlayUi;
   23968                 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
   23969                 updateOomAdjLocked(pr, true);
   23970             }
   23971         }
   23972 
   23973         /**
   23974          * Called after the network policy rules are updated by
   23975          * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
   23976          * and {@param procStateSeq}.
   23977          */
   23978         @Override
   23979         public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
   23980             if (DEBUG_NETWORK) {
   23981                 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
   23982                         + uid + " seq: " + procStateSeq);
   23983             }
   23984             UidRecord record;
   23985             synchronized (ActivityManagerService.this) {
   23986                 record = mActiveUids.get(uid);
   23987                 if (record == null) {
   23988                     if (DEBUG_NETWORK) {
   23989                         Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
   23990                                 + " procStateSeq: " + procStateSeq);
   23991                     }
   23992                     return;
   23993                 }
   23994             }
   23995             synchronized (record.networkStateLock) {
   23996                 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
   23997                     if (DEBUG_NETWORK) {
   23998                         Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
   23999                                 + " been handled for uid: " + uid);
   24000                     }
   24001                     return;
   24002                 }
   24003                 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
   24004                 if (record.curProcStateSeq > procStateSeq) {
   24005                     if (DEBUG_NETWORK) {
   24006                         Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
   24007                                 + ", curProcstateSeq: " + record.curProcStateSeq
   24008                                 + ", procStateSeq: " + procStateSeq);
   24009                     }
   24010                     return;
   24011                 }
   24012                 if (record.waitingForNetwork) {
   24013                     if (DEBUG_NETWORK) {
   24014                         Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
   24015                                 + ", procStateSeq: " + procStateSeq);
   24016                     }
   24017                     record.networkStateLock.notifyAll();
   24018                 }
   24019             }
   24020         }
   24021 
   24022         /**
   24023          * Called after virtual display Id is updated by
   24024          * {@link com.android.server.vr.Vr2dDisplay} with a specific
   24025          * {@param vrVr2dDisplayId}.
   24026          */
   24027         @Override
   24028         public void setVr2dDisplayId(int vr2dDisplayId) {
   24029             if (DEBUG_STACK) {
   24030                 Slog.d(TAG, "setVr2dDisplayId called for: " +
   24031                         vr2dDisplayId);
   24032             }
   24033             synchronized (ActivityManagerService.this) {
   24034                 mVr2dDisplayId = vr2dDisplayId;
   24035             }
   24036         }
   24037 
   24038         @Override
   24039         public void saveANRState(String reason) {
   24040             synchronized (ActivityManagerService.this) {
   24041                 final StringWriter sw = new StringWriter();
   24042                 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
   24043                 pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
   24044                 if (reason != null) {
   24045                     pw.println("  Reason: " + reason);
   24046                 }
   24047                 pw.println();
   24048                 mActivityStarter.dump(pw, "  ");
   24049                 pw.println();
   24050                 pw.println("-------------------------------------------------------------------------------");
   24051                 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
   24052                         true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
   24053                         "" /* header */);
   24054                 pw.println();
   24055                 pw.close();
   24056 
   24057                 mLastANRState = sw.toString();
   24058             }
   24059         }
   24060 
   24061         @Override
   24062         public void clearSavedANRState() {
   24063             synchronized (ActivityManagerService.this) {
   24064                 mLastANRState = null;
   24065             }
   24066         }
   24067     }
   24068 
   24069     /**
   24070      * Called by app main thread to wait for the network policy rules to get updated.
   24071      *
   24072      * @param procStateSeq The sequence number indicating the process state change that the main
   24073      *                     thread is interested in.
   24074      */
   24075     @Override
   24076     public void waitForNetworkStateUpdate(long procStateSeq) {
   24077         final int callingUid = Binder.getCallingUid();
   24078         if (DEBUG_NETWORK) {
   24079             Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
   24080         }
   24081         UidRecord record;
   24082         synchronized (this) {
   24083             record = mActiveUids.get(callingUid);
   24084             if (record == null) {
   24085                 return;
   24086             }
   24087         }
   24088         synchronized (record.networkStateLock) {
   24089             if (record.lastDispatchedProcStateSeq < procStateSeq) {
   24090                 if (DEBUG_NETWORK) {
   24091                     Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
   24092                             + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
   24093                             + " lastProcStateSeqDispatchedToObservers: "
   24094                             + record.lastDispatchedProcStateSeq);
   24095                 }
   24096                 return;
   24097             }
   24098             if (record.curProcStateSeq > procStateSeq) {
   24099                 if (DEBUG_NETWORK) {
   24100                     Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
   24101                             + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
   24102                             + ", procStateSeq: " + procStateSeq);
   24103                 }
   24104                 return;
   24105             }
   24106             if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
   24107                 if (DEBUG_NETWORK) {
   24108                     Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
   24109                             + procStateSeq + ", so no need to wait. Uid: "
   24110                             + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
   24111                             + record.lastNetworkUpdatedProcStateSeq);
   24112                 }
   24113                 return;
   24114             }
   24115             try {
   24116                 if (DEBUG_NETWORK) {
   24117                     Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
   24118                         + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
   24119                 }
   24120                 final long startTime = SystemClock.uptimeMillis();
   24121                 record.waitingForNetwork = true;
   24122                 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
   24123                 record.waitingForNetwork = false;
   24124                 final long totalTime = SystemClock.uptimeMillis() - startTime;
   24125                 if (totalTime >= mWaitForNetworkTimeoutMs) {
   24126                     Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
   24127                             + totalTime + ". Uid: " + callingUid + " procStateSeq: "
   24128                             + procStateSeq + " UidRec: " + record
   24129                             + " validateUidRec: " + mValidateUids.get(callingUid));
   24130                 }
   24131             } catch (InterruptedException e) {
   24132                 Thread.currentThread().interrupt();
   24133             }
   24134         }
   24135     }
   24136 
   24137     public void waitForBroadcastIdle(PrintWriter pw) {
   24138         enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
   24139         while (true) {
   24140             boolean idle = true;
   24141             synchronized (this) {
   24142                 for (BroadcastQueue queue : mBroadcastQueues) {
   24143                     if (!queue.isIdle()) {
   24144                         final String msg = "Waiting for queue " + queue + " to become idle...";
   24145                         pw.println(msg);
   24146                         pw.flush();
   24147                         Slog.v(TAG, msg);
   24148                         idle = false;
   24149                     }
   24150                 }
   24151             }
   24152 
   24153             if (idle) {
   24154                 final String msg = "All broadcast queues are idle!";
   24155                 pw.println(msg);
   24156                 pw.flush();
   24157                 Slog.v(TAG, msg);
   24158                 return;
   24159             } else {
   24160                 SystemClock.sleep(1000);
   24161             }
   24162         }
   24163     }
   24164 
   24165     /**
   24166      * Return the user id of the last resumed activity.
   24167      */
   24168     @Override
   24169     public @UserIdInt int getLastResumedActivityUserId() {
   24170         enforceCallingPermission(
   24171                 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
   24172         synchronized (this) {
   24173             if (mLastResumedActivity == null) {
   24174                 return mUserController.getCurrentUserIdLocked();
   24175             }
   24176             return mLastResumedActivity.userId;
   24177         }
   24178     }
   24179 
   24180     private final class SleepTokenImpl extends SleepToken {
   24181         private final String mTag;
   24182         private final long mAcquireTime;
   24183 
   24184         public SleepTokenImpl(String tag) {
   24185             mTag = tag;
   24186             mAcquireTime = SystemClock.uptimeMillis();
   24187         }
   24188 
   24189         @Override
   24190         public void release() {
   24191             synchronized (ActivityManagerService.this) {
   24192                 if (mSleepTokens.remove(this)) {
   24193                     updateSleepIfNeededLocked();
   24194                 }
   24195             }
   24196         }
   24197 
   24198         @Override
   24199         public String toString() {
   24200             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
   24201         }
   24202     }
   24203 
   24204     /**
   24205      * An implementation of IAppTask, that allows an app to manage its own tasks via
   24206      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
   24207      * only the process that calls getAppTasks() can call the AppTask methods.
   24208      */
   24209     class AppTaskImpl extends IAppTask.Stub {
   24210         private int mTaskId;
   24211         private int mCallingUid;
   24212 
   24213         public AppTaskImpl(int taskId, int callingUid) {
   24214             mTaskId = taskId;
   24215             mCallingUid = callingUid;
   24216         }
   24217 
   24218         private void checkCaller() {
   24219             if (mCallingUid != Binder.getCallingUid()) {
   24220                 throw new SecurityException("Caller " + mCallingUid
   24221                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
   24222             }
   24223         }
   24224 
   24225         @Override
   24226         public void finishAndRemoveTask() {
   24227             checkCaller();
   24228 
   24229             synchronized (ActivityManagerService.this) {
   24230                 long origId = Binder.clearCallingIdentity();
   24231                 try {
   24232                     // We remove the task from recents to preserve backwards
   24233                     if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
   24234                             REMOVE_FROM_RECENTS)) {
   24235                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   24236                     }
   24237                 } finally {
   24238                     Binder.restoreCallingIdentity(origId);
   24239                 }
   24240             }
   24241         }
   24242 
   24243         @Override
   24244         public ActivityManager.RecentTaskInfo getTaskInfo() {
   24245             checkCaller();
   24246 
   24247             synchronized (ActivityManagerService.this) {
   24248                 long origId = Binder.clearCallingIdentity();
   24249                 try {
   24250                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
   24251                     if (tr == null) {
   24252                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   24253                     }
   24254                     return createRecentTaskInfoFromTaskRecord(tr);
   24255                 } finally {
   24256                     Binder.restoreCallingIdentity(origId);
   24257                 }
   24258             }
   24259         }
   24260 
   24261         @Override
   24262         public void moveToFront() {
   24263             checkCaller();
   24264             // Will bring task to front if it already has a root activity.
   24265             final long origId = Binder.clearCallingIdentity();
   24266             try {
   24267                 synchronized (this) {
   24268                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
   24269                 }
   24270             } finally {
   24271                 Binder.restoreCallingIdentity(origId);
   24272             }
   24273         }
   24274 
   24275         @Override
   24276         public int startActivity(IBinder whoThread, String callingPackage,
   24277                 Intent intent, String resolvedType, Bundle bOptions) {
   24278             checkCaller();
   24279 
   24280             int callingUser = UserHandle.getCallingUserId();
   24281             TaskRecord tr;
   24282             IApplicationThread appThread;
   24283             synchronized (ActivityManagerService.this) {
   24284                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
   24285                 if (tr == null) {
   24286                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   24287                 }
   24288                 appThread = IApplicationThread.Stub.asInterface(whoThread);
   24289                 if (appThread == null) {
   24290                     throw new IllegalArgumentException("Bad app thread " + appThread);
   24291                 }
   24292             }
   24293             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
   24294                     resolvedType, null, null, null, null, 0, 0, null, null,
   24295                     null, bOptions, false, callingUser, null, tr, "AppTaskImpl");
   24296         }
   24297 
   24298         @Override
   24299         public void setExcludeFromRecents(boolean exclude) {
   24300             checkCaller();
   24301 
   24302             synchronized (ActivityManagerService.this) {
   24303                 long origId = Binder.clearCallingIdentity();
   24304                 try {
   24305                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
   24306                     if (tr == null) {
   24307                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   24308                     }
   24309                     Intent intent = tr.getBaseIntent();
   24310                     if (exclude) {
   24311                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
   24312                     } else {
   24313                         intent.setFlags(intent.getFlags()
   24314                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
   24315                     }
   24316                 } finally {
   24317                     Binder.restoreCallingIdentity(origId);
   24318                 }
   24319             }
   24320         }
   24321     }
   24322 
   24323     /**
   24324      * Kill processes for the user with id userId and that depend on the package named packageName
   24325      */
   24326     @Override
   24327     public void killPackageDependents(String packageName, int userId) {
   24328         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
   24329         if (packageName == null) {
   24330             throw new NullPointerException(
   24331                     "Cannot kill the dependents of a package without its name.");
   24332         }
   24333 
   24334         long callingId = Binder.clearCallingIdentity();
   24335         IPackageManager pm = AppGlobals.getPackageManager();
   24336         int pkgUid = -1;
   24337         try {
   24338             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
   24339         } catch (RemoteException e) {
   24340         }
   24341         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
   24342             throw new IllegalArgumentException(
   24343                     "Cannot kill dependents of non-existing package " + packageName);
   24344         }
   24345         try {
   24346             synchronized(this) {
   24347                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
   24348                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
   24349                         "dep: " + packageName);
   24350             }
   24351         } finally {
   24352             Binder.restoreCallingIdentity(callingId);
   24353         }
   24354     }
   24355 
   24356     @Override
   24357     public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
   24358             throws RemoteException {
   24359         final long callingId = Binder.clearCallingIdentity();
   24360         try {
   24361             mKeyguardController.dismissKeyguard(token, callback);
   24362         } finally {
   24363             Binder.restoreCallingIdentity(callingId);
   24364         }
   24365     }
   24366 
   24367     @Override
   24368     public int restartUserInBackground(final int userId) {
   24369         return mUserController.restartUser(userId, /* foreground */ false);
   24370     }
   24371 
   24372     @Override
   24373     public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
   24374         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   24375                 "scheduleApplicationInfoChanged()");
   24376 
   24377         synchronized (this) {
   24378             final long origId = Binder.clearCallingIdentity();
   24379             try {
   24380                 updateApplicationInfoLocked(packageNames, userId);
   24381             } finally {
   24382                 Binder.restoreCallingIdentity(origId);
   24383             }
   24384         }
   24385     }
   24386 
   24387     void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
   24388         final boolean updateFrameworkRes = packagesToUpdate.contains("android");
   24389         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   24390             final ProcessRecord app = mLruProcesses.get(i);
   24391             if (app.thread == null) {
   24392                 continue;
   24393             }
   24394 
   24395             if (userId != UserHandle.USER_ALL && app.userId != userId) {
   24396                 continue;
   24397             }
   24398 
   24399             final int packageCount = app.pkgList.size();
   24400             for (int j = 0; j < packageCount; j++) {
   24401                 final String packageName = app.pkgList.keyAt(j);
   24402                 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
   24403                     try {
   24404                         final ApplicationInfo ai = AppGlobals.getPackageManager()
   24405                                 .getApplicationInfo(packageName, 0 /*flags*/, app.userId);
   24406                         if (ai != null) {
   24407                             app.thread.scheduleApplicationInfoChanged(ai);
   24408                         }
   24409                     } catch (RemoteException e) {
   24410                         Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
   24411                                     packageName, app));
   24412                     }
   24413                 }
   24414             }
   24415         }
   24416     }
   24417 
   24418     /**
   24419      * Attach an agent to the specified process (proces name or PID)
   24420      */
   24421     public void attachAgent(String process, String path) {
   24422         try {
   24423             synchronized (this) {
   24424                 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
   24425                 if (proc == null || proc.thread == null) {
   24426                     throw new IllegalArgumentException("Unknown process: " + process);
   24427                 }
   24428 
   24429                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   24430                 if (!isDebuggable) {
   24431                     if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   24432                         throw new SecurityException("Process not debuggable: " + proc);
   24433                     }
   24434                 }
   24435 
   24436                 proc.thread.attachAgent(path);
   24437             }
   24438         } catch (RemoteException e) {
   24439             throw new IllegalStateException("Process disappeared");
   24440         }
   24441     }
   24442 
   24443     @VisibleForTesting
   24444     public static class Injector {
   24445         private NetworkManagementInternal mNmi;
   24446 
   24447         public Context getContext() {
   24448             return null;
   24449         }
   24450 
   24451         public AppOpsService getAppOpsService(File file, Handler handler) {
   24452             return new AppOpsService(file, handler);
   24453         }
   24454 
   24455         public Handler getUiHandler(ActivityManagerService service) {
   24456             return service.new UiHandler();
   24457         }
   24458 
   24459         public boolean isNetworkRestrictedForUid(int uid) {
   24460             if (ensureHasNetworkManagementInternal()) {
   24461                 return mNmi.isNetworkRestrictedForUid(uid);
   24462             }
   24463             return false;
   24464         }
   24465 
   24466         private boolean ensureHasNetworkManagementInternal() {
   24467             if (mNmi == null) {
   24468                 mNmi = LocalServices.getService(NetworkManagementInternal.class);
   24469             }
   24470             return mNmi != null;
   24471         }
   24472     }
   24473 }
   24474