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.BIND_VOICE_INTERACTION;
     20 import static android.Manifest.permission.CHANGE_CONFIGURATION;
     21 import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
     22 import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
     23 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
     24 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
     25 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
     26 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
     27 import static android.Manifest.permission.READ_FRAME_BUFFER;
     28 import static android.Manifest.permission.REMOVE_TASKS;
     29 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
     30 import static android.Manifest.permission.STOP_APP_SWITCHES;
     31 import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
     32 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
     33 import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
     34 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
     35 import static android.app.ActivityManagerInternal.ASSIST_KEY_CONTENT;
     36 import static android.app.ActivityManagerInternal.ASSIST_KEY_DATA;
     37 import static android.app.ActivityManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
     38 import static android.app.ActivityManagerInternal.ASSIST_KEY_STRUCTURE;
     39 import static android.app.ActivityThread.PROC_START_SEQ_IDENT;
     40 import static android.app.AppOpsManager.OP_NONE;
     41 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
     42 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
     43 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
     44 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
     45 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
     46 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
     47 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
     48 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
     49 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
     50 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
     51 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
     52 import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
     53 import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT;
     54 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
     55 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
     56 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
     57 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
     58 import static android.content.pm.PackageManager.GET_PROVIDERS;
     59 import static android.content.pm.PackageManager.MATCH_ANY_USER;
     60 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
     61 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
     62 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
     63 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
     64 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
     65 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
     66 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
     67 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
     68 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
     69 import static android.os.Build.VERSION_CODES.N;
     70 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
     71 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
     72 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
     73 import static android.os.IServiceManager.DUMP_FLAG_PROTO;
     74 import static android.os.Process.BLUETOOTH_UID;
     75 import static android.os.Process.FIRST_APPLICATION_UID;
     76 import static android.os.Process.FIRST_ISOLATED_UID;
     77 import static android.os.Process.LAST_ISOLATED_UID;
     78 import static android.os.Process.NFC_UID;
     79 import static android.os.Process.PHONE_UID;
     80 import static android.os.Process.PROC_CHAR;
     81 import static android.os.Process.PROC_OUT_LONG;
     82 import static android.os.Process.PROC_PARENS;
     83 import static android.os.Process.PROC_SPACE_TERM;
     84 import static android.os.Process.ProcessStartResult;
     85 import static android.os.Process.ROOT_UID;
     86 import static android.os.Process.SCHED_FIFO;
     87 import static android.os.Process.SCHED_OTHER;
     88 import static android.os.Process.SCHED_RESET_ON_FORK;
     89 import static android.os.Process.SE_UID;
     90 import static android.os.Process.SHELL_UID;
     91 import static android.os.Process.SIGNAL_QUIT;
     92 import static android.os.Process.SIGNAL_USR1;
     93 import static android.os.Process.SYSTEM_UID;
     94 import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
     95 import static android.os.Process.THREAD_GROUP_DEFAULT;
     96 import static android.os.Process.THREAD_GROUP_RESTRICTED;
     97 import static android.os.Process.THREAD_GROUP_TOP_APP;
     98 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
     99 import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
    100 import static android.os.Process.getFreeMemory;
    101 import static android.os.Process.getTotalMemory;
    102 import static android.os.Process.isThreadInProcess;
    103 import static android.os.Process.killProcess;
    104 import static android.os.Process.killProcessQuiet;
    105 import static android.os.Process.myPid;
    106 import static android.os.Process.myUid;
    107 import static android.os.Process.readProcFile;
    108 import static android.os.Process.removeAllProcessGroups;
    109 import static android.os.Process.sendSignal;
    110 import static android.os.Process.setProcessGroup;
    111 import static android.os.Process.setThreadPriority;
    112 import static android.os.Process.setThreadScheduler;
    113 import static android.os.Process.startWebView;
    114 import static android.os.Process.zygoteProcess;
    115 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
    116 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
    117 import static android.provider.Settings.Global.DEBUG_APP;
    118 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
    119 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
    120 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
    121 import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
    122 import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
    123 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
    124 import static android.provider.Settings.System.FONT_SCALE;
    125 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
    126 import static android.text.format.DateUtils.DAY_IN_MILLIS;
    127 import static android.view.Display.DEFAULT_DISPLAY;
    128 import static android.view.Display.INVALID_DISPLAY;
    129 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
    130 import static com.android.internal.util.XmlUtils.readIntAttribute;
    131 import static com.android.internal.util.XmlUtils.readLongAttribute;
    132 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
    133 import static com.android.internal.util.XmlUtils.writeIntAttribute;
    134 import static com.android.internal.util.XmlUtils.writeLongAttribute;
    135 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
    136 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
    137 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
    138 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
    139 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
    140 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
    141 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
    142 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
    143 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
    144 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
    145 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
    146 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
    147 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
    148 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
    149 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
    150 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
    151 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
    152 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
    153 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
    154 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
    155 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
    156 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
    157 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
    158 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
    159 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
    160 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
    161 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
    162 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
    163 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
    164 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
    165 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
    166 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
    167 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
    168 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
    169 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
    170 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
    171 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
    172 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
    173 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
    174 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
    175 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
    176 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
    177 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
    178 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
    179 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
    180 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
    181 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
    182 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
    183 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
    184 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
    185 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
    186 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
    187 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
    188 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
    189 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
    190 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
    191 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
    192 import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
    193 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
    194 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
    195 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
    196 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
    197 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
    198 import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
    199 import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
    200 import static com.android.server.am.MemoryStatUtil.hasMemcg;
    201 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
    202 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
    203 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
    204 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
    205 import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
    206 import static android.view.WindowManager.TRANSIT_NONE;
    207 import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
    208 import static android.view.WindowManager.TRANSIT_TASK_OPEN;
    209 import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
    210 import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
    211 import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
    212 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
    213 import static org.xmlpull.v1.XmlPullParser.START_TAG;
    214 
    215 import android.Manifest;
    216 import android.Manifest.permission;
    217 import android.annotation.NonNull;
    218 import android.annotation.Nullable;
    219 import android.annotation.UserIdInt;
    220 import android.app.Activity;
    221 import android.app.ActivityManager;
    222 import android.app.ActivityManager.RunningTaskInfo;
    223 import android.app.ActivityManager.StackInfo;
    224 import android.app.ActivityManager.TaskSnapshot;
    225 import android.app.ActivityManagerInternal;
    226 import android.app.ActivityManagerInternal.ScreenObserver;
    227 import android.app.ActivityManagerInternal.SleepToken;
    228 import android.app.ActivityManagerProto;
    229 import android.app.ActivityOptions;
    230 import android.app.ActivityThread;
    231 import android.app.AlertDialog;
    232 import android.app.AppGlobals;
    233 import android.app.AppOpsManager;
    234 import android.app.ApplicationErrorReport;
    235 import android.app.ApplicationThreadConstants;
    236 import android.app.BroadcastOptions;
    237 import android.app.ContentProviderHolder;
    238 import android.app.Dialog;
    239 import android.app.GrantedUriPermission;
    240 import android.app.IActivityController;
    241 import android.app.IActivityManager;
    242 import android.app.IApplicationThread;
    243 import android.app.IAssistDataReceiver;
    244 import android.app.IInstrumentationWatcher;
    245 import android.app.INotificationManager;
    246 import android.app.IProcessObserver;
    247 import android.app.IServiceConnection;
    248 import android.app.IStopUserCallback;
    249 import android.app.ITaskStackListener;
    250 import android.app.IUiAutomationConnection;
    251 import android.app.IUidObserver;
    252 import android.app.IUserSwitchObserver;
    253 import android.app.Instrumentation;
    254 import android.app.Notification;
    255 import android.app.NotificationManager;
    256 import android.app.PendingIntent;
    257 import android.app.PictureInPictureParams;
    258 import android.app.ProcessMemoryState;
    259 import android.app.ProfilerInfo;
    260 import android.app.RemoteAction;
    261 import android.app.WaitResult;
    262 import android.app.WindowConfiguration.ActivityType;
    263 import android.app.WindowConfiguration.WindowingMode;
    264 import android.app.admin.DevicePolicyCache;
    265 import android.app.assist.AssistContent;
    266 import android.app.assist.AssistStructure;
    267 import android.app.backup.IBackupManager;
    268 import android.app.servertransaction.ConfigurationChangeItem;
    269 import android.app.usage.UsageEvents;
    270 import android.app.usage.UsageStatsManagerInternal;
    271 import android.appwidget.AppWidgetManager;
    272 import android.content.ActivityNotFoundException;
    273 import android.content.BroadcastReceiver;
    274 import android.content.ClipData;
    275 import android.content.ComponentCallbacks2;
    276 import android.content.ComponentName;
    277 import android.content.ContentProvider;
    278 import android.content.ContentResolver;
    279 import android.content.Context;
    280 import android.content.DialogInterface;
    281 import android.content.IContentProvider;
    282 import android.content.IIntentReceiver;
    283 import android.content.IIntentSender;
    284 import android.content.Intent;
    285 import android.content.IntentFilter;
    286 import android.content.pm.ActivityInfo;
    287 import android.content.pm.ApplicationInfo;
    288 import android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy;
    289 import android.content.pm.ConfigurationInfo;
    290 import android.content.pm.IPackageDataObserver;
    291 import android.content.pm.IPackageManager;
    292 import android.content.pm.InstrumentationInfo;
    293 import android.content.pm.PackageInfo;
    294 import android.content.pm.PackageManager;
    295 import android.content.pm.PackageManager.NameNotFoundException;
    296 import android.content.pm.PackageManagerInternal;
    297 import android.content.pm.ParceledListSlice;
    298 import android.content.pm.PathPermission;
    299 import android.content.pm.PermissionInfo;
    300 import android.content.pm.ProviderInfo;
    301 import android.content.pm.ResolveInfo;
    302 import android.content.pm.SELinuxUtil;
    303 import android.content.pm.ServiceInfo;
    304 import android.content.pm.UserInfo;
    305 import android.content.res.CompatibilityInfo;
    306 import android.content.res.Configuration;
    307 import android.content.res.Resources;
    308 import android.database.ContentObserver;
    309 import android.graphics.Bitmap;
    310 import android.graphics.Point;
    311 import android.graphics.Rect;
    312 import android.hardware.display.DisplayManagerInternal;
    313 import android.location.LocationManager;
    314 import android.media.audiofx.AudioEffect;
    315 import android.metrics.LogMaker;
    316 import android.net.Proxy;
    317 import android.net.ProxyInfo;
    318 import android.net.Uri;
    319 import android.os.BatteryStats;
    320 import android.os.Binder;
    321 import android.os.Build;
    322 import android.os.Bundle;
    323 import android.os.Debug;
    324 import android.os.DropBoxManager;
    325 import android.os.Environment;
    326 import android.os.FactoryTest;
    327 import android.os.FileObserver;
    328 import android.os.FileUtils;
    329 import android.os.Handler;
    330 import android.os.IBinder;
    331 import android.os.IDeviceIdentifiersPolicyService;
    332 import android.os.IPermissionController;
    333 import android.os.IProcessInfoService;
    334 import android.os.IProgressListener;
    335 import android.os.LocaleList;
    336 import android.os.Looper;
    337 import android.os.Message;
    338 import android.os.Parcel;
    339 import android.os.ParcelFileDescriptor;
    340 import android.os.PersistableBundle;
    341 import android.os.PowerManager;
    342 import android.os.PowerManager.ServiceType;
    343 import android.os.PowerManagerInternal;
    344 import android.os.Process;
    345 import android.os.RemoteCallbackList;
    346 import android.os.RemoteException;
    347 import android.os.ResultReceiver;
    348 import android.os.ServiceManager;
    349 import android.os.ShellCallback;
    350 import android.os.StrictMode;
    351 import android.os.SystemClock;
    352 import android.os.SystemProperties;
    353 import android.os.Trace;
    354 import android.os.TransactionTooLargeException;
    355 import android.os.UpdateLock;
    356 import android.os.UserHandle;
    357 import android.os.UserManager;
    358 import android.os.WorkSource;
    359 import android.os.storage.IStorageManager;
    360 import android.os.storage.StorageManager;
    361 import android.os.storage.StorageManagerInternal;
    362 import android.provider.Downloads;
    363 import android.provider.Settings;
    364 import android.service.voice.IVoiceInteractionSession;
    365 import android.service.voice.VoiceInteractionManagerInternal;
    366 import android.telecom.TelecomManager;
    367 import android.text.TextUtils;
    368 import android.text.format.DateUtils;
    369 import android.text.format.Time;
    370 import android.text.style.SuggestionSpan;
    371 import android.util.ArrayMap;
    372 import android.util.ArraySet;
    373 import android.util.AtomicFile;
    374 import android.util.DebugUtils;
    375 import android.util.EventLog;
    376 import android.util.Log;
    377 import android.util.LongSparseArray;
    378 import android.util.Pair;
    379 import android.util.PrintWriterPrinter;
    380 import android.util.Slog;
    381 import android.util.SparseArray;
    382 import android.util.SparseIntArray;
    383 import android.util.StatsLog;
    384 import android.util.TimeUtils;
    385 import android.util.TimingsTraceLog;
    386 import android.util.Xml;
    387 import android.util.proto.ProtoOutputStream;
    388 import android.util.proto.ProtoUtils;
    389 import android.view.Gravity;
    390 import android.view.IRecentsAnimationRunner;
    391 import android.view.LayoutInflater;
    392 import android.view.RemoteAnimationAdapter;
    393 import android.view.RemoteAnimationDefinition;
    394 import android.view.View;
    395 import android.view.WindowManager;
    396 import android.view.autofill.AutofillManagerInternal;
    397 
    398 import com.android.internal.R;
    399 import com.android.internal.annotations.GuardedBy;
    400 import com.android.internal.annotations.VisibleForTesting;
    401 import com.android.internal.app.AssistUtils;
    402 import com.android.internal.app.DumpHeapActivity;
    403 import com.android.internal.app.IAppOpsCallback;
    404 import com.android.internal.app.IAppOpsService;
    405 import com.android.internal.app.IVoiceInteractor;
    406 import com.android.internal.app.ProcessMap;
    407 import com.android.internal.app.SystemUserHomeActivity;
    408 import com.android.internal.app.procstats.ProcessStats;
    409 import com.android.internal.logging.MetricsLogger;
    410 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
    411 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
    412 import com.android.internal.notification.SystemNotificationChannels;
    413 import com.android.internal.os.BackgroundThread;
    414 import com.android.internal.os.BatteryStatsImpl;
    415 import com.android.internal.os.BinderInternal;
    416 import com.android.internal.os.logging.MetricsLoggerWrapper;
    417 import com.android.internal.os.ByteTransferPipe;
    418 import com.android.internal.os.IResultReceiver;
    419 import com.android.internal.os.ProcessCpuTracker;
    420 import com.android.internal.os.TransferPipe;
    421 import com.android.internal.os.Zygote;
    422 import com.android.internal.policy.IKeyguardDismissCallback;
    423 import com.android.internal.policy.KeyguardDismissCallback;
    424 import com.android.internal.telephony.TelephonyIntents;
    425 import com.android.internal.util.ArrayUtils;
    426 import com.android.internal.util.DumpUtils;
    427 import com.android.internal.util.FastPrintWriter;
    428 import com.android.internal.util.FastXmlSerializer;
    429 import com.android.internal.util.MemInfoReader;
    430 import com.android.internal.util.Preconditions;
    431 import com.android.server.AlarmManagerInternal;
    432 import com.android.server.AppOpsService;
    433 import com.android.server.AttributeCache;
    434 import com.android.server.BinderCallsStatsService;
    435 import com.android.server.DeviceIdleController;
    436 import com.android.server.IntentResolver;
    437 import com.android.server.IoThread;
    438 import com.android.server.LocalServices;
    439 import com.android.server.LockGuard;
    440 import com.android.server.NetworkManagementInternal;
    441 import com.android.server.RescueParty;
    442 import com.android.server.ServiceThread;
    443 import com.android.server.SystemConfig;
    444 import com.android.server.SystemService;
    445 import com.android.server.SystemServiceManager;
    446 import com.android.server.ThreadPriorityBooster;
    447 import com.android.server.Watchdog;
    448 import com.android.server.am.ActivityStack.ActivityState;
    449 import com.android.server.am.MemoryStatUtil.MemoryStat;
    450 import com.android.server.am.ActivityManagerServiceProto;
    451 import com.android.server.am.ActivityManagerServiceDumpActivitiesProto;
    452 import com.android.server.am.ActivityManagerServiceDumpBroadcastsProto;
    453 import com.android.server.am.ActivityManagerServiceDumpProcessesProto;
    454 import com.android.server.am.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto;
    455 import com.android.server.am.ActivityManagerServiceDumpServicesProto;
    456 import com.android.server.am.GrantUriProto;
    457 import com.android.server.am.ImportanceTokenProto;
    458 import com.android.server.am.MemInfoDumpProto;
    459 import com.android.server.am.NeededUriGrantsProto;
    460 import com.android.server.am.ProcessOomProto;
    461 import com.android.server.am.ProcessToGcProto;
    462 import com.android.server.am.StickyBroadcastProto;
    463 import com.android.server.firewall.IntentFirewall;
    464 import com.android.server.job.JobSchedulerInternal;
    465 import com.android.server.pm.Installer;
    466 import com.android.server.pm.Installer.InstallerException;
    467 import com.android.server.pm.dex.DexManager;
    468 import com.android.server.utils.PriorityDump;
    469 import com.android.server.vr.VrManagerInternal;
    470 import com.android.server.wm.PinnedStackWindowController;
    471 import com.android.server.wm.WindowManagerService;
    472 
    473 import dalvik.system.VMRuntime;
    474 
    475 import libcore.io.IoUtils;
    476 import libcore.util.EmptyArray;
    477 
    478 import com.google.android.collect.Lists;
    479 import com.google.android.collect.Maps;
    480 
    481 import org.xmlpull.v1.XmlPullParser;
    482 import org.xmlpull.v1.XmlPullParserException;
    483 import org.xmlpull.v1.XmlSerializer;
    484 
    485 import java.io.File;
    486 import java.io.FileDescriptor;
    487 import java.io.FileInputStream;
    488 import java.io.FileNotFoundException;
    489 import java.io.FileOutputStream;
    490 import java.io.IOException;
    491 import java.io.InputStreamReader;
    492 import java.io.PrintWriter;
    493 import java.io.StringWriter;
    494 import java.io.UnsupportedEncodingException;
    495 import java.lang.ref.WeakReference;
    496 import java.nio.charset.StandardCharsets;
    497 import java.text.DateFormat;
    498 import java.text.SimpleDateFormat;
    499 import java.util.ArrayList;
    500 import java.util.Arrays;
    501 import java.util.Collections;
    502 import java.util.Comparator;
    503 import java.util.Date;
    504 import java.util.HashMap;
    505 import java.util.HashSet;
    506 import java.util.Iterator;
    507 import java.util.List;
    508 import java.util.Locale;
    509 import java.util.Map;
    510 import java.util.Objects;
    511 import java.util.Set;
    512 import java.util.concurrent.CountDownLatch;
    513 import java.util.concurrent.Executor;
    514 import java.util.concurrent.atomic.AtomicBoolean;
    515 import java.util.concurrent.atomic.AtomicLong;
    516 
    517 public class ActivityManagerService extends IActivityManager.Stub
    518         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    519 
    520     /**
    521      * Priority we boost main thread and RT of top app to.
    522      */
    523     public static final int TOP_APP_PRIORITY_BOOST = -10;
    524 
    525     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
    526     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
    527     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
    528     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
    529     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
    530     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
    531     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
    532     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
    533     private static final String TAG_LRU = TAG + POSTFIX_LRU;
    534     private static final String TAG_MU = TAG + POSTFIX_MU;
    535     private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
    536     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
    537     private static final String TAG_POWER = TAG + POSTFIX_POWER;
    538     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
    539     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
    540     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
    541     private static final String TAG_PSS = TAG + POSTFIX_PSS;
    542     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
    543     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
    544     private static final String TAG_STACK = TAG + POSTFIX_STACK;
    545     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
    546     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
    547     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
    548     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
    549 
    550     // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
    551     // here so that while the job scheduler can depend on AMS, the other way around
    552     // need not be the case.
    553     public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
    554 
    555     /** Control over CPU and battery monitoring */
    556     // write battery stats every 30 minutes.
    557     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
    558     static final boolean MONITOR_CPU_USAGE = true;
    559     // don't sample cpu less than every 5 seconds.
    560     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
    561     // wait possibly forever for next cpu sample.
    562     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
    563     static final boolean MONITOR_THREAD_CPU_USAGE = false;
    564 
    565     // The flags that are set for all calls we make to the package manager.
    566     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
    567 
    568     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
    569 
    570     // Maximum number of receivers an app can register.
    571     private static final int MAX_RECEIVERS_ALLOWED_PER_APP = 1000;
    572 
    573     // Amount of time after a call to stopAppSwitches() during which we will
    574     // prevent further untrusted switches from happening.
    575     static final long APP_SWITCH_DELAY_TIME = 5*1000;
    576 
    577     // How long we wait for a launched process to attach to the activity manager
    578     // before we decide it's never going to come up for real.
    579     static final int PROC_START_TIMEOUT = 10*1000;
    580     // How long we wait for an attached process to publish its content providers
    581     // before we decide it must be hung.
    582     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
    583 
    584     // How long we wait for a launched process to attach to the activity manager
    585     // before we decide it's never going to come up for real, when the process was
    586     // started with a wrapper for instrumentation (such as Valgrind) because it
    587     // could take much longer than usual.
    588     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
    589 
    590     // How long we allow a receiver to run before giving up on it.
    591     static final int BROADCAST_FG_TIMEOUT = 10*1000;
    592     static final int BROADCAST_BG_TIMEOUT = 60*1000;
    593 
    594     // How long we wait until we timeout on key dispatching.
    595     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
    596 
    597     // How long we wait until we timeout on key dispatching during instrumentation.
    598     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
    599 
    600     // Disable hidden API checks for the newly started instrumentation.
    601     // Must be kept in sync with Am.
    602     private static final int INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS = 1 << 0;
    603 
    604     // How long to wait in getAssistContextExtras for the activity and foreground services
    605     // to respond with the result.
    606     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
    607 
    608     // How long top wait when going through the modern assist (which doesn't need to block
    609     // on getting this result before starting to launch its UI).
    610     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
    611 
    612     // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
    613     static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
    614 
    615     // Maximum number of persisted Uri grants a package is allowed
    616     static final int MAX_PERSISTED_URI_GRANTS = 128;
    617 
    618     static final int MY_PID = myPid();
    619 
    620     static final String[] EMPTY_STRING_ARRAY = new String[0];
    621 
    622     // How many bytes to write into the dropbox log before truncating
    623     static final int DROPBOX_MAX_SIZE = 192 * 1024;
    624     // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
    625     // as one line, but close enough for now.
    626     static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
    627 
    628     /** If a UID observer takes more than this long, send a WTF. */
    629     private static final int SLOW_UID_OBSERVER_THRESHOLD_MS = 20;
    630 
    631     // Access modes for handleIncomingUser.
    632     static final int ALLOW_NON_FULL = 0;
    633     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
    634     static final int ALLOW_FULL_ONLY = 2;
    635 
    636     // Necessary ApplicationInfo flags to mark an app as persistent
    637     private static final int PERSISTENT_MASK =
    638             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
    639 
    640     // Intent sent when remote bugreport collection has been completed
    641     private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
    642             "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
    643 
    644     // Used to indicate that an app transition should be animated.
    645     static final boolean ANIMATE = true;
    646 
    647     // Determines whether to take full screen screenshots
    648     static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
    649 
    650     /**
    651      * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
    652      */
    653     private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
    654 
    655     /**
    656      * State indicating that there is no need for any blocking for network.
    657      */
    658     @VisibleForTesting
    659     static final int NETWORK_STATE_NO_CHANGE = 0;
    660 
    661     /**
    662      * State indicating that the main thread needs to be informed about the network wait.
    663      */
    664     @VisibleForTesting
    665     static final int NETWORK_STATE_BLOCK = 1;
    666 
    667     /**
    668      * State indicating that any threads waiting for network state to get updated can be unblocked.
    669      */
    670     @VisibleForTesting
    671     static final int NETWORK_STATE_UNBLOCK = 2;
    672 
    673     // Max character limit for a notification title. If the notification title is larger than this
    674     // the notification will not be legible to the user.
    675     private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
    676 
    677     private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
    678 
    679     /** All system services */
    680     SystemServiceManager mSystemServiceManager;
    681 
    682     // Wrapper around VoiceInteractionServiceManager
    683     private AssistUtils mAssistUtils;
    684 
    685     // Keeps track of the active voice interaction service component, notified from
    686     // VoiceInteractionManagerService
    687     ComponentName mActiveVoiceInteractionServiceComponent;
    688 
    689     private Installer mInstaller;
    690 
    691     /** Run all ActivityStacks through this */
    692     final ActivityStackSupervisor mStackSupervisor;
    693     private final KeyguardController mKeyguardController;
    694 
    695     private final ActivityStartController mActivityStartController;
    696 
    697     private final ClientLifecycleManager mLifecycleManager;
    698 
    699     final TaskChangeNotificationController mTaskChangeNotificationController;
    700 
    701     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
    702 
    703     final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
    704 
    705     public final IntentFirewall mIntentFirewall;
    706 
    707     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
    708     // default action automatically.  Important for devices without direct input
    709     // devices.
    710     private boolean mShowDialogs = true;
    711 
    712     private final VrController mVrController;
    713 
    714     // VR Vr2d Display Id.
    715     int mVr2dDisplayId = INVALID_DISPLAY;
    716 
    717     // Whether we should use SCHED_FIFO for UI and RenderThreads.
    718     private boolean mUseFifoUiScheduling = false;
    719 
    720     private static final String SYSUI_COMPONENT_NAME = "com.android.systemui/.SystemUIService";
    721 
    722     BroadcastQueue mFgBroadcastQueue;
    723     BroadcastQueue mBgBroadcastQueue;
    724     // Convenient for easy iteration over the queues. Foreground is first
    725     // so that dispatch of foreground broadcasts gets precedence.
    726     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
    727 
    728     BroadcastStats mLastBroadcastStats;
    729     BroadcastStats mCurBroadcastStats;
    730 
    731     BroadcastQueue broadcastQueueForIntent(Intent intent) {
    732         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
    733         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
    734                 "Broadcast intent " + intent + " on "
    735                 + (isFg ? "foreground" : "background") + " queue");
    736         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
    737     }
    738 
    739     /**
    740      * The last resumed activity. This is identical to the current resumed activity most
    741      * of the time but could be different when we're pausing one activity before we resume
    742      * another activity.
    743      */
    744     private ActivityRecord mLastResumedActivity;
    745 
    746     /**
    747      * The activity that is currently being traced as the active resumed activity.
    748      *
    749      * @see #updateResumedAppTrace
    750      */
    751     private @Nullable ActivityRecord mTracedResumedActivity;
    752 
    753     /**
    754      * If non-null, we are tracking the time the user spends in the currently focused app.
    755      */
    756     private AppTimeTracker mCurAppTimeTracker;
    757 
    758     /**
    759      * List of intents that were used to start the most recent tasks.
    760      */
    761     private final RecentTasks mRecentTasks;
    762 
    763     /**
    764      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
    765      */
    766     String mDeviceOwnerName;
    767 
    768     /**
    769      * The controller for all operations related to locktask.
    770      */
    771     private final LockTaskController mLockTaskController;
    772 
    773     final UserController mUserController;
    774 
    775     /**
    776      * Packages that are being allowed to perform unrestricted app switches.  Mapping is
    777      * User -> Type -> uid.
    778      */
    779     final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
    780 
    781     final AppErrors mAppErrors;
    782 
    783     final AppWarnings mAppWarnings;
    784 
    785     /**
    786      * Dump of the activity state at the time of the last ANR. Cleared after
    787      * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
    788      */
    789     String mLastANRState;
    790 
    791     /**
    792      * Indicates the maximum time spent waiting for the network rules to get updated.
    793      */
    794     @VisibleForTesting
    795     long mWaitForNetworkTimeoutMs;
    796 
    797     /** Total # of UID change events dispatched, shown in dumpsys. */
    798     int mUidChangeDispatchCount;
    799 
    800     /**
    801      * Helper class which strips out priority and proto arguments then calls the dump function with
    802      * the appropriate arguments. If priority arguments are omitted, function calls the legacy
    803      * dump command.
    804      * If priority arguments are omitted all sections are dumped, otherwise sections are dumped
    805      * according to their priority.
    806      */
    807     private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
    808         @Override
    809         public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
    810                 boolean asProto) {
    811             if (asProto) return;
    812             doDump(fd, pw, new String[]{"activities"}, asProto);
    813             doDump(fd, pw, new String[]{"service", SYSUI_COMPONENT_NAME}, asProto);
    814         }
    815 
    816         @Override
    817         public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
    818             doDump(fd, pw, new String[]{"-a", "--normal-priority"}, asProto);
    819         }
    820 
    821         @Override
    822         public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
    823             doDump(fd, pw, args, asProto);
    824         }
    825     };
    826 
    827     public boolean canShowErrorDialogs() {
    828         return mShowDialogs && !mSleeping && !mShuttingDown
    829                 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
    830                 && !mUserController.hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
    831                         mUserController.getCurrentUserId())
    832                 && !(UserManager.isDeviceInDemoMode(mContext)
    833                         && mUserController.getCurrentUser().isDemo());
    834     }
    835 
    836     private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
    837             THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
    838 
    839     static void boostPriorityForLockedSection() {
    840         sThreadPriorityBooster.boost();
    841     }
    842 
    843     static void resetPriorityAfterLockedSection() {
    844         sThreadPriorityBooster.reset();
    845     }
    846 
    847     public class PendingAssistExtras extends Binder implements Runnable {
    848         public final ActivityRecord activity;
    849         public boolean isHome;
    850         public final Bundle extras;
    851         public final Intent intent;
    852         public final String hint;
    853         public final IAssistDataReceiver receiver;
    854         public final int userHandle;
    855         public boolean haveResult = false;
    856         public Bundle result = null;
    857         public AssistStructure structure = null;
    858         public AssistContent content = null;
    859         public Bundle receiverExtras;
    860 
    861         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
    862                 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
    863                 int _userHandle) {
    864             activity = _activity;
    865             extras = _extras;
    866             intent = _intent;
    867             hint = _hint;
    868             receiver = _receiver;
    869             receiverExtras = _receiverExtras;
    870             userHandle = _userHandle;
    871         }
    872 
    873         @Override
    874         public void run() {
    875             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
    876             synchronized (this) {
    877                 haveResult = true;
    878                 notifyAll();
    879             }
    880             pendingAssistExtrasTimedOut(this);
    881         }
    882     }
    883 
    884     final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
    885 
    886     /**
    887      * Process management.
    888      */
    889     final ProcessList mProcessList = new ProcessList();
    890 
    891     /**
    892      * All of the applications we currently have running organized by name.
    893      * The keys are strings of the application package name (as
    894      * returned by the package manager), and the keys are ApplicationRecord
    895      * objects.
    896      */
    897     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
    898 
    899     /**
    900      * Tracking long-term execution of processes to look for abuse and other
    901      * bad app behavior.
    902      */
    903     final ProcessStatsService mProcessStats;
    904 
    905     /**
    906      * The currently running isolated processes.
    907      */
    908     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
    909 
    910     /**
    911      * Counter for assigning isolated process uids, to avoid frequently reusing the
    912      * same ones.
    913      */
    914     int mNextIsolatedProcessUid = 0;
    915 
    916     /**
    917      * The currently running heavy-weight process, if any.
    918      */
    919     ProcessRecord mHeavyWeightProcess = null;
    920 
    921     /**
    922      * Non-persistent appId whitelist for background restrictions
    923      */
    924     int[] mBackgroundAppIdWhitelist = new int[] {
    925             BLUETOOTH_UID
    926     };
    927 
    928     /**
    929      * Broadcast actions that will always be deliverable to unlaunched/background apps
    930      */
    931     ArraySet<String> mBackgroundLaunchBroadcasts;
    932 
    933     /**
    934      * All of the processes we currently have running organized by pid.
    935      * The keys are the pid running the application.
    936      *
    937      * <p>NOTE: This object is protected by its own lock, NOT the global
    938      * activity manager lock!
    939      */
    940     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
    941 
    942     /**
    943      * All of the processes that have been forced to be important.  The key
    944      * is the pid of the caller who requested it (we hold a death
    945      * link on it).
    946      */
    947     abstract class ImportanceToken implements IBinder.DeathRecipient {
    948         final int pid;
    949         final IBinder token;
    950         final String reason;
    951 
    952         ImportanceToken(int _pid, IBinder _token, String _reason) {
    953             pid = _pid;
    954             token = _token;
    955             reason = _reason;
    956         }
    957 
    958         @Override
    959         public String toString() {
    960             return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
    961                     + " " + reason + " " + pid + " " + token + " }";
    962         }
    963 
    964         void writeToProto(ProtoOutputStream proto, long fieldId) {
    965             final long pToken = proto.start(fieldId);
    966             proto.write(ImportanceTokenProto.PID, pid);
    967             if (token != null) {
    968                 proto.write(ImportanceTokenProto.TOKEN, token.toString());
    969             }
    970             proto.write(ImportanceTokenProto.REASON, reason);
    971             proto.end(pToken);
    972         }
    973     }
    974     final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
    975 
    976     /**
    977      * List of records for processes that someone had tried to start before the
    978      * system was ready.  We don't start them at that point, but ensure they
    979      * are started by the time booting is complete.
    980      */
    981     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
    982 
    983     /**
    984      * List of persistent applications that are in the process
    985      * of being started.
    986      */
    987     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
    988 
    989     /**
    990      * Processes that are being forcibly torn down.
    991      */
    992     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
    993 
    994     /**
    995      * List of running applications, sorted by recent usage.
    996      * The first entry in the list is the least recently used.
    997      */
    998     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
    999 
   1000     /**
   1001      * Where in mLruProcesses that the processes hosting activities start.
   1002      */
   1003     int mLruProcessActivityStart = 0;
   1004 
   1005     /**
   1006      * Where in mLruProcesses that the processes hosting services start.
   1007      * This is after (lower index) than mLruProcessesActivityStart.
   1008      */
   1009     int mLruProcessServiceStart = 0;
   1010 
   1011     /**
   1012      * List of processes that should gc as soon as things are idle.
   1013      */
   1014     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
   1015 
   1016     /**
   1017      * Processes we want to collect PSS data from.
   1018      */
   1019     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
   1020 
   1021     private boolean mBinderTransactionTrackingEnabled = false;
   1022 
   1023     /**
   1024      * Last time we requested PSS data of all processes.
   1025      */
   1026     long mLastFullPssTime = SystemClock.uptimeMillis();
   1027 
   1028     /**
   1029      * If set, the next time we collect PSS data we should do a full collection
   1030      * with data from native processes and the kernel.
   1031      */
   1032     boolean mFullPssPending = false;
   1033 
   1034     /**
   1035      * This is the process holding what we currently consider to be
   1036      * the "home" activity.
   1037      */
   1038     ProcessRecord mHomeProcess;
   1039 
   1040     /**
   1041      * This is the process holding the activity the user last visited that
   1042      * is in a different process from the one they are currently in.
   1043      */
   1044     ProcessRecord mPreviousProcess;
   1045 
   1046     /**
   1047      * The time at which the previous process was last visible.
   1048      */
   1049     long mPreviousProcessVisibleTime;
   1050 
   1051     /**
   1052      * Track all uids that have actively running processes.
   1053      */
   1054     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
   1055 
   1056     /**
   1057      * This is for verifying the UID report flow.
   1058      */
   1059     static final boolean VALIDATE_UID_STATES = true;
   1060     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
   1061 
   1062     /**
   1063      * Packages that the user has asked to have run in screen size
   1064      * compatibility mode instead of filling the screen.
   1065      */
   1066     final CompatModePackages mCompatModePackages;
   1067 
   1068     /**
   1069      * Set of IntentSenderRecord objects that are currently active.
   1070      */
   1071     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
   1072             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
   1073 
   1074     /**
   1075      * Fingerprints (hashCode()) of stack traces that we've
   1076      * already logged DropBox entries for.  Guarded by itself.  If
   1077      * something (rogue user app) forces this over
   1078      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
   1079      */
   1080     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
   1081     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
   1082 
   1083     /**
   1084      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
   1085      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
   1086      */
   1087     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
   1088 
   1089     /**
   1090      * Resolver for broadcast intents to registered receivers.
   1091      * Holds BroadcastFilter (subclass of IntentFilter).
   1092      */
   1093     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
   1094             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
   1095         @Override
   1096         protected boolean allowFilterResult(
   1097                 BroadcastFilter filter, List<BroadcastFilter> dest) {
   1098             IBinder target = filter.receiverList.receiver.asBinder();
   1099             for (int i = dest.size() - 1; i >= 0; i--) {
   1100                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
   1101                     return false;
   1102                 }
   1103             }
   1104             return true;
   1105         }
   1106 
   1107         @Override
   1108         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
   1109             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
   1110                     || userId == filter.owningUserId) {
   1111                 return super.newResult(filter, match, userId);
   1112             }
   1113             return null;
   1114         }
   1115 
   1116         @Override
   1117         protected BroadcastFilter[] newArray(int size) {
   1118             return new BroadcastFilter[size];
   1119         }
   1120 
   1121         @Override
   1122         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
   1123             return packageName.equals(filter.packageName);
   1124         }
   1125     };
   1126 
   1127     /**
   1128      * State of all active sticky broadcasts per user.  Keys are the action of the
   1129      * sticky Intent, values are an ArrayList of all broadcasted intents with
   1130      * that action (which should usually be one).  The SparseArray is keyed
   1131      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
   1132      * for stickies that are sent to all users.
   1133      */
   1134     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
   1135             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
   1136 
   1137     final ActiveServices mServices;
   1138 
   1139     final static class Association {
   1140         final int mSourceUid;
   1141         final String mSourceProcess;
   1142         final int mTargetUid;
   1143         final ComponentName mTargetComponent;
   1144         final String mTargetProcess;
   1145 
   1146         int mCount;
   1147         long mTime;
   1148 
   1149         int mNesting;
   1150         long mStartTime;
   1151 
   1152         // states of the source process when the bind occurred.
   1153         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
   1154         long mLastStateUptime;
   1155         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
   1156                 - ActivityManager.MIN_PROCESS_STATE+1];
   1157 
   1158         Association(int sourceUid, String sourceProcess, int targetUid,
   1159                 ComponentName targetComponent, String targetProcess) {
   1160             mSourceUid = sourceUid;
   1161             mSourceProcess = sourceProcess;
   1162             mTargetUid = targetUid;
   1163             mTargetComponent = targetComponent;
   1164             mTargetProcess = targetProcess;
   1165         }
   1166     }
   1167 
   1168     /**
   1169      * When service association tracking is enabled, this is all of the associations we
   1170      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
   1171      * -> association data.
   1172      */
   1173     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
   1174             mAssociations = new SparseArray<>();
   1175     boolean mTrackingAssociations;
   1176 
   1177     /**
   1178      * Backup/restore process management
   1179      */
   1180     String mBackupAppName = null;
   1181     BackupRecord mBackupTarget = null;
   1182 
   1183     final ProviderMap mProviderMap;
   1184 
   1185     /**
   1186      * List of content providers who have clients waiting for them.  The
   1187      * application is currently being launched and the provider will be
   1188      * removed from this list once it is published.
   1189      */
   1190     final ArrayList<ContentProviderRecord> mLaunchingProviders
   1191             = new ArrayList<ContentProviderRecord>();
   1192 
   1193     /**
   1194      * File storing persisted {@link #mGrantedUriPermissions}.
   1195      */
   1196     private final AtomicFile mGrantFile;
   1197 
   1198     /** XML constants used in {@link #mGrantFile} */
   1199     private static final String TAG_URI_GRANTS = "uri-grants";
   1200     private static final String TAG_URI_GRANT = "uri-grant";
   1201     private static final String ATTR_USER_HANDLE = "userHandle";
   1202     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
   1203     private static final String ATTR_TARGET_USER_ID = "targetUserId";
   1204     private static final String ATTR_SOURCE_PKG = "sourcePkg";
   1205     private static final String ATTR_TARGET_PKG = "targetPkg";
   1206     private static final String ATTR_URI = "uri";
   1207     private static final String ATTR_MODE_FLAGS = "modeFlags";
   1208     private static final String ATTR_CREATED_TIME = "createdTime";
   1209     private static final String ATTR_PREFIX = "prefix";
   1210 
   1211     /**
   1212      * Global set of specific {@link Uri} permissions that have been granted.
   1213      * This optimized lookup structure maps from {@link UriPermission#targetUid}
   1214      * to {@link UriPermission#uri} to {@link UriPermission}.
   1215      */
   1216     @GuardedBy("this")
   1217     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
   1218             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
   1219 
   1220     public static class GrantUri {
   1221         public final int sourceUserId;
   1222         public final Uri uri;
   1223         public boolean prefix;
   1224 
   1225         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
   1226             this.sourceUserId = sourceUserId;
   1227             this.uri = uri;
   1228             this.prefix = prefix;
   1229         }
   1230 
   1231         @Override
   1232         public int hashCode() {
   1233             int hashCode = 1;
   1234             hashCode = 31 * hashCode + sourceUserId;
   1235             hashCode = 31 * hashCode + uri.hashCode();
   1236             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
   1237             return hashCode;
   1238         }
   1239 
   1240         @Override
   1241         public boolean equals(Object o) {
   1242             if (o instanceof GrantUri) {
   1243                 GrantUri other = (GrantUri) o;
   1244                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
   1245                         && prefix == other.prefix;
   1246             }
   1247             return false;
   1248         }
   1249 
   1250         @Override
   1251         public String toString() {
   1252             String result = uri.toString() + " [user " + sourceUserId + "]";
   1253             if (prefix) result += " [prefix]";
   1254             return result;
   1255         }
   1256 
   1257         public String toSafeString() {
   1258             String result = uri.toSafeString() + " [user " + sourceUserId + "]";
   1259             if (prefix) result += " [prefix]";
   1260             return result;
   1261         }
   1262 
   1263         public void writeToProto(ProtoOutputStream proto, long fieldId) {
   1264             long token = proto.start(fieldId);
   1265             proto.write(GrantUriProto.URI, uri.toString());
   1266             proto.write(GrantUriProto.SOURCE_USER_ID, sourceUserId);
   1267             proto.end(token);
   1268         }
   1269 
   1270         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
   1271             if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
   1272                 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
   1273                         ContentProvider.getUriWithoutUserId(uri), false);
   1274             } else {
   1275                 return new GrantUri(defaultSourceUserHandle, uri, false);
   1276             }
   1277         }
   1278     }
   1279 
   1280     boolean mSystemProvidersInstalled;
   1281 
   1282     CoreSettingsObserver mCoreSettingsObserver;
   1283 
   1284     FontScaleSettingObserver mFontScaleSettingObserver;
   1285 
   1286     private final class FontScaleSettingObserver extends ContentObserver {
   1287         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
   1288         private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
   1289 
   1290         public FontScaleSettingObserver() {
   1291             super(mHandler);
   1292             ContentResolver resolver = mContext.getContentResolver();
   1293             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
   1294             resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
   1295                     UserHandle.USER_ALL);
   1296         }
   1297 
   1298         @Override
   1299         public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
   1300             if (mFontScaleUri.equals(uri)) {
   1301                 updateFontScaleIfNeeded(userId);
   1302             } else if (mHideErrorDialogsUri.equals(uri)) {
   1303                 synchronized (ActivityManagerService.this) {
   1304                     updateShouldShowDialogsLocked(getGlobalConfiguration());
   1305                 }
   1306             }
   1307         }
   1308     }
   1309 
   1310     DevelopmentSettingsObserver mDevelopmentSettingsObserver;
   1311 
   1312     private final class DevelopmentSettingsObserver extends ContentObserver {
   1313         private final Uri mUri = Settings.Global
   1314                 .getUriFor(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
   1315 
   1316         private final ComponentName mBugreportStorageProvider = new ComponentName(
   1317                 "com.android.shell", "com.android.shell.BugreportStorageProvider");
   1318 
   1319         public DevelopmentSettingsObserver() {
   1320             super(mHandler);
   1321             mContext.getContentResolver().registerContentObserver(mUri, false, this,
   1322                     UserHandle.USER_ALL);
   1323             // Always kick once to ensure that we match current state
   1324             onChange();
   1325         }
   1326 
   1327         @Override
   1328         public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
   1329             if (mUri.equals(uri)) {
   1330                 onChange();
   1331             }
   1332         }
   1333 
   1334         public void onChange() {
   1335             final boolean enabled = Settings.Global.getInt(mContext.getContentResolver(),
   1336                     Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, Build.IS_ENG ? 1 : 0) != 0;
   1337             mContext.getPackageManager().setComponentEnabledSetting(mBugreportStorageProvider,
   1338                     enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
   1339                             : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
   1340                     0);
   1341         }
   1342     }
   1343 
   1344     /**
   1345      * Thread-local storage used to carry caller permissions over through
   1346      * indirect content-provider access.
   1347      */
   1348     private class Identity {
   1349         public final IBinder token;
   1350         public final int pid;
   1351         public final int uid;
   1352 
   1353         Identity(IBinder _token, int _pid, int _uid) {
   1354             token = _token;
   1355             pid = _pid;
   1356             uid = _uid;
   1357         }
   1358     }
   1359 
   1360     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
   1361 
   1362     /**
   1363      * All information we have collected about the runtime performance of
   1364      * any user id that can impact battery performance.
   1365      */
   1366     final BatteryStatsService mBatteryStatsService;
   1367 
   1368     /**
   1369      * Information about component usage
   1370      */
   1371     UsageStatsManagerInternal mUsageStatsService;
   1372 
   1373     /**
   1374      * Access to DeviceIdleController service.
   1375      */
   1376     DeviceIdleController.LocalService mLocalDeviceIdleController;
   1377 
   1378     /**
   1379      * Power-save whitelisted app-ids (not including except-idle-whitelisted ones).
   1380      */
   1381     int[] mDeviceIdleWhitelist = new int[0];
   1382 
   1383     /**
   1384      * Power-save whitelisted app-ids (including except-idle-whitelisted ones).
   1385      */
   1386     int[] mDeviceIdleExceptIdleWhitelist = new int[0];
   1387 
   1388     /**
   1389      * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
   1390      */
   1391     int[] mDeviceIdleTempWhitelist = new int[0];
   1392 
   1393     static final class PendingTempWhitelist {
   1394         final int targetUid;
   1395         final long duration;
   1396         final String tag;
   1397 
   1398         PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
   1399             targetUid = _targetUid;
   1400             duration = _duration;
   1401             tag = _tag;
   1402         }
   1403 
   1404         void writeToProto(ProtoOutputStream proto, long fieldId) {
   1405             final long token = proto.start(fieldId);
   1406             proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TARGET_UID, targetUid);
   1407             proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.DURATION_MS, duration);
   1408             proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TAG, tag);
   1409             proto.end(token);
   1410         }
   1411     }
   1412 
   1413     final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
   1414 
   1415     /**
   1416      * Information about and control over application operations
   1417      */
   1418     final AppOpsService mAppOpsService;
   1419 
   1420     /** Current sequencing integer of the configuration, for skipping old configurations. */
   1421     private int mConfigurationSeq;
   1422 
   1423     /**
   1424      * Temp object used when global and/or display override configuration is updated. It is also
   1425      * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
   1426      * anyone...
   1427      */
   1428     private Configuration mTempConfig = new Configuration();
   1429 
   1430     private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
   1431             new UpdateConfigurationResult();
   1432     private static final class UpdateConfigurationResult {
   1433         // Configuration changes that were updated.
   1434         int changes;
   1435         // If the activity was relaunched to match the new configuration.
   1436         boolean activityRelaunched;
   1437 
   1438         void reset() {
   1439             changes = 0;
   1440             activityRelaunched = false;
   1441         }
   1442     }
   1443 
   1444     boolean mSuppressResizeConfigChanges;
   1445 
   1446     /**
   1447      * Hardware-reported OpenGLES version.
   1448      */
   1449     final int GL_ES_VERSION;
   1450 
   1451     /**
   1452      * List of initialization arguments to pass to all processes when binding applications to them.
   1453      * For example, references to the commonly used services.
   1454      */
   1455     ArrayMap<String, IBinder> mAppBindArgs;
   1456     ArrayMap<String, IBinder> mIsolatedAppBindArgs;
   1457 
   1458     /**
   1459      * Temporary to avoid allocations.  Protected by main lock.
   1460      */
   1461     final StringBuilder mStringBuilder = new StringBuilder(256);
   1462 
   1463     /**
   1464      * Used to control how we initialize the service.
   1465      */
   1466     ComponentName mTopComponent;
   1467     String mTopAction = Intent.ACTION_MAIN;
   1468     String mTopData;
   1469 
   1470     volatile boolean mProcessesReady = false;
   1471     volatile boolean mSystemReady = false;
   1472     volatile boolean mOnBattery = false;
   1473     volatile int mFactoryTest;
   1474 
   1475     @GuardedBy("this") boolean mBooting = false;
   1476     @GuardedBy("this") boolean mCallFinishBooting = false;
   1477     @GuardedBy("this") boolean mBootAnimationComplete = false;
   1478     @GuardedBy("this") boolean mLaunchWarningShown = false;
   1479     private @GuardedBy("this") boolean mCheckedForSetup = false;
   1480 
   1481     final Context mContext;
   1482 
   1483     /**
   1484      * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
   1485      * change at runtime. Use mContext for non-UI purposes.
   1486      */
   1487     final Context mUiContext;
   1488 
   1489     /**
   1490      * The time at which we will allow normal application switches again,
   1491      * after a call to {@link #stopAppSwitches()}.
   1492      */
   1493     long mAppSwitchesAllowedTime;
   1494 
   1495     /**
   1496      * This is set to true after the first switch after mAppSwitchesAllowedTime
   1497      * is set; any switches after that will clear the time.
   1498      */
   1499     boolean mDidAppSwitch;
   1500 
   1501     /**
   1502      * Last time (in uptime) at which we checked for power usage.
   1503      */
   1504     long mLastPowerCheckUptime;
   1505 
   1506     /**
   1507      * Set while we are wanting to sleep, to prevent any
   1508      * activities from being started/resumed.
   1509      *
   1510      * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
   1511      *
   1512      * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
   1513      * while in the sleep state until there is a pending transition out of sleep, in which case
   1514      * mSleeping is set to false, and remains false while awake.
   1515      *
   1516      * Whether mSleeping can quickly toggled between true/false without the device actually
   1517      * display changing states is undefined.
   1518      */
   1519     private boolean mSleeping = false;
   1520 
   1521     /**
   1522      * The process state used for processes that are running the top activities.
   1523      * This changes between TOP and TOP_SLEEPING to following mSleeping.
   1524      */
   1525     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
   1526 
   1527     /**
   1528      * Set while we are running a voice interaction.  This overrides
   1529      * sleeping while it is active.
   1530      */
   1531     IVoiceInteractionSession mRunningVoice;
   1532 
   1533     /**
   1534      * For some direct access we need to power manager.
   1535      */
   1536     PowerManagerInternal mLocalPowerManager;
   1537 
   1538     /**
   1539      * We want to hold a wake lock while running a voice interaction session, since
   1540      * this may happen with the screen off and we need to keep the CPU running to
   1541      * be able to continue to interact with the user.
   1542      */
   1543     PowerManager.WakeLock mVoiceWakeLock;
   1544 
   1545     /**
   1546      * State of external calls telling us if the device is awake or asleep.
   1547      */
   1548     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
   1549 
   1550     /**
   1551      * State of external calls telling us if the device is awake or asleep.
   1552      */
   1553     private boolean mKeyguardShown = false;
   1554 
   1555     /**
   1556      * Set if we are shutting down the system, similar to sleeping.
   1557      */
   1558     boolean mShuttingDown = false;
   1559 
   1560     /**
   1561      * Current sequence id for oom_adj computation traversal.
   1562      */
   1563     int mAdjSeq = 0;
   1564 
   1565     /**
   1566      * Current sequence id for process LRU updating.
   1567      */
   1568     int mLruSeq = 0;
   1569 
   1570     /**
   1571      * Keep track of the non-cached/empty process we last found, to help
   1572      * determine how to distribute cached/empty processes next time.
   1573      */
   1574     int mNumNonCachedProcs = 0;
   1575 
   1576     /**
   1577      * Keep track of the number of cached hidden procs, to balance oom adj
   1578      * distribution between those and empty procs.
   1579      */
   1580     int mNumCachedHiddenProcs = 0;
   1581 
   1582     /**
   1583      * Keep track of the number of service processes we last found, to
   1584      * determine on the next iteration which should be B services.
   1585      */
   1586     int mNumServiceProcs = 0;
   1587     int mNewNumAServiceProcs = 0;
   1588     int mNewNumServiceProcs = 0;
   1589 
   1590     /**
   1591      * Allow the current computed overall memory level of the system to go down?
   1592      * This is set to false when we are killing processes for reasons other than
   1593      * memory management, so that the now smaller process list will not be taken as
   1594      * an indication that memory is tighter.
   1595      */
   1596     boolean mAllowLowerMemLevel = false;
   1597 
   1598     /**
   1599      * The last computed memory level, for holding when we are in a state that
   1600      * processes are going away for other reasons.
   1601      */
   1602     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
   1603 
   1604     /**
   1605      * The last total number of process we have, to determine if changes actually look
   1606      * like a shrinking number of process due to lower RAM.
   1607      */
   1608     int mLastNumProcesses;
   1609 
   1610     /**
   1611      * The uptime of the last time we performed idle maintenance.
   1612      */
   1613     long mLastIdleTime = SystemClock.uptimeMillis();
   1614 
   1615     /**
   1616      * Total time spent with RAM that has been added in the past since the last idle time.
   1617      */
   1618     long mLowRamTimeSinceLastIdle = 0;
   1619 
   1620     /**
   1621      * If RAM is currently low, when that horrible situation started.
   1622      */
   1623     long mLowRamStartTime = 0;
   1624 
   1625     /**
   1626      * For reporting to battery stats the current top application.
   1627      */
   1628     private String mCurResumedPackage = null;
   1629     private int mCurResumedUid = -1;
   1630 
   1631     /**
   1632      * For reporting to battery stats the apps currently running foreground
   1633      * service.  The ProcessMap is package/uid tuples; each of these contain
   1634      * an array of the currently foreground processes.
   1635      */
   1636     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
   1637             = new ProcessMap<ArrayList<ProcessRecord>>();
   1638 
   1639     /**
   1640      * Set if the systemServer made a call to enterSafeMode.
   1641      */
   1642     boolean mSafeMode;
   1643 
   1644     /**
   1645      * If true, we are running under a test environment so will sample PSS from processes
   1646      * much more rapidly to try to collect better data when the tests are rapidly
   1647      * running through apps.
   1648      */
   1649     boolean mTestPssMode = false;
   1650 
   1651     String mDebugApp = null;
   1652     boolean mWaitForDebugger = false;
   1653     boolean mDebugTransient = false;
   1654     String mOrigDebugApp = null;
   1655     boolean mOrigWaitForDebugger = false;
   1656     boolean mAlwaysFinishActivities = false;
   1657     boolean mForceResizableActivities;
   1658     /**
   1659      * Flag that indicates if multi-window is enabled.
   1660      *
   1661      * For any particular form of multi-window to be enabled, generic multi-window must be enabled
   1662      * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
   1663      * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
   1664      * At least one of the forms of multi-window must be enabled in order for this flag to be
   1665      * initialized to 'true'.
   1666      *
   1667      * @see #mSupportsSplitScreenMultiWindow
   1668      * @see #mSupportsFreeformWindowManagement
   1669      * @see #mSupportsPictureInPicture
   1670      * @see #mSupportsMultiDisplay
   1671      */
   1672     boolean mSupportsMultiWindow;
   1673     boolean mSupportsSplitScreenMultiWindow;
   1674     boolean mSupportsFreeformWindowManagement;
   1675     boolean mSupportsPictureInPicture;
   1676     boolean mSupportsMultiDisplay;
   1677     boolean mSupportsLeanbackOnly;
   1678     IActivityController mController = null;
   1679     boolean mControllerIsAMonkey = false;
   1680     String mProfileApp = null;
   1681     ProcessRecord mProfileProc = null;
   1682     ProfilerInfo mProfilerInfo = null;
   1683 
   1684     /**
   1685      * Stores a map of process name -> agent string. When a process is started and mAgentAppMap
   1686      * is not null, this map is checked and the mapped agent installed during bind-time. Note:
   1687      * A non-null agent in mProfileInfo overrides this.
   1688      */
   1689     private @Nullable Map<String, String> mAppAgentMap = null;
   1690 
   1691     int mProfileType = 0;
   1692     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
   1693     String mMemWatchDumpProcName;
   1694     String mMemWatchDumpFile;
   1695     int mMemWatchDumpPid;
   1696     int mMemWatchDumpUid;
   1697     String mTrackAllocationApp = null;
   1698     String mNativeDebuggingApp = null;
   1699 
   1700     final long[] mTmpLong = new long[3];
   1701 
   1702     private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
   1703 
   1704     /**
   1705      * A global counter for generating sequence numbers.
   1706      * This value will be used when incrementing sequence numbers in individual uidRecords.
   1707      *
   1708      * Having a global counter ensures that seq numbers are monotonically increasing for a
   1709      * particular uid even when the uidRecord is re-created.
   1710      */
   1711     @GuardedBy("this")
   1712     @VisibleForTesting
   1713     long mProcStateSeqCounter = 0;
   1714 
   1715     /**
   1716      * A global counter for generating sequence numbers to uniquely identify pending process starts.
   1717      */
   1718     @GuardedBy("this")
   1719     private long mProcStartSeqCounter = 0;
   1720 
   1721     /**
   1722      * Contains {@link ProcessRecord} objects for pending process starts.
   1723      *
   1724      * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
   1725      */
   1726     @GuardedBy("this")
   1727     private final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
   1728 
   1729     private final Injector mInjector;
   1730 
   1731     static final class ProcessChangeItem {
   1732         static final int CHANGE_ACTIVITIES = 1<<0;
   1733         int changes;
   1734         int uid;
   1735         int pid;
   1736         int processState;
   1737         boolean foregroundActivities;
   1738     }
   1739 
   1740     static final class UidObserverRegistration {
   1741         final int uid;
   1742         final String pkg;
   1743         final int which;
   1744         final int cutpoint;
   1745 
   1746         /**
   1747          * Total # of callback calls that took more than {@link #SLOW_UID_OBSERVER_THRESHOLD_MS}.
   1748          * We show it in dumpsys.
   1749          */
   1750         int mSlowDispatchCount;
   1751 
   1752         /** Max time it took for each dispatch. */
   1753         int mMaxDispatchTime;
   1754 
   1755         final SparseIntArray lastProcStates;
   1756 
   1757         // Please keep the enum lists in sync
   1758         private static int[] ORIG_ENUMS = new int[]{
   1759                 ActivityManager.UID_OBSERVER_IDLE,
   1760                 ActivityManager.UID_OBSERVER_ACTIVE,
   1761                 ActivityManager.UID_OBSERVER_GONE,
   1762                 ActivityManager.UID_OBSERVER_PROCSTATE,
   1763         };
   1764         private static int[] PROTO_ENUMS = new int[]{
   1765                 ActivityManagerProto.UID_OBSERVER_FLAG_IDLE,
   1766                 ActivityManagerProto.UID_OBSERVER_FLAG_ACTIVE,
   1767                 ActivityManagerProto.UID_OBSERVER_FLAG_GONE,
   1768                 ActivityManagerProto.UID_OBSERVER_FLAG_PROCSTATE,
   1769         };
   1770 
   1771         UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
   1772             uid = _uid;
   1773             pkg = _pkg;
   1774             which = _which;
   1775             cutpoint = _cutpoint;
   1776             if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
   1777                 lastProcStates = new SparseIntArray();
   1778             } else {
   1779                 lastProcStates = null;
   1780             }
   1781         }
   1782 
   1783         void writeToProto(ProtoOutputStream proto, long fieldId) {
   1784             final long token = proto.start(fieldId);
   1785             proto.write(UidObserverRegistrationProto.UID, uid);
   1786             proto.write(UidObserverRegistrationProto.PACKAGE, pkg);
   1787             ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, UidObserverRegistrationProto.FLAGS,
   1788                     which, ORIG_ENUMS, PROTO_ENUMS);
   1789             proto.write(UidObserverRegistrationProto.CUT_POINT, cutpoint);
   1790             if (lastProcStates != null) {
   1791                 final int NI = lastProcStates.size();
   1792                 for (int i=0; i<NI; i++) {
   1793                     final long pToken = proto.start(UidObserverRegistrationProto.LAST_PROC_STATES);
   1794                     proto.write(UidObserverRegistrationProto.ProcState.UID, lastProcStates.keyAt(i));
   1795                     proto.write(UidObserverRegistrationProto.ProcState.STATE, lastProcStates.valueAt(i));
   1796                     proto.end(pToken);
   1797                 }
   1798             }
   1799             proto.end(token);
   1800         }
   1801     }
   1802 
   1803     final List<ScreenObserver> mScreenObservers = new ArrayList<>();
   1804 
   1805     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
   1806     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
   1807 
   1808     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
   1809     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
   1810 
   1811     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
   1812     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
   1813 
   1814     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
   1815     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
   1816 
   1817     OomAdjObserver mCurOomAdjObserver;
   1818     int mCurOomAdjUid;
   1819 
   1820     interface OomAdjObserver {
   1821         void onOomAdjMessage(String msg);
   1822     }
   1823 
   1824     /**
   1825      * Runtime CPU use collection thread.  This object's lock is used to
   1826      * perform synchronization with the thread (notifying it to run).
   1827      */
   1828     final Thread mProcessCpuThread;
   1829 
   1830     /**
   1831      * Used to collect per-process CPU use for ANRs, battery stats, etc.
   1832      * Must acquire this object's lock when accessing it.
   1833      * NOTE: this lock will be held while doing long operations (trawling
   1834      * through all processes in /proc), so it should never be acquired by
   1835      * any critical paths such as when holding the main activity manager lock.
   1836      */
   1837     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
   1838             MONITOR_THREAD_CPU_USAGE);
   1839     final AtomicLong mLastCpuTime = new AtomicLong(0);
   1840     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
   1841     final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
   1842 
   1843     long mLastWriteTime = 0;
   1844 
   1845     /**
   1846      * Used to retain an update lock when the foreground activity is in
   1847      * immersive mode.
   1848      */
   1849     final UpdateLock mUpdateLock = new UpdateLock("immersive");
   1850 
   1851     /**
   1852      * Set to true after the system has finished booting.
   1853      */
   1854     boolean mBooted = false;
   1855 
   1856     /**
   1857      * Current boot phase.
   1858      */
   1859     int mBootPhase;
   1860 
   1861     WindowManagerService mWindowManager;
   1862     final ActivityThread mSystemThread;
   1863 
   1864     private final class AppDeathRecipient implements IBinder.DeathRecipient {
   1865         final ProcessRecord mApp;
   1866         final int mPid;
   1867         final IApplicationThread mAppThread;
   1868 
   1869         AppDeathRecipient(ProcessRecord app, int pid,
   1870                 IApplicationThread thread) {
   1871             if (DEBUG_ALL) Slog.v(
   1872                 TAG, "New death recipient " + this
   1873                 + " for thread " + thread.asBinder());
   1874             mApp = app;
   1875             mPid = pid;
   1876             mAppThread = thread;
   1877         }
   1878 
   1879         @Override
   1880         public void binderDied() {
   1881             if (DEBUG_ALL) Slog.v(
   1882                 TAG, "Death received in " + this
   1883                 + " for thread " + mAppThread.asBinder());
   1884             synchronized(ActivityManagerService.this) {
   1885                 appDiedLocked(mApp, mPid, mAppThread, true);
   1886             }
   1887         }
   1888     }
   1889 
   1890     static final int SHOW_ERROR_UI_MSG = 1;
   1891     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
   1892     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
   1893     static final int UPDATE_CONFIGURATION_MSG = 4;
   1894     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
   1895     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
   1896     static final int SERVICE_TIMEOUT_MSG = 12;
   1897     static final int UPDATE_TIME_ZONE = 13;
   1898     static final int SHOW_UID_ERROR_UI_MSG = 14;
   1899     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
   1900     static final int PROC_START_TIMEOUT_MSG = 20;
   1901     static final int KILL_APPLICATION_MSG = 22;
   1902     static final int FINALIZE_PENDING_INTENT_MSG = 23;
   1903     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
   1904     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
   1905     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
   1906     static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
   1907     static final int CLEAR_DNS_CACHE_MSG = 28;
   1908     static final int UPDATE_HTTP_PROXY_MSG = 29;
   1909     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
   1910     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
   1911     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
   1912     static final int REPORT_MEM_USAGE_MSG = 33;
   1913     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
   1914     static final int PERSIST_URI_GRANTS_MSG = 38;
   1915     static final int UPDATE_TIME_PREFERENCE_MSG = 41;
   1916     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
   1917     static final int FINISH_BOOTING_MSG = 45;
   1918     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
   1919     static final int DISMISS_DIALOG_UI_MSG = 48;
   1920     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
   1921     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
   1922     static final int DELETE_DUMPHEAP_MSG = 51;
   1923     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
   1924     static final int REPORT_TIME_TRACKER_MSG = 54;
   1925     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
   1926     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
   1927     static final int IDLE_UIDS_MSG = 58;
   1928     static final int LOG_STACK_STATE = 60;
   1929     static final int VR_MODE_CHANGE_MSG = 61;
   1930     static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
   1931     static final int DISPATCH_SCREEN_AWAKE_MSG = 64;
   1932     static final int DISPATCH_SCREEN_KEYGUARD_MSG = 65;
   1933     static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
   1934     static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
   1935     static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
   1936     static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
   1937     static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
   1938 
   1939     static final int FIRST_ACTIVITY_STACK_MSG = 100;
   1940     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
   1941     static final int FIRST_COMPAT_MODE_MSG = 300;
   1942     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
   1943 
   1944     static final String SERVICE_RECORD_KEY = "servicerecord";
   1945 
   1946     static ServiceThread sKillThread = null;
   1947     static KillHandler sKillHandler = null;
   1948 
   1949     CompatModeDialog mCompatModeDialog;
   1950     long mLastMemUsageReportTime = 0;
   1951 
   1952     /**
   1953      * Flag whether the current user is a "monkey", i.e. whether
   1954      * the UI is driven by a UI automation tool.
   1955      */
   1956     private boolean mUserIsMonkey;
   1957 
   1958     /** The dimensions of the thumbnails in the Recents UI. */
   1959     int mThumbnailWidth;
   1960     int mThumbnailHeight;
   1961     float mFullscreenThumbnailScale;
   1962 
   1963     final ServiceThread mHandlerThread;
   1964     final MainHandler mHandler;
   1965     final Handler mUiHandler;
   1966     final ServiceThread mProcStartHandlerThread;
   1967     final Handler mProcStartHandler;
   1968 
   1969     final ActivityManagerConstants mConstants;
   1970 
   1971     // Encapsulates the global setting "hidden_api_blacklist_exemptions"
   1972     final HiddenApiSettings mHiddenApiBlacklist;
   1973 
   1974     PackageManagerInternal mPackageManagerInt;
   1975 
   1976     // VoiceInteraction session ID that changes for each new request except when
   1977     // being called for multiwindow assist in a single session.
   1978     private int mViSessionId = 1000;
   1979 
   1980     final boolean mPermissionReviewRequired;
   1981 
   1982     boolean mHasHeavyWeightFeature;
   1983 
   1984     /**
   1985      * Whether to force background check on all apps (for battery saver) or not.
   1986      */
   1987     boolean mForceBackgroundCheck;
   1988 
   1989     private static String sTheRealBuildSerial = Build.UNKNOWN;
   1990 
   1991     /**
   1992      * Current global configuration information. Contains general settings for the entire system,
   1993      * also corresponds to the merged configuration of the default display.
   1994      */
   1995     Configuration getGlobalConfiguration() {
   1996         return mStackSupervisor.getConfiguration();
   1997     }
   1998 
   1999     final class KillHandler extends Handler {
   2000         static final int KILL_PROCESS_GROUP_MSG = 4000;
   2001 
   2002         public KillHandler(Looper looper) {
   2003             super(looper, null, true);
   2004         }
   2005 
   2006         @Override
   2007         public void handleMessage(Message msg) {
   2008             switch (msg.what) {
   2009                 case KILL_PROCESS_GROUP_MSG:
   2010                 {
   2011                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
   2012                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
   2013                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   2014                 }
   2015                 break;
   2016 
   2017                 default:
   2018                     super.handleMessage(msg);
   2019             }
   2020         }
   2021     }
   2022 
   2023     final class UiHandler extends Handler {
   2024         public UiHandler() {
   2025             super(com.android.server.UiThread.get().getLooper(), null, true);
   2026         }
   2027 
   2028         @Override
   2029         public void handleMessage(Message msg) {
   2030             switch (msg.what) {
   2031             case SHOW_ERROR_UI_MSG: {
   2032                 mAppErrors.handleShowAppErrorUi(msg);
   2033                 ensureBootCompleted();
   2034             } break;
   2035             case SHOW_NOT_RESPONDING_UI_MSG: {
   2036                 mAppErrors.handleShowAnrUi(msg);
   2037                 ensureBootCompleted();
   2038             } break;
   2039             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
   2040                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
   2041                 synchronized (ActivityManagerService.this) {
   2042                     ProcessRecord proc = (ProcessRecord) data.get("app");
   2043                     if (proc == null) {
   2044                         Slog.e(TAG, "App not found when showing strict mode dialog.");
   2045                         break;
   2046                     }
   2047                     if (proc.crashDialog != null) {
   2048                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
   2049                         return;
   2050                     }
   2051                     AppErrorResult res = (AppErrorResult) data.get("result");
   2052                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
   2053                         Dialog d = new StrictModeViolationDialog(mUiContext,
   2054                                 ActivityManagerService.this, res, proc);
   2055                         d.show();
   2056                         proc.crashDialog = d;
   2057                     } else {
   2058                         // The device is asleep, so just pretend that the user
   2059                         // saw a crash dialog and hit "force quit".
   2060                         res.set(0);
   2061                     }
   2062                 }
   2063                 ensureBootCompleted();
   2064             } break;
   2065             case SHOW_FACTORY_ERROR_UI_MSG: {
   2066                 Dialog d = new FactoryErrorDialog(
   2067                         mUiContext, msg.getData().getCharSequence("msg"));
   2068                 d.show();
   2069                 ensureBootCompleted();
   2070             } break;
   2071             case WAIT_FOR_DEBUGGER_UI_MSG: {
   2072                 synchronized (ActivityManagerService.this) {
   2073                     ProcessRecord app = (ProcessRecord)msg.obj;
   2074                     if (msg.arg1 != 0) {
   2075                         if (!app.waitedForDebugger) {
   2076                             Dialog d = new AppWaitingForDebuggerDialog(
   2077                                     ActivityManagerService.this,
   2078                                     mUiContext, app);
   2079                             app.waitDialog = d;
   2080                             app.waitedForDebugger = true;
   2081                             d.show();
   2082                         }
   2083                     } else {
   2084                         if (app.waitDialog != null) {
   2085                             app.waitDialog.dismiss();
   2086                             app.waitDialog = null;
   2087                         }
   2088                     }
   2089                 }
   2090             } break;
   2091             case SHOW_UID_ERROR_UI_MSG: {
   2092                 if (mShowDialogs) {
   2093                     AlertDialog d = new BaseErrorDialog(mUiContext);
   2094                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   2095                     d.setCancelable(false);
   2096                     d.setTitle(mUiContext.getText(R.string.android_system_label));
   2097                     d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
   2098                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
   2099                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
   2100                     d.show();
   2101                 }
   2102             } break;
   2103             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
   2104                 if (mShowDialogs) {
   2105                     AlertDialog d = new BaseErrorDialog(mUiContext);
   2106                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   2107                     d.setCancelable(false);
   2108                     d.setTitle(mUiContext.getText(R.string.android_system_label));
   2109                     d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
   2110                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
   2111                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
   2112                     d.show();
   2113                 }
   2114             } break;
   2115             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
   2116                 synchronized (ActivityManagerService.this) {
   2117                     ActivityRecord ar = (ActivityRecord) msg.obj;
   2118                     if (mCompatModeDialog != null) {
   2119                         if (mCompatModeDialog.mAppInfo.packageName.equals(
   2120                                 ar.info.applicationInfo.packageName)) {
   2121                             return;
   2122                         }
   2123                         mCompatModeDialog.dismiss();
   2124                         mCompatModeDialog = null;
   2125                     }
   2126                     if (ar != null && false) {
   2127                         if (mCompatModePackages.getPackageAskCompatModeLocked(
   2128                                 ar.packageName)) {
   2129                             int mode = mCompatModePackages.computeCompatModeLocked(
   2130                                     ar.info.applicationInfo);
   2131                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
   2132                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
   2133                                 mCompatModeDialog = new CompatModeDialog(
   2134                                         ActivityManagerService.this, mUiContext,
   2135                                         ar.info.applicationInfo);
   2136                                 mCompatModeDialog.show();
   2137                             }
   2138                         }
   2139                     }
   2140                 }
   2141                 break;
   2142             }
   2143             case DISMISS_DIALOG_UI_MSG: {
   2144                 final Dialog d = (Dialog) msg.obj;
   2145                 d.dismiss();
   2146                 break;
   2147             }
   2148             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
   2149                 dispatchProcessesChanged();
   2150                 break;
   2151             }
   2152             case DISPATCH_PROCESS_DIED_UI_MSG: {
   2153                 final int pid = msg.arg1;
   2154                 final int uid = msg.arg2;
   2155                 dispatchProcessDied(pid, uid);
   2156                 break;
   2157             }
   2158             case DISPATCH_UIDS_CHANGED_UI_MSG: {
   2159                 dispatchUidsChanged();
   2160             } break;
   2161             case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
   2162                 dispatchOomAdjObserver((String)msg.obj);
   2163             } break;
   2164             case PUSH_TEMP_WHITELIST_UI_MSG: {
   2165                 pushTempWhitelist();
   2166             } break;
   2167             }
   2168         }
   2169     }
   2170 
   2171     final class MainHandler extends Handler {
   2172         public MainHandler(Looper looper) {
   2173             super(looper, null, true);
   2174         }
   2175 
   2176         @Override
   2177         public void handleMessage(Message msg) {
   2178             switch (msg.what) {
   2179             case UPDATE_CONFIGURATION_MSG: {
   2180                 final ContentResolver resolver = mContext.getContentResolver();
   2181                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
   2182                         msg.arg1);
   2183             } break;
   2184             case GC_BACKGROUND_PROCESSES_MSG: {
   2185                 synchronized (ActivityManagerService.this) {
   2186                     performAppGcsIfAppropriateLocked();
   2187                 }
   2188             } break;
   2189             case SERVICE_TIMEOUT_MSG: {
   2190                 mServices.serviceTimeout((ProcessRecord)msg.obj);
   2191             } break;
   2192             case SERVICE_FOREGROUND_TIMEOUT_MSG: {
   2193                 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
   2194             } break;
   2195             case SERVICE_FOREGROUND_CRASH_MSG: {
   2196                 mServices.serviceForegroundCrash(
   2197                     (ProcessRecord) msg.obj, msg.getData().getCharSequence(SERVICE_RECORD_KEY));
   2198             } break;
   2199             case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
   2200                 RemoteCallbackList<IResultReceiver> callbacks
   2201                         = (RemoteCallbackList<IResultReceiver>)msg.obj;
   2202                 int N = callbacks.beginBroadcast();
   2203                 for (int i = 0; i < N; i++) {
   2204                     try {
   2205                         callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
   2206                     } catch (RemoteException e) {
   2207                     }
   2208                 }
   2209                 callbacks.finishBroadcast();
   2210             } break;
   2211             case UPDATE_TIME_ZONE: {
   2212                 synchronized (ActivityManagerService.this) {
   2213                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   2214                         ProcessRecord r = mLruProcesses.get(i);
   2215                         if (r.thread != null) {
   2216                             try {
   2217                                 r.thread.updateTimeZone();
   2218                             } catch (RemoteException ex) {
   2219                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
   2220                             }
   2221                         }
   2222                     }
   2223                 }
   2224             } break;
   2225             case CLEAR_DNS_CACHE_MSG: {
   2226                 synchronized (ActivityManagerService.this) {
   2227                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   2228                         ProcessRecord r = mLruProcesses.get(i);
   2229                         if (r.thread != null) {
   2230                             try {
   2231                                 r.thread.clearDnsCache();
   2232                             } catch (RemoteException ex) {
   2233                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
   2234                             }
   2235                         }
   2236                     }
   2237                 }
   2238             } break;
   2239             case UPDATE_HTTP_PROXY_MSG: {
   2240                 ProxyInfo proxy = (ProxyInfo)msg.obj;
   2241                 String host = "";
   2242                 String port = "";
   2243                 String exclList = "";
   2244                 Uri pacFileUrl = Uri.EMPTY;
   2245                 if (proxy != null) {
   2246                     host = proxy.getHost();
   2247                     port = Integer.toString(proxy.getPort());
   2248                     exclList = proxy.getExclusionListAsString();
   2249                     pacFileUrl = proxy.getPacFileUrl();
   2250                 }
   2251                 synchronized (ActivityManagerService.this) {
   2252                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   2253                         ProcessRecord r = mLruProcesses.get(i);
   2254                         // Don't dispatch to isolated processes as they can't access
   2255                         // ConnectivityManager and don't have network privileges anyway.
   2256                         if (r.thread != null && !r.isolated) {
   2257                             try {
   2258                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
   2259                             } catch (RemoteException ex) {
   2260                                 Slog.w(TAG, "Failed to update http proxy for: " +
   2261                                         r.info.processName);
   2262                             }
   2263                         }
   2264                     }
   2265                 }
   2266             } break;
   2267             case PROC_START_TIMEOUT_MSG: {
   2268                 ProcessRecord app = (ProcessRecord)msg.obj;
   2269                 synchronized (ActivityManagerService.this) {
   2270                     processStartTimedOutLocked(app);
   2271                 }
   2272             } break;
   2273             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
   2274                 ProcessRecord app = (ProcessRecord)msg.obj;
   2275                 synchronized (ActivityManagerService.this) {
   2276                     processContentProviderPublishTimedOutLocked(app);
   2277                 }
   2278             } break;
   2279             case KILL_APPLICATION_MSG: {
   2280                 synchronized (ActivityManagerService.this) {
   2281                     final int appId = msg.arg1;
   2282                     final int userId = msg.arg2;
   2283                     Bundle bundle = (Bundle)msg.obj;
   2284                     String pkg = bundle.getString("pkg");
   2285                     String reason = bundle.getString("reason");
   2286                     forceStopPackageLocked(pkg, appId, false, false, true, false,
   2287                             false, userId, reason);
   2288                 }
   2289             } break;
   2290             case FINALIZE_PENDING_INTENT_MSG: {
   2291                 ((PendingIntentRecord)msg.obj).completeFinalize();
   2292             } break;
   2293             case POST_HEAVY_NOTIFICATION_MSG: {
   2294                 INotificationManager inm = NotificationManager.getService();
   2295                 if (inm == null) {
   2296                     return;
   2297                 }
   2298 
   2299                 ActivityRecord root = (ActivityRecord)msg.obj;
   2300                 ProcessRecord process = root.app;
   2301                 if (process == null) {
   2302                     return;
   2303                 }
   2304 
   2305                 try {
   2306                     Context context = mContext.createPackageContext(process.info.packageName, 0);
   2307                     String text = mContext.getString(R.string.heavy_weight_notification,
   2308                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
   2309                     Notification notification =
   2310                             new Notification.Builder(context,
   2311                                     SystemNotificationChannels.HEAVY_WEIGHT_APP)
   2312                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
   2313                             .setWhen(0)
   2314                             .setOngoing(true)
   2315                             .setTicker(text)
   2316                             .setColor(mContext.getColor(
   2317                                     com.android.internal.R.color.system_notification_accent_color))
   2318                             .setContentTitle(text)
   2319                             .setContentText(
   2320                                     mContext.getText(R.string.heavy_weight_notification_detail))
   2321                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
   2322                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
   2323                                     new UserHandle(root.userId)))
   2324                             .build();
   2325                     try {
   2326                         inm.enqueueNotificationWithTag("android", "android", null,
   2327                                 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
   2328                                 notification, root.userId);
   2329                     } catch (RuntimeException e) {
   2330                         Slog.w(ActivityManagerService.TAG,
   2331                                 "Error showing notification for heavy-weight app", e);
   2332                     } catch (RemoteException e) {
   2333                     }
   2334                 } catch (NameNotFoundException e) {
   2335                     Slog.w(TAG, "Unable to create context for heavy notification", e);
   2336                 }
   2337             } break;
   2338             case CANCEL_HEAVY_NOTIFICATION_MSG: {
   2339                 INotificationManager inm = NotificationManager.getService();
   2340                 if (inm == null) {
   2341                     return;
   2342                 }
   2343                 try {
   2344                     inm.cancelNotificationWithTag("android", null,
   2345                             SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
   2346                 } catch (RuntimeException e) {
   2347                     Slog.w(ActivityManagerService.TAG,
   2348                             "Error canceling notification for service", e);
   2349                 } catch (RemoteException e) {
   2350                 }
   2351             } break;
   2352             case CHECK_EXCESSIVE_POWER_USE_MSG: {
   2353                 synchronized (ActivityManagerService.this) {
   2354                     checkExcessivePowerUsageLocked();
   2355                     removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
   2356                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
   2357                     sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
   2358                 }
   2359             } break;
   2360             case REPORT_MEM_USAGE_MSG: {
   2361                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
   2362                 Thread thread = new Thread() {
   2363                     @Override public void run() {
   2364                         reportMemUsage(memInfos);
   2365                     }
   2366                 };
   2367                 thread.start();
   2368                 break;
   2369             }
   2370             case IMMERSIVE_MODE_LOCK_MSG: {
   2371                 final boolean nextState = (msg.arg1 != 0);
   2372                 if (mUpdateLock.isHeld() != nextState) {
   2373                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
   2374                             "Applying new update lock state '" + nextState
   2375                             + "' for " + (ActivityRecord)msg.obj);
   2376                     if (nextState) {
   2377                         mUpdateLock.acquire();
   2378                     } else {
   2379                         mUpdateLock.release();
   2380                     }
   2381                 }
   2382                 break;
   2383             }
   2384             case PERSIST_URI_GRANTS_MSG: {
   2385                 writeGrantedUriPermissions();
   2386                 break;
   2387             }
   2388             case UPDATE_TIME_PREFERENCE_MSG: {
   2389                 // The user's time format preference might have changed.
   2390                 // For convenience we re-use the Intent extra values.
   2391                 synchronized (ActivityManagerService.this) {
   2392                     for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   2393                         ProcessRecord r = mLruProcesses.get(i);
   2394                         if (r.thread != null) {
   2395                             try {
   2396                                 r.thread.updateTimePrefs(msg.arg1);
   2397                             } catch (RemoteException ex) {
   2398                                 Slog.w(TAG, "Failed to update preferences for: "
   2399                                         + r.info.processName);
   2400                             }
   2401                         }
   2402                     }
   2403                 }
   2404                 break;
   2405             }
   2406             case ENTER_ANIMATION_COMPLETE_MSG: {
   2407                 synchronized (ActivityManagerService.this) {
   2408                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
   2409                     if (r != null && r.app != null && r.app.thread != null) {
   2410                         try {
   2411                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
   2412                         } catch (RemoteException e) {
   2413                         }
   2414                     }
   2415                 }
   2416                 break;
   2417             }
   2418             case FINISH_BOOTING_MSG: {
   2419                 if (msg.arg1 != 0) {
   2420                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
   2421                     finishBooting();
   2422                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   2423                 }
   2424                 if (msg.arg2 != 0) {
   2425                     enableScreenAfterBoot();
   2426                 }
   2427                 break;
   2428             }
   2429             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
   2430                 try {
   2431                     Locale l = (Locale) msg.obj;
   2432                     IBinder service = ServiceManager.getService("mount");
   2433                     IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
   2434                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
   2435                     storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
   2436                 } catch (RemoteException e) {
   2437                     Log.e(TAG, "Error storing locale for decryption UI", e);
   2438                 }
   2439                 break;
   2440             }
   2441             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
   2442                 final int uid = msg.arg1;
   2443                 final byte[] firstPacket = (byte[]) msg.obj;
   2444 
   2445                 synchronized (mPidsSelfLocked) {
   2446                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
   2447                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
   2448                         if (p.uid == uid) {
   2449                             try {
   2450                                 p.thread.notifyCleartextNetwork(firstPacket);
   2451                             } catch (RemoteException ignored) {
   2452                             }
   2453                         }
   2454                     }
   2455                 }
   2456                 break;
   2457             }
   2458             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
   2459                 final String procName;
   2460                 final int uid;
   2461                 final long memLimit;
   2462                 final String reportPackage;
   2463                 synchronized (ActivityManagerService.this) {
   2464                     procName = mMemWatchDumpProcName;
   2465                     uid = mMemWatchDumpUid;
   2466                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
   2467                     if (val == null) {
   2468                         val = mMemWatchProcesses.get(procName, 0);
   2469                     }
   2470                     if (val != null) {
   2471                         memLimit = val.first;
   2472                         reportPackage = val.second;
   2473                     } else {
   2474                         memLimit = 0;
   2475                         reportPackage = null;
   2476                     }
   2477                 }
   2478                 if (procName == null) {
   2479                     return;
   2480                 }
   2481 
   2482                 if (DEBUG_PSS) Slog.d(TAG_PSS,
   2483                         "Showing dump heap notification from " + procName + "/" + uid);
   2484 
   2485                 INotificationManager inm = NotificationManager.getService();
   2486                 if (inm == null) {
   2487                     return;
   2488                 }
   2489 
   2490                 String text = mContext.getString(R.string.dump_heap_notification, procName);
   2491 
   2492 
   2493                 Intent deleteIntent = new Intent();
   2494                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
   2495                 Intent intent = new Intent();
   2496                 intent.setClassName("android", DumpHeapActivity.class.getName());
   2497                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
   2498                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
   2499                 if (reportPackage != null) {
   2500                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
   2501                 }
   2502                 int userId = UserHandle.getUserId(uid);
   2503                 Notification notification =
   2504                         new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
   2505                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
   2506                         .setWhen(0)
   2507                         .setOngoing(true)
   2508                         .setAutoCancel(true)
   2509                         .setTicker(text)
   2510                         .setColor(mContext.getColor(
   2511                                 com.android.internal.R.color.system_notification_accent_color))
   2512                         .setContentTitle(text)
   2513                         .setContentText(
   2514                                 mContext.getText(R.string.dump_heap_notification_detail))
   2515                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
   2516                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
   2517                                 new UserHandle(userId)))
   2518                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
   2519                                 deleteIntent, 0, UserHandle.SYSTEM))
   2520                         .build();
   2521 
   2522                 try {
   2523                     inm.enqueueNotificationWithTag("android", "android", null,
   2524                             SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
   2525                             notification, userId);
   2526                 } catch (RuntimeException e) {
   2527                     Slog.w(ActivityManagerService.TAG,
   2528                             "Error showing notification for dump heap", e);
   2529                 } catch (RemoteException e) {
   2530                 }
   2531             } break;
   2532             case DELETE_DUMPHEAP_MSG: {
   2533                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
   2534                         null, DumpHeapActivity.JAVA_URI,
   2535                         Intent.FLAG_GRANT_READ_URI_PERMISSION
   2536                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
   2537                         UserHandle.myUserId());
   2538                 synchronized (ActivityManagerService.this) {
   2539                     mMemWatchDumpFile = null;
   2540                     mMemWatchDumpProcName = null;
   2541                     mMemWatchDumpPid = -1;
   2542                     mMemWatchDumpUid = -1;
   2543                 }
   2544             } break;
   2545             case REPORT_TIME_TRACKER_MSG: {
   2546                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
   2547                 tracker.deliverResult(mContext);
   2548             } break;
   2549             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
   2550                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
   2551                 try {
   2552                     connection.shutdown();
   2553                 } catch (RemoteException e) {
   2554                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
   2555                 }
   2556                 // Only a UiAutomation can set this flag and now that
   2557                 // it is finished we make sure it is reset to its default.
   2558                 mUserIsMonkey = false;
   2559             } break;
   2560             case IDLE_UIDS_MSG: {
   2561                 idleUids();
   2562             } break;
   2563             case VR_MODE_CHANGE_MSG: {
   2564                 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
   2565                     return;
   2566                 }
   2567                 synchronized (ActivityManagerService.this) {
   2568                     final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
   2569                     mWindowManager.disableNonVrUi(disableNonVrUi);
   2570                     if (disableNonVrUi) {
   2571                         // If we are in a VR mode where Picture-in-Picture mode is unsupported,
   2572                         // then remove the pinned stack.
   2573                         mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
   2574                     }
   2575                 }
   2576             } break;
   2577             case DISPATCH_SCREEN_AWAKE_MSG: {
   2578                 final boolean isAwake = msg.arg1 != 0;
   2579                 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
   2580                     mScreenObservers.get(i).onAwakeStateChanged(isAwake);
   2581                 }
   2582             } break;
   2583             case DISPATCH_SCREEN_KEYGUARD_MSG: {
   2584                 final boolean isShowing = msg.arg1 != 0;
   2585                 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
   2586                     mScreenObservers.get(i).onKeyguardStateChanged(isShowing);
   2587                 }
   2588             } break;
   2589             case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
   2590                 synchronized (ActivityManagerService.this) {
   2591                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   2592                         ProcessRecord r = mLruProcesses.get(i);
   2593                         if (r.thread != null) {
   2594                             try {
   2595                                 r.thread.handleTrustStorageUpdate();
   2596                             } catch (RemoteException ex) {
   2597                                 Slog.w(TAG, "Failed to handle trust storage update for: " +
   2598                                         r.info.processName);
   2599                             }
   2600                         }
   2601                     }
   2602                 }
   2603             } break;
   2604             }
   2605         }
   2606     };
   2607 
   2608     static final int COLLECT_PSS_BG_MSG = 1;
   2609 
   2610     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
   2611         @Override
   2612         public void handleMessage(Message msg) {
   2613             switch (msg.what) {
   2614             case COLLECT_PSS_BG_MSG: {
   2615                 long start = SystemClock.uptimeMillis();
   2616                 MemInfoReader memInfo = null;
   2617                 synchronized (ActivityManagerService.this) {
   2618                     if (mFullPssPending) {
   2619                         mFullPssPending = false;
   2620                         memInfo = new MemInfoReader();
   2621                     }
   2622                 }
   2623                 if (memInfo != null) {
   2624                     updateCpuStatsNow();
   2625                     long nativeTotalPss = 0;
   2626                     final List<ProcessCpuTracker.Stats> stats;
   2627                     synchronized (mProcessCpuTracker) {
   2628                         stats = mProcessCpuTracker.getStats( (st)-> {
   2629                             return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
   2630                         });
   2631                     }
   2632                     final int N = stats.size();
   2633                     for (int j = 0; j < N; j++) {
   2634                         synchronized (mPidsSelfLocked) {
   2635                             if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
   2636                                 // This is one of our own processes; skip it.
   2637                                 continue;
   2638                             }
   2639                         }
   2640                         nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
   2641                     }
   2642                     memInfo.readMemInfo();
   2643                     synchronized (ActivityManagerService.this) {
   2644                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
   2645                                 + (SystemClock.uptimeMillis()-start) + "ms");
   2646                         final long cachedKb = memInfo.getCachedSizeKb();
   2647                         final long freeKb = memInfo.getFreeSizeKb();
   2648                         final long zramKb = memInfo.getZramTotalSizeKb();
   2649                         final long kernelKb = memInfo.getKernelUsedSizeKb();
   2650                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
   2651                                 kernelKb*1024, nativeTotalPss*1024);
   2652                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
   2653                                 nativeTotalPss);
   2654                     }
   2655                 }
   2656 
   2657                 int num = 0;
   2658                 long[] tmp = new long[3];
   2659                 do {
   2660                     ProcessRecord proc;
   2661                     int procState;
   2662                     int statType;
   2663                     int pid;
   2664                     long lastPssTime;
   2665                     synchronized (ActivityManagerService.this) {
   2666                         if (mPendingPssProcesses.size() <= 0) {
   2667                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
   2668                                     "Collected pss of " + num + " processes in "
   2669                                     + (SystemClock.uptimeMillis() - start) + "ms");
   2670                             mPendingPssProcesses.clear();
   2671                             return;
   2672                         }
   2673                         proc = mPendingPssProcesses.remove(0);
   2674                         procState = proc.pssProcState;
   2675                         statType = proc.pssStatType;
   2676                         lastPssTime = proc.lastPssTime;
   2677                         long now = SystemClock.uptimeMillis();
   2678                         if (proc.thread != null && procState == proc.setProcState
   2679                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
   2680                                         < now) {
   2681                             pid = proc.pid;
   2682                         } else {
   2683                             ProcessList.abortNextPssTime(proc.procStateMemTracker);
   2684                             if (DEBUG_PSS) Slog.d(TAG_PSS, "Skipped pss collection of " + pid +
   2685                                     ": still need " +
   2686                                     (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE-now) +
   2687                                     "ms until safe");
   2688                             proc = null;
   2689                             pid = 0;
   2690                         }
   2691                     }
   2692                     if (proc != null) {
   2693                         long startTime = SystemClock.currentThreadTimeMillis();
   2694                         long pss = Debug.getPss(pid, tmp, null);
   2695                         long endTime = SystemClock.currentThreadTimeMillis();
   2696                         synchronized (ActivityManagerService.this) {
   2697                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
   2698                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
   2699                                 num++;
   2700                                 ProcessList.commitNextPssTime(proc.procStateMemTracker);
   2701                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1], tmp[2],
   2702                                         statType, endTime-startTime, SystemClock.uptimeMillis());
   2703                             } else {
   2704                                 ProcessList.abortNextPssTime(proc.procStateMemTracker);
   2705                                 if (DEBUG_PSS) Slog.d(TAG_PSS, "Skipped pss collection of " + pid +
   2706                                         ": " + (proc.thread == null ? "NO_THREAD " : "") +
   2707                                         (proc.pid != pid ? "PID_CHANGED " : "") +
   2708                                         " initState=" + procState + " curState=" +
   2709                                         proc.setProcState + " " +
   2710                                         (proc.lastPssTime != lastPssTime ? "TIME_CHANGED" : ""));
   2711                             }
   2712                         }
   2713                     }
   2714                 } while (true);
   2715             }
   2716             }
   2717         }
   2718     };
   2719 
   2720     public void setSystemProcess() {
   2721         try {
   2722             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
   2723                     DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
   2724             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
   2725             ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
   2726                     DUMP_FLAG_PRIORITY_HIGH);
   2727             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
   2728             ServiceManager.addService("dbinfo", new DbBinder(this));
   2729             if (MONITOR_CPU_USAGE) {
   2730                 ServiceManager.addService("cpuinfo", new CpuBinder(this),
   2731                         /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
   2732             }
   2733             ServiceManager.addService("permission", new PermissionController(this));
   2734             ServiceManager.addService("processinfo", new ProcessInfoService(this));
   2735 
   2736             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
   2737                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
   2738             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
   2739 
   2740             synchronized (this) {
   2741                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
   2742                 app.persistent = true;
   2743                 app.pid = MY_PID;
   2744                 app.maxAdj = ProcessList.SYSTEM_ADJ;
   2745                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
   2746                 synchronized (mPidsSelfLocked) {
   2747                     mPidsSelfLocked.put(app.pid, app);
   2748                 }
   2749                 updateLruProcessLocked(app, false, null);
   2750                 updateOomAdjLocked();
   2751             }
   2752         } catch (PackageManager.NameNotFoundException e) {
   2753             throw new RuntimeException(
   2754                     "Unable to find android system package", e);
   2755         }
   2756 
   2757         // Start watching app ops after we and the package manager are up and running.
   2758         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
   2759                 new IAppOpsCallback.Stub() {
   2760                     @Override public void opChanged(int op, int uid, String packageName) {
   2761                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
   2762                             if (mAppOpsService.checkOperation(op, uid, packageName)
   2763                                     != AppOpsManager.MODE_ALLOWED) {
   2764                                 runInBackgroundDisabled(uid);
   2765                             }
   2766                         }
   2767                     }
   2768                 });
   2769     }
   2770 
   2771     public void setWindowManager(WindowManagerService wm) {
   2772         synchronized (this) {
   2773             mWindowManager = wm;
   2774             mStackSupervisor.setWindowManager(wm);
   2775             mLockTaskController.setWindowManager(wm);
   2776         }
   2777     }
   2778 
   2779     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
   2780         mUsageStatsService = usageStatsManager;
   2781     }
   2782 
   2783     public void startObservingNativeCrashes() {
   2784         final NativeCrashListener ncl = new NativeCrashListener(this);
   2785         ncl.start();
   2786     }
   2787 
   2788     public IAppOpsService getAppOpsService() {
   2789         return mAppOpsService;
   2790     }
   2791 
   2792     static class MemBinder extends Binder {
   2793         ActivityManagerService mActivityManagerService;
   2794         private final PriorityDump.PriorityDumper mPriorityDumper =
   2795                 new PriorityDump.PriorityDumper() {
   2796             @Override
   2797             public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args,
   2798                     boolean asProto) {
   2799                 dump(fd, pw, new String[] {"-a"}, asProto);
   2800             }
   2801 
   2802             @Override
   2803             public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
   2804                 mActivityManagerService.dumpApplicationMemoryUsage(
   2805                         fd, pw, "  ", args, false, null, asProto);
   2806             }
   2807         };
   2808 
   2809         MemBinder(ActivityManagerService activityManagerService) {
   2810             mActivityManagerService = activityManagerService;
   2811         }
   2812 
   2813         @Override
   2814         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2815             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
   2816                     "meminfo", pw)) return;
   2817             PriorityDump.dump(mPriorityDumper, fd, pw, args);
   2818         }
   2819     }
   2820 
   2821     static class GraphicsBinder extends Binder {
   2822         ActivityManagerService mActivityManagerService;
   2823         GraphicsBinder(ActivityManagerService activityManagerService) {
   2824             mActivityManagerService = activityManagerService;
   2825         }
   2826 
   2827         @Override
   2828         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2829             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
   2830                     "gfxinfo", pw)) return;
   2831             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
   2832         }
   2833     }
   2834 
   2835     static class DbBinder extends Binder {
   2836         ActivityManagerService mActivityManagerService;
   2837         DbBinder(ActivityManagerService activityManagerService) {
   2838             mActivityManagerService = activityManagerService;
   2839         }
   2840 
   2841         @Override
   2842         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2843             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
   2844                     "dbinfo", pw)) return;
   2845             mActivityManagerService.dumpDbInfo(fd, pw, args);
   2846         }
   2847     }
   2848 
   2849     static class CpuBinder extends Binder {
   2850         ActivityManagerService mActivityManagerService;
   2851         private final PriorityDump.PriorityDumper mPriorityDumper =
   2852                 new PriorityDump.PriorityDumper() {
   2853             @Override
   2854             public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
   2855                     boolean asProto) {
   2856                 if (asProto) return;
   2857                 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
   2858                         "cpuinfo", pw)) return;
   2859                 synchronized (mActivityManagerService.mProcessCpuTracker) {
   2860                     pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
   2861                     pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
   2862                             SystemClock.uptimeMillis()));
   2863                 }
   2864             }
   2865         };
   2866 
   2867         CpuBinder(ActivityManagerService activityManagerService) {
   2868             mActivityManagerService = activityManagerService;
   2869         }
   2870 
   2871         @Override
   2872         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2873             PriorityDump.dump(mPriorityDumper, fd, pw, args);
   2874         }
   2875     }
   2876 
   2877     public static final class Lifecycle extends SystemService {
   2878         private final ActivityManagerService mService;
   2879 
   2880         public Lifecycle(Context context) {
   2881             super(context);
   2882             mService = new ActivityManagerService(context);
   2883         }
   2884 
   2885         @Override
   2886         public void onStart() {
   2887             mService.start();
   2888         }
   2889 
   2890         @Override
   2891         public void onBootPhase(int phase) {
   2892             mService.mBootPhase = phase;
   2893             if (phase == PHASE_SYSTEM_SERVICES_READY) {
   2894                 mService.mBatteryStatsService.systemServicesReady();
   2895                 mService.mServices.systemServicesReady();
   2896             }
   2897         }
   2898 
   2899         @Override
   2900         public void onCleanupUser(int userId) {
   2901             mService.mBatteryStatsService.onCleanupUser(userId);
   2902         }
   2903 
   2904         public ActivityManagerService getService() {
   2905             return mService;
   2906         }
   2907     }
   2908 
   2909     /**
   2910      * Encapsulates global settings related to hidden API enforcement behaviour, including tracking
   2911      * the latest value via a content observer.
   2912      */
   2913     static class HiddenApiSettings extends ContentObserver {
   2914 
   2915         private final Context mContext;
   2916         private boolean mBlacklistDisabled;
   2917         private String mExemptionsStr;
   2918         private List<String> mExemptions = Collections.emptyList();
   2919         private int mLogSampleRate = -1;
   2920         @HiddenApiEnforcementPolicy private int mPolicyPreP = HIDDEN_API_ENFORCEMENT_DEFAULT;
   2921         @HiddenApiEnforcementPolicy private int mPolicyP = HIDDEN_API_ENFORCEMENT_DEFAULT;
   2922 
   2923         public HiddenApiSettings(Handler handler, Context context) {
   2924             super(handler);
   2925             mContext = context;
   2926         }
   2927 
   2928         public void registerObserver() {
   2929             mContext.getContentResolver().registerContentObserver(
   2930                     Settings.Global.getUriFor(Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS),
   2931                     false,
   2932                     this);
   2933             mContext.getContentResolver().registerContentObserver(
   2934                     Settings.Global.getUriFor(Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE),
   2935                     false,
   2936                     this);
   2937             mContext.getContentResolver().registerContentObserver(
   2938                     Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS),
   2939                     false,
   2940                     this);
   2941             mContext.getContentResolver().registerContentObserver(
   2942                     Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_P_APPS),
   2943                     false,
   2944                     this);
   2945             update();
   2946         }
   2947 
   2948         private void update() {
   2949             String exemptions = Settings.Global.getString(mContext.getContentResolver(),
   2950                     Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS);
   2951             if (!TextUtils.equals(exemptions, mExemptionsStr)) {
   2952                 mExemptionsStr = exemptions;
   2953                 if ("*".equals(exemptions)) {
   2954                     mBlacklistDisabled = true;
   2955                     mExemptions = Collections.emptyList();
   2956                 } else {
   2957                     mBlacklistDisabled = false;
   2958                     mExemptions = TextUtils.isEmpty(exemptions)
   2959                             ? Collections.emptyList()
   2960                             : Arrays.asList(exemptions.split(","));
   2961                 }
   2962                 if (!zygoteProcess.setApiBlacklistExemptions(mExemptions)) {
   2963                   Slog.e(TAG, "Failed to set API blacklist exemptions!");
   2964                   // leave mExemptionsStr as is, so we don't try to send the same list again.
   2965                   mExemptions = Collections.emptyList();
   2966                 }
   2967             }
   2968             int logSampleRate = Settings.Global.getInt(mContext.getContentResolver(),
   2969                     Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE, -1);
   2970             if (logSampleRate < 0 || logSampleRate > 0x10000) {
   2971                 logSampleRate = -1;
   2972             }
   2973             if (logSampleRate != -1 && logSampleRate != mLogSampleRate) {
   2974                 mLogSampleRate = logSampleRate;
   2975                 zygoteProcess.setHiddenApiAccessLogSampleRate(mLogSampleRate);
   2976             }
   2977             mPolicyPreP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS);
   2978             mPolicyP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_P_APPS);
   2979         }
   2980 
   2981         private @HiddenApiEnforcementPolicy int getValidEnforcementPolicy(String settingsKey) {
   2982             int policy = Settings.Global.getInt(mContext.getContentResolver(), settingsKey,
   2983                     ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT);
   2984             if (ApplicationInfo.isValidHiddenApiEnforcementPolicy(policy)) {
   2985                 return policy;
   2986             } else {
   2987                 return ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT;
   2988             }
   2989         }
   2990 
   2991         boolean isDisabled() {
   2992             return mBlacklistDisabled;
   2993         }
   2994 
   2995         @HiddenApiEnforcementPolicy int getPolicyForPrePApps() {
   2996             return mPolicyPreP;
   2997         }
   2998 
   2999         @HiddenApiEnforcementPolicy int getPolicyForPApps() {
   3000             return mPolicyP;
   3001         }
   3002 
   3003         public void onChange(boolean selfChange) {
   3004             update();
   3005         }
   3006     }
   3007 
   3008     @VisibleForTesting
   3009     public ActivityManagerService(Injector injector) {
   3010         mInjector = injector;
   3011         mContext = mInjector.getContext();
   3012         mUiContext = null;
   3013         GL_ES_VERSION = 0;
   3014         mActivityStartController = null;
   3015         mAppErrors = null;
   3016         mAppWarnings = null;
   3017         mAppOpsService = mInjector.getAppOpsService(null, null);
   3018         mBatteryStatsService = null;
   3019         mCompatModePackages = null;
   3020         mConstants = null;
   3021         mGrantFile = null;
   3022         mHandler = null;
   3023         mHandlerThread = null;
   3024         mIntentFirewall = null;
   3025         mKeyguardController = null;
   3026         mPermissionReviewRequired = false;
   3027         mProcessCpuThread = null;
   3028         mProcessStats = null;
   3029         mProviderMap = null;
   3030         mRecentTasks = null;
   3031         mServices = null;
   3032         mStackSupervisor = null;
   3033         mSystemThread = null;
   3034         mTaskChangeNotificationController = null;
   3035         mUiHandler = injector.getUiHandler(null);
   3036         mUserController = null;
   3037         mVrController = null;
   3038         mLockTaskController = null;
   3039         mLifecycleManager = null;
   3040         mProcStartHandlerThread = null;
   3041         mProcStartHandler = null;
   3042         mHiddenApiBlacklist = null;
   3043     }
   3044 
   3045     // Note: This method is invoked on the main thread but may need to attach various
   3046     // handlers to other threads.  So take care to be explicit about the looper.
   3047     public ActivityManagerService(Context systemContext) {
   3048         LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
   3049         mInjector = new Injector();
   3050         mContext = systemContext;
   3051 
   3052         mFactoryTest = FactoryTest.getMode();
   3053         mSystemThread = ActivityThread.currentActivityThread();
   3054         mUiContext = mSystemThread.getSystemUiContext();
   3055 
   3056         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
   3057 
   3058         mPermissionReviewRequired = mContext.getResources().getBoolean(
   3059                 com.android.internal.R.bool.config_permissionReviewRequired);
   3060 
   3061         mHandlerThread = new ServiceThread(TAG,
   3062                 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
   3063         mHandlerThread.start();
   3064         mHandler = new MainHandler(mHandlerThread.getLooper());
   3065         mUiHandler = mInjector.getUiHandler(this);
   3066 
   3067         mProcStartHandlerThread = new ServiceThread(TAG + ":procStart",
   3068                 THREAD_PRIORITY_FOREGROUND, false /* allowIo */);
   3069         mProcStartHandlerThread.start();
   3070         mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper());
   3071 
   3072         mConstants = new ActivityManagerConstants(this, mHandler);
   3073 
   3074         /* static; one-time init here */
   3075         if (sKillHandler == null) {
   3076             sKillThread = new ServiceThread(TAG + ":kill",
   3077                     THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
   3078             sKillThread.start();
   3079             sKillHandler = new KillHandler(sKillThread.getLooper());
   3080         }
   3081 
   3082         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
   3083                 "foreground", BROADCAST_FG_TIMEOUT, false);
   3084         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
   3085                 "background", BROADCAST_BG_TIMEOUT, true);
   3086         mBroadcastQueues[0] = mFgBroadcastQueue;
   3087         mBroadcastQueues[1] = mBgBroadcastQueue;
   3088 
   3089         mServices = new ActiveServices(this);
   3090         mProviderMap = new ProviderMap(this);
   3091         mAppErrors = new AppErrors(mUiContext, this);
   3092 
   3093         File dataDir = Environment.getDataDirectory();
   3094         File systemDir = new File(dataDir, "system");
   3095         systemDir.mkdirs();
   3096 
   3097         mAppWarnings = new AppWarnings(this, mUiContext, mHandler, mUiHandler, systemDir);
   3098 
   3099         // TODO: Move creation of battery stats service outside of activity manager service.
   3100         mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
   3101         mBatteryStatsService.getActiveStatistics().readLocked();
   3102         mBatteryStatsService.scheduleWriteToDisk();
   3103         mOnBattery = DEBUG_POWER ? true
   3104                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
   3105         mBatteryStatsService.getActiveStatistics().setCallback(this);
   3106 
   3107         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
   3108 
   3109         mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
   3110 
   3111         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"), "uri-grants");
   3112 
   3113         mUserController = new UserController(this);
   3114 
   3115         mVrController = new VrController(this);
   3116 
   3117         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
   3118             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
   3119 
   3120         if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
   3121             mUseFifoUiScheduling = true;
   3122         }
   3123 
   3124         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
   3125         mTempConfig.setToDefaults();
   3126         mTempConfig.setLocales(LocaleList.getDefault());
   3127         mConfigurationSeq = mTempConfig.seq = 1;
   3128         mStackSupervisor = createStackSupervisor();
   3129         mStackSupervisor.onConfigurationChanged(mTempConfig);
   3130         mKeyguardController = mStackSupervisor.getKeyguardController();
   3131         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
   3132         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
   3133         mTaskChangeNotificationController =
   3134                 new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
   3135         mActivityStartController = new ActivityStartController(this);
   3136         mRecentTasks = createRecentTasks();
   3137         mStackSupervisor.setRecentTasks(mRecentTasks);
   3138         mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mHandler);
   3139         mLifecycleManager = new ClientLifecycleManager();
   3140 
   3141         mProcessCpuThread = new Thread("CpuTracker") {
   3142             @Override
   3143             public void run() {
   3144                 synchronized (mProcessCpuTracker) {
   3145                     mProcessCpuInitLatch.countDown();
   3146                     mProcessCpuTracker.init();
   3147                 }
   3148                 while (true) {
   3149                     try {
   3150                         try {
   3151                             synchronized(this) {
   3152                                 final long now = SystemClock.uptimeMillis();
   3153                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
   3154                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
   3155                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
   3156                                 //        + ", write delay=" + nextWriteDelay);
   3157                                 if (nextWriteDelay < nextCpuDelay) {
   3158                                     nextCpuDelay = nextWriteDelay;
   3159                                 }
   3160                                 if (nextCpuDelay > 0) {
   3161                                     mProcessCpuMutexFree.set(true);
   3162                                     this.wait(nextCpuDelay);
   3163                                 }
   3164                             }
   3165                         } catch (InterruptedException e) {
   3166                         }
   3167                         updateCpuStatsNow();
   3168                     } catch (Exception e) {
   3169                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
   3170                     }
   3171                 }
   3172             }
   3173         };
   3174 
   3175         mHiddenApiBlacklist = new HiddenApiSettings(mHandler, mContext);
   3176 
   3177         Watchdog.getInstance().addMonitor(this);
   3178         Watchdog.getInstance().addThread(mHandler);
   3179 
   3180         // bind background thread to little cores
   3181         // this is expected to fail inside of framework tests because apps can't touch cpusets directly
   3182         // make sure we've already adjusted system_server's internal view of itself first
   3183         updateOomAdjLocked();
   3184         try {
   3185             Process.setThreadGroupAndCpuset(BackgroundThread.get().getThreadId(),
   3186                     Process.THREAD_GROUP_BG_NONINTERACTIVE);
   3187         } catch (Exception e) {
   3188             Slog.w(TAG, "Setting background thread cpuset failed");
   3189         }
   3190 
   3191     }
   3192 
   3193     protected ActivityStackSupervisor createStackSupervisor() {
   3194         final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mHandler.getLooper());
   3195         supervisor.initialize();
   3196         return supervisor;
   3197     }
   3198 
   3199     protected RecentTasks createRecentTasks() {
   3200         return new RecentTasks(this, mStackSupervisor);
   3201     }
   3202 
   3203     RecentTasks getRecentTasks() {
   3204         return mRecentTasks;
   3205     }
   3206 
   3207     public void setSystemServiceManager(SystemServiceManager mgr) {
   3208         mSystemServiceManager = mgr;
   3209     }
   3210 
   3211     public void setInstaller(Installer installer) {
   3212         mInstaller = installer;
   3213     }
   3214 
   3215     private void start() {
   3216         removeAllProcessGroups();
   3217         mProcessCpuThread.start();
   3218 
   3219         mBatteryStatsService.publish();
   3220         mAppOpsService.publish(mContext);
   3221         Slog.d("AppOps", "AppOpsService published");
   3222         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
   3223         // Wait for the synchronized block started in mProcessCpuThread,
   3224         // so that any other acccess to mProcessCpuTracker from main thread
   3225         // will be blocked during mProcessCpuTracker initialization.
   3226         try {
   3227             mProcessCpuInitLatch.await();
   3228         } catch (InterruptedException e) {
   3229             Slog.wtf(TAG, "Interrupted wait during start", e);
   3230             Thread.currentThread().interrupt();
   3231             throw new IllegalStateException("Interrupted wait during start");
   3232         }
   3233     }
   3234 
   3235     void onUserStoppedLocked(int userId) {
   3236         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
   3237         mAllowAppSwitchUids.remove(userId);
   3238     }
   3239 
   3240     public void initPowerManagement() {
   3241         mStackSupervisor.initPowerManagement();
   3242         mBatteryStatsService.initPowerManagement();
   3243         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
   3244         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
   3245         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
   3246         mVoiceWakeLock.setReferenceCounted(false);
   3247     }
   3248 
   3249     private ArraySet<String> getBackgroundLaunchBroadcasts() {
   3250         if (mBackgroundLaunchBroadcasts == null) {
   3251             mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
   3252         }
   3253         return mBackgroundLaunchBroadcasts;
   3254     }
   3255 
   3256     @Override
   3257     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   3258             throws RemoteException {
   3259         if (code == SYSPROPS_TRANSACTION) {
   3260             // We need to tell all apps about the system property change.
   3261             ArrayList<IBinder> procs = new ArrayList<IBinder>();
   3262             synchronized(this) {
   3263                 final int NP = mProcessNames.getMap().size();
   3264                 for (int ip=0; ip<NP; ip++) {
   3265                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   3266                     final int NA = apps.size();
   3267                     for (int ia=0; ia<NA; ia++) {
   3268                         ProcessRecord app = apps.valueAt(ia);
   3269                         if (app.thread != null) {
   3270                             procs.add(app.thread.asBinder());
   3271                         }
   3272                     }
   3273                 }
   3274             }
   3275 
   3276             int N = procs.size();
   3277             for (int i=0; i<N; i++) {
   3278                 Parcel data2 = Parcel.obtain();
   3279                 try {
   3280                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
   3281                             Binder.FLAG_ONEWAY);
   3282                 } catch (RemoteException e) {
   3283                 }
   3284                 data2.recycle();
   3285             }
   3286         }
   3287         try {
   3288             return super.onTransact(code, data, reply, flags);
   3289         } catch (RuntimeException e) {
   3290             // The activity manager only throws certain exceptions intentionally, so let's
   3291             // log all others.
   3292             if (!(e instanceof SecurityException
   3293                     || e instanceof IllegalArgumentException
   3294                     || e instanceof IllegalStateException)) {
   3295                 Slog.wtf(TAG, "Activity Manager Crash."
   3296                         + " UID:" + Binder.getCallingUid()
   3297                         + " PID:" + Binder.getCallingPid()
   3298                         + " TRANS:" + code, e);
   3299             }
   3300             throw e;
   3301         }
   3302     }
   3303 
   3304     void updateCpuStats() {
   3305         final long now = SystemClock.uptimeMillis();
   3306         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
   3307             return;
   3308         }
   3309         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
   3310             synchronized (mProcessCpuThread) {
   3311                 mProcessCpuThread.notify();
   3312             }
   3313         }
   3314     }
   3315 
   3316     void updateCpuStatsNow() {
   3317         synchronized (mProcessCpuTracker) {
   3318             mProcessCpuMutexFree.set(false);
   3319             final long now = SystemClock.uptimeMillis();
   3320             boolean haveNewCpuStats = false;
   3321 
   3322             if (MONITOR_CPU_USAGE &&
   3323                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
   3324                 mLastCpuTime.set(now);
   3325                 mProcessCpuTracker.update();
   3326                 if (mProcessCpuTracker.hasGoodLastStats()) {
   3327                     haveNewCpuStats = true;
   3328                     //Slog.i(TAG, mProcessCpu.printCurrentState());
   3329                     //Slog.i(TAG, "Total CPU usage: "
   3330                     //        + mProcessCpu.getTotalCpuPercent() + "%");
   3331 
   3332                     // Slog the cpu usage if the property is set.
   3333                     if ("true".equals(SystemProperties.get("events.cpu"))) {
   3334                         int user = mProcessCpuTracker.getLastUserTime();
   3335                         int system = mProcessCpuTracker.getLastSystemTime();
   3336                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
   3337                         int irq = mProcessCpuTracker.getLastIrqTime();
   3338                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
   3339                         int idle = mProcessCpuTracker.getLastIdleTime();
   3340 
   3341                         int total = user + system + iowait + irq + softIrq + idle;
   3342                         if (total == 0) total = 1;
   3343 
   3344                         EventLog.writeEvent(EventLogTags.CPU,
   3345                                 ((user+system+iowait+irq+softIrq) * 100) / total,
   3346                                 (user * 100) / total,
   3347                                 (system * 100) / total,
   3348                                 (iowait * 100) / total,
   3349                                 (irq * 100) / total,
   3350                                 (softIrq * 100) / total);
   3351                     }
   3352                 }
   3353             }
   3354 
   3355             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
   3356             synchronized(bstats) {
   3357                 synchronized(mPidsSelfLocked) {
   3358                     if (haveNewCpuStats) {
   3359                         if (bstats.startAddingCpuLocked()) {
   3360                             int totalUTime = 0;
   3361                             int totalSTime = 0;
   3362                             final int N = mProcessCpuTracker.countStats();
   3363                             for (int i=0; i<N; i++) {
   3364                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   3365                                 if (!st.working) {
   3366                                     continue;
   3367                                 }
   3368                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
   3369                                 totalUTime += st.rel_utime;
   3370                                 totalSTime += st.rel_stime;
   3371                                 if (pr != null) {
   3372                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
   3373                                     if (ps == null || !ps.isActive()) {
   3374                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
   3375                                                 pr.info.uid, pr.processName);
   3376                                     }
   3377                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
   3378                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
   3379                                     if (pr.lastCpuTime == 0) {
   3380                                         pr.lastCpuTime = pr.curCpuTime;
   3381                                     }
   3382                                 } else {
   3383                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
   3384                                     if (ps == null || !ps.isActive()) {
   3385                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
   3386                                                 bstats.mapUid(st.uid), st.name);
   3387                                     }
   3388                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
   3389                                 }
   3390                             }
   3391                             final int userTime = mProcessCpuTracker.getLastUserTime();
   3392                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
   3393                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
   3394                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
   3395                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
   3396                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
   3397                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
   3398                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
   3399                         }
   3400                     }
   3401                 }
   3402 
   3403                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
   3404                     mLastWriteTime = now;
   3405                     mBatteryStatsService.scheduleWriteToDisk();
   3406                 }
   3407             }
   3408         }
   3409     }
   3410 
   3411     @Override
   3412     public void batteryNeedsCpuUpdate() {
   3413         updateCpuStatsNow();
   3414     }
   3415 
   3416     @Override
   3417     public void batteryPowerChanged(boolean onBattery) {
   3418         // When plugging in, update the CPU stats first before changing
   3419         // the plug state.
   3420         updateCpuStatsNow();
   3421         synchronized (this) {
   3422             synchronized(mPidsSelfLocked) {
   3423                 mOnBattery = DEBUG_POWER ? true : onBattery;
   3424             }
   3425         }
   3426     }
   3427 
   3428     @Override
   3429     public void batteryStatsReset() {
   3430         BinderCallsStatsService.reset();
   3431     }
   3432 
   3433     @Override
   3434     public void batterySendBroadcast(Intent intent) {
   3435         synchronized (this) {
   3436             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
   3437                     OP_NONE, null, false, false,
   3438                     -1, SYSTEM_UID, UserHandle.USER_ALL);
   3439         }
   3440     }
   3441 
   3442     /**
   3443      * Initialize the application bind args. These are passed to each
   3444      * process when the bindApplication() IPC is sent to the process. They're
   3445      * lazily setup to make sure the services are running when they're asked for.
   3446      */
   3447     private ArrayMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
   3448         // Isolated processes won't get this optimization, so that we don't
   3449         // violate the rules about which services they have access to.
   3450         if (isolated) {
   3451             if (mIsolatedAppBindArgs == null) {
   3452                 mIsolatedAppBindArgs = new ArrayMap<>(1);
   3453                 addServiceToMap(mIsolatedAppBindArgs, "package");
   3454             }
   3455             return mIsolatedAppBindArgs;
   3456         }
   3457 
   3458         if (mAppBindArgs == null) {
   3459             mAppBindArgs = new ArrayMap<>();
   3460 
   3461             // Add common services.
   3462             // IMPORTANT: Before adding services here, make sure ephemeral apps can access them too.
   3463             // Enable the check in ApplicationThread.bindApplication() to make sure.
   3464             addServiceToMap(mAppBindArgs, "package");
   3465             addServiceToMap(mAppBindArgs, Context.WINDOW_SERVICE);
   3466             addServiceToMap(mAppBindArgs, Context.ALARM_SERVICE);
   3467             addServiceToMap(mAppBindArgs, Context.DISPLAY_SERVICE);
   3468             addServiceToMap(mAppBindArgs, Context.NETWORKMANAGEMENT_SERVICE);
   3469             addServiceToMap(mAppBindArgs, Context.CONNECTIVITY_SERVICE);
   3470             addServiceToMap(mAppBindArgs, Context.ACCESSIBILITY_SERVICE);
   3471             addServiceToMap(mAppBindArgs, Context.INPUT_METHOD_SERVICE);
   3472             addServiceToMap(mAppBindArgs, Context.INPUT_SERVICE);
   3473             addServiceToMap(mAppBindArgs, "graphicsstats");
   3474             addServiceToMap(mAppBindArgs, Context.APP_OPS_SERVICE);
   3475             addServiceToMap(mAppBindArgs, "content");
   3476             addServiceToMap(mAppBindArgs, Context.JOB_SCHEDULER_SERVICE);
   3477             addServiceToMap(mAppBindArgs, Context.NOTIFICATION_SERVICE);
   3478             addServiceToMap(mAppBindArgs, Context.VIBRATOR_SERVICE);
   3479             addServiceToMap(mAppBindArgs, Context.ACCOUNT_SERVICE);
   3480             addServiceToMap(mAppBindArgs, Context.POWER_SERVICE);
   3481             addServiceToMap(mAppBindArgs, Context.USER_SERVICE);
   3482             addServiceToMap(mAppBindArgs, "mount");
   3483         }
   3484         return mAppBindArgs;
   3485     }
   3486 
   3487     private static void addServiceToMap(ArrayMap<String, IBinder> map, String name) {
   3488         final IBinder service = ServiceManager.getService(name);
   3489         if (service != null) {
   3490             map.put(name, service);
   3491             if (false) {
   3492                 Log.i(TAG, "Adding " + name + " to the pre-loaded service cache.");
   3493             }
   3494         }
   3495     }
   3496 
   3497     /**
   3498      * Update AMS states when an activity is resumed. This should only be called by
   3499      * {@link ActivityStack#onActivityStateChanged(ActivityRecord, ActivityState, String)} when an
   3500      * activity is resumed.
   3501      */
   3502     @GuardedBy("this")
   3503     void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
   3504         final TaskRecord task = r.getTask();
   3505         if (task.isActivityTypeStandard()) {
   3506             if (mCurAppTimeTracker != r.appTimeTracker) {
   3507                 // We are switching app tracking.  Complete the current one.
   3508                 if (mCurAppTimeTracker != null) {
   3509                     mCurAppTimeTracker.stop();
   3510                     mHandler.obtainMessage(
   3511                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
   3512                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
   3513                     mCurAppTimeTracker = null;
   3514                 }
   3515                 if (r.appTimeTracker != null) {
   3516                     mCurAppTimeTracker = r.appTimeTracker;
   3517                     startTimeTrackingFocusedActivityLocked();
   3518                 }
   3519             } else {
   3520                 startTimeTrackingFocusedActivityLocked();
   3521             }
   3522         } else {
   3523             r.appTimeTracker = null;
   3524         }
   3525         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
   3526         // TODO: Probably not, because we don't want to resume voice on switching
   3527         // back to this activity
   3528         if (task.voiceInteractor != null) {
   3529             startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
   3530         } else {
   3531             finishRunningVoiceLocked();
   3532 
   3533             if (mLastResumedActivity != null) {
   3534                 final IVoiceInteractionSession session;
   3535 
   3536                 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
   3537                 if (lastResumedActivityTask != null
   3538                         && lastResumedActivityTask.voiceSession != null) {
   3539                     session = lastResumedActivityTask.voiceSession;
   3540                 } else {
   3541                     session = mLastResumedActivity.voiceSession;
   3542                 }
   3543 
   3544                 if (session != null) {
   3545                     // We had been in a voice interaction session, but now focused has
   3546                     // move to something different.  Just finish the session, we can't
   3547                     // return to it and retain the proper state and synchronization with
   3548                     // the voice interaction service.
   3549                     finishVoiceTask(session);
   3550                 }
   3551             }
   3552         }
   3553 
   3554         if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
   3555             mUserController.sendForegroundProfileChanged(r.userId);
   3556         }
   3557         updateResumedAppTrace(r);
   3558         mLastResumedActivity = r;
   3559 
   3560         mWindowManager.setFocusedApp(r.appToken, true);
   3561 
   3562         applyUpdateLockStateLocked(r);
   3563         applyUpdateVrModeLocked(r);
   3564 
   3565         EventLogTags.writeAmSetResumedActivity(
   3566                 r == null ? -1 : r.userId,
   3567                 r == null ? "NULL" : r.shortComponentName,
   3568                 reason);
   3569     }
   3570 
   3571     private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
   3572         if (mTracedResumedActivity != null) {
   3573             Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
   3574                     constructResumedTraceName(mTracedResumedActivity.packageName), 0);
   3575         }
   3576         if (resumed != null) {
   3577             Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
   3578                     constructResumedTraceName(resumed.packageName), 0);
   3579         }
   3580         mTracedResumedActivity = resumed;
   3581     }
   3582 
   3583     private String constructResumedTraceName(String packageName) {
   3584         return "focused app: " + packageName;
   3585     }
   3586 
   3587     @Override
   3588     public void setFocusedStack(int stackId) {
   3589         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
   3590         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
   3591         final long callingId = Binder.clearCallingIdentity();
   3592         try {
   3593             synchronized (this) {
   3594                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
   3595                 if (stack == null) {
   3596                     Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
   3597                     return;
   3598                 }
   3599                 final ActivityRecord r = stack.topRunningActivityLocked();
   3600                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
   3601                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
   3602                 }
   3603             }
   3604         } finally {
   3605             Binder.restoreCallingIdentity(callingId);
   3606         }
   3607     }
   3608 
   3609     @Override
   3610     public void setFocusedTask(int taskId) {
   3611         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
   3612         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
   3613         final long callingId = Binder.clearCallingIdentity();
   3614         try {
   3615             synchronized (this) {
   3616                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   3617                 if (task == null) {
   3618                     return;
   3619                 }
   3620                 final ActivityRecord r = task.topRunningActivityLocked();
   3621                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
   3622                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
   3623                 }
   3624             }
   3625         } finally {
   3626             Binder.restoreCallingIdentity(callingId);
   3627         }
   3628     }
   3629 
   3630     /** Sets the task stack listener that gets callbacks when a task stack changes. */
   3631     @Override
   3632     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
   3633         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
   3634                 "registerTaskStackListener()");
   3635         mTaskChangeNotificationController.registerTaskStackListener(listener);
   3636     }
   3637 
   3638     /**
   3639      * Unregister a task stack listener so that it stops receiving callbacks.
   3640      */
   3641     @Override
   3642     public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
   3643         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
   3644                 "unregisterTaskStackListener()");
   3645          mTaskChangeNotificationController.unregisterTaskStackListener(listener);
   3646      }
   3647 
   3648     @Override
   3649     public void notifyActivityDrawn(IBinder token) {
   3650         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
   3651         synchronized (this) {
   3652             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
   3653             if (r != null) {
   3654                 r.getStack().notifyActivityDrawnLocked(r);
   3655             }
   3656         }
   3657     }
   3658 
   3659     final void applyUpdateLockStateLocked(ActivityRecord r) {
   3660         // Modifications to the UpdateLock state are done on our handler, outside
   3661         // the activity manager's locks.  The new state is determined based on the
   3662         // state *now* of the relevant activity record.  The object is passed to
   3663         // the handler solely for logging detail, not to be consulted/modified.
   3664         final boolean nextState = r != null && r.immersive;
   3665         mHandler.sendMessage(
   3666                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
   3667     }
   3668 
   3669     final void applyUpdateVrModeLocked(ActivityRecord r) {
   3670         // VR apps are expected to run in a main display. If an app is turning on VR for
   3671         // itself, but lives in a dynamic stack, then make sure that it is moved to the main
   3672         // fullscreen stack before enabling VR Mode.
   3673         // TODO: The goal of this code is to keep the VR app on the main display. When the
   3674         // stack implementation changes in the future, keep in mind that the use of the fullscreen
   3675         // stack is a means to move the activity to the main display and a moveActivityToDisplay()
   3676         // option would be a better choice here.
   3677         if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
   3678             Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
   3679                     + " to main stack for VR");
   3680             final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
   3681                     WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
   3682             moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
   3683         }
   3684         mHandler.sendMessage(
   3685                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
   3686     }
   3687 
   3688     final void showAskCompatModeDialogLocked(ActivityRecord r) {
   3689         Message msg = Message.obtain();
   3690         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
   3691         msg.obj = r.getTask().askedCompatMode ? null : r;
   3692         mUiHandler.sendMessage(msg);
   3693     }
   3694 
   3695     final AppWarnings getAppWarningsLocked() {
   3696         return mAppWarnings;
   3697     }
   3698 
   3699     /**
   3700      * Shows app warning dialogs, if necessary.
   3701      *
   3702      * @param r activity record for which the warnings may be displayed
   3703      */
   3704     final void showAppWarningsIfNeededLocked(ActivityRecord r) {
   3705         mAppWarnings.showUnsupportedCompileSdkDialogIfNeeded(r);
   3706         mAppWarnings.showUnsupportedDisplaySizeDialogIfNeeded(r);
   3707         mAppWarnings.showDeprecatedTargetDialogIfNeeded(r);
   3708     }
   3709 
   3710     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
   3711             String what, Object obj, ProcessRecord srcApp) {
   3712         app.lastActivityTime = now;
   3713 
   3714         if (app.activities.size() > 0 || app.recentTasks.size() > 0) {
   3715             // Don't want to touch dependent processes that are hosting activities.
   3716             return index;
   3717         }
   3718 
   3719         int lrui = mLruProcesses.lastIndexOf(app);
   3720         if (lrui < 0) {
   3721             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
   3722                     + what + " " + obj + " from " + srcApp);
   3723             return index;
   3724         }
   3725 
   3726         if (lrui >= index) {
   3727             // Don't want to cause this to move dependent processes *back* in the
   3728             // list as if they were less frequently used.
   3729             return index;
   3730         }
   3731 
   3732         if (lrui >= mLruProcessActivityStart) {
   3733             // Don't want to touch dependent processes that are hosting activities.
   3734             return index;
   3735         }
   3736 
   3737         mLruProcesses.remove(lrui);
   3738         if (index > 0) {
   3739             index--;
   3740         }
   3741         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
   3742                 + " in LRU list: " + app);
   3743         mLruProcesses.add(index, app);
   3744         return index;
   3745     }
   3746 
   3747     static void killProcessGroup(int uid, int pid) {
   3748         if (sKillHandler != null) {
   3749             sKillHandler.sendMessage(
   3750                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
   3751         } else {
   3752             Slog.w(TAG, "Asked to kill process group before system bringup!");
   3753             Process.killProcessGroup(uid, pid);
   3754         }
   3755     }
   3756 
   3757     final void removeLruProcessLocked(ProcessRecord app) {
   3758         int lrui = mLruProcesses.lastIndexOf(app);
   3759         if (lrui >= 0) {
   3760             if (!app.killed) {
   3761                 if (app.persistent) {
   3762                     Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app);
   3763                 } else {
   3764                     Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
   3765                     if (app.pid > 0) {
   3766                         killProcessQuiet(app.pid);
   3767                         killProcessGroup(app.uid, app.pid);
   3768                     } else {
   3769                         app.pendingStart = false;
   3770                     }
   3771                 }
   3772             }
   3773             if (lrui <= mLruProcessActivityStart) {
   3774                 mLruProcessActivityStart--;
   3775             }
   3776             if (lrui <= mLruProcessServiceStart) {
   3777                 mLruProcessServiceStart--;
   3778             }
   3779             mLruProcesses.remove(lrui);
   3780         }
   3781     }
   3782 
   3783     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
   3784             ProcessRecord client) {
   3785         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
   3786                 || app.treatLikeActivity || app.recentTasks.size() > 0;
   3787         final boolean hasService = false; // not impl yet. app.services.size() > 0;
   3788         if (!activityChange && hasActivity) {
   3789             // The process has activities, so we are only allowing activity-based adjustments
   3790             // to move it.  It should be kept in the front of the list with other
   3791             // processes that have activities, and we don't want those to change their
   3792             // order except due to activity operations.
   3793             return;
   3794         }
   3795 
   3796         mLruSeq++;
   3797         final long now = SystemClock.uptimeMillis();
   3798         app.lastActivityTime = now;
   3799 
   3800         // First a quick reject: if the app is already at the position we will
   3801         // put it, then there is nothing to do.
   3802         if (hasActivity) {
   3803             final int N = mLruProcesses.size();
   3804             if (N > 0 && mLruProcesses.get(N-1) == app) {
   3805                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
   3806                 return;
   3807             }
   3808         } else {
   3809             if (mLruProcessServiceStart > 0
   3810                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
   3811                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
   3812                 return;
   3813             }
   3814         }
   3815 
   3816         int lrui = mLruProcesses.lastIndexOf(app);
   3817 
   3818         if (app.persistent && lrui >= 0) {
   3819             // We don't care about the position of persistent processes, as long as
   3820             // they are in the list.
   3821             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
   3822             return;
   3823         }
   3824 
   3825         /* In progress: compute new position first, so we can avoid doing work
   3826            if the process is not actually going to move.  Not yet working.
   3827         int addIndex;
   3828         int nextIndex;
   3829         boolean inActivity = false, inService = false;
   3830         if (hasActivity) {
   3831             // Process has activities, put it at the very tipsy-top.
   3832             addIndex = mLruProcesses.size();
   3833             nextIndex = mLruProcessServiceStart;
   3834             inActivity = true;
   3835         } else if (hasService) {
   3836             // Process has services, put it at the top of the service list.
   3837             addIndex = mLruProcessActivityStart;
   3838             nextIndex = mLruProcessServiceStart;
   3839             inActivity = true;
   3840             inService = true;
   3841         } else  {
   3842             // Process not otherwise of interest, it goes to the top of the non-service area.
   3843             addIndex = mLruProcessServiceStart;
   3844             if (client != null) {
   3845                 int clientIndex = mLruProcesses.lastIndexOf(client);
   3846                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
   3847                         + app);
   3848                 if (clientIndex >= 0 && addIndex > clientIndex) {
   3849                     addIndex = clientIndex;
   3850                 }
   3851             }
   3852             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
   3853         }
   3854 
   3855         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
   3856                 + mLruProcessActivityStart + "): " + app);
   3857         */
   3858 
   3859         if (lrui >= 0) {
   3860             if (lrui < mLruProcessActivityStart) {
   3861                 mLruProcessActivityStart--;
   3862             }
   3863             if (lrui < mLruProcessServiceStart) {
   3864                 mLruProcessServiceStart--;
   3865             }
   3866             /*
   3867             if (addIndex > lrui) {
   3868                 addIndex--;
   3869             }
   3870             if (nextIndex > lrui) {
   3871                 nextIndex--;
   3872             }
   3873             */
   3874             mLruProcesses.remove(lrui);
   3875         }
   3876 
   3877         /*
   3878         mLruProcesses.add(addIndex, app);
   3879         if (inActivity) {
   3880             mLruProcessActivityStart++;
   3881         }
   3882         if (inService) {
   3883             mLruProcessActivityStart++;
   3884         }
   3885         */
   3886 
   3887         int nextIndex;
   3888         if (hasActivity) {
   3889             final int N = mLruProcesses.size();
   3890             if ((app.activities.size() == 0 || app.recentTasks.size() > 0)
   3891                     && mLruProcessActivityStart < (N - 1)) {
   3892                 // Process doesn't have activities, but has clients with
   3893                 // activities...  move it up, but one below the top (the top
   3894                 // should always have a real activity).
   3895                 if (DEBUG_LRU) Slog.d(TAG_LRU,
   3896                         "Adding to second-top of LRU activity list: " + app);
   3897                 mLruProcesses.add(N - 1, app);
   3898                 // To keep it from spamming the LRU list (by making a bunch of clients),
   3899                 // we will push down any other entries owned by the app.
   3900                 final int uid = app.info.uid;
   3901                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
   3902                     ProcessRecord subProc = mLruProcesses.get(i);
   3903                     if (subProc.info.uid == uid) {
   3904                         // We want to push this one down the list.  If the process after
   3905                         // it is for the same uid, however, don't do so, because we don't
   3906                         // want them internally to be re-ordered.
   3907                         if (mLruProcesses.get(i - 1).info.uid != uid) {
   3908                             if (DEBUG_LRU) Slog.d(TAG_LRU,
   3909                                     "Pushing uid " + uid + " swapping at " + i + ": "
   3910                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
   3911                             ProcessRecord tmp = mLruProcesses.get(i);
   3912                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
   3913                             mLruProcesses.set(i - 1, tmp);
   3914                             i--;
   3915                         }
   3916                     } else {
   3917                         // A gap, we can stop here.
   3918                         break;
   3919                     }
   3920                 }
   3921             } else {
   3922                 // Process has activities, put it at the very tipsy-top.
   3923                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
   3924                 mLruProcesses.add(app);
   3925             }
   3926             nextIndex = mLruProcessServiceStart;
   3927         } else if (hasService) {
   3928             // Process has services, put it at the top of the service list.
   3929             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
   3930             mLruProcesses.add(mLruProcessActivityStart, app);
   3931             nextIndex = mLruProcessServiceStart;
   3932             mLruProcessActivityStart++;
   3933         } else  {
   3934             // Process not otherwise of interest, it goes to the top of the non-service area.
   3935             int index = mLruProcessServiceStart;
   3936             if (client != null) {
   3937                 // If there is a client, don't allow the process to be moved up higher
   3938                 // in the list than that client.
   3939                 int clientIndex = mLruProcesses.lastIndexOf(client);
   3940                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
   3941                         + " when updating " + app);
   3942                 if (clientIndex <= lrui) {
   3943                     // Don't allow the client index restriction to push it down farther in the
   3944                     // list than it already is.
   3945                     clientIndex = lrui;
   3946                 }
   3947                 if (clientIndex >= 0 && index > clientIndex) {
   3948                     index = clientIndex;
   3949                 }
   3950             }
   3951             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
   3952             mLruProcesses.add(index, app);
   3953             nextIndex = index-1;
   3954             mLruProcessActivityStart++;
   3955             mLruProcessServiceStart++;
   3956         }
   3957 
   3958         // If the app is currently using a content provider or service,
   3959         // bump those processes as well.
   3960         for (int j=app.connections.size()-1; j>=0; j--) {
   3961             ConnectionRecord cr = app.connections.valueAt(j);
   3962             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
   3963                     && cr.binding.service.app != null
   3964                     && cr.binding.service.app.lruSeq != mLruSeq
   3965                     && !cr.binding.service.app.persistent) {
   3966                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
   3967                         "service connection", cr, app);
   3968             }
   3969         }
   3970         for (int j=app.conProviders.size()-1; j>=0; j--) {
   3971             ContentProviderRecord cpr = app.conProviders.get(j).provider;
   3972             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
   3973                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
   3974                         "provider reference", cpr, app);
   3975             }
   3976         }
   3977     }
   3978 
   3979     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
   3980         if (uid == SYSTEM_UID) {
   3981             // The system gets to run in any process.  If there are multiple
   3982             // processes with the same uid, just pick the first (this
   3983             // should never happen).
   3984             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
   3985             if (procs == null) return null;
   3986             final int procCount = procs.size();
   3987             for (int i = 0; i < procCount; i++) {
   3988                 final int procUid = procs.keyAt(i);
   3989                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
   3990                     // Don't use an app process or different user process for system component.
   3991                     continue;
   3992                 }
   3993                 return procs.valueAt(i);
   3994             }
   3995         }
   3996         ProcessRecord proc = mProcessNames.get(processName, uid);
   3997         if (false && proc != null && !keepIfLarge
   3998                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
   3999                 && proc.lastCachedPss >= 4000) {
   4000             // Turn this condition on to cause killing to happen regularly, for testing.
   4001             if (proc.baseProcessTracker != null) {
   4002                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
   4003             }
   4004             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
   4005         } else if (proc != null && !keepIfLarge
   4006                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
   4007                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
   4008             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
   4009             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
   4010                 if (proc.baseProcessTracker != null) {
   4011                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
   4012                 }
   4013                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
   4014             }
   4015         }
   4016         return proc;
   4017     }
   4018 
   4019     void notifyPackageUse(String packageName, int reason) {
   4020         synchronized(this) {
   4021             getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
   4022         }
   4023     }
   4024 
   4025     boolean isNextTransitionForward() {
   4026         int transit = mWindowManager.getPendingAppTransition();
   4027         return transit == TRANSIT_ACTIVITY_OPEN
   4028                 || transit == TRANSIT_TASK_OPEN
   4029                 || transit == TRANSIT_TASK_TO_FRONT;
   4030     }
   4031 
   4032     boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
   4033             String processName, String abiOverride, int uid, Runnable crashHandler) {
   4034         synchronized(this) {
   4035             ApplicationInfo info = new ApplicationInfo();
   4036             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
   4037             // For isolated processes, the former contains the parent's uid and the latter the
   4038             // actual uid of the isolated process.
   4039             // In the special case introduced by this method (which is, starting an isolated
   4040             // process directly from the SystemServer without an actual parent app process) the
   4041             // closest thing to a parent's uid is SYSTEM_UID.
   4042             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
   4043             // the |isolated| logic in the ProcessRecord constructor.
   4044             info.uid = SYSTEM_UID;
   4045             info.processName = processName;
   4046             info.className = entryPoint;
   4047             info.packageName = "android";
   4048             info.seInfoUser = SELinuxUtil.COMPLETE_STR;
   4049             info.targetSdkVersion = Build.VERSION.SDK_INT;
   4050             ProcessRecord proc = startProcessLocked(processName, info /* info */,
   4051                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
   4052                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
   4053                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
   4054                     crashHandler);
   4055             return proc != null;
   4056         }
   4057     }
   4058 
   4059     @GuardedBy("this")
   4060     final ProcessRecord startProcessLocked(String processName,
   4061             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
   4062             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
   4063             boolean isolated, boolean keepIfLarge) {
   4064         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
   4065                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
   4066                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
   4067                 null /* crashHandler */);
   4068     }
   4069 
   4070     @GuardedBy("this")
   4071     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
   4072             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
   4073             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
   4074             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
   4075         long startTime = SystemClock.elapsedRealtime();
   4076         ProcessRecord app;
   4077         if (!isolated) {
   4078             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
   4079             checkTime(startTime, "startProcess: after getProcessRecord");
   4080 
   4081             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
   4082                 // If we are in the background, then check to see if this process
   4083                 // is bad.  If so, we will just silently fail.
   4084                 if (mAppErrors.isBadProcessLocked(info)) {
   4085                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
   4086                             + "/" + info.processName);
   4087                     return null;
   4088                 }
   4089             } else {
   4090                 // When the user is explicitly starting a process, then clear its
   4091                 // crash count so that we won't make it bad until they see at
   4092                 // least one crash dialog again, and make the process good again
   4093                 // if it had been bad.
   4094                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
   4095                         + "/" + info.processName);
   4096                 mAppErrors.resetProcessCrashTimeLocked(info);
   4097                 if (mAppErrors.isBadProcessLocked(info)) {
   4098                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
   4099                             UserHandle.getUserId(info.uid), info.uid,
   4100                             info.processName);
   4101                     mAppErrors.clearBadProcessLocked(info);
   4102                     if (app != null) {
   4103                         app.bad = false;
   4104                     }
   4105                 }
   4106             }
   4107         } else {
   4108             // If this is an isolated process, it can't re-use an existing process.
   4109             app = null;
   4110         }
   4111 
   4112         // We don't have to do anything more if:
   4113         // (1) There is an existing application record; and
   4114         // (2) The caller doesn't think it is dead, OR there is no thread
   4115         //     object attached to it so we know it couldn't have crashed; and
   4116         // (3) There is a pid assigned to it, so it is either starting or
   4117         //     already running.
   4118         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
   4119                 + " app=" + app + " knownToBeDead=" + knownToBeDead
   4120                 + " thread=" + (app != null ? app.thread : null)
   4121                 + " pid=" + (app != null ? app.pid : -1));
   4122         if (app != null && app.pid > 0) {
   4123             if ((!knownToBeDead && !app.killed) || app.thread == null) {
   4124                 // We already have the app running, or are waiting for it to
   4125                 // come up (we have a pid but not yet its thread), so keep it.
   4126                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
   4127                 // If this is a new package in the process, add the package to the list
   4128                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
   4129                 checkTime(startTime, "startProcess: done, added package to proc");
   4130                 return app;
   4131             }
   4132 
   4133             // An application record is attached to a previous process,
   4134             // clean it up now.
   4135             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
   4136             checkTime(startTime, "startProcess: bad proc running, killing");
   4137             killProcessGroup(app.uid, app.pid);
   4138             handleAppDiedLocked(app, true, true);
   4139             checkTime(startTime, "startProcess: done killing old proc");
   4140         }
   4141 
   4142         String hostingNameStr = hostingName != null
   4143                 ? hostingName.flattenToShortString() : null;
   4144 
   4145         if (app == null) {
   4146             checkTime(startTime, "startProcess: creating new process record");
   4147             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
   4148             if (app == null) {
   4149                 Slog.w(TAG, "Failed making new process record for "
   4150                         + processName + "/" + info.uid + " isolated=" + isolated);
   4151                 return null;
   4152             }
   4153             app.crashHandler = crashHandler;
   4154             app.isolatedEntryPoint = entryPoint;
   4155             app.isolatedEntryPointArgs = entryPointArgs;
   4156             checkTime(startTime, "startProcess: done creating new process record");
   4157         } else {
   4158             // If this is a new package in the process, add the package to the list
   4159             app.addPackage(info.packageName, info.versionCode, mProcessStats);
   4160             checkTime(startTime, "startProcess: added package to existing proc");
   4161         }
   4162 
   4163         // If the system is not ready yet, then hold off on starting this
   4164         // process until it is.
   4165         if (!mProcessesReady
   4166                 && !isAllowedWhileBooting(info)
   4167                 && !allowWhileBooting) {
   4168             if (!mProcessesOnHold.contains(app)) {
   4169                 mProcessesOnHold.add(app);
   4170             }
   4171             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
   4172                     "System not ready, putting on hold: " + app);
   4173             checkTime(startTime, "startProcess: returning with proc on hold");
   4174             return app;
   4175         }
   4176 
   4177         checkTime(startTime, "startProcess: stepping in to startProcess");
   4178         final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
   4179         checkTime(startTime, "startProcess: done starting proc!");
   4180         return success ? app : null;
   4181     }
   4182 
   4183     boolean isAllowedWhileBooting(ApplicationInfo ai) {
   4184         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
   4185     }
   4186 
   4187     @GuardedBy("this")
   4188     private final void startProcessLocked(ProcessRecord app,
   4189             String hostingType, String hostingNameStr) {
   4190         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
   4191     }
   4192 
   4193     @GuardedBy("this")
   4194     private final boolean startProcessLocked(ProcessRecord app,
   4195             String hostingType, String hostingNameStr, String abiOverride) {
   4196         return startProcessLocked(app, hostingType, hostingNameStr,
   4197                 false /* disableHiddenApiChecks */, abiOverride);
   4198     }
   4199 
   4200     /**
   4201      * @return {@code true} if process start is successful, false otherwise.
   4202      */
   4203     @GuardedBy("this")
   4204     private final boolean startProcessLocked(ProcessRecord app, String hostingType,
   4205             String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
   4206         if (app.pendingStart) {
   4207             return true;
   4208         }
   4209         long startTime = SystemClock.elapsedRealtime();
   4210         if (app.pid > 0 && app.pid != MY_PID) {
   4211             checkTime(startTime, "startProcess: removing from pids map");
   4212             synchronized (mPidsSelfLocked) {
   4213                 mPidsSelfLocked.remove(app.pid);
   4214                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   4215             }
   4216             checkTime(startTime, "startProcess: done removing from pids map");
   4217             app.setPid(0);
   4218         }
   4219 
   4220         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
   4221                 "startProcessLocked removing on hold: " + app);
   4222         mProcessesOnHold.remove(app);
   4223 
   4224         checkTime(startTime, "startProcess: starting to update cpu stats");
   4225         updateCpuStats();
   4226         checkTime(startTime, "startProcess: done updating cpu stats");
   4227 
   4228         try {
   4229             try {
   4230                 final int userId = UserHandle.getUserId(app.uid);
   4231                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
   4232             } catch (RemoteException e) {
   4233                 throw e.rethrowAsRuntimeException();
   4234             }
   4235 
   4236             int uid = app.uid;
   4237             int[] gids = null;
   4238             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
   4239             if (!app.isolated) {
   4240                 int[] permGids = null;
   4241                 try {
   4242                     checkTime(startTime, "startProcess: getting gids from package manager");
   4243                     final IPackageManager pm = AppGlobals.getPackageManager();
   4244                     permGids = pm.getPackageGids(app.info.packageName,
   4245                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
   4246                     StorageManagerInternal storageManagerInternal = LocalServices.getService(
   4247                             StorageManagerInternal.class);
   4248                     mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
   4249                             app.info.packageName);
   4250                 } catch (RemoteException e) {
   4251                     throw e.rethrowAsRuntimeException();
   4252                 }
   4253 
   4254                 /*
   4255                  * Add shared application and profile GIDs so applications can share some
   4256                  * resources like shared libraries and access user-wide resources
   4257                  */
   4258                 if (ArrayUtils.isEmpty(permGids)) {
   4259                     gids = new int[3];
   4260                 } else {
   4261                     gids = new int[permGids.length + 3];
   4262                     System.arraycopy(permGids, 0, gids, 3, permGids.length);
   4263                 }
   4264                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
   4265                 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
   4266                 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
   4267 
   4268                 // Replace any invalid GIDs
   4269                 if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
   4270                 if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
   4271             }
   4272             checkTime(startTime, "startProcess: building args");
   4273             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
   4274                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
   4275                         && mTopComponent != null
   4276                         && app.processName.equals(mTopComponent.getPackageName())) {
   4277                     uid = 0;
   4278                 }
   4279                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
   4280                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
   4281                     uid = 0;
   4282                 }
   4283             }
   4284             int runtimeFlags = 0;
   4285             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   4286                 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
   4287                 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
   4288                 // Also turn on CheckJNI for debuggable apps. It's quite
   4289                 // awkward to turn on otherwise.
   4290                 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   4291             }
   4292             // Run the app in safe mode if its manifest requests so or the
   4293             // system is booted in safe mode.
   4294             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
   4295                 mSafeMode == true) {
   4296                 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
   4297             }
   4298             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
   4299                 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   4300             }
   4301             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
   4302             if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
   4303                 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
   4304             }
   4305             String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
   4306             if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
   4307                 runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
   4308             }
   4309             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
   4310                 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
   4311             }
   4312             if ("1".equals(SystemProperties.get("debug.assert"))) {
   4313                 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
   4314             }
   4315             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
   4316                 // Enable all debug flags required by the native debugger.
   4317                 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
   4318                 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
   4319                 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
   4320                 mNativeDebuggingApp = null;
   4321             }
   4322 
   4323             if (app.info.isPrivilegedApp() &&
   4324                     DexManager.isPackageSelectedToRunOob(app.pkgList.keySet())) {
   4325                 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
   4326             }
   4327 
   4328             if (!disableHiddenApiChecks && !mHiddenApiBlacklist.isDisabled()) {
   4329                 app.info.maybeUpdateHiddenApiEnforcementPolicy(
   4330                         mHiddenApiBlacklist.getPolicyForPrePApps(),
   4331                         mHiddenApiBlacklist.getPolicyForPApps());
   4332                 @HiddenApiEnforcementPolicy int policy =
   4333                         app.info.getHiddenApiEnforcementPolicy();
   4334                 int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT);
   4335                 if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) {
   4336                     throw new IllegalStateException("Invalid API policy: " + policy);
   4337                 }
   4338                 runtimeFlags |= policyBits;
   4339             }
   4340 
   4341             String invokeWith = null;
   4342             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   4343                 // Debuggable apps may include a wrapper script with their library directory.
   4344                 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
   4345                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
   4346                 try {
   4347                     if (new File(wrapperFileName).exists()) {
   4348                         invokeWith = "/system/bin/logwrapper " + wrapperFileName;
   4349                     }
   4350                 } finally {
   4351                     StrictMode.setThreadPolicy(oldPolicy);
   4352                 }
   4353             }
   4354 
   4355             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
   4356             if (requiredAbi == null) {
   4357                 requiredAbi = Build.SUPPORTED_ABIS[0];
   4358             }
   4359 
   4360             String instructionSet = null;
   4361             if (app.info.primaryCpuAbi != null) {
   4362                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
   4363             }
   4364 
   4365             app.gids = gids;
   4366             app.requiredAbi = requiredAbi;
   4367             app.instructionSet = instructionSet;
   4368 
   4369             // the per-user SELinux context must be set
   4370             if (TextUtils.isEmpty(app.info.seInfoUser)) {
   4371                 Slog.wtf(TAG, "SELinux tag not defined",
   4372                         new IllegalStateException("SELinux tag not defined for "
   4373                         + app.info.packageName + " (uid " + app.uid + ")"));
   4374             }
   4375             final String seInfo = app.info.seInfo
   4376                     + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
   4377             // Start the process.  It will either succeed and return a result containing
   4378             // the PID of the new process, or else throw a RuntimeException.
   4379             final String entryPoint = "android.app.ActivityThread";
   4380 
   4381             return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
   4382                     runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
   4383                     startTime);
   4384         } catch (RuntimeException e) {
   4385             Slog.e(TAG, "Failure starting process " + app.processName, e);
   4386 
   4387             // Something went very wrong while trying to start this process; one
   4388             // common case is when the package is frozen due to an active
   4389             // upgrade. To recover, clean up any active bookkeeping related to
   4390             // starting this process. (We already invoked this method once when
   4391             // the package was initially frozen through KILL_APPLICATION_MSG, so
   4392             // it doesn't hurt to use it again.)
   4393             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
   4394                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
   4395             return false;
   4396         }
   4397     }
   4398 
   4399     @GuardedBy("this")
   4400     private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
   4401             ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
   4402             String seInfo, String requiredAbi, String instructionSet, String invokeWith,
   4403             long startTime) {
   4404         app.pendingStart = true;
   4405         app.killedByAm = false;
   4406         app.removed = false;
   4407         app.killed = false;
   4408         final long startSeq = app.startSeq = ++mProcStartSeqCounter;
   4409         app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
   4410         if (mConstants.FLAG_PROCESS_START_ASYNC) {
   4411             if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
   4412                     "Posting procStart msg for " + app.toShortString());
   4413             mProcStartHandler.post(() -> {
   4414                 try {
   4415                     synchronized (ActivityManagerService.this) {
   4416                         final String reason = isProcStartValidLocked(app, startSeq);
   4417                         if (reason != null) {
   4418                             Slog.w(TAG_PROCESSES, app + " not valid anymore,"
   4419                                     + " don't start process, " + reason);
   4420                             app.pendingStart = false;
   4421                             return;
   4422                         }
   4423                         app.usingWrapper = invokeWith != null
   4424                                 || SystemProperties.get("wrap." + app.processName) != null;
   4425                         mPendingStarts.put(startSeq, app);
   4426                     }
   4427                     final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
   4428                             app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
   4429                             requiredAbi, instructionSet, invokeWith, app.startTime);
   4430                     synchronized (ActivityManagerService.this) {
   4431                         handleProcessStartedLocked(app, startResult, startSeq);
   4432                     }
   4433                 } catch (RuntimeException e) {
   4434                     synchronized (ActivityManagerService.this) {
   4435                         Slog.e(TAG, "Failure starting process " + app.processName, e);
   4436                         mPendingStarts.remove(startSeq);
   4437                         app.pendingStart = false;
   4438                         forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
   4439                                 false, false, true, false, false,
   4440                                 UserHandle.getUserId(app.userId), "start failure");
   4441                     }
   4442                 }
   4443             });
   4444             return true;
   4445         } else {
   4446             try {
   4447                 final ProcessStartResult startResult = startProcess(hostingType, entryPoint, app,
   4448                         uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
   4449                         invokeWith, startTime);
   4450                 handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
   4451                         startSeq, false);
   4452             } catch (RuntimeException e) {
   4453                 Slog.e(TAG, "Failure starting process " + app.processName, e);
   4454                 app.pendingStart = false;
   4455                 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
   4456                         false, false, true, false, false,
   4457                         UserHandle.getUserId(app.userId), "start failure");
   4458             }
   4459             return app.pid > 0;
   4460         }
   4461     }
   4462 
   4463     private ProcessStartResult startProcess(String hostingType, String entryPoint,
   4464             ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
   4465             String seInfo, String requiredAbi, String instructionSet, String invokeWith,
   4466             long startTime) {
   4467         try {
   4468             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
   4469                     app.processName);
   4470             checkTime(startTime, "startProcess: asking zygote to start proc");
   4471             final ProcessStartResult startResult;
   4472             if (hostingType.equals("webview_service")) {
   4473                 startResult = startWebView(entryPoint,
   4474                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
   4475                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
   4476                         app.info.dataDir, null,
   4477                         new String[] {PROC_START_SEQ_IDENT + app.startSeq});
   4478             } else {
   4479                 startResult = Process.start(entryPoint,
   4480                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
   4481                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
   4482                         app.info.dataDir, invokeWith,
   4483                         new String[] {PROC_START_SEQ_IDENT + app.startSeq});
   4484             }
   4485             checkTime(startTime, "startProcess: returned from zygote!");
   4486             return startResult;
   4487         } finally {
   4488             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   4489         }
   4490     }
   4491 
   4492     @GuardedBy("this")
   4493     private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
   4494         StringBuilder sb = null;
   4495         if (app.killedByAm) {
   4496             if (sb == null) sb = new StringBuilder();
   4497             sb.append("killedByAm=true;");
   4498         }
   4499         if (mProcessNames.get(app.processName, app.uid) != app) {
   4500             if (sb == null) sb = new StringBuilder();
   4501             sb.append("No entry in mProcessNames;");
   4502         }
   4503         if (!app.pendingStart) {
   4504             if (sb == null) sb = new StringBuilder();
   4505             sb.append("pendingStart=false;");
   4506         }
   4507         if (app.startSeq > expectedStartSeq) {
   4508             if (sb == null) sb = new StringBuilder();
   4509             sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
   4510         }
   4511         return sb == null ? null : sb.toString();
   4512     }
   4513 
   4514     @GuardedBy("this")
   4515     private boolean handleProcessStartedLocked(ProcessRecord pending,
   4516             ProcessStartResult startResult, long expectedStartSeq) {
   4517         // Indicates that this process start has been taken care of.
   4518         if (mPendingStarts.get(expectedStartSeq) == null) {
   4519             if (pending.pid == startResult.pid) {
   4520                 pending.usingWrapper = startResult.usingWrapper;
   4521                 // TODO: Update already existing clients of usingWrapper
   4522             }
   4523             return false;
   4524         }
   4525         return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
   4526                 expectedStartSeq, false);
   4527     }
   4528 
   4529     @GuardedBy("this")
   4530     private boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
   4531             long expectedStartSeq, boolean procAttached) {
   4532         mPendingStarts.remove(expectedStartSeq);
   4533         final String reason = isProcStartValidLocked(app, expectedStartSeq);
   4534         if (reason != null) {
   4535             Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" + pid
   4536                     + ", " + reason);
   4537             app.pendingStart = false;
   4538             Process.killProcessQuiet(pid);
   4539             Process.killProcessGroup(app.uid, app.pid);
   4540             return false;
   4541         }
   4542         mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
   4543         checkTime(app.startTime, "startProcess: done updating battery stats");
   4544 
   4545         EventLog.writeEvent(EventLogTags.AM_PROC_START,
   4546                 UserHandle.getUserId(app.startUid), pid, app.startUid,
   4547                 app.processName, app.hostingType,
   4548                 app.hostingNameStr != null ? app.hostingNameStr : "");
   4549 
   4550         try {
   4551             AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
   4552                     app.seInfo, app.info.sourceDir, pid);
   4553         } catch (RemoteException ex) {
   4554             // Ignore
   4555         }
   4556 
   4557         if (app.persistent) {
   4558             Watchdog.getInstance().processStarted(app.processName, pid);
   4559         }
   4560 
   4561         checkTime(app.startTime, "startProcess: building log message");
   4562         StringBuilder buf = mStringBuilder;
   4563         buf.setLength(0);
   4564         buf.append("Start proc ");
   4565         buf.append(pid);
   4566         buf.append(':');
   4567         buf.append(app.processName);
   4568         buf.append('/');
   4569         UserHandle.formatUid(buf, app.startUid);
   4570         if (app.isolatedEntryPoint != null) {
   4571             buf.append(" [");
   4572             buf.append(app.isolatedEntryPoint);
   4573             buf.append("]");
   4574         }
   4575         buf.append(" for ");
   4576         buf.append(app.hostingType);
   4577         if (app.hostingNameStr != null) {
   4578             buf.append(" ");
   4579             buf.append(app.hostingNameStr);
   4580         }
   4581         reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
   4582         app.setPid(pid);
   4583         app.usingWrapper = usingWrapper;
   4584         app.pendingStart = false;
   4585         checkTime(app.startTime, "startProcess: starting to update pids map");
   4586         ProcessRecord oldApp;
   4587         synchronized (mPidsSelfLocked) {
   4588             oldApp = mPidsSelfLocked.get(pid);
   4589         }
   4590         // If there is already an app occupying that pid that hasn't been cleaned up
   4591         if (oldApp != null && !app.isolated) {
   4592             // Clean up anything relating to this pid first
   4593             Slog.w(TAG, "Reusing pid " + pid
   4594                     + " while app is still mapped to it");
   4595             cleanUpApplicationRecordLocked(oldApp, false, false, -1,
   4596                     true /*replacingPid*/);
   4597         }
   4598         synchronized (mPidsSelfLocked) {
   4599             this.mPidsSelfLocked.put(pid, app);
   4600             if (!procAttached) {
   4601                 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   4602                 msg.obj = app;
   4603                 mHandler.sendMessageDelayed(msg, usingWrapper
   4604                         ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
   4605             }
   4606         }
   4607         checkTime(app.startTime, "startProcess: done updating pids map");
   4608         return true;
   4609     }
   4610 
   4611     void updateUsageStats(ActivityRecord component, boolean resumed) {
   4612         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
   4613                 "updateUsageStats: comp=" + component + "res=" + resumed);
   4614         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   4615         StatsLog.write(StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED,
   4616             component.app.uid, component.realActivity.getPackageName(),
   4617             component.realActivity.getShortClassName(), resumed ?
   4618                         StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__FOREGROUND :
   4619                         StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__BACKGROUND);
   4620         if (resumed) {
   4621             if (mUsageStatsService != null) {
   4622                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
   4623                         UsageEvents.Event.MOVE_TO_FOREGROUND);
   4624 
   4625             }
   4626             synchronized (stats) {
   4627                 stats.noteActivityResumedLocked(component.app.uid);
   4628             }
   4629         } else {
   4630             if (mUsageStatsService != null) {
   4631                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
   4632                         UsageEvents.Event.MOVE_TO_BACKGROUND);
   4633             }
   4634             synchronized (stats) {
   4635                 stats.noteActivityPausedLocked(component.app.uid);
   4636             }
   4637         }
   4638     }
   4639 
   4640     Intent getHomeIntent() {
   4641         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
   4642         intent.setComponent(mTopComponent);
   4643         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
   4644         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   4645             intent.addCategory(Intent.CATEGORY_HOME);
   4646         }
   4647         return intent;
   4648     }
   4649 
   4650     boolean startHomeActivityLocked(int userId, String reason) {
   4651         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
   4652                 && mTopAction == null) {
   4653             // We are running in factory test mode, but unable to find
   4654             // the factory test app, so just sit around displaying the
   4655             // error message and don't try to start anything.
   4656             return false;
   4657         }
   4658         Intent intent = getHomeIntent();
   4659         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
   4660         if (aInfo != null) {
   4661             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
   4662             // Don't do this if the home app is currently being
   4663             // instrumented.
   4664             aInfo = new ActivityInfo(aInfo);
   4665             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
   4666             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
   4667                     aInfo.applicationInfo.uid, true);
   4668             if (app == null || app.instr == null) {
   4669                 intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
   4670                 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
   4671                 // For ANR debugging to verify if the user activity is the one that actually
   4672                 // launched.
   4673                 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
   4674                 mActivityStartController.startHomeActivity(intent, aInfo, myReason);
   4675             }
   4676         } else {
   4677             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
   4678         }
   4679 
   4680         return true;
   4681     }
   4682 
   4683     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
   4684         ActivityInfo ai = null;
   4685         ComponentName comp = intent.getComponent();
   4686         try {
   4687             if (comp != null) {
   4688                 // Factory test.
   4689                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
   4690             } else {
   4691                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
   4692                         intent,
   4693                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
   4694                         flags, userId);
   4695 
   4696                 if (info != null) {
   4697                     ai = info.activityInfo;
   4698                 }
   4699             }
   4700         } catch (RemoteException e) {
   4701             // ignore
   4702         }
   4703 
   4704         return ai;
   4705     }
   4706 
   4707     boolean getCheckedForSetup() {
   4708         return mCheckedForSetup;
   4709     }
   4710 
   4711     void setCheckedForSetup(boolean checked) {
   4712         mCheckedForSetup = checked;
   4713     }
   4714 
   4715     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
   4716         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
   4717     }
   4718 
   4719     void enforceNotIsolatedCaller(String caller) {
   4720         if (UserHandle.isIsolated(Binder.getCallingUid())) {
   4721             throw new SecurityException("Isolated process not allowed to call " + caller);
   4722         }
   4723     }
   4724 
   4725     @Override
   4726     public int getFrontActivityScreenCompatMode() {
   4727         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
   4728         synchronized (this) {
   4729             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
   4730         }
   4731     }
   4732 
   4733     @Override
   4734     public void setFrontActivityScreenCompatMode(int mode) {
   4735         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   4736                 "setFrontActivityScreenCompatMode");
   4737         synchronized (this) {
   4738             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
   4739         }
   4740     }
   4741 
   4742     @Override
   4743     public int getPackageScreenCompatMode(String packageName) {
   4744         enforceNotIsolatedCaller("getPackageScreenCompatMode");
   4745         synchronized (this) {
   4746             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
   4747         }
   4748     }
   4749 
   4750     @Override
   4751     public void setPackageScreenCompatMode(String packageName, int mode) {
   4752         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   4753                 "setPackageScreenCompatMode");
   4754         synchronized (this) {
   4755             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
   4756         }
   4757     }
   4758 
   4759     @Override
   4760     public boolean getPackageAskScreenCompat(String packageName) {
   4761         enforceNotIsolatedCaller("getPackageAskScreenCompat");
   4762         synchronized (this) {
   4763             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
   4764         }
   4765     }
   4766 
   4767     @Override
   4768     public void setPackageAskScreenCompat(String packageName, boolean ask) {
   4769         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   4770                 "setPackageAskScreenCompat");
   4771         synchronized (this) {
   4772             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
   4773         }
   4774     }
   4775 
   4776     private boolean hasUsageStatsPermission(String callingPackage) {
   4777         final int mode = mAppOpsService.noteOperation(AppOpsManager.OP_GET_USAGE_STATS,
   4778                 Binder.getCallingUid(), callingPackage);
   4779         if (mode == AppOpsManager.MODE_DEFAULT) {
   4780             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
   4781                     == PackageManager.PERMISSION_GRANTED;
   4782         }
   4783         return mode == AppOpsManager.MODE_ALLOWED;
   4784     }
   4785 
   4786     @Override
   4787     public int getPackageProcessState(String packageName, String callingPackage) {
   4788         if (!hasUsageStatsPermission(callingPackage)) {
   4789             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
   4790                     "getPackageProcessState");
   4791         }
   4792 
   4793         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
   4794         synchronized (this) {
   4795             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   4796                 final ProcessRecord proc = mLruProcesses.get(i);
   4797                 if (procState > proc.setProcState) {
   4798                     if (proc.pkgList.containsKey(packageName) ||
   4799                             (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
   4800                         procState = proc.setProcState;
   4801                     }
   4802                 }
   4803             }
   4804         }
   4805         return procState;
   4806     }
   4807 
   4808     @Override
   4809     public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
   4810             throws RemoteException {
   4811         synchronized (this) {
   4812             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
   4813             if (app == null) {
   4814                 throw new IllegalArgumentException("Unknown process: " + process);
   4815             }
   4816             if (app.thread == null) {
   4817                 throw new IllegalArgumentException("Process has no app thread");
   4818             }
   4819             if (app.trimMemoryLevel >= level) {
   4820                 throw new IllegalArgumentException(
   4821                         "Unable to set a higher trim level than current level");
   4822             }
   4823             if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
   4824                     app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
   4825                 throw new IllegalArgumentException("Unable to set a background trim level "
   4826                     + "on a foreground process");
   4827             }
   4828             app.thread.scheduleTrimMemory(level);
   4829             app.trimMemoryLevel = level;
   4830             return true;
   4831         }
   4832     }
   4833 
   4834     private void dispatchProcessesChanged() {
   4835         int N;
   4836         synchronized (this) {
   4837             N = mPendingProcessChanges.size();
   4838             if (mActiveProcessChanges.length < N) {
   4839                 mActiveProcessChanges = new ProcessChangeItem[N];
   4840             }
   4841             mPendingProcessChanges.toArray(mActiveProcessChanges);
   4842             mPendingProcessChanges.clear();
   4843             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   4844                     "*** Delivering " + N + " process changes");
   4845         }
   4846 
   4847         int i = mProcessObservers.beginBroadcast();
   4848         while (i > 0) {
   4849             i--;
   4850             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   4851             if (observer != null) {
   4852                 try {
   4853                     for (int j=0; j<N; j++) {
   4854                         ProcessChangeItem item = mActiveProcessChanges[j];
   4855                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
   4856                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   4857                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
   4858                                     + item.uid + ": " + item.foregroundActivities);
   4859                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
   4860                                     item.foregroundActivities);
   4861                         }
   4862                     }
   4863                 } catch (RemoteException e) {
   4864                 }
   4865             }
   4866         }
   4867         mProcessObservers.finishBroadcast();
   4868 
   4869         synchronized (this) {
   4870             for (int j=0; j<N; j++) {
   4871                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
   4872             }
   4873         }
   4874     }
   4875 
   4876     private void dispatchProcessDied(int pid, int uid) {
   4877         int i = mProcessObservers.beginBroadcast();
   4878         while (i > 0) {
   4879             i--;
   4880             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   4881             if (observer != null) {
   4882                 try {
   4883                     observer.onProcessDied(pid, uid);
   4884                 } catch (RemoteException e) {
   4885                 }
   4886             }
   4887         }
   4888         mProcessObservers.finishBroadcast();
   4889     }
   4890 
   4891     @VisibleForTesting
   4892     void dispatchUidsChanged() {
   4893         int N;
   4894         synchronized (this) {
   4895             N = mPendingUidChanges.size();
   4896             if (mActiveUidChanges.length < N) {
   4897                 mActiveUidChanges = new UidRecord.ChangeItem[N];
   4898             }
   4899             for (int i=0; i<N; i++) {
   4900                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
   4901                 mActiveUidChanges[i] = change;
   4902                 if (change.uidRecord != null) {
   4903                     change.uidRecord.pendingChange = null;
   4904                     change.uidRecord = null;
   4905                 }
   4906             }
   4907             mPendingUidChanges.clear();
   4908             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4909                     "*** Delivering " + N + " uid changes");
   4910         }
   4911 
   4912         mUidChangeDispatchCount += N;
   4913         int i = mUidObservers.beginBroadcast();
   4914         while (i > 0) {
   4915             i--;
   4916             dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
   4917                     (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
   4918         }
   4919         mUidObservers.finishBroadcast();
   4920 
   4921         if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
   4922             for (int j = 0; j < N; ++j) {
   4923                 final UidRecord.ChangeItem item = mActiveUidChanges[j];
   4924                 if ((item.change & UidRecord.CHANGE_GONE) != 0) {
   4925                     mValidateUids.remove(item.uid);
   4926                 } else {
   4927                     UidRecord validateUid = mValidateUids.get(item.uid);
   4928                     if (validateUid == null) {
   4929                         validateUid = new UidRecord(item.uid);
   4930                         mValidateUids.put(item.uid, validateUid);
   4931                     }
   4932                     if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
   4933                         validateUid.idle = true;
   4934                     } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
   4935                         validateUid.idle = false;
   4936                     }
   4937                     validateUid.curProcState = validateUid.setProcState = item.processState;
   4938                     validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
   4939                 }
   4940             }
   4941         }
   4942 
   4943         synchronized (this) {
   4944             for (int j = 0; j < N; j++) {
   4945                 mAvailUidChanges.add(mActiveUidChanges[j]);
   4946             }
   4947         }
   4948     }
   4949 
   4950     private void dispatchUidsChangedForObserver(IUidObserver observer,
   4951             UidObserverRegistration reg, int changesSize) {
   4952         if (observer == null) {
   4953             return;
   4954         }
   4955         try {
   4956             for (int j = 0; j < changesSize; j++) {
   4957                 UidRecord.ChangeItem item = mActiveUidChanges[j];
   4958                 final int change = item.change;
   4959                 if (change == UidRecord.CHANGE_PROCSTATE &&
   4960                         (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
   4961                     // No-op common case: no significant change, the observer is not
   4962                     // interested in all proc state changes.
   4963                     continue;
   4964                 }
   4965                 final long start = SystemClock.uptimeMillis();
   4966                 if ((change & UidRecord.CHANGE_IDLE) != 0) {
   4967                     if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
   4968                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4969                                 "UID idle uid=" + item.uid);
   4970                         observer.onUidIdle(item.uid, item.ephemeral);
   4971                     }
   4972                 } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
   4973                     if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
   4974                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4975                                 "UID active uid=" + item.uid);
   4976                         observer.onUidActive(item.uid);
   4977                     }
   4978                 }
   4979                 if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
   4980                     if ((change & UidRecord.CHANGE_CACHED) != 0) {
   4981                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4982                                 "UID cached uid=" + item.uid);
   4983                         observer.onUidCachedChanged(item.uid, true);
   4984                     } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
   4985                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4986                                 "UID active uid=" + item.uid);
   4987                         observer.onUidCachedChanged(item.uid, false);
   4988                     }
   4989                 }
   4990                 if ((change & UidRecord.CHANGE_GONE) != 0) {
   4991                     if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
   4992                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   4993                                 "UID gone uid=" + item.uid);
   4994                         observer.onUidGone(item.uid, item.ephemeral);
   4995                     }
   4996                     if (reg.lastProcStates != null) {
   4997                         reg.lastProcStates.delete(item.uid);
   4998                     }
   4999                 } else {
   5000                     if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
   5001                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   5002                                 "UID CHANGED uid=" + item.uid
   5003                                         + ": " + item.processState);
   5004                         boolean doReport = true;
   5005                         if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
   5006                             final int lastState = reg.lastProcStates.get(item.uid,
   5007                                     ActivityManager.PROCESS_STATE_UNKNOWN);
   5008                             if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
   5009                                 final boolean lastAboveCut = lastState <= reg.cutpoint;
   5010                                 final boolean newAboveCut = item.processState <= reg.cutpoint;
   5011                                 doReport = lastAboveCut != newAboveCut;
   5012                             } else {
   5013                                 doReport = item.processState
   5014                                         != ActivityManager.PROCESS_STATE_NONEXISTENT;
   5015                             }
   5016                         }
   5017                         if (doReport) {
   5018                             if (reg.lastProcStates != null) {
   5019                                 reg.lastProcStates.put(item.uid, item.processState);
   5020                             }
   5021                             observer.onUidStateChanged(item.uid, item.processState,
   5022                                     item.procStateSeq);
   5023                         }
   5024                     }
   5025                 }
   5026                 final int duration = (int) (SystemClock.uptimeMillis() - start);
   5027                 if (reg.mMaxDispatchTime < duration) {
   5028                     reg.mMaxDispatchTime = duration;
   5029                 }
   5030                 if (duration >= SLOW_UID_OBSERVER_THRESHOLD_MS) {
   5031                     reg.mSlowDispatchCount++;
   5032                 }
   5033             }
   5034         } catch (RemoteException e) {
   5035         }
   5036     }
   5037 
   5038     void dispatchOomAdjObserver(String msg) {
   5039         OomAdjObserver observer;
   5040         synchronized (this) {
   5041             observer = mCurOomAdjObserver;
   5042         }
   5043 
   5044         if (observer != null) {
   5045             observer.onOomAdjMessage(msg);
   5046         }
   5047     }
   5048 
   5049     void setOomAdjObserver(int uid, OomAdjObserver observer) {
   5050         synchronized (this) {
   5051             mCurOomAdjUid = uid;
   5052             mCurOomAdjObserver = observer;
   5053         }
   5054     }
   5055 
   5056     void clearOomAdjObserver() {
   5057         synchronized (this) {
   5058             mCurOomAdjUid = -1;
   5059             mCurOomAdjObserver = null;
   5060         }
   5061     }
   5062 
   5063     void reportOomAdjMessageLocked(String tag, String msg) {
   5064         Slog.d(tag, msg);
   5065         if (mCurOomAdjObserver != null) {
   5066             mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
   5067         }
   5068     }
   5069 
   5070     void reportUidInfoMessageLocked(String tag, String msg, int uid) {
   5071         Slog.i(TAG, msg);
   5072         if (mCurOomAdjObserver != null && uid == mCurOomAdjUid) {
   5073             mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
   5074         }
   5075 
   5076     }
   5077 
   5078     @Override
   5079     public final int startActivity(IApplicationThread caller, String callingPackage,
   5080             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   5081             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
   5082         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
   5083                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
   5084                 UserHandle.getCallingUserId());
   5085     }
   5086 
   5087     @Override
   5088     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
   5089             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   5090             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
   5091         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
   5092                 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
   5093                 true /*validateIncomingUser*/);
   5094     }
   5095 
   5096     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
   5097             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   5098             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
   5099             boolean validateIncomingUser) {
   5100         enforceNotIsolatedCaller("startActivity");
   5101 
   5102         userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
   5103                 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
   5104 
   5105         // TODO: Switch to user app stacks here.
   5106         return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
   5107                 .setCaller(caller)
   5108                 .setCallingPackage(callingPackage)
   5109                 .setResolvedType(resolvedType)
   5110                 .setResultTo(resultTo)
   5111                 .setResultWho(resultWho)
   5112                 .setRequestCode(requestCode)
   5113                 .setStartFlags(startFlags)
   5114                 .setProfilerInfo(profilerInfo)
   5115                 .setActivityOptions(bOptions)
   5116                 .setMayWait(userId)
   5117                 .execute();
   5118 
   5119     }
   5120 
   5121     @Override
   5122     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
   5123             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   5124             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
   5125             int userId) {
   5126 
   5127         // This is very dangerous -- it allows you to perform a start activity (including
   5128         // permission grants) as any app that may launch one of your own activities.  So
   5129         // we will only allow this to be done from activities that are part of the core framework,
   5130         // and then only when they are running as the system.
   5131         final ActivityRecord sourceRecord;
   5132         final int targetUid;
   5133         final String targetPackage;
   5134         final boolean isResolver;
   5135         synchronized (this) {
   5136             if (resultTo == null) {
   5137                 throw new SecurityException("Must be called from an activity");
   5138             }
   5139             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
   5140             if (sourceRecord == null) {
   5141                 throw new SecurityException("Called with bad activity token: " + resultTo);
   5142             }
   5143             if (!sourceRecord.info.packageName.equals("android")) {
   5144                 throw new SecurityException(
   5145                         "Must be called from an activity that is declared in the android package");
   5146             }
   5147             if (sourceRecord.app == null) {
   5148                 throw new SecurityException("Called without a process attached to activity");
   5149             }
   5150             if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
   5151                 // This is still okay, as long as this activity is running under the
   5152                 // uid of the original calling activity.
   5153                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
   5154                     throw new SecurityException(
   5155                             "Calling activity in uid " + sourceRecord.app.uid
   5156                                     + " must be system uid or original calling uid "
   5157                                     + sourceRecord.launchedFromUid);
   5158                 }
   5159             }
   5160             if (ignoreTargetSecurity) {
   5161                 if (intent.getComponent() == null) {
   5162                     throw new SecurityException(
   5163                             "Component must be specified with ignoreTargetSecurity");
   5164                 }
   5165                 if (intent.getSelector() != null) {
   5166                     throw new SecurityException(
   5167                             "Selector not allowed with ignoreTargetSecurity");
   5168                 }
   5169             }
   5170             targetUid = sourceRecord.launchedFromUid;
   5171             targetPackage = sourceRecord.launchedFromPackage;
   5172             isResolver = sourceRecord.isResolverOrChildActivity();
   5173         }
   5174 
   5175         if (userId == UserHandle.USER_NULL) {
   5176             userId = UserHandle.getUserId(sourceRecord.app.uid);
   5177         }
   5178 
   5179         // TODO: Switch to user app stacks here.
   5180         try {
   5181             return mActivityStartController.obtainStarter(intent, "startActivityAsCaller")
   5182                     .setCallingUid(targetUid)
   5183                     .setCallingPackage(targetPackage)
   5184                     .setResolvedType(resolvedType)
   5185                     .setResultTo(resultTo)
   5186                     .setResultWho(resultWho)
   5187                     .setRequestCode(requestCode)
   5188                     .setStartFlags(startFlags)
   5189                     .setActivityOptions(bOptions)
   5190                     .setMayWait(userId)
   5191                     .setIgnoreTargetSecurity(ignoreTargetSecurity)
   5192                     .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
   5193                     .execute();
   5194         } catch (SecurityException e) {
   5195             // XXX need to figure out how to propagate to original app.
   5196             // A SecurityException here is generally actually a fault of the original
   5197             // calling activity (such as a fairly granting permissions), so propagate it
   5198             // back to them.
   5199             /*
   5200             StringBuilder msg = new StringBuilder();
   5201             msg.append("While launching");
   5202             msg.append(intent.toString());
   5203             msg.append(": ");
   5204             msg.append(e.getMessage());
   5205             */
   5206             throw e;
   5207         }
   5208     }
   5209 
   5210     @Override
   5211     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
   5212             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   5213             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
   5214         enforceNotIsolatedCaller("startActivityAndWait");
   5215         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   5216                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
   5217         WaitResult res = new WaitResult();
   5218         // TODO: Switch to user app stacks here.
   5219         mActivityStartController.obtainStarter(intent, "startActivityAndWait")
   5220                 .setCaller(caller)
   5221                 .setCallingPackage(callingPackage)
   5222                 .setResolvedType(resolvedType)
   5223                 .setResultTo(resultTo)
   5224                 .setResultWho(resultWho)
   5225                 .setRequestCode(requestCode)
   5226                 .setStartFlags(startFlags)
   5227                 .setActivityOptions(bOptions)
   5228                 .setMayWait(userId)
   5229                 .setProfilerInfo(profilerInfo)
   5230                 .setWaitResult(res)
   5231                 .execute();
   5232         return res;
   5233     }
   5234 
   5235     @Override
   5236     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
   5237             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   5238             int startFlags, Configuration config, Bundle bOptions, int userId) {
   5239         enforceNotIsolatedCaller("startActivityWithConfig");
   5240         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   5241                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
   5242         // TODO: Switch to user app stacks here.
   5243         return mActivityStartController.obtainStarter(intent, "startActivityWithConfig")
   5244                 .setCaller(caller)
   5245                 .setCallingPackage(callingPackage)
   5246                 .setResolvedType(resolvedType)
   5247                 .setResultTo(resultTo)
   5248                 .setResultWho(resultWho)
   5249                 .setRequestCode(requestCode)
   5250                 .setStartFlags(startFlags)
   5251                 .setGlobalConfiguration(config)
   5252                 .setActivityOptions(bOptions)
   5253                 .setMayWait(userId)
   5254                 .execute();
   5255     }
   5256 
   5257     @Override
   5258     public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
   5259             IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
   5260             String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
   5261             throws TransactionTooLargeException {
   5262         enforceNotIsolatedCaller("startActivityIntentSender");
   5263         // Refuse possible leaked file descriptors
   5264         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
   5265             throw new IllegalArgumentException("File descriptors passed in Intent");
   5266         }
   5267 
   5268         if (!(target instanceof PendingIntentRecord)) {
   5269             throw new IllegalArgumentException("Bad PendingIntent object");
   5270         }
   5271 
   5272         PendingIntentRecord pir = (PendingIntentRecord)target;
   5273 
   5274         synchronized (this) {
   5275             // If this is coming from the currently resumed activity, it is
   5276             // effectively saying that app switches are allowed at this point.
   5277             final ActivityStack stack = getFocusedStack();
   5278             if (stack.mResumedActivity != null &&
   5279                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
   5280                 mAppSwitchesAllowedTime = 0;
   5281             }
   5282         }
   5283         int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
   5284                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
   5285         return ret;
   5286     }
   5287 
   5288     @Override
   5289     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
   5290             Intent intent, String resolvedType, IVoiceInteractionSession session,
   5291             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
   5292             Bundle bOptions, int userId) {
   5293         enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
   5294         if (session == null || interactor == null) {
   5295             throw new NullPointerException("null session or interactor");
   5296         }
   5297         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
   5298                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
   5299         // TODO: Switch to user app stacks here.
   5300         return mActivityStartController.obtainStarter(intent, "startVoiceActivity")
   5301                 .setCallingUid(callingUid)
   5302                 .setCallingPackage(callingPackage)
   5303                 .setResolvedType(resolvedType)
   5304                 .setVoiceSession(session)
   5305                 .setVoiceInteractor(interactor)
   5306                 .setStartFlags(startFlags)
   5307                 .setProfilerInfo(profilerInfo)
   5308                 .setActivityOptions(bOptions)
   5309                 .setMayWait(userId)
   5310                 .execute();
   5311     }
   5312 
   5313     @Override
   5314     public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
   5315             Intent intent, String resolvedType, Bundle bOptions, int userId) {
   5316         enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
   5317         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
   5318                 ALLOW_FULL_ONLY, "startAssistantActivity", null);
   5319 
   5320         return mActivityStartController.obtainStarter(intent, "startAssistantActivity")
   5321                 .setCallingUid(callingUid)
   5322                 .setCallingPackage(callingPackage)
   5323                 .setResolvedType(resolvedType)
   5324                 .setActivityOptions(bOptions)
   5325                 .setMayWait(userId)
   5326                 .execute();
   5327     }
   5328 
   5329     @Override
   5330     public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
   5331                 IRecentsAnimationRunner recentsAnimationRunner) {
   5332         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
   5333         final int callingPid = Binder.getCallingPid();
   5334         final long origId = Binder.clearCallingIdentity();
   5335         try {
   5336             synchronized (this) {
   5337                 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
   5338                 final int recentsUid = mRecentTasks.getRecentsComponentUid();
   5339 
   5340                 // Start a new recents animation
   5341                 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
   5342                         mActivityStartController, mWindowManager, mUserController, callingPid);
   5343                 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
   5344                         recentsUid, assistDataReceiver);
   5345             }
   5346         } finally {
   5347             Binder.restoreCallingIdentity(origId);
   5348         }
   5349     }
   5350 
   5351     @Override
   5352     public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
   5353         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
   5354         final long callingUid = Binder.getCallingUid();
   5355         final long origId = Binder.clearCallingIdentity();
   5356         try {
   5357             synchronized (this) {
   5358                 // Cancel the recents animation synchronously (do not hold the WM lock)
   5359                 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
   5360                         ? REORDER_MOVE_TO_ORIGINAL_POSITION
   5361                         : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
   5362             }
   5363         } finally {
   5364             Binder.restoreCallingIdentity(origId);
   5365         }
   5366     }
   5367 
   5368     @Override
   5369     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
   5370             throws RemoteException {
   5371         Slog.i(TAG, "Activity tried to startVoiceInteraction");
   5372         synchronized (this) {
   5373             ActivityRecord activity = getFocusedStack().getTopActivity();
   5374             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
   5375                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
   5376             }
   5377             if (mRunningVoice != null || activity.getTask().voiceSession != null
   5378                     || activity.voiceSession != null) {
   5379                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
   5380                 return;
   5381             }
   5382             if (activity.pendingVoiceInteractionStart) {
   5383                 Slog.w(TAG, "Pending start of voice interaction already.");
   5384                 return;
   5385             }
   5386             activity.pendingVoiceInteractionStart = true;
   5387         }
   5388         LocalServices.getService(VoiceInteractionManagerInternal.class)
   5389                 .startLocalVoiceInteraction(callingActivity, options);
   5390     }
   5391 
   5392     @Override
   5393     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
   5394         LocalServices.getService(VoiceInteractionManagerInternal.class)
   5395                 .stopLocalVoiceInteraction(callingActivity);
   5396     }
   5397 
   5398     @Override
   5399     public boolean supportsLocalVoiceInteraction() throws RemoteException {
   5400         return LocalServices.getService(VoiceInteractionManagerInternal.class)
   5401                 .supportsLocalVoiceInteraction();
   5402     }
   5403 
   5404     @GuardedBy("this")
   5405     void onLocalVoiceInteractionStartedLocked(IBinder activity,
   5406             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
   5407         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
   5408         if (activityToCallback == null) return;
   5409         activityToCallback.setVoiceSessionLocked(voiceSession);
   5410 
   5411         // Inform the activity
   5412         try {
   5413             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
   5414                     voiceInteractor);
   5415             long token = Binder.clearCallingIdentity();
   5416             try {
   5417                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
   5418             } finally {
   5419                 Binder.restoreCallingIdentity(token);
   5420             }
   5421             // TODO: VI Should we cache the activity so that it's easier to find later
   5422             // rather than scan through all the stacks and activities?
   5423         } catch (RemoteException re) {
   5424             activityToCallback.clearVoiceSessionLocked();
   5425             // TODO: VI Should this terminate the voice session?
   5426         }
   5427     }
   5428 
   5429     @Override
   5430     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
   5431         synchronized (this) {
   5432             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
   5433                 if (keepAwake) {
   5434                     mVoiceWakeLock.acquire();
   5435                 } else {
   5436                     mVoiceWakeLock.release();
   5437                 }
   5438             }
   5439         }
   5440     }
   5441 
   5442     @Override
   5443     public boolean startNextMatchingActivity(IBinder callingActivity,
   5444             Intent intent, Bundle bOptions) {
   5445         // Refuse possible leaked file descriptors
   5446         if (intent != null && intent.hasFileDescriptors() == true) {
   5447             throw new IllegalArgumentException("File descriptors passed in Intent");
   5448         }
   5449         SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
   5450 
   5451         synchronized (this) {
   5452             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
   5453             if (r == null) {
   5454                 SafeActivityOptions.abort(options);
   5455                 return false;
   5456             }
   5457             if (r.app == null || r.app.thread == null) {
   5458                 // The caller is not running...  d'oh!
   5459                 SafeActivityOptions.abort(options);
   5460                 return false;
   5461             }
   5462             intent = new Intent(intent);
   5463             // The caller is not allowed to change the data.
   5464             intent.setDataAndType(r.intent.getData(), r.intent.getType());
   5465             // And we are resetting to find the next component...
   5466             intent.setComponent(null);
   5467 
   5468             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
   5469 
   5470             ActivityInfo aInfo = null;
   5471             try {
   5472                 List<ResolveInfo> resolves =
   5473                     AppGlobals.getPackageManager().queryIntentActivities(
   5474                             intent, r.resolvedType,
   5475                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
   5476                             UserHandle.getCallingUserId()).getList();
   5477 
   5478                 // Look for the original activity in the list...
   5479                 final int N = resolves != null ? resolves.size() : 0;
   5480                 for (int i=0; i<N; i++) {
   5481                     ResolveInfo rInfo = resolves.get(i);
   5482                     if (rInfo.activityInfo.packageName.equals(r.packageName)
   5483                             && rInfo.activityInfo.name.equals(r.info.name)) {
   5484                         // We found the current one...  the next matching is
   5485                         // after it.
   5486                         i++;
   5487                         if (i<N) {
   5488                             aInfo = resolves.get(i).activityInfo;
   5489                         }
   5490                         if (debug) {
   5491                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
   5492                                     + "/" + r.info.name);
   5493                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
   5494                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
   5495                         }
   5496                         break;
   5497                     }
   5498                 }
   5499             } catch (RemoteException e) {
   5500             }
   5501 
   5502             if (aInfo == null) {
   5503                 // Nobody who is next!
   5504                 SafeActivityOptions.abort(options);
   5505                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
   5506                 return false;
   5507             }
   5508 
   5509             intent.setComponent(new ComponentName(
   5510                     aInfo.applicationInfo.packageName, aInfo.name));
   5511             intent.setFlags(intent.getFlags()&~(
   5512                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
   5513                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
   5514                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
   5515                     FLAG_ACTIVITY_NEW_TASK));
   5516 
   5517             // Okay now we need to start the new activity, replacing the
   5518             // currently running activity.  This is a little tricky because
   5519             // we want to start the new one as if the current one is finished,
   5520             // but not finish the current one first so that there is no flicker.
   5521             // And thus...
   5522             final boolean wasFinishing = r.finishing;
   5523             r.finishing = true;
   5524 
   5525             // Propagate reply information over to the new activity.
   5526             final ActivityRecord resultTo = r.resultTo;
   5527             final String resultWho = r.resultWho;
   5528             final int requestCode = r.requestCode;
   5529             r.resultTo = null;
   5530             if (resultTo != null) {
   5531                 resultTo.removeResultsLocked(r, resultWho, requestCode);
   5532             }
   5533 
   5534             final long origId = Binder.clearCallingIdentity();
   5535             // TODO(b/64750076): Check if calling pid should really be -1.
   5536             final int res = mActivityStartController
   5537                     .obtainStarter(intent, "startNextMatchingActivity")
   5538                     .setCaller(r.app.thread)
   5539                     .setResolvedType(r.resolvedType)
   5540                     .setActivityInfo(aInfo)
   5541                     .setResultTo(resultTo != null ? resultTo.appToken : null)
   5542                     .setResultWho(resultWho)
   5543                     .setRequestCode(requestCode)
   5544                     .setCallingPid(-1)
   5545                     .setCallingUid(r.launchedFromUid)
   5546                     .setCallingPackage(r.launchedFromPackage)
   5547                     .setRealCallingPid(-1)
   5548                     .setRealCallingUid(r.launchedFromUid)
   5549                     .setActivityOptions(options)
   5550                     .execute();
   5551             Binder.restoreCallingIdentity(origId);
   5552 
   5553             r.finishing = wasFinishing;
   5554             if (res != ActivityManager.START_SUCCESS) {
   5555                 return false;
   5556             }
   5557             return true;
   5558         }
   5559     }
   5560 
   5561     @Override
   5562     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
   5563         enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
   5564                 "startActivityFromRecents()");
   5565 
   5566         final int callingPid = Binder.getCallingPid();
   5567         final int callingUid = Binder.getCallingUid();
   5568         final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
   5569         final long origId = Binder.clearCallingIdentity();
   5570         try {
   5571             synchronized (this) {
   5572                 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
   5573                         safeOptions);
   5574             }
   5575         } finally {
   5576             Binder.restoreCallingIdentity(origId);
   5577         }
   5578     }
   5579 
   5580     @Override
   5581     public final int startActivities(IApplicationThread caller, String callingPackage,
   5582             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
   5583             int userId) {
   5584         final String reason = "startActivities";
   5585         enforceNotIsolatedCaller(reason);
   5586         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   5587                 userId, false, ALLOW_FULL_ONLY, reason, null);
   5588         // TODO: Switch to user app stacks here.
   5589         int ret = mActivityStartController.startActivities(caller, -1, callingPackage,
   5590                 intents, resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId,
   5591                 reason);
   5592         return ret;
   5593     }
   5594 
   5595     @Override
   5596     public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
   5597         synchronized (this) {
   5598             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   5599             if (r == null) {
   5600                 return;
   5601             }
   5602             r.reportFullyDrawnLocked(restoredFromBundle);
   5603         }
   5604     }
   5605 
   5606     @Override
   5607     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
   5608         synchronized (this) {
   5609             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   5610             if (r == null) {
   5611                 return;
   5612             }
   5613             final long origId = Binder.clearCallingIdentity();
   5614             try {
   5615                 r.setRequestedOrientation(requestedOrientation);
   5616             } finally {
   5617                 Binder.restoreCallingIdentity(origId);
   5618             }
   5619         }
   5620     }
   5621 
   5622     @Override
   5623     public int getRequestedOrientation(IBinder token) {
   5624         synchronized (this) {
   5625             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   5626             if (r == null) {
   5627                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
   5628             }
   5629             return r.getRequestedOrientation();
   5630         }
   5631     }
   5632 
   5633     /**
   5634      * This is the internal entry point for handling Activity.finish().
   5635      *
   5636      * @param token The Binder token referencing the Activity we want to finish.
   5637      * @param resultCode Result code, if any, from this Activity.
   5638      * @param resultData Result data (Intent), if any, from this Activity.
   5639      * @param finishTask Whether to finish the task associated with this Activity.
   5640      *
   5641      * @return Returns true if the activity successfully finished, or false if it is still running.
   5642      */
   5643     @Override
   5644     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
   5645             int finishTask) {
   5646         // Refuse possible leaked file descriptors
   5647         if (resultData != null && resultData.hasFileDescriptors() == true) {
   5648             throw new IllegalArgumentException("File descriptors passed in Intent");
   5649         }
   5650 
   5651         synchronized(this) {
   5652             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   5653             if (r == null) {
   5654                 return true;
   5655             }
   5656             // Keep track of the root activity of the task before we finish it
   5657             TaskRecord tr = r.getTask();
   5658             ActivityRecord rootR = tr.getRootActivity();
   5659             if (rootR == null) {
   5660                 Slog.w(TAG, "Finishing task with all activities already finished");
   5661             }
   5662             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
   5663             // finish.
   5664             if (mLockTaskController.activityBlockedFromFinish(r)) {
   5665                 return false;
   5666             }
   5667 
   5668             if (mController != null) {
   5669                 // Find the first activity that is not finishing.
   5670                 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
   5671                 if (next != null) {
   5672                     // ask watcher if this is allowed
   5673                     boolean resumeOK = true;
   5674                     try {
   5675                         resumeOK = mController.activityResuming(next.packageName);
   5676                     } catch (RemoteException e) {
   5677                         mController = null;
   5678                         Watchdog.getInstance().setActivityController(null);
   5679                     }
   5680 
   5681                     if (!resumeOK) {
   5682                         Slog.i(TAG, "Not finishing activity because controller resumed");
   5683                         return false;
   5684                     }
   5685                 }
   5686             }
   5687             final long origId = Binder.clearCallingIdentity();
   5688             try {
   5689                 boolean res;
   5690                 final boolean finishWithRootActivity =
   5691                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
   5692                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
   5693                         || (finishWithRootActivity && r == rootR)) {
   5694                     // If requested, remove the task that is associated to this activity only if it
   5695                     // was the root activity in the task. The result code and data is ignored
   5696                     // because we don't support returning them across task boundaries. Also, to
   5697                     // keep backwards compatibility we remove the task from recents when finishing
   5698                     // task with root activity.
   5699                     res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
   5700                             finishWithRootActivity, "finish-activity");
   5701                     if (!res) {
   5702                         Slog.i(TAG, "Removing task failed to finish activity");
   5703                     }
   5704                 } else {
   5705                     res = tr.getStack().requestFinishActivityLocked(token, resultCode,
   5706                             resultData, "app-request", true);
   5707                     if (!res) {
   5708                         Slog.i(TAG, "Failed to finish by app-request");
   5709                     }
   5710                 }
   5711                 return res;
   5712             } finally {
   5713                 Binder.restoreCallingIdentity(origId);
   5714             }
   5715         }
   5716     }
   5717 
   5718     @Override
   5719     public final void finishHeavyWeightApp() {
   5720         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   5721                 != PackageManager.PERMISSION_GRANTED) {
   5722             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
   5723                     + Binder.getCallingPid()
   5724                     + ", uid=" + Binder.getCallingUid()
   5725                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   5726             Slog.w(TAG, msg);
   5727             throw new SecurityException(msg);
   5728         }
   5729 
   5730         synchronized(this) {
   5731             final ProcessRecord proc = mHeavyWeightProcess;
   5732             if (proc == null) {
   5733                 return;
   5734             }
   5735 
   5736             ArrayList<ActivityRecord> activities = new ArrayList<>(proc.activities);
   5737             for (int i = 0; i < activities.size(); i++) {
   5738                 ActivityRecord r = activities.get(i);
   5739                 if (!r.finishing && r.isInStackLocked()) {
   5740                     r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
   5741                             null, "finish-heavy", true);
   5742                 }
   5743             }
   5744 
   5745             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   5746                     proc.userId, 0));
   5747             mHeavyWeightProcess = null;
   5748         }
   5749     }
   5750 
   5751     @Override
   5752     public void crashApplication(int uid, int initialPid, String packageName, int userId,
   5753             String message) {
   5754         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   5755                 != PackageManager.PERMISSION_GRANTED) {
   5756             String msg = "Permission Denial: crashApplication() from pid="
   5757                     + Binder.getCallingPid()
   5758                     + ", uid=" + Binder.getCallingUid()
   5759                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   5760             Slog.w(TAG, msg);
   5761             throw new SecurityException(msg);
   5762         }
   5763 
   5764         synchronized(this) {
   5765             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
   5766         }
   5767     }
   5768 
   5769     @Override
   5770     public final void finishSubActivity(IBinder token, String resultWho,
   5771             int requestCode) {
   5772         synchronized(this) {
   5773             final long origId = Binder.clearCallingIdentity();
   5774             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   5775             if (r != null) {
   5776                 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
   5777             }
   5778             Binder.restoreCallingIdentity(origId);
   5779         }
   5780     }
   5781 
   5782     @Override
   5783     public boolean finishActivityAffinity(IBinder token) {
   5784         synchronized(this) {
   5785             final long origId = Binder.clearCallingIdentity();
   5786             try {
   5787                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
   5788                 if (r == null) {
   5789                     return false;
   5790                 }
   5791 
   5792                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
   5793                 // can finish.
   5794                 final TaskRecord task = r.getTask();
   5795                 if (mLockTaskController.activityBlockedFromFinish(r)) {
   5796                     return false;
   5797                 }
   5798                 return task.getStack().finishActivityAffinityLocked(r);
   5799             } finally {
   5800                 Binder.restoreCallingIdentity(origId);
   5801             }
   5802         }
   5803     }
   5804 
   5805     @Override
   5806     public void finishVoiceTask(IVoiceInteractionSession session) {
   5807         synchronized (this) {
   5808             final long origId = Binder.clearCallingIdentity();
   5809             try {
   5810                 // TODO: VI Consider treating local voice interactions and voice tasks
   5811                 // differently here
   5812                 mStackSupervisor.finishVoiceTask(session);
   5813             } finally {
   5814                 Binder.restoreCallingIdentity(origId);
   5815             }
   5816         }
   5817 
   5818     }
   5819 
   5820     @Override
   5821     public boolean releaseActivityInstance(IBinder token) {
   5822         synchronized(this) {
   5823             final long origId = Binder.clearCallingIdentity();
   5824             try {
   5825                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
   5826                 if (r == null) {
   5827                     return false;
   5828                 }
   5829                 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
   5830             } finally {
   5831                 Binder.restoreCallingIdentity(origId);
   5832             }
   5833         }
   5834     }
   5835 
   5836     @Override
   5837     public void releaseSomeActivities(IApplicationThread appInt) {
   5838         synchronized(this) {
   5839             final long origId = Binder.clearCallingIdentity();
   5840             try {
   5841                 ProcessRecord app = getRecordForAppLocked(appInt);
   5842                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
   5843             } finally {
   5844                 Binder.restoreCallingIdentity(origId);
   5845             }
   5846         }
   5847     }
   5848 
   5849     @Override
   5850     public boolean willActivityBeVisible(IBinder token) {
   5851         synchronized(this) {
   5852             ActivityStack stack = ActivityRecord.getStackLocked(token);
   5853             if (stack != null) {
   5854                 return stack.willActivityBeVisibleLocked(token);
   5855             }
   5856             return false;
   5857         }
   5858     }
   5859 
   5860     @Override
   5861     public void overridePendingTransition(IBinder token, String packageName,
   5862             int enterAnim, int exitAnim) {
   5863         synchronized(this) {
   5864             ActivityRecord self = ActivityRecord.isInStackLocked(token);
   5865             if (self == null) {
   5866                 return;
   5867             }
   5868 
   5869             final long origId = Binder.clearCallingIdentity();
   5870 
   5871             if (self.isState(ActivityState.RESUMED, ActivityState.PAUSING)) {
   5872                 mWindowManager.overridePendingAppTransition(packageName,
   5873                         enterAnim, exitAnim, null);
   5874             }
   5875 
   5876             Binder.restoreCallingIdentity(origId);
   5877         }
   5878     }
   5879 
   5880     /**
   5881      * Main function for removing an existing process from the activity manager
   5882      * as a result of that process going away.  Clears out all connections
   5883      * to the process.
   5884      */
   5885     @GuardedBy("this")
   5886     private final void handleAppDiedLocked(ProcessRecord app,
   5887             boolean restarting, boolean allowRestart) {
   5888         int pid = app.pid;
   5889         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
   5890                 false /*replacingPid*/);
   5891         if (!kept && !restarting) {
   5892             removeLruProcessLocked(app);
   5893             if (pid > 0) {
   5894                 ProcessList.remove(pid);
   5895             }
   5896         }
   5897 
   5898         if (mProfileProc == app) {
   5899             clearProfilerLocked();
   5900         }
   5901 
   5902         // Remove this application's activities from active lists.
   5903         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
   5904 
   5905         app.clearRecentTasks();
   5906 
   5907         app.activities.clear();
   5908 
   5909         if (app.instr != null) {
   5910             Slog.w(TAG, "Crash of app " + app.processName
   5911                   + " running instrumentation " + app.instr.mClass);
   5912             Bundle info = new Bundle();
   5913             info.putString("shortMsg", "Process crashed.");
   5914             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
   5915         }
   5916 
   5917         mWindowManager.deferSurfaceLayout();
   5918         try {
   5919             if (!restarting && hasVisibleActivities
   5920                     && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
   5921                 // If there was nothing to resume, and we are not already restarting this process, but
   5922                 // there is a visible activity that is hosted by the process...  then make sure all
   5923                 // visible activities are running, taking care of restarting this process.
   5924                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   5925             }
   5926         } finally {
   5927             mWindowManager.continueSurfaceLayout();
   5928         }
   5929     }
   5930 
   5931     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
   5932         final IBinder threadBinder = thread.asBinder();
   5933         // Find the application record.
   5934         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   5935             final ProcessRecord rec = mLruProcesses.get(i);
   5936             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
   5937                 return i;
   5938             }
   5939         }
   5940         return -1;
   5941     }
   5942 
   5943     ProcessRecord getRecordForAppLocked(IApplicationThread thread) {
   5944         if (thread == null) {
   5945             return null;
   5946         }
   5947 
   5948         int appIndex = getLRURecordIndexForAppLocked(thread);
   5949         if (appIndex >= 0) {
   5950             return mLruProcesses.get(appIndex);
   5951         }
   5952 
   5953         // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
   5954         // double-check that.
   5955         final IBinder threadBinder = thread.asBinder();
   5956         final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
   5957         for (int i = pmap.size()-1; i >= 0; i--) {
   5958             final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
   5959             for (int j = procs.size()-1; j >= 0; j--) {
   5960                 final ProcessRecord proc = procs.valueAt(j);
   5961                 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
   5962                     Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
   5963                             + proc);
   5964                     return proc;
   5965                 }
   5966             }
   5967         }
   5968 
   5969         return null;
   5970     }
   5971 
   5972     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
   5973         // If there are no longer any background processes running,
   5974         // and the app that died was not running instrumentation,
   5975         // then tell everyone we are now low on memory.
   5976         boolean haveBg = false;
   5977         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   5978             ProcessRecord rec = mLruProcesses.get(i);
   5979             if (rec.thread != null
   5980                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   5981                 haveBg = true;
   5982                 break;
   5983             }
   5984         }
   5985 
   5986         if (!haveBg) {
   5987             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   5988             if (doReport) {
   5989                 long now = SystemClock.uptimeMillis();
   5990                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
   5991                     doReport = false;
   5992                 } else {
   5993                     mLastMemUsageReportTime = now;
   5994                 }
   5995             }
   5996             final ArrayList<ProcessMemInfo> memInfos
   5997                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
   5998             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
   5999             long now = SystemClock.uptimeMillis();
   6000             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   6001                 ProcessRecord rec = mLruProcesses.get(i);
   6002                 if (rec == dyingProc || rec.thread == null) {
   6003                     continue;
   6004                 }
   6005                 if (doReport) {
   6006                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
   6007                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
   6008                 }
   6009                 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
   6010                     // The low memory report is overriding any current
   6011                     // state for a GC request.  Make sure to do
   6012                     // heavy/important/visible/foreground processes first.
   6013                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   6014                         rec.lastRequestedGc = 0;
   6015                     } else {
   6016                         rec.lastRequestedGc = rec.lastLowMemory;
   6017                     }
   6018                     rec.reportLowMemory = true;
   6019                     rec.lastLowMemory = now;
   6020                     mProcessesToGc.remove(rec);
   6021                     addProcessToGcListLocked(rec);
   6022                 }
   6023             }
   6024             if (doReport) {
   6025                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
   6026                 mHandler.sendMessage(msg);
   6027             }
   6028             scheduleAppGcsLocked();
   6029         }
   6030     }
   6031 
   6032     @GuardedBy("this")
   6033     final void appDiedLocked(ProcessRecord app) {
   6034        appDiedLocked(app, app.pid, app.thread, false);
   6035     }
   6036 
   6037     @GuardedBy("this")
   6038     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
   6039             boolean fromBinderDied) {
   6040         // First check if this ProcessRecord is actually active for the pid.
   6041         synchronized (mPidsSelfLocked) {
   6042             ProcessRecord curProc = mPidsSelfLocked.get(pid);
   6043             if (curProc != app) {
   6044                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
   6045                 return;
   6046             }
   6047         }
   6048 
   6049         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   6050         synchronized (stats) {
   6051             stats.noteProcessDiedLocked(app.info.uid, pid);
   6052         }
   6053 
   6054         if (!app.killed) {
   6055             if (!fromBinderDied) {
   6056                 killProcessQuiet(pid);
   6057             }
   6058             killProcessGroup(app.uid, pid);
   6059             app.killed = true;
   6060         }
   6061 
   6062         // Clean up already done if the process has been re-started.
   6063         if (app.pid == pid && app.thread != null &&
   6064                 app.thread.asBinder() == thread.asBinder()) {
   6065             boolean doLowMem = app.instr == null;
   6066             boolean doOomAdj = doLowMem;
   6067             if (!app.killedByAm) {
   6068                 reportUidInfoMessageLocked(TAG,
   6069                         "Process " + app.processName + " (pid " + pid + ") has died: "
   6070                                 + ProcessList.makeOomAdjString(app.setAdj)
   6071                                 + ProcessList.makeProcStateString(app.setProcState), app.info.uid);
   6072                 mAllowLowerMemLevel = true;
   6073             } else {
   6074                 // Note that we always want to do oom adj to update our state with the
   6075                 // new number of procs.
   6076                 mAllowLowerMemLevel = false;
   6077                 doLowMem = false;
   6078             }
   6079             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
   6080                     app.setAdj, app.setProcState);
   6081             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
   6082                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
   6083             handleAppDiedLocked(app, false, true);
   6084 
   6085             if (doOomAdj) {
   6086                 updateOomAdjLocked();
   6087             }
   6088             if (doLowMem) {
   6089                 doLowMemReportIfNeededLocked(app);
   6090             }
   6091         } else if (app.pid != pid) {
   6092             // A new process has already been started.
   6093             reportUidInfoMessageLocked(TAG,
   6094                     "Process " + app.processName + " (pid " + pid
   6095                             + ") has died and restarted (pid " + app.pid + ").", app.info.uid);
   6096             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   6097         } else if (DEBUG_PROCESSES) {
   6098             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
   6099                     + thread.asBinder());
   6100         }
   6101 
   6102         // On the device which doesn't have Cgroup, log LmkStateChanged which is used as a signal
   6103         // for pulling memory stats of other running processes when this process died.
   6104         if (!hasMemcg()) {
   6105             StatsLog.write(StatsLog.APP_DIED, SystemClock.elapsedRealtime());
   6106         }
   6107     }
   6108 
   6109     /**
   6110      * If a stack trace dump file is configured, dump process stack traces.
   6111      * @param clearTraces causes the dump file to be erased prior to the new
   6112      *    traces being written, if true; when false, the new traces will be
   6113      *    appended to any existing file content.
   6114      * @param firstPids of dalvik VM processes to dump stack traces for first
   6115      * @param lastPids of dalvik VM processes to dump stack traces for last
   6116      * @param nativePids optional list of native pids to dump stack crawls
   6117      */
   6118     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
   6119             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
   6120             ArrayList<Integer> nativePids) {
   6121         ArrayList<Integer> extraPids = null;
   6122 
   6123         // Measure CPU usage as soon as we're called in order to get a realistic sampling
   6124         // of the top users at the time of the request.
   6125         if (processCpuTracker != null) {
   6126             processCpuTracker.init();
   6127             try {
   6128                 Thread.sleep(200);
   6129             } catch (InterruptedException ignored) {
   6130             }
   6131 
   6132             processCpuTracker.update();
   6133 
   6134             // We'll take the stack crawls of just the top apps using CPU.
   6135             final int N = processCpuTracker.countWorkingStats();
   6136             extraPids = new ArrayList<>();
   6137             for (int i = 0; i < N && extraPids.size() < 5; i++) {
   6138                 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
   6139                 if (lastPids.indexOfKey(stats.pid) >= 0) {
   6140                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
   6141 
   6142                     extraPids.add(stats.pid);
   6143                 } else if (DEBUG_ANR) {
   6144                     Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
   6145                             + stats.pid);
   6146                 }
   6147             }
   6148         }
   6149 
   6150         boolean useTombstonedForJavaTraces = false;
   6151         File tracesFile;
   6152 
   6153         final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
   6154         if (tracesDirProp.isEmpty()) {
   6155             // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
   6156             // dumping scheme. All traces are written to a global trace file (usually
   6157             // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
   6158             // the file if requested.
   6159             //
   6160             // This mode of operation will be removed in the near future.
   6161 
   6162 
   6163             String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   6164             if (globalTracesPath.isEmpty()) {
   6165                 Slog.w(TAG, "dumpStackTraces: no trace path configured");
   6166                 return null;
   6167             }
   6168 
   6169             tracesFile = new File(globalTracesPath);
   6170             try {
   6171                 if (clearTraces && tracesFile.exists()) {
   6172                     tracesFile.delete();
   6173                 }
   6174 
   6175                 tracesFile.createNewFile();
   6176                 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
   6177             } catch (IOException e) {
   6178                 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
   6179                 return null;
   6180             }
   6181         } else {
   6182             File tracesDir = new File(tracesDirProp);
   6183             // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
   6184             // Each set of ANR traces is written to a separate file and dumpstate will process
   6185             // all such files and add them to a captured bug report if they're recent enough.
   6186             maybePruneOldTraces(tracesDir);
   6187 
   6188             // NOTE: We should consider creating the file in native code atomically once we've
   6189             // gotten rid of the old scheme of dumping and lot of the code that deals with paths
   6190             // can be removed.
   6191             tracesFile = createAnrDumpFile(tracesDir);
   6192             if (tracesFile == null) {
   6193                 return null;
   6194             }
   6195 
   6196             useTombstonedForJavaTraces = true;
   6197         }
   6198 
   6199         dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
   6200                 useTombstonedForJavaTraces);
   6201         return tracesFile;
   6202     }
   6203 
   6204     @GuardedBy("ActivityManagerService.class")
   6205     private static SimpleDateFormat sAnrFileDateFormat;
   6206 
   6207     private static synchronized File createAnrDumpFile(File tracesDir) {
   6208         if (sAnrFileDateFormat == null) {
   6209             sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
   6210         }
   6211 
   6212         final String formattedDate = sAnrFileDateFormat.format(new Date());
   6213         final File anrFile = new File(tracesDir, "anr_" + formattedDate);
   6214 
   6215         try {
   6216             if (anrFile.createNewFile()) {
   6217                 FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
   6218                 return anrFile;
   6219             } else {
   6220                 Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
   6221             }
   6222         } catch (IOException ioe) {
   6223             Slog.w(TAG, "Exception creating ANR dump file:", ioe);
   6224         }
   6225 
   6226         return null;
   6227     }
   6228 
   6229     /**
   6230      * Prune all trace files that are more than a day old.
   6231      *
   6232      * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
   6233      * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
   6234      * since it's the system_server that creates trace files for most ANRs.
   6235      */
   6236     private static void maybePruneOldTraces(File tracesDir) {
   6237         final long now = System.currentTimeMillis();
   6238         final File[] traceFiles = tracesDir.listFiles();
   6239 
   6240         if (traceFiles != null) {
   6241             for (File file : traceFiles) {
   6242                 if ((now - file.lastModified()) > DAY_IN_MILLIS)  {
   6243                     if (!file.delete()) {
   6244                         Slog.w(TAG, "Unable to prune stale trace file: " + file);
   6245                     }
   6246                 }
   6247             }
   6248         }
   6249     }
   6250 
   6251     /**
   6252      * Legacy code, do not use. Existing users will be deleted.
   6253      *
   6254      * @deprecated
   6255      */
   6256     @Deprecated
   6257     public static class DumpStackFileObserver extends FileObserver {
   6258         // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
   6259         private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
   6260 
   6261         private final String mTracesPath;
   6262         private boolean mClosed;
   6263 
   6264         public DumpStackFileObserver(String tracesPath) {
   6265             super(tracesPath, FileObserver.CLOSE_WRITE);
   6266             mTracesPath = tracesPath;
   6267         }
   6268 
   6269         @Override
   6270         public synchronized void onEvent(int event, String path) {
   6271             mClosed = true;
   6272             notify();
   6273         }
   6274 
   6275         public long dumpWithTimeout(int pid, long timeout) {
   6276             sendSignal(pid, SIGNAL_QUIT);
   6277             final long start = SystemClock.elapsedRealtime();
   6278 
   6279             final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
   6280             synchronized (this) {
   6281                 try {
   6282                     wait(waitTime); // Wait for traces file to be closed.
   6283                 } catch (InterruptedException e) {
   6284                     Slog.wtf(TAG, e);
   6285                 }
   6286             }
   6287 
   6288             // This avoids a corner case of passing a negative time to the native
   6289             // trace in case we've already hit the overall timeout.
   6290             final long timeWaited = SystemClock.elapsedRealtime() - start;
   6291             if (timeWaited >= timeout) {
   6292                 return timeWaited;
   6293             }
   6294 
   6295             if (!mClosed) {
   6296                 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
   6297                        ". Attempting native stack collection.");
   6298 
   6299                 final long nativeDumpTimeoutMs = Math.min(
   6300                         NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
   6301 
   6302                 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
   6303                         (int) (nativeDumpTimeoutMs / 1000));
   6304             }
   6305 
   6306             final long end = SystemClock.elapsedRealtime();
   6307             mClosed = false;
   6308 
   6309             return (end - start);
   6310         }
   6311     }
   6312 
   6313     /**
   6314      * Dump java traces for process {@code pid} to the specified file. If java trace dumping
   6315      * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
   6316      * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
   6317      * attempting to obtain native traces in the case of a failure. Returns the total time spent
   6318      * capturing traces.
   6319      */
   6320     private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
   6321         final long timeStart = SystemClock.elapsedRealtime();
   6322         if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
   6323             Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
   6324                     (NATIVE_DUMP_TIMEOUT_MS / 1000));
   6325         }
   6326 
   6327         return SystemClock.elapsedRealtime() - timeStart;
   6328     }
   6329 
   6330     private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
   6331             ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
   6332             boolean useTombstonedForJavaTraces) {
   6333 
   6334         // We don't need any sort of inotify based monitoring when we're dumping traces via
   6335         // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
   6336         // control of all writes to the file in question.
   6337         final DumpStackFileObserver observer;
   6338         if (useTombstonedForJavaTraces) {
   6339             observer = null;
   6340         } else {
   6341             // Use a FileObserver to detect when traces finish writing.
   6342             // The order of traces is considered important to maintain for legibility.
   6343             observer = new DumpStackFileObserver(tracesFile);
   6344         }
   6345 
   6346         // We must complete all stack dumps within 20 seconds.
   6347         long remainingTime = 20 * 1000;
   6348         try {
   6349             if (observer != null) {
   6350                 observer.startWatching();
   6351             }
   6352 
   6353             // First collect all of the stacks of the most important pids.
   6354             if (firstPids != null) {
   6355                 int num = firstPids.size();
   6356                 for (int i = 0; i < num; i++) {
   6357                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
   6358                             + firstPids.get(i));
   6359                     final long timeTaken;
   6360                     if (useTombstonedForJavaTraces) {
   6361                         timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
   6362                     } else {
   6363                         timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
   6364                     }
   6365 
   6366                     remainingTime -= timeTaken;
   6367                     if (remainingTime <= 0) {
   6368                         Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
   6369                             "); deadline exceeded.");
   6370                         return;
   6371                     }
   6372 
   6373                     if (DEBUG_ANR) {
   6374                         Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
   6375                     }
   6376                 }
   6377             }
   6378 
   6379             // Next collect the stacks of the native pids
   6380             if (nativePids != null) {
   6381                 for (int pid : nativePids) {
   6382                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
   6383                     final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
   6384 
   6385                     final long start = SystemClock.elapsedRealtime();
   6386                     Debug.dumpNativeBacktraceToFileTimeout(
   6387                             pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
   6388                     final long timeTaken = SystemClock.elapsedRealtime() - start;
   6389 
   6390                     remainingTime -= timeTaken;
   6391                     if (remainingTime <= 0) {
   6392                         Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
   6393                             "); deadline exceeded.");
   6394                         return;
   6395                     }
   6396 
   6397                     if (DEBUG_ANR) {
   6398                         Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
   6399                     }
   6400                 }
   6401             }
   6402 
   6403             // Lastly, dump stacks for all extra PIDs from the CPU tracker.
   6404             if (extraPids != null) {
   6405                 for (int pid : extraPids) {
   6406                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
   6407 
   6408                     final long timeTaken;
   6409                     if (useTombstonedForJavaTraces) {
   6410                         timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
   6411                     } else {
   6412                         timeTaken = observer.dumpWithTimeout(pid, remainingTime);
   6413                     }
   6414 
   6415                     remainingTime -= timeTaken;
   6416                     if (remainingTime <= 0) {
   6417                         Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
   6418                                 "); deadline exceeded.");
   6419                         return;
   6420                     }
   6421 
   6422                     if (DEBUG_ANR) {
   6423                         Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
   6424                     }
   6425                 }
   6426             }
   6427         } finally {
   6428             if (observer != null) {
   6429                 observer.stopWatching();
   6430             }
   6431         }
   6432     }
   6433 
   6434     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
   6435         if (true || Build.IS_USER) {
   6436             return;
   6437         }
   6438         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   6439         if (tracesPath == null || tracesPath.length() == 0) {
   6440             return;
   6441         }
   6442 
   6443         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
   6444         StrictMode.allowThreadDiskWrites();
   6445         try {
   6446             final File tracesFile = new File(tracesPath);
   6447             final File tracesDir = tracesFile.getParentFile();
   6448             final File tracesTmp = new File(tracesDir, "__tmp__");
   6449             try {
   6450                 if (tracesFile.exists()) {
   6451                     tracesTmp.delete();
   6452                     tracesFile.renameTo(tracesTmp);
   6453                 }
   6454                 StringBuilder sb = new StringBuilder();
   6455                 Time tobj = new Time();
   6456                 tobj.set(System.currentTimeMillis());
   6457                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
   6458                 sb.append(": ");
   6459                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
   6460                 sb.append(" since ");
   6461                 sb.append(msg);
   6462                 FileOutputStream fos = new FileOutputStream(tracesFile);
   6463                 fos.write(sb.toString().getBytes());
   6464                 if (app == null) {
   6465                     fos.write("\n*** No application process!".getBytes());
   6466                 }
   6467                 fos.close();
   6468                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   6469             } catch (IOException e) {
   6470                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
   6471                 return;
   6472             }
   6473 
   6474             if (app != null && app.pid > 0) {
   6475                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
   6476                 firstPids.add(app.pid);
   6477                 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
   6478             }
   6479 
   6480             File lastTracesFile = null;
   6481             File curTracesFile = null;
   6482             for (int i=9; i>=0; i--) {
   6483                 String name = String.format(Locale.US, "slow%02d.txt", i);
   6484                 curTracesFile = new File(tracesDir, name);
   6485                 if (curTracesFile.exists()) {
   6486                     if (lastTracesFile != null) {
   6487                         curTracesFile.renameTo(lastTracesFile);
   6488                     } else {
   6489                         curTracesFile.delete();
   6490                     }
   6491                 }
   6492                 lastTracesFile = curTracesFile;
   6493             }
   6494             tracesFile.renameTo(curTracesFile);
   6495             if (tracesTmp.exists()) {
   6496                 tracesTmp.renameTo(tracesFile);
   6497             }
   6498         } finally {
   6499             StrictMode.setThreadPolicy(oldPolicy);
   6500         }
   6501     }
   6502 
   6503     @GuardedBy("this")
   6504     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
   6505         if (!mLaunchWarningShown) {
   6506             mLaunchWarningShown = true;
   6507             mUiHandler.post(new Runnable() {
   6508                 @Override
   6509                 public void run() {
   6510                     synchronized (ActivityManagerService.this) {
   6511                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
   6512                         d.show();
   6513                         mUiHandler.postDelayed(new Runnable() {
   6514                             @Override
   6515                             public void run() {
   6516                                 synchronized (ActivityManagerService.this) {
   6517                                     d.dismiss();
   6518                                     mLaunchWarningShown = false;
   6519                                 }
   6520                             }
   6521                         }, 4000);
   6522                     }
   6523                 }
   6524             });
   6525         }
   6526     }
   6527 
   6528     @Override
   6529     public boolean clearApplicationUserData(final String packageName, boolean keepState,
   6530             final IPackageDataObserver observer, int userId) {
   6531         enforceNotIsolatedCaller("clearApplicationUserData");
   6532         int uid = Binder.getCallingUid();
   6533         int pid = Binder.getCallingPid();
   6534         final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
   6535                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
   6536 
   6537         final ApplicationInfo appInfo;
   6538         final boolean isInstantApp;
   6539 
   6540         long callingId = Binder.clearCallingIdentity();
   6541         try {
   6542             IPackageManager pm = AppGlobals.getPackageManager();
   6543             synchronized(this) {
   6544                 // Instant packages are not protected
   6545                 if (getPackageManagerInternalLocked().isPackageDataProtected(
   6546                         resolvedUserId, packageName)) {
   6547                     throw new SecurityException(
   6548                             "Cannot clear data for a protected package: " + packageName);
   6549                 }
   6550 
   6551                 ApplicationInfo applicationInfo = null;
   6552                 try {
   6553                     applicationInfo = pm.getApplicationInfo(packageName,
   6554                             MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
   6555                 } catch (RemoteException e) {
   6556                     /* ignore */
   6557                 }
   6558                 appInfo = applicationInfo;
   6559 
   6560                 final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
   6561 
   6562                 if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
   6563                         pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
   6564                     throw new SecurityException("PID " + pid + " does not have permission "
   6565                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
   6566                             + " of package " + packageName);
   6567                 }
   6568 
   6569                 final boolean hasInstantMetadata = getPackageManagerInternalLocked()
   6570                         .hasInstantApplicationMetadata(packageName, resolvedUserId);
   6571                 final boolean isUninstalledAppWithoutInstantMetadata =
   6572                         (appInfo == null && !hasInstantMetadata);
   6573                 isInstantApp = (appInfo != null && appInfo.isInstantApp())
   6574                         || hasInstantMetadata;
   6575                 final boolean canAccessInstantApps = checkComponentPermission(
   6576                         permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
   6577                         == PackageManager.PERMISSION_GRANTED;
   6578 
   6579                 if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
   6580                         && !canAccessInstantApps)) {
   6581                     Slog.w(TAG, "Invalid packageName: " + packageName);
   6582                     if (observer != null) {
   6583                         try {
   6584                             observer.onRemoveCompleted(packageName, false);
   6585                         } catch (RemoteException e) {
   6586                             Slog.i(TAG, "Observer no longer exists.");
   6587                         }
   6588                     }
   6589                     return false;
   6590                 }
   6591 
   6592                 if (appInfo != null) {
   6593                     forceStopPackageLocked(packageName, appInfo.uid, "clear data");
   6594                     mRecentTasks.removeTasksByPackageName(packageName, resolvedUserId);
   6595                 }
   6596             }
   6597 
   6598             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
   6599                 @Override
   6600                 public void onRemoveCompleted(String packageName, boolean succeeded)
   6601                         throws RemoteException {
   6602                     if (appInfo != null) {
   6603                         synchronized (ActivityManagerService.this) {
   6604                             finishForceStopPackageLocked(packageName, appInfo.uid);
   6605                         }
   6606                     }
   6607                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
   6608                             Uri.fromParts("package", packageName, null));
   6609                     intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
   6610                     intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
   6611                     intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
   6612                     if (isInstantApp) {
   6613                         intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
   6614                         broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
   6615                                 null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
   6616                                 resolvedUserId);
   6617                     } else {
   6618                         broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
   6619                                 null, null, null, null, false, false, resolvedUserId);
   6620                     }
   6621 
   6622                     if (observer != null) {
   6623                         observer.onRemoveCompleted(packageName, succeeded);
   6624                     }
   6625                 }
   6626             };
   6627 
   6628             try {
   6629                 // Clear application user data
   6630                 pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
   6631 
   6632                 if (appInfo != null) {
   6633                     // Restore already established notification state and permission grants,
   6634                     // so it told us to keep those intact -- it's about to emplace app data
   6635                     // that is appropriate for those bits of system state.
   6636                     if (!keepState) {
   6637                         synchronized (this) {
   6638                             // Remove all permissions granted from/to this package
   6639                             removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true,
   6640                                     false);
   6641                         }
   6642 
   6643                         // Reset notification state
   6644                         INotificationManager inm = NotificationManager.getService();
   6645                         inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
   6646                     }
   6647 
   6648                     // Clear its scheduled jobs
   6649                     JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
   6650                     js.cancelJobsForUid(appInfo.uid, "clear data");
   6651 
   6652                     // Clear its pending alarms
   6653                     AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class);
   6654                     ami.removeAlarmsForUid(appInfo.uid);
   6655                 }
   6656             } catch (RemoteException e) {
   6657             }
   6658         } finally {
   6659             Binder.restoreCallingIdentity(callingId);
   6660         }
   6661         return true;
   6662     }
   6663 
   6664     @Override
   6665     public void killBackgroundProcesses(final String packageName, int userId) {
   6666         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   6667                 != PackageManager.PERMISSION_GRANTED &&
   6668                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
   6669                         != PackageManager.PERMISSION_GRANTED) {
   6670             String msg = "Permission Denial: killBackgroundProcesses() from pid="
   6671                     + Binder.getCallingPid()
   6672                     + ", uid=" + Binder.getCallingUid()
   6673                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   6674             Slog.w(TAG, msg);
   6675             throw new SecurityException(msg);
   6676         }
   6677 
   6678         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   6679                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
   6680         final int[] userIds = mUserController.expandUserId(userId);
   6681 
   6682         long callingId = Binder.clearCallingIdentity();
   6683         try {
   6684             IPackageManager pm = AppGlobals.getPackageManager();
   6685             for (int targetUserId : userIds) {
   6686                 int appId = -1;
   6687                 try {
   6688                     appId = UserHandle.getAppId(
   6689                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
   6690                                     targetUserId));
   6691                 } catch (RemoteException e) {
   6692                 }
   6693                 if (appId == -1) {
   6694                     Slog.w(TAG, "Invalid packageName: " + packageName);
   6695                     return;
   6696                 }
   6697                 synchronized (this) {
   6698                     killPackageProcessesLocked(packageName, appId, targetUserId,
   6699                             ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
   6700                 }
   6701             }
   6702         } finally {
   6703             Binder.restoreCallingIdentity(callingId);
   6704         }
   6705     }
   6706 
   6707     @Override
   6708     public void killAllBackgroundProcesses() {
   6709         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   6710                 != PackageManager.PERMISSION_GRANTED) {
   6711             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
   6712                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   6713                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   6714             Slog.w(TAG, msg);
   6715             throw new SecurityException(msg);
   6716         }
   6717 
   6718         final long callingId = Binder.clearCallingIdentity();
   6719         try {
   6720             synchronized (this) {
   6721                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
   6722                 final int NP = mProcessNames.getMap().size();
   6723                 for (int ip = 0; ip < NP; ip++) {
   6724                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   6725                     final int NA = apps.size();
   6726                     for (int ia = 0; ia < NA; ia++) {
   6727                         final ProcessRecord app = apps.valueAt(ia);
   6728                         if (app.persistent) {
   6729                             // We don't kill persistent processes.
   6730                             continue;
   6731                         }
   6732                         if (app.removed) {
   6733                             procs.add(app);
   6734                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   6735                             app.removed = true;
   6736                             procs.add(app);
   6737                         }
   6738                     }
   6739                 }
   6740 
   6741                 final int N = procs.size();
   6742                 for (int i = 0; i < N; i++) {
   6743                     removeProcessLocked(procs.get(i), false, true, "kill all background");
   6744                 }
   6745 
   6746                 mAllowLowerMemLevel = true;
   6747 
   6748                 updateOomAdjLocked();
   6749                 doLowMemReportIfNeededLocked(null);
   6750             }
   6751         } finally {
   6752             Binder.restoreCallingIdentity(callingId);
   6753         }
   6754     }
   6755 
   6756     /**
   6757      * Kills all background processes, except those matching any of the
   6758      * specified properties.
   6759      *
   6760      * @param minTargetSdk the target SDK version at or above which to preserve
   6761      *                     processes, or {@code -1} to ignore the target SDK
   6762      * @param maxProcState the process state at or below which to preserve
   6763      *                     processes, or {@code -1} to ignore the process state
   6764      */
   6765     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
   6766         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   6767                 != PackageManager.PERMISSION_GRANTED) {
   6768             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
   6769                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   6770                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   6771             Slog.w(TAG, msg);
   6772             throw new SecurityException(msg);
   6773         }
   6774 
   6775         final long callingId = Binder.clearCallingIdentity();
   6776         try {
   6777             synchronized (this) {
   6778                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
   6779                 final int NP = mProcessNames.getMap().size();
   6780                 for (int ip = 0; ip < NP; ip++) {
   6781                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   6782                     final int NA = apps.size();
   6783                     for (int ia = 0; ia < NA; ia++) {
   6784                         final ProcessRecord app = apps.valueAt(ia);
   6785                         if (app.removed) {
   6786                             procs.add(app);
   6787                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
   6788                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
   6789                             app.removed = true;
   6790                             procs.add(app);
   6791                         }
   6792                     }
   6793                 }
   6794 
   6795                 final int N = procs.size();
   6796                 for (int i = 0; i < N; i++) {
   6797                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
   6798                 }
   6799             }
   6800         } finally {
   6801             Binder.restoreCallingIdentity(callingId);
   6802         }
   6803     }
   6804 
   6805     @Override
   6806     public void forceStopPackage(final String packageName, int userId) {
   6807         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   6808                 != PackageManager.PERMISSION_GRANTED) {
   6809             String msg = "Permission Denial: forceStopPackage() from pid="
   6810                     + Binder.getCallingPid()
   6811                     + ", uid=" + Binder.getCallingUid()
   6812                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   6813             Slog.w(TAG, msg);
   6814             throw new SecurityException(msg);
   6815         }
   6816         final int callingPid = Binder.getCallingPid();
   6817         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
   6818                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
   6819         long callingId = Binder.clearCallingIdentity();
   6820         try {
   6821             IPackageManager pm = AppGlobals.getPackageManager();
   6822             synchronized(this) {
   6823                 int[] users = userId == UserHandle.USER_ALL
   6824                         ? mUserController.getUsers() : new int[] { userId };
   6825                 for (int user : users) {
   6826                     if (getPackageManagerInternalLocked().isPackageStateProtected(
   6827                             packageName, user)) {
   6828                         Slog.w(TAG, "Ignoring request to force stop protected package "
   6829                                 + packageName + " u" + user);
   6830                         return;
   6831                     }
   6832 
   6833                     int pkgUid = -1;
   6834                     try {
   6835                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
   6836                                 user);
   6837                     } catch (RemoteException e) {
   6838                     }
   6839                     if (pkgUid == -1) {
   6840                         Slog.w(TAG, "Invalid packageName: " + packageName);
   6841                         continue;
   6842                     }
   6843                     try {
   6844                         pm.setPackageStoppedState(packageName, true, user);
   6845                     } catch (RemoteException e) {
   6846                     } catch (IllegalArgumentException e) {
   6847                         Slog.w(TAG, "Failed trying to unstop package "
   6848                                 + packageName + ": " + e);
   6849                     }
   6850                     if (mUserController.isUserRunning(user, 0)) {
   6851                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
   6852                         finishForceStopPackageLocked(packageName, pkgUid);
   6853                     }
   6854                 }
   6855             }
   6856         } finally {
   6857             Binder.restoreCallingIdentity(callingId);
   6858         }
   6859     }
   6860 
   6861     @Override
   6862     public void addPackageDependency(String packageName) {
   6863         synchronized (this) {
   6864             int callingPid = Binder.getCallingPid();
   6865             if (callingPid == myPid()) {
   6866                 //  Yeah, um, no.
   6867                 return;
   6868             }
   6869             ProcessRecord proc;
   6870             synchronized (mPidsSelfLocked) {
   6871                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   6872             }
   6873             if (proc != null) {
   6874                 if (proc.pkgDeps == null) {
   6875                     proc.pkgDeps = new ArraySet<String>(1);
   6876                 }
   6877                 proc.pkgDeps.add(packageName);
   6878             }
   6879         }
   6880     }
   6881 
   6882     /*
   6883      * The pkg name and app id have to be specified.
   6884      */
   6885     @Override
   6886     public void killApplication(String pkg, int appId, int userId, String reason) {
   6887         if (pkg == null) {
   6888             return;
   6889         }
   6890         // Make sure the uid is valid.
   6891         if (appId < 0) {
   6892             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
   6893             return;
   6894         }
   6895         int callerUid = Binder.getCallingUid();
   6896         // Only the system server can kill an application
   6897         if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
   6898             // Post an aysnc message to kill the application
   6899             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
   6900             msg.arg1 = appId;
   6901             msg.arg2 = userId;
   6902             Bundle bundle = new Bundle();
   6903             bundle.putString("pkg", pkg);
   6904             bundle.putString("reason", reason);
   6905             msg.obj = bundle;
   6906             mHandler.sendMessage(msg);
   6907         } else {
   6908             throw new SecurityException(callerUid + " cannot kill pkg: " +
   6909                     pkg);
   6910         }
   6911     }
   6912 
   6913     @Override
   6914     public void closeSystemDialogs(String reason) {
   6915         enforceNotIsolatedCaller("closeSystemDialogs");
   6916 
   6917         final int pid = Binder.getCallingPid();
   6918         final int uid = Binder.getCallingUid();
   6919         final long origId = Binder.clearCallingIdentity();
   6920         try {
   6921             synchronized (this) {
   6922                 // Only allow this from foreground processes, so that background
   6923                 // applications can't abuse it to prevent system UI from being shown.
   6924                 if (uid >= FIRST_APPLICATION_UID) {
   6925                     ProcessRecord proc;
   6926                     synchronized (mPidsSelfLocked) {
   6927                         proc = mPidsSelfLocked.get(pid);
   6928                     }
   6929                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   6930                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
   6931                                 + " from background process " + proc);
   6932                         return;
   6933                     }
   6934                 }
   6935                 closeSystemDialogsLocked(reason);
   6936             }
   6937         } finally {
   6938             Binder.restoreCallingIdentity(origId);
   6939         }
   6940     }
   6941 
   6942     @GuardedBy("this")
   6943     void closeSystemDialogsLocked(String reason) {
   6944         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
   6945         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   6946                 | Intent.FLAG_RECEIVER_FOREGROUND);
   6947         if (reason != null) {
   6948             intent.putExtra("reason", reason);
   6949         }
   6950         mWindowManager.closeSystemDialogs(reason);
   6951 
   6952         mStackSupervisor.closeSystemDialogsLocked();
   6953 
   6954         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
   6955                 OP_NONE, null, false, false,
   6956                 -1, SYSTEM_UID, UserHandle.USER_ALL);
   6957     }
   6958 
   6959     @Override
   6960     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
   6961         enforceNotIsolatedCaller("getProcessMemoryInfo");
   6962         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
   6963         for (int i=pids.length-1; i>=0; i--) {
   6964             ProcessRecord proc;
   6965             int oomAdj;
   6966             synchronized (this) {
   6967                 synchronized (mPidsSelfLocked) {
   6968                     proc = mPidsSelfLocked.get(pids[i]);
   6969                     oomAdj = proc != null ? proc.setAdj : 0;
   6970                 }
   6971             }
   6972             infos[i] = new Debug.MemoryInfo();
   6973             long startTime = SystemClock.currentThreadTimeMillis();
   6974             Debug.getMemoryInfo(pids[i], infos[i]);
   6975             long endTime = SystemClock.currentThreadTimeMillis();
   6976             if (proc != null) {
   6977                 synchronized (this) {
   6978                     if (proc.thread != null && proc.setAdj == oomAdj) {
   6979                         // Record this for posterity if the process has been stable.
   6980                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
   6981                                 infos[i].getTotalUss(), infos[i].getTotalRss(), false,
   6982                                 ProcessStats.ADD_PSS_EXTERNAL_SLOW, endTime-startTime,
   6983                                 proc.pkgList);
   6984                     }
   6985                 }
   6986             }
   6987         }
   6988         return infos;
   6989     }
   6990 
   6991     @Override
   6992     public long[] getProcessPss(int[] pids) {
   6993         enforceNotIsolatedCaller("getProcessPss");
   6994         long[] pss = new long[pids.length];
   6995         for (int i=pids.length-1; i>=0; i--) {
   6996             ProcessRecord proc;
   6997             int oomAdj;
   6998             synchronized (this) {
   6999                 synchronized (mPidsSelfLocked) {
   7000                     proc = mPidsSelfLocked.get(pids[i]);
   7001                     oomAdj = proc != null ? proc.setAdj : 0;
   7002                 }
   7003             }
   7004             long[] tmpUss = new long[3];
   7005             long startTime = SystemClock.currentThreadTimeMillis();
   7006             pss[i] = Debug.getPss(pids[i], tmpUss, null);
   7007             long endTime = SystemClock.currentThreadTimeMillis();
   7008             if (proc != null) {
   7009                 synchronized (this) {
   7010                     if (proc.thread != null && proc.setAdj == oomAdj) {
   7011                         // Record this for posterity if the process has been stable.
   7012                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], tmpUss[2], false,
   7013                                 ProcessStats.ADD_PSS_EXTERNAL, endTime-startTime, proc.pkgList);
   7014                     }
   7015                 }
   7016             }
   7017         }
   7018         return pss;
   7019     }
   7020 
   7021     @Override
   7022     public void killApplicationProcess(String processName, int uid) {
   7023         if (processName == null) {
   7024             return;
   7025         }
   7026 
   7027         int callerUid = Binder.getCallingUid();
   7028         // Only the system server can kill an application
   7029         if (callerUid == SYSTEM_UID) {
   7030             synchronized (this) {
   7031                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
   7032                 if (app != null && app.thread != null) {
   7033                     try {
   7034                         app.thread.scheduleSuicide();
   7035                     } catch (RemoteException e) {
   7036                         // If the other end already died, then our work here is done.
   7037                     }
   7038                 } else {
   7039                     Slog.w(TAG, "Process/uid not found attempting kill of "
   7040                             + processName + " / " + uid);
   7041                 }
   7042             }
   7043         } else {
   7044             throw new SecurityException(callerUid + " cannot kill app process: " +
   7045                     processName);
   7046         }
   7047     }
   7048 
   7049     @GuardedBy("this")
   7050     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
   7051         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
   7052                 false, true, false, false, UserHandle.getUserId(uid), reason);
   7053     }
   7054 
   7055     @GuardedBy("this")
   7056     private void finishForceStopPackageLocked(final String packageName, int uid) {
   7057         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
   7058                 Uri.fromParts("package", packageName, null));
   7059         if (!mProcessesReady) {
   7060             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   7061                     | Intent.FLAG_RECEIVER_FOREGROUND);
   7062         }
   7063         intent.putExtra(Intent.EXTRA_UID, uid);
   7064         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
   7065         broadcastIntentLocked(null, null, intent,
   7066                 null, null, 0, null, null, null, OP_NONE,
   7067                 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
   7068     }
   7069 
   7070 
   7071     @GuardedBy("this")
   7072     private final boolean killPackageProcessesLocked(String packageName, int appId,
   7073             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
   7074             boolean doit, boolean evenPersistent, String reason) {
   7075         ArrayList<ProcessRecord> procs = new ArrayList<>();
   7076 
   7077         // Remove all processes this package may have touched: all with the
   7078         // same UID (except for the system or root user), and all whose name
   7079         // matches the package name.
   7080         final int NP = mProcessNames.getMap().size();
   7081         for (int ip=0; ip<NP; ip++) {
   7082             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   7083             final int NA = apps.size();
   7084             for (int ia=0; ia<NA; ia++) {
   7085                 ProcessRecord app = apps.valueAt(ia);
   7086                 if (app.persistent && !evenPersistent) {
   7087                     // we don't kill persistent processes
   7088                     continue;
   7089                 }
   7090                 if (app.removed) {
   7091                     if (doit) {
   7092                         procs.add(app);
   7093                     }
   7094                     continue;
   7095                 }
   7096 
   7097                 // Skip process if it doesn't meet our oom adj requirement.
   7098                 if (app.setAdj < minOomAdj) {
   7099                     continue;
   7100                 }
   7101 
   7102                 // If no package is specified, we call all processes under the
   7103                 // give user id.
   7104                 if (packageName == null) {
   7105                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
   7106                         continue;
   7107                     }
   7108                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
   7109                         continue;
   7110                     }
   7111                 // Package has been specified, we want to hit all processes
   7112                 // that match it.  We need to qualify this by the processes
   7113                 // that are running under the specified app and user ID.
   7114                 } else {
   7115                     final boolean isDep = app.pkgDeps != null
   7116                             && app.pkgDeps.contains(packageName);
   7117                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
   7118                         continue;
   7119                     }
   7120                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
   7121                         continue;
   7122                     }
   7123                     if (!app.pkgList.containsKey(packageName) && !isDep) {
   7124                         continue;
   7125                     }
   7126                 }
   7127 
   7128                 // Process has passed all conditions, kill it!
   7129                 if (!doit) {
   7130                     return true;
   7131                 }
   7132                 app.removed = true;
   7133                 procs.add(app);
   7134             }
   7135         }
   7136 
   7137         int N = procs.size();
   7138         for (int i=0; i<N; i++) {
   7139             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
   7140         }
   7141         updateOomAdjLocked();
   7142         return N > 0;
   7143     }
   7144 
   7145     private void cleanupDisabledPackageComponentsLocked(
   7146             String packageName, int userId, boolean killProcess, String[] changedClasses) {
   7147 
   7148         Set<String> disabledClasses = null;
   7149         boolean packageDisabled = false;
   7150         IPackageManager pm = AppGlobals.getPackageManager();
   7151 
   7152         if (changedClasses == null) {
   7153             // Nothing changed...
   7154             return;
   7155         }
   7156 
   7157         // Determine enable/disable state of the package and its components.
   7158         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
   7159         for (int i = changedClasses.length - 1; i >= 0; i--) {
   7160             final String changedClass = changedClasses[i];
   7161 
   7162             if (changedClass.equals(packageName)) {
   7163                 try {
   7164                     // Entire package setting changed
   7165                     enabled = pm.getApplicationEnabledSetting(packageName,
   7166                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
   7167                 } catch (Exception e) {
   7168                     // No such package/component; probably racing with uninstall.  In any
   7169                     // event it means we have nothing further to do here.
   7170                     return;
   7171                 }
   7172                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
   7173                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
   7174                 if (packageDisabled) {
   7175                     // Entire package is disabled.
   7176                     // No need to continue to check component states.
   7177                     disabledClasses = null;
   7178                     break;
   7179                 }
   7180             } else {
   7181                 try {
   7182                     enabled = pm.getComponentEnabledSetting(
   7183                             new ComponentName(packageName, changedClass),
   7184                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
   7185                 } catch (Exception e) {
   7186                     // As above, probably racing with uninstall.
   7187                     return;
   7188                 }
   7189                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
   7190                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
   7191                     if (disabledClasses == null) {
   7192                         disabledClasses = new ArraySet<>(changedClasses.length);
   7193                     }
   7194                     disabledClasses.add(changedClass);
   7195                 }
   7196             }
   7197         }
   7198 
   7199         if (!packageDisabled && disabledClasses == null) {
   7200             // Nothing to do here...
   7201             return;
   7202         }
   7203 
   7204         // Clean-up disabled activities.
   7205         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
   7206                 packageName, disabledClasses, true, false, userId) && mBooted) {
   7207             mStackSupervisor.resumeFocusedStackTopActivityLocked();
   7208             mStackSupervisor.scheduleIdleLocked();
   7209         }
   7210 
   7211         // Clean-up disabled tasks
   7212         mRecentTasks.cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
   7213 
   7214         // Clean-up disabled services.
   7215         mServices.bringDownDisabledPackageServicesLocked(
   7216                 packageName, disabledClasses, userId, false, killProcess, true);
   7217 
   7218         // Clean-up disabled providers.
   7219         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
   7220         mProviderMap.collectPackageProvidersLocked(
   7221                 packageName, disabledClasses, true, false, userId, providers);
   7222         for (int i = providers.size() - 1; i >= 0; i--) {
   7223             removeDyingProviderLocked(null, providers.get(i), true);
   7224         }
   7225 
   7226         // Clean-up disabled broadcast receivers.
   7227         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
   7228             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
   7229                     packageName, disabledClasses, userId, true);
   7230         }
   7231 
   7232     }
   7233 
   7234     final boolean clearBroadcastQueueForUserLocked(int userId) {
   7235         boolean didSomething = false;
   7236         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
   7237             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
   7238                     null, null, userId, true);
   7239         }
   7240         return didSomething;
   7241     }
   7242 
   7243     @GuardedBy("this")
   7244     final boolean forceStopPackageLocked(String packageName, int appId,
   7245             boolean callerWillRestart, boolean purgeCache, boolean doit,
   7246             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
   7247         int i;
   7248 
   7249         if (userId == UserHandle.USER_ALL && packageName == null) {
   7250             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
   7251         }
   7252 
   7253         if (appId < 0 && packageName != null) {
   7254             try {
   7255                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
   7256                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
   7257             } catch (RemoteException e) {
   7258             }
   7259         }
   7260 
   7261         if (doit) {
   7262             if (packageName != null) {
   7263                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
   7264                         + " user=" + userId + ": " + reason);
   7265             } else {
   7266                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
   7267             }
   7268 
   7269             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
   7270         }
   7271 
   7272         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
   7273                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
   7274                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
   7275 
   7276         didSomething |= mActivityStartController.clearPendingActivityLaunches(packageName);
   7277 
   7278         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
   7279                 packageName, null, doit, evenPersistent, userId)) {
   7280             if (!doit) {
   7281                 return true;
   7282             }
   7283             didSomething = true;
   7284         }
   7285 
   7286         if (mServices.bringDownDisabledPackageServicesLocked(
   7287                 packageName, null, userId, evenPersistent, true, doit)) {
   7288             if (!doit) {
   7289                 return true;
   7290             }
   7291             didSomething = true;
   7292         }
   7293 
   7294         if (packageName == null) {
   7295             // Remove all sticky broadcasts from this user.
   7296             mStickyBroadcasts.remove(userId);
   7297         }
   7298 
   7299         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
   7300         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
   7301                 userId, providers)) {
   7302             if (!doit) {
   7303                 return true;
   7304             }
   7305             didSomething = true;
   7306         }
   7307         for (i = providers.size() - 1; i >= 0; i--) {
   7308             removeDyingProviderLocked(null, providers.get(i), true);
   7309         }
   7310 
   7311         // Remove transient permissions granted from/to this package/user
   7312         removeUriPermissionsForPackageLocked(packageName, userId, false, false);
   7313 
   7314         if (doit) {
   7315             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
   7316                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
   7317                         packageName, null, userId, doit);
   7318             }
   7319         }
   7320 
   7321         if (packageName == null || uninstalling) {
   7322             // Remove pending intents.  For now we only do this when force
   7323             // stopping users, because we have some problems when doing this
   7324             // for packages -- app widgets are not currently cleaned up for
   7325             // such packages, so they can be left with bad pending intents.
   7326             if (mIntentSenderRecords.size() > 0) {
   7327                 Iterator<WeakReference<PendingIntentRecord>> it
   7328                         = mIntentSenderRecords.values().iterator();
   7329                 while (it.hasNext()) {
   7330                     WeakReference<PendingIntentRecord> wpir = it.next();
   7331                     if (wpir == null) {
   7332                         it.remove();
   7333                         continue;
   7334                     }
   7335                     PendingIntentRecord pir = wpir.get();
   7336                     if (pir == null) {
   7337                         it.remove();
   7338                         continue;
   7339                     }
   7340                     if (packageName == null) {
   7341                         // Stopping user, remove all objects for the user.
   7342                         if (pir.key.userId != userId) {
   7343                             // Not the same user, skip it.
   7344                             continue;
   7345                         }
   7346                     } else {
   7347                         if (UserHandle.getAppId(pir.uid) != appId) {
   7348                             // Different app id, skip it.
   7349                             continue;
   7350                         }
   7351                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
   7352                             // Different user, skip it.
   7353                             continue;
   7354                         }
   7355                         if (!pir.key.packageName.equals(packageName)) {
   7356                             // Different package, skip it.
   7357                             continue;
   7358                         }
   7359                     }
   7360                     if (!doit) {
   7361                         return true;
   7362                     }
   7363                     didSomething = true;
   7364                     it.remove();
   7365                     makeIntentSenderCanceledLocked(pir);
   7366                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
   7367                         pir.key.activity.pendingResults.remove(pir.ref);
   7368                     }
   7369                 }
   7370             }
   7371         }
   7372 
   7373         if (doit) {
   7374             if (purgeCache && packageName != null) {
   7375                 AttributeCache ac = AttributeCache.instance();
   7376                 if (ac != null) {
   7377                     ac.removePackage(packageName);
   7378                 }
   7379             }
   7380             if (mBooted) {
   7381                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
   7382                 mStackSupervisor.scheduleIdleLocked();
   7383             }
   7384         }
   7385 
   7386         return didSomething;
   7387     }
   7388 
   7389     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
   7390         return removeProcessNameLocked(name, uid, null);
   7391     }
   7392 
   7393     private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
   7394             final ProcessRecord expecting) {
   7395         ProcessRecord old = mProcessNames.get(name, uid);
   7396         // Only actually remove when the currently recorded value matches the
   7397         // record that we expected; if it doesn't match then we raced with a
   7398         // newly created process and we don't want to destroy the new one.
   7399         if ((expecting == null) || (old == expecting)) {
   7400             mProcessNames.remove(name, uid);
   7401         }
   7402         if (old != null && old.uidRecord != null) {
   7403             old.uidRecord.numProcs--;
   7404             if (old.uidRecord.numProcs == 0) {
   7405                 // No more processes using this uid, tell clients it is gone.
   7406                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   7407                         "No more processes in " + old.uidRecord);
   7408                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
   7409                 EventLogTags.writeAmUidStopped(uid);
   7410                 mActiveUids.remove(uid);
   7411                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
   7412             }
   7413             old.uidRecord = null;
   7414         }
   7415         mIsolatedProcesses.remove(uid);
   7416         return old;
   7417     }
   7418 
   7419     private final void addProcessNameLocked(ProcessRecord proc) {
   7420         // We shouldn't already have a process under this name, but just in case we
   7421         // need to clean up whatever may be there now.
   7422         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
   7423         if (old == proc && proc.persistent) {
   7424             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
   7425             Slog.w(TAG, "Re-adding persistent process " + proc);
   7426         } else if (old != null) {
   7427             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
   7428         }
   7429         UidRecord uidRec = mActiveUids.get(proc.uid);
   7430         if (uidRec == null) {
   7431             uidRec = new UidRecord(proc.uid);
   7432             // This is the first appearance of the uid, report it now!
   7433             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   7434                     "Creating new process uid: " + uidRec);
   7435             if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
   7436                     || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
   7437                 uidRec.setWhitelist = uidRec.curWhitelist = true;
   7438             }
   7439             uidRec.updateHasInternetPermission();
   7440             mActiveUids.put(proc.uid, uidRec);
   7441             EventLogTags.writeAmUidRunning(uidRec.uid);
   7442             noteUidProcessState(uidRec.uid, uidRec.curProcState);
   7443         }
   7444         proc.uidRecord = uidRec;
   7445 
   7446         // Reset render thread tid if it was already set, so new process can set it again.
   7447         proc.renderThreadTid = 0;
   7448         uidRec.numProcs++;
   7449         mProcessNames.put(proc.processName, proc.uid, proc);
   7450         if (proc.isolated) {
   7451             mIsolatedProcesses.put(proc.uid, proc);
   7452         }
   7453     }
   7454 
   7455     @GuardedBy("this")
   7456     boolean removeProcessLocked(ProcessRecord app,
   7457             boolean callerWillRestart, boolean allowRestart, String reason) {
   7458         final String name = app.processName;
   7459         final int uid = app.uid;
   7460         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
   7461             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
   7462 
   7463         ProcessRecord old = mProcessNames.get(name, uid);
   7464         if (old != app) {
   7465             // This process is no longer active, so nothing to do.
   7466             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
   7467             return false;
   7468         }
   7469         removeProcessNameLocked(name, uid);
   7470         if (mHeavyWeightProcess == app) {
   7471             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   7472                     mHeavyWeightProcess.userId, 0));
   7473             mHeavyWeightProcess = null;
   7474         }
   7475         boolean needRestart = false;
   7476         if ((app.pid > 0 && app.pid != MY_PID) || (app.pid == 0 && app.pendingStart)) {
   7477             int pid = app.pid;
   7478             if (pid > 0) {
   7479                 synchronized (mPidsSelfLocked) {
   7480                     mPidsSelfLocked.remove(pid);
   7481                     mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   7482                 }
   7483                 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   7484                 if (app.isolated) {
   7485                     mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   7486                     getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
   7487                 }
   7488             }
   7489             boolean willRestart = false;
   7490             if (app.persistent && !app.isolated) {
   7491                 if (!callerWillRestart) {
   7492                     willRestart = true;
   7493                 } else {
   7494                     needRestart = true;
   7495                 }
   7496             }
   7497             app.kill(reason, true);
   7498             handleAppDiedLocked(app, willRestart, allowRestart);
   7499             if (willRestart) {
   7500                 removeLruProcessLocked(app);
   7501                 addAppLocked(app.info, null, false, null /* ABI override */);
   7502             }
   7503         } else {
   7504             mRemovedProcesses.add(app);
   7505         }
   7506 
   7507         return needRestart;
   7508     }
   7509 
   7510     @GuardedBy("this")
   7511     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
   7512         cleanupAppInLaunchingProvidersLocked(app, true);
   7513         removeProcessLocked(app, false, true, "timeout publishing content providers");
   7514     }
   7515 
   7516     private final void processStartTimedOutLocked(ProcessRecord app) {
   7517         final int pid = app.pid;
   7518         boolean gone = false;
   7519         synchronized (mPidsSelfLocked) {
   7520             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
   7521             if (knownApp != null && knownApp.thread == null) {
   7522                 mPidsSelfLocked.remove(pid);
   7523                 gone = true;
   7524             }
   7525         }
   7526 
   7527         if (gone) {
   7528             Slog.w(TAG, "Process " + app + " failed to attach");
   7529             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
   7530                     pid, app.uid, app.processName);
   7531             removeProcessNameLocked(app.processName, app.uid);
   7532             if (mHeavyWeightProcess == app) {
   7533                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   7534                         mHeavyWeightProcess.userId, 0));
   7535                 mHeavyWeightProcess = null;
   7536             }
   7537             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   7538             // Take care of any launching providers waiting for this process.
   7539             cleanupAppInLaunchingProvidersLocked(app, true);
   7540             // Take care of any services that are waiting for the process.
   7541             mServices.processStartTimedOutLocked(app);
   7542             app.kill("start timeout", true);
   7543             if (app.isolated) {
   7544                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   7545             }
   7546             removeLruProcessLocked(app);
   7547             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
   7548                 Slog.w(TAG, "Unattached app died before backup, skipping");
   7549                 mHandler.post(new Runnable() {
   7550                 @Override
   7551                     public void run(){
   7552                         try {
   7553                             IBackupManager bm = IBackupManager.Stub.asInterface(
   7554                                     ServiceManager.getService(Context.BACKUP_SERVICE));
   7555                             bm.agentDisconnected(app.info.packageName);
   7556                         } catch (RemoteException e) {
   7557                             // Can't happen; the backup manager is local
   7558                         }
   7559                     }
   7560                 });
   7561             }
   7562             if (isPendingBroadcastProcessLocked(pid)) {
   7563                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   7564                 skipPendingBroadcastLocked(pid);
   7565             }
   7566         } else {
   7567             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
   7568         }
   7569     }
   7570 
   7571     @GuardedBy("this")
   7572     private final boolean attachApplicationLocked(IApplicationThread thread,
   7573             int pid, int callingUid, long startSeq) {
   7574 
   7575         // Find the application record that is being attached...  either via
   7576         // the pid if we are running in multiple processes, or just pull the
   7577         // next app record if we are emulating process with anonymous threads.
   7578         ProcessRecord app;
   7579         long startTime = SystemClock.uptimeMillis();
   7580         if (pid != MY_PID && pid >= 0) {
   7581             synchronized (mPidsSelfLocked) {
   7582                 app = mPidsSelfLocked.get(pid);
   7583             }
   7584         } else {
   7585             app = null;
   7586         }
   7587 
   7588         // It's possible that process called attachApplication before we got a chance to
   7589         // update the internal state.
   7590         if (app == null && startSeq > 0) {
   7591             final ProcessRecord pending = mPendingStarts.get(startSeq);
   7592             if (pending != null && pending.startUid == callingUid
   7593                     && handleProcessStartedLocked(pending, pid, pending.usingWrapper,
   7594                             startSeq, true)) {
   7595                 app = pending;
   7596             }
   7597         }
   7598 
   7599         if (app == null) {
   7600             Slog.w(TAG, "No pending application record for pid " + pid
   7601                     + " (IApplicationThread " + thread + "); dropping process");
   7602             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
   7603             if (pid > 0 && pid != MY_PID) {
   7604                 killProcessQuiet(pid);
   7605                 //TODO: killProcessGroup(app.info.uid, pid);
   7606             } else {
   7607                 try {
   7608                     thread.scheduleExit();
   7609                 } catch (Exception e) {
   7610                     // Ignore exceptions.
   7611                 }
   7612             }
   7613             return false;
   7614         }
   7615 
   7616         // If this application record is still attached to a previous
   7617         // process, clean it up now.
   7618         if (app.thread != null) {
   7619             handleAppDiedLocked(app, true, true);
   7620         }
   7621 
   7622         // Tell the process all about itself.
   7623 
   7624         if (DEBUG_ALL) Slog.v(
   7625                 TAG, "Binding process pid " + pid + " to record " + app);
   7626 
   7627         final String processName = app.processName;
   7628         try {
   7629             AppDeathRecipient adr = new AppDeathRecipient(
   7630                     app, pid, thread);
   7631             thread.asBinder().linkToDeath(adr, 0);
   7632             app.deathRecipient = adr;
   7633         } catch (RemoteException e) {
   7634             app.resetPackageList(mProcessStats);
   7635             startProcessLocked(app, "link fail", processName);
   7636             return false;
   7637         }
   7638 
   7639         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
   7640 
   7641         app.makeActive(thread, mProcessStats);
   7642         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
   7643         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   7644         app.forcingToImportant = null;
   7645         updateProcessForegroundLocked(app, false, false);
   7646         app.hasShownUi = false;
   7647         app.debugging = false;
   7648         app.cached = false;
   7649         app.killedByAm = false;
   7650         app.killed = false;
   7651 
   7652 
   7653         // We carefully use the same state that PackageManager uses for
   7654         // filtering, since we use this flag to decide if we need to install
   7655         // providers when user is unlocked later
   7656         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
   7657 
   7658         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   7659 
   7660         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
   7661         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
   7662 
   7663         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
   7664             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
   7665             msg.obj = app;
   7666             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
   7667         }
   7668 
   7669         checkTime(startTime, "attachApplicationLocked: before bindApplication");
   7670 
   7671         if (!normalMode) {
   7672             Slog.i(TAG, "Launching preboot mode app: " + app);
   7673         }
   7674 
   7675         if (DEBUG_ALL) Slog.v(
   7676             TAG, "New app record " + app
   7677             + " thread=" + thread.asBinder() + " pid=" + pid);
   7678         try {
   7679             int testMode = ApplicationThreadConstants.DEBUG_OFF;
   7680             if (mDebugApp != null && mDebugApp.equals(processName)) {
   7681                 testMode = mWaitForDebugger
   7682                     ? ApplicationThreadConstants.DEBUG_WAIT
   7683                     : ApplicationThreadConstants.DEBUG_ON;
   7684                 app.debugging = true;
   7685                 if (mDebugTransient) {
   7686                     mDebugApp = mOrigDebugApp;
   7687                     mWaitForDebugger = mOrigWaitForDebugger;
   7688                 }
   7689             }
   7690 
   7691             boolean enableTrackAllocation = false;
   7692             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
   7693                 enableTrackAllocation = true;
   7694                 mTrackAllocationApp = null;
   7695             }
   7696 
   7697             // If the app is being launched for restore or full backup, set it up specially
   7698             boolean isRestrictedBackupMode = false;
   7699             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
   7700                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
   7701                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
   7702                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
   7703                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
   7704             }
   7705 
   7706             if (app.instr != null) {
   7707                 notifyPackageUse(app.instr.mClass.getPackageName(),
   7708                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
   7709             }
   7710             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
   7711                     + processName + " with config " + getGlobalConfiguration());
   7712             ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
   7713             app.compat = compatibilityInfoForPackageLocked(appInfo);
   7714 
   7715             ProfilerInfo profilerInfo = null;
   7716             String preBindAgent = null;
   7717             if (mProfileApp != null && mProfileApp.equals(processName)) {
   7718                 mProfileProc = app;
   7719                 if (mProfilerInfo != null) {
   7720                     // Send a profiler info object to the app if either a file is given, or
   7721                     // an agent should be loaded at bind-time.
   7722                     boolean needsInfo = mProfilerInfo.profileFile != null
   7723                             || mProfilerInfo.attachAgentDuringBind;
   7724                     profilerInfo = needsInfo ? new ProfilerInfo(mProfilerInfo) : null;
   7725                     if (mProfilerInfo.agent != null) {
   7726                         preBindAgent = mProfilerInfo.agent;
   7727                     }
   7728                 }
   7729             } else if (app.instr != null && app.instr.mProfileFile != null) {
   7730                 profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
   7731                         null, false);
   7732             }
   7733             if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) {
   7734                 // We need to do a debuggable check here. See setAgentApp for why the check is
   7735                 // postponed to here.
   7736                 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   7737                     String agent = mAppAgentMap.get(processName);
   7738                     // Do not overwrite already requested agent.
   7739                     if (profilerInfo == null) {
   7740                         profilerInfo = new ProfilerInfo(null, null, 0, false, false,
   7741                                 mAppAgentMap.get(processName), true);
   7742                     } else if (profilerInfo.agent == null) {
   7743                         profilerInfo = profilerInfo.setAgent(mAppAgentMap.get(processName), true);
   7744                     }
   7745                 }
   7746             }
   7747 
   7748             if (profilerInfo != null && profilerInfo.profileFd != null) {
   7749                 profilerInfo.profileFd = profilerInfo.profileFd.dup();
   7750                 if (TextUtils.equals(mProfileApp, processName) && mProfilerInfo != null) {
   7751                     clearProfilerLocked();
   7752                 }
   7753             }
   7754 
   7755             // We deprecated Build.SERIAL and it is not accessible to
   7756             // apps that target the v2 security sandbox and to apps that
   7757             // target APIs higher than O MR1. Since access to the serial
   7758             // is now behind a permission we push down the value.
   7759             final String buildSerial = (appInfo.targetSandboxVersion < 2
   7760                     && appInfo.targetSdkVersion < Build.VERSION_CODES.P)
   7761                             ? sTheRealBuildSerial : Build.UNKNOWN;
   7762 
   7763             // Check if this is a secondary process that should be incorporated into some
   7764             // currently active instrumentation.  (Note we do this AFTER all of the profiling
   7765             // stuff above because profiling can currently happen only in the primary
   7766             // instrumentation process.)
   7767             if (mActiveInstrumentation.size() > 0 && app.instr == null) {
   7768                 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
   7769                     ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
   7770                     if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
   7771                         if (aInstr.mTargetProcesses.length == 0) {
   7772                             // This is the wildcard mode, where every process brought up for
   7773                             // the target instrumentation should be included.
   7774                             if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
   7775                                 app.instr = aInstr;
   7776                                 aInstr.mRunningProcesses.add(app);
   7777                             }
   7778                         } else {
   7779                             for (String proc : aInstr.mTargetProcesses) {
   7780                                 if (proc.equals(app.processName)) {
   7781                                     app.instr = aInstr;
   7782                                     aInstr.mRunningProcesses.add(app);
   7783                                     break;
   7784                                 }
   7785                             }
   7786                         }
   7787                     }
   7788                 }
   7789             }
   7790 
   7791             // If we were asked to attach an agent on startup, do so now, before we're binding
   7792             // application code.
   7793             if (preBindAgent != null) {
   7794                 thread.attachAgent(preBindAgent);
   7795             }
   7796 
   7797 
   7798             // Figure out whether the app needs to run in autofill compat mode.
   7799             boolean isAutofillCompatEnabled = false;
   7800             if (UserHandle.getAppId(app.info.uid) >= Process.FIRST_APPLICATION_UID) {
   7801                 final AutofillManagerInternal afm = LocalServices.getService(
   7802                         AutofillManagerInternal.class);
   7803                 if (afm != null) {
   7804                     isAutofillCompatEnabled = afm.isCompatibilityModeRequested(
   7805                             app.info.packageName, app.info.versionCode, app.userId);
   7806                 }
   7807             }
   7808 
   7809             checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
   7810             mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(app);
   7811             if (app.isolatedEntryPoint != null) {
   7812                 // This is an isolated process which should just call an entry point instead of
   7813                 // being bound to an application.
   7814                 thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
   7815             } else if (app.instr != null) {
   7816                 thread.bindApplication(processName, appInfo, providers,
   7817                         app.instr.mClass,
   7818                         profilerInfo, app.instr.mArguments,
   7819                         app.instr.mWatcher,
   7820                         app.instr.mUiAutomationConnection, testMode,
   7821                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
   7822                         isRestrictedBackupMode || !normalMode, app.persistent,
   7823                         new Configuration(getGlobalConfiguration()), app.compat,
   7824                         getCommonServicesLocked(app.isolated),
   7825                         mCoreSettingsObserver.getCoreSettingsLocked(),
   7826                         buildSerial, isAutofillCompatEnabled);
   7827             } else {
   7828                 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
   7829                         null, null, null, testMode,
   7830                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
   7831                         isRestrictedBackupMode || !normalMode, app.persistent,
   7832                         new Configuration(getGlobalConfiguration()), app.compat,
   7833                         getCommonServicesLocked(app.isolated),
   7834                         mCoreSettingsObserver.getCoreSettingsLocked(),
   7835                         buildSerial, isAutofillCompatEnabled);
   7836             }
   7837             if (profilerInfo != null) {
   7838                 profilerInfo.closeFd();
   7839                 profilerInfo = null;
   7840             }
   7841             checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
   7842             updateLruProcessLocked(app, false, null);
   7843             checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
   7844             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
   7845         } catch (Exception e) {
   7846             // todo: Yikes!  What should we do?  For now we will try to
   7847             // start another process, but that could easily get us in
   7848             // an infinite loop of restarting processes...
   7849             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
   7850 
   7851             app.resetPackageList(mProcessStats);
   7852             app.unlinkDeathRecipient();
   7853             startProcessLocked(app, "bind fail", processName);
   7854             return false;
   7855         }
   7856 
   7857         // Remove this record from the list of starting applications.
   7858         mPersistentStartingProcesses.remove(app);
   7859         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
   7860                 "Attach application locked removing on hold: " + app);
   7861         mProcessesOnHold.remove(app);
   7862 
   7863         boolean badApp = false;
   7864         boolean didSomething = false;
   7865 
   7866         // See if the top visible activity is waiting to run in this process...
   7867         if (normalMode) {
   7868             try {
   7869                 if (mStackSupervisor.attachApplicationLocked(app)) {
   7870                     didSomething = true;
   7871                 }
   7872             } catch (Exception e) {
   7873                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
   7874                 badApp = true;
   7875             }
   7876         }
   7877 
   7878         // Find any services that should be running in this process...
   7879         if (!badApp) {
   7880             try {
   7881                 didSomething |= mServices.attachApplicationLocked(app, processName);
   7882                 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
   7883             } catch (Exception e) {
   7884                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
   7885                 badApp = true;
   7886             }
   7887         }
   7888 
   7889         // Check if a next-broadcast receiver is in this process...
   7890         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
   7891             try {
   7892                 didSomething |= sendPendingBroadcastsLocked(app);
   7893                 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
   7894             } catch (Exception e) {
   7895                 // If the app died trying to launch the receiver we declare it 'bad'
   7896                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
   7897                 badApp = true;
   7898             }
   7899         }
   7900 
   7901         // Check whether the next backup agent is in this process...
   7902         if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
   7903             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
   7904                     "New app is backup target, launching agent for " + app);
   7905             notifyPackageUse(mBackupTarget.appInfo.packageName,
   7906                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
   7907             try {
   7908                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
   7909                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
   7910                         mBackupTarget.backupMode);
   7911             } catch (Exception e) {
   7912                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
   7913                 badApp = true;
   7914             }
   7915         }
   7916 
   7917         if (badApp) {
   7918             app.kill("error during init", true);
   7919             handleAppDiedLocked(app, false, true);
   7920             return false;
   7921         }
   7922 
   7923         if (!didSomething) {
   7924             updateOomAdjLocked();
   7925             checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
   7926         }
   7927 
   7928         return true;
   7929     }
   7930 
   7931     @Override
   7932     public final void attachApplication(IApplicationThread thread, long startSeq) {
   7933         synchronized (this) {
   7934             int callingPid = Binder.getCallingPid();
   7935             final int callingUid = Binder.getCallingUid();
   7936             final long origId = Binder.clearCallingIdentity();
   7937             attachApplicationLocked(thread, callingPid, callingUid, startSeq);
   7938             Binder.restoreCallingIdentity(origId);
   7939         }
   7940     }
   7941 
   7942     @Override
   7943     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
   7944         final long origId = Binder.clearCallingIdentity();
   7945         synchronized (this) {
   7946             ActivityStack stack = ActivityRecord.getStackLocked(token);
   7947             if (stack != null) {
   7948                 ActivityRecord r =
   7949                         mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
   7950                                 false /* processPausingActivities */, config);
   7951                 if (stopProfiling) {
   7952                     if ((mProfileProc == r.app) && mProfilerInfo != null) {
   7953                         clearProfilerLocked();
   7954                     }
   7955                 }
   7956             }
   7957         }
   7958         Binder.restoreCallingIdentity(origId);
   7959     }
   7960 
   7961     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
   7962         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
   7963                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
   7964     }
   7965 
   7966     void enableScreenAfterBoot() {
   7967         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
   7968                 SystemClock.uptimeMillis());
   7969         mWindowManager.enableScreenAfterBoot();
   7970 
   7971         synchronized (this) {
   7972             updateEventDispatchingLocked();
   7973         }
   7974     }
   7975 
   7976     @Override
   7977     public void showBootMessage(final CharSequence msg, final boolean always) {
   7978         if (Binder.getCallingUid() != myUid()) {
   7979             throw new SecurityException();
   7980         }
   7981         mWindowManager.showBootMessage(msg, always);
   7982     }
   7983 
   7984     @Override
   7985     public void keyguardGoingAway(int flags) {
   7986         enforceNotIsolatedCaller("keyguardGoingAway");
   7987         final long token = Binder.clearCallingIdentity();
   7988         try {
   7989             synchronized (this) {
   7990                 mKeyguardController.keyguardGoingAway(flags);
   7991             }
   7992         } finally {
   7993             Binder.restoreCallingIdentity(token);
   7994         }
   7995     }
   7996 
   7997     /**
   7998      * @return whther the keyguard is currently locked.
   7999      */
   8000     boolean isKeyguardLocked() {
   8001         return mKeyguardController.isKeyguardLocked();
   8002     }
   8003 
   8004     final void finishBooting() {
   8005         synchronized (this) {
   8006             if (!mBootAnimationComplete) {
   8007                 mCallFinishBooting = true;
   8008                 return;
   8009             }
   8010             mCallFinishBooting = false;
   8011         }
   8012 
   8013         ArraySet<String> completedIsas = new ArraySet<String>();
   8014         for (String abi : Build.SUPPORTED_ABIS) {
   8015             zygoteProcess.establishZygoteConnectionForAbi(abi);
   8016             final String instructionSet = VMRuntime.getInstructionSet(abi);
   8017             if (!completedIsas.contains(instructionSet)) {
   8018                 try {
   8019                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
   8020                 } catch (InstallerException e) {
   8021                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
   8022                             e.getMessage() +")");
   8023                 }
   8024                 completedIsas.add(instructionSet);
   8025             }
   8026         }
   8027 
   8028         IntentFilter pkgFilter = new IntentFilter();
   8029         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
   8030         pkgFilter.addDataScheme("package");
   8031         mContext.registerReceiver(new BroadcastReceiver() {
   8032             @Override
   8033             public void onReceive(Context context, Intent intent) {
   8034                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
   8035                 if (pkgs != null) {
   8036                     for (String pkg : pkgs) {
   8037                         synchronized (ActivityManagerService.this) {
   8038                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
   8039                                     0, "query restart")) {
   8040                                 setResultCode(Activity.RESULT_OK);
   8041                                 return;
   8042                             }
   8043                         }
   8044                     }
   8045                 }
   8046             }
   8047         }, pkgFilter);
   8048 
   8049         IntentFilter dumpheapFilter = new IntentFilter();
   8050         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
   8051         mContext.registerReceiver(new BroadcastReceiver() {
   8052             @Override
   8053             public void onReceive(Context context, Intent intent) {
   8054                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
   8055                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
   8056                 } else {
   8057                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
   8058                 }
   8059             }
   8060         }, dumpheapFilter);
   8061 
   8062         // Let system services know.
   8063         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
   8064 
   8065         synchronized (this) {
   8066             // Ensure that any processes we had put on hold are now started
   8067             // up.
   8068             final int NP = mProcessesOnHold.size();
   8069             if (NP > 0) {
   8070                 ArrayList<ProcessRecord> procs =
   8071                     new ArrayList<ProcessRecord>(mProcessesOnHold);
   8072                 for (int ip=0; ip<NP; ip++) {
   8073                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
   8074                             + procs.get(ip));
   8075                     startProcessLocked(procs.get(ip), "on-hold", null);
   8076                 }
   8077             }
   8078             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   8079                 return;
   8080             }
   8081             // Start looking for apps that are abusing wake locks.
   8082             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
   8083             mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
   8084             // Tell anyone interested that we are done booting!
   8085             SystemProperties.set("sys.boot_completed", "1");
   8086 
   8087             // And trigger dev.bootcomplete if we are not showing encryption progress
   8088             if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
   8089                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
   8090                 SystemProperties.set("dev.bootcomplete", "1");
   8091             }
   8092             mUserController.sendBootCompleted(
   8093                     new IIntentReceiver.Stub() {
   8094                         @Override
   8095                         public void performReceive(Intent intent, int resultCode,
   8096                                 String data, Bundle extras, boolean ordered,
   8097                                 boolean sticky, int sendingUser) {
   8098                             synchronized (ActivityManagerService.this) {
   8099                                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
   8100                             }
   8101                         }
   8102                     });
   8103             mUserController.scheduleStartProfiles();
   8104         }
   8105     }
   8106 
   8107     @Override
   8108     public void bootAnimationComplete() {
   8109         final boolean callFinishBooting;
   8110         synchronized (this) {
   8111             callFinishBooting = mCallFinishBooting;
   8112             mBootAnimationComplete = true;
   8113         }
   8114         if (callFinishBooting) {
   8115             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
   8116             finishBooting();
   8117             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   8118         }
   8119     }
   8120 
   8121     final void ensureBootCompleted() {
   8122         boolean booting;
   8123         boolean enableScreen;
   8124         synchronized (this) {
   8125             booting = mBooting;
   8126             mBooting = false;
   8127             enableScreen = !mBooted;
   8128             mBooted = true;
   8129         }
   8130 
   8131         if (booting) {
   8132             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
   8133             finishBooting();
   8134             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   8135         }
   8136 
   8137         if (enableScreen) {
   8138             enableScreenAfterBoot();
   8139         }
   8140     }
   8141 
   8142     @Override
   8143     public final void activityResumed(IBinder token) {
   8144         final long origId = Binder.clearCallingIdentity();
   8145         synchronized(this) {
   8146             ActivityRecord.activityResumedLocked(token);
   8147             mWindowManager.notifyAppResumedFinished(token);
   8148         }
   8149         Binder.restoreCallingIdentity(origId);
   8150     }
   8151 
   8152     @Override
   8153     public final void activityPaused(IBinder token) {
   8154         final long origId = Binder.clearCallingIdentity();
   8155         synchronized(this) {
   8156             ActivityStack stack = ActivityRecord.getStackLocked(token);
   8157             if (stack != null) {
   8158                 stack.activityPausedLocked(token, false);
   8159             }
   8160         }
   8161         Binder.restoreCallingIdentity(origId);
   8162     }
   8163 
   8164     @Override
   8165     public final void activityStopped(IBinder token, Bundle icicle,
   8166             PersistableBundle persistentState, CharSequence description) {
   8167         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
   8168 
   8169         // Refuse possible leaked file descriptors
   8170         if (icicle != null && icicle.hasFileDescriptors()) {
   8171             throw new IllegalArgumentException("File descriptors passed in Bundle");
   8172         }
   8173 
   8174         final long origId = Binder.clearCallingIdentity();
   8175 
   8176         synchronized (this) {
   8177             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   8178             if (r != null) {
   8179                 r.activityStoppedLocked(icicle, persistentState, description);
   8180             }
   8181         }
   8182 
   8183         trimApplications();
   8184 
   8185         Binder.restoreCallingIdentity(origId);
   8186     }
   8187 
   8188     @Override
   8189     public final void activityDestroyed(IBinder token) {
   8190         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
   8191         synchronized (this) {
   8192             ActivityStack stack = ActivityRecord.getStackLocked(token);
   8193             if (stack != null) {
   8194                 stack.activityDestroyedLocked(token, "activityDestroyed");
   8195             }
   8196         }
   8197     }
   8198 
   8199     @Override
   8200     public final void activityRelaunched(IBinder token) {
   8201         final long origId = Binder.clearCallingIdentity();
   8202         synchronized (this) {
   8203             mStackSupervisor.activityRelaunchedLocked(token);
   8204         }
   8205         Binder.restoreCallingIdentity(origId);
   8206     }
   8207 
   8208     @Override
   8209     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
   8210             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
   8211         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
   8212                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
   8213         synchronized (this) {
   8214             ActivityRecord record = ActivityRecord.isInStackLocked(token);
   8215             if (record == null) {
   8216                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
   8217                         + "found for: " + token);
   8218             }
   8219             record.setSizeConfigurations(horizontalSizeConfiguration,
   8220                     verticalSizeConfigurations, smallestSizeConfigurations);
   8221         }
   8222     }
   8223 
   8224     @Override
   8225     public final void notifyLaunchTaskBehindComplete(IBinder token) {
   8226         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
   8227     }
   8228 
   8229     @Override
   8230     public final void notifyEnterAnimationComplete(IBinder token) {
   8231         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
   8232     }
   8233 
   8234     @Override
   8235     public String getCallingPackage(IBinder token) {
   8236         synchronized (this) {
   8237             ActivityRecord r = getCallingRecordLocked(token);
   8238             return r != null ? r.info.packageName : null;
   8239         }
   8240     }
   8241 
   8242     @Override
   8243     public ComponentName getCallingActivity(IBinder token) {
   8244         synchronized (this) {
   8245             ActivityRecord r = getCallingRecordLocked(token);
   8246             return r != null ? r.intent.getComponent() : null;
   8247         }
   8248     }
   8249 
   8250     private ActivityRecord getCallingRecordLocked(IBinder token) {
   8251         ActivityRecord r = ActivityRecord.isInStackLocked(token);
   8252         if (r == null) {
   8253             return null;
   8254         }
   8255         return r.resultTo;
   8256     }
   8257 
   8258     @Override
   8259     public ComponentName getActivityClassForToken(IBinder token) {
   8260         synchronized(this) {
   8261             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   8262             if (r == null) {
   8263                 return null;
   8264             }
   8265             return r.intent.getComponent();
   8266         }
   8267     }
   8268 
   8269     @Override
   8270     public String getPackageForToken(IBinder token) {
   8271         synchronized(this) {
   8272             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   8273             if (r == null) {
   8274                 return null;
   8275             }
   8276             return r.packageName;
   8277         }
   8278     }
   8279 
   8280     @Override
   8281     public boolean isRootVoiceInteraction(IBinder token) {
   8282         synchronized(this) {
   8283             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   8284             if (r == null) {
   8285                 return false;
   8286             }
   8287             return r.rootVoiceInteraction;
   8288         }
   8289     }
   8290 
   8291     @Override
   8292     public IIntentSender getIntentSender(int type,
   8293             String packageName, IBinder token, String resultWho,
   8294             int requestCode, Intent[] intents, String[] resolvedTypes,
   8295             int flags, Bundle bOptions, int userId) {
   8296         enforceNotIsolatedCaller("getIntentSender");
   8297         // Refuse possible leaked file descriptors
   8298         if (intents != null) {
   8299             if (intents.length < 1) {
   8300                 throw new IllegalArgumentException("Intents array length must be >= 1");
   8301             }
   8302             for (int i=0; i<intents.length; i++) {
   8303                 Intent intent = intents[i];
   8304                 if (intent != null) {
   8305                     if (intent.hasFileDescriptors()) {
   8306                         throw new IllegalArgumentException("File descriptors passed in Intent");
   8307                     }
   8308                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
   8309                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   8310                         throw new IllegalArgumentException(
   8311                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   8312                     }
   8313                     intents[i] = new Intent(intent);
   8314                 }
   8315             }
   8316             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
   8317                 throw new IllegalArgumentException(
   8318                         "Intent array length does not match resolvedTypes length");
   8319             }
   8320         }
   8321         if (bOptions != null) {
   8322             if (bOptions.hasFileDescriptors()) {
   8323                 throw new IllegalArgumentException("File descriptors passed in options");
   8324             }
   8325         }
   8326 
   8327         synchronized(this) {
   8328             int callingUid = Binder.getCallingUid();
   8329             int origUserId = userId;
   8330             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
   8331                     type == ActivityManager.INTENT_SENDER_BROADCAST,
   8332                     ALLOW_NON_FULL, "getIntentSender", null);
   8333             if (origUserId == UserHandle.USER_CURRENT) {
   8334                 // We don't want to evaluate this until the pending intent is
   8335                 // actually executed.  However, we do want to always do the
   8336                 // security checking for it above.
   8337                 userId = UserHandle.USER_CURRENT;
   8338             }
   8339             try {
   8340                 if (callingUid != 0 && callingUid != SYSTEM_UID) {
   8341                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
   8342                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
   8343                     if (!UserHandle.isSameApp(callingUid, uid)) {
   8344                         String msg = "Permission Denial: getIntentSender() from pid="
   8345                             + Binder.getCallingPid()
   8346                             + ", uid=" + Binder.getCallingUid()
   8347                             + ", (need uid=" + uid + ")"
   8348                             + " is not allowed to send as package " + packageName;
   8349                         Slog.w(TAG, msg);
   8350                         throw new SecurityException(msg);
   8351                     }
   8352                 }
   8353 
   8354                 return getIntentSenderLocked(type, packageName, callingUid, userId,
   8355                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
   8356 
   8357             } catch (RemoteException e) {
   8358                 throw new SecurityException(e);
   8359             }
   8360         }
   8361     }
   8362 
   8363     IIntentSender getIntentSenderLocked(int type, String packageName,
   8364             int callingUid, int userId, IBinder token, String resultWho,
   8365             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
   8366             Bundle bOptions) {
   8367         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
   8368         ActivityRecord activity = null;
   8369         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   8370             activity = ActivityRecord.isInStackLocked(token);
   8371             if (activity == null) {
   8372                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
   8373                 return null;
   8374             }
   8375             if (activity.finishing) {
   8376                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
   8377                 return null;
   8378             }
   8379         }
   8380 
   8381         // We're going to be splicing together extras before sending, so we're
   8382         // okay poking into any contained extras.
   8383         if (intents != null) {
   8384             for (int i = 0; i < intents.length; i++) {
   8385                 intents[i].setDefusable(true);
   8386             }
   8387         }
   8388         Bundle.setDefusable(bOptions, true);
   8389 
   8390         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
   8391         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
   8392         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
   8393         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
   8394                 |PendingIntent.FLAG_UPDATE_CURRENT);
   8395 
   8396         PendingIntentRecord.Key key = new PendingIntentRecord.Key(type, packageName, activity,
   8397                 resultWho, requestCode, intents, resolvedTypes, flags,
   8398                 SafeActivityOptions.fromBundle(bOptions), userId);
   8399         WeakReference<PendingIntentRecord> ref;
   8400         ref = mIntentSenderRecords.get(key);
   8401         PendingIntentRecord rec = ref != null ? ref.get() : null;
   8402         if (rec != null) {
   8403             if (!cancelCurrent) {
   8404                 if (updateCurrent) {
   8405                     if (rec.key.requestIntent != null) {
   8406                         rec.key.requestIntent.replaceExtras(intents != null ?
   8407                                 intents[intents.length - 1] : null);
   8408                     }
   8409                     if (intents != null) {
   8410                         intents[intents.length-1] = rec.key.requestIntent;
   8411                         rec.key.allIntents = intents;
   8412                         rec.key.allResolvedTypes = resolvedTypes;
   8413                     } else {
   8414                         rec.key.allIntents = null;
   8415                         rec.key.allResolvedTypes = null;
   8416                     }
   8417                 }
   8418                 return rec;
   8419             }
   8420             makeIntentSenderCanceledLocked(rec);
   8421             mIntentSenderRecords.remove(key);
   8422         }
   8423         if (noCreate) {
   8424             return rec;
   8425         }
   8426         rec = new PendingIntentRecord(this, key, callingUid);
   8427         mIntentSenderRecords.put(key, rec.ref);
   8428         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   8429             if (activity.pendingResults == null) {
   8430                 activity.pendingResults
   8431                         = new HashSet<WeakReference<PendingIntentRecord>>();
   8432             }
   8433             activity.pendingResults.add(rec.ref);
   8434         }
   8435         return rec;
   8436     }
   8437 
   8438     @Override
   8439     public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
   8440             Intent intent, String resolvedType,
   8441             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
   8442         if (target instanceof PendingIntentRecord) {
   8443             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
   8444                     whitelistToken, finishedReceiver, requiredPermission, options);
   8445         } else {
   8446             if (intent == null) {
   8447                 // Weird case: someone has given us their own custom IIntentSender, and now
   8448                 // they have someone else trying to send to it but of course this isn't
   8449                 // really a PendingIntent, so there is no base Intent, and the caller isn't
   8450                 // supplying an Intent... but we never want to dispatch a null Intent to
   8451                 // a receiver, so um...  let's make something up.
   8452                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
   8453                 intent = new Intent(Intent.ACTION_MAIN);
   8454             }
   8455             try {
   8456                 target.send(code, intent, resolvedType, whitelistToken, null,
   8457                         requiredPermission, options);
   8458             } catch (RemoteException e) {
   8459             }
   8460             // Platform code can rely on getting a result back when the send is done, but if
   8461             // this intent sender is from outside of the system we can't rely on it doing that.
   8462             // So instead we don't give it the result receiver, and instead just directly
   8463             // report the finish immediately.
   8464             if (finishedReceiver != null) {
   8465                 try {
   8466                     finishedReceiver.performReceive(intent, 0,
   8467                             null, null, false, false, UserHandle.getCallingUserId());
   8468                 } catch (RemoteException e) {
   8469                 }
   8470             }
   8471             return 0;
   8472         }
   8473     }
   8474 
   8475     @Override
   8476     public void cancelIntentSender(IIntentSender sender) {
   8477         if (!(sender instanceof PendingIntentRecord)) {
   8478             return;
   8479         }
   8480         synchronized(this) {
   8481             PendingIntentRecord rec = (PendingIntentRecord)sender;
   8482             try {
   8483                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
   8484                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
   8485                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
   8486                     String msg = "Permission Denial: cancelIntentSender() from pid="
   8487                         + Binder.getCallingPid()
   8488                         + ", uid=" + Binder.getCallingUid()
   8489                         + " is not allowed to cancel package "
   8490                         + rec.key.packageName;
   8491                     Slog.w(TAG, msg);
   8492                     throw new SecurityException(msg);
   8493                 }
   8494             } catch (RemoteException e) {
   8495                 throw new SecurityException(e);
   8496             }
   8497             cancelIntentSenderLocked(rec, true);
   8498         }
   8499     }
   8500 
   8501     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
   8502         makeIntentSenderCanceledLocked(rec);
   8503         mIntentSenderRecords.remove(rec.key);
   8504         if (cleanActivity && rec.key.activity != null) {
   8505             rec.key.activity.pendingResults.remove(rec.ref);
   8506         }
   8507     }
   8508 
   8509     void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
   8510         rec.canceled = true;
   8511         RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
   8512         if (callbacks != null) {
   8513             mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
   8514         }
   8515     }
   8516 
   8517     @Override
   8518     public String getPackageForIntentSender(IIntentSender pendingResult) {
   8519         if (!(pendingResult instanceof PendingIntentRecord)) {
   8520             return null;
   8521         }
   8522         try {
   8523             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   8524             return res.key.packageName;
   8525         } catch (ClassCastException e) {
   8526         }
   8527         return null;
   8528     }
   8529 
   8530     @Override
   8531     public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
   8532         if (!(sender instanceof PendingIntentRecord)) {
   8533             return;
   8534         }
   8535         boolean isCancelled;
   8536         synchronized(this) {
   8537             PendingIntentRecord pendingIntent = (PendingIntentRecord) sender;
   8538             isCancelled = pendingIntent.canceled;
   8539             if (!isCancelled) {
   8540                 pendingIntent.registerCancelListenerLocked(receiver);
   8541             }
   8542         }
   8543         if (isCancelled) {
   8544             try {
   8545                 receiver.send(Activity.RESULT_CANCELED, null);
   8546             } catch (RemoteException e) {
   8547             }
   8548         }
   8549     }
   8550 
   8551     @Override
   8552     public void unregisterIntentSenderCancelListener(IIntentSender sender,
   8553             IResultReceiver receiver) {
   8554         if (!(sender instanceof PendingIntentRecord)) {
   8555             return;
   8556         }
   8557         synchronized(this) {
   8558             ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
   8559         }
   8560     }
   8561 
   8562     @Override
   8563     public int getUidForIntentSender(IIntentSender sender) {
   8564         if (sender instanceof PendingIntentRecord) {
   8565             try {
   8566                 PendingIntentRecord res = (PendingIntentRecord)sender;
   8567                 return res.uid;
   8568             } catch (ClassCastException e) {
   8569             }
   8570         }
   8571         return -1;
   8572     }
   8573 
   8574     @Override
   8575     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
   8576         if (!(pendingResult instanceof PendingIntentRecord)) {
   8577             return false;
   8578         }
   8579         try {
   8580             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   8581             if (res.key.allIntents == null) {
   8582                 return false;
   8583             }
   8584             for (int i=0; i<res.key.allIntents.length; i++) {
   8585                 Intent intent = res.key.allIntents[i];
   8586                 if (intent.getPackage() != null && intent.getComponent() != null) {
   8587                     return false;
   8588                 }
   8589             }
   8590             return true;
   8591         } catch (ClassCastException e) {
   8592         }
   8593         return false;
   8594     }
   8595 
   8596     @Override
   8597     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
   8598         if (!(pendingResult instanceof PendingIntentRecord)) {
   8599             return false;
   8600         }
   8601         try {
   8602             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   8603             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
   8604                 return true;
   8605             }
   8606             return false;
   8607         } catch (ClassCastException e) {
   8608         }
   8609         return false;
   8610     }
   8611 
   8612     @Override
   8613     public boolean isIntentSenderAForegroundService(IIntentSender pendingResult) {
   8614         if (pendingResult instanceof PendingIntentRecord) {
   8615             final PendingIntentRecord res = (PendingIntentRecord) pendingResult;
   8616             return res.key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE;
   8617         }
   8618         return false;
   8619     }
   8620 
   8621     @Override
   8622     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
   8623         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
   8624                 "getIntentForIntentSender()");
   8625         if (!(pendingResult instanceof PendingIntentRecord)) {
   8626             return null;
   8627         }
   8628         try {
   8629             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   8630             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
   8631         } catch (ClassCastException e) {
   8632         }
   8633         return null;
   8634     }
   8635 
   8636     @Override
   8637     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
   8638         if (!(pendingResult instanceof PendingIntentRecord)) {
   8639             return null;
   8640         }
   8641         try {
   8642             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   8643             synchronized (this) {
   8644                 return getTagForIntentSenderLocked(res, prefix);
   8645             }
   8646         } catch (ClassCastException e) {
   8647         }
   8648         return null;
   8649     }
   8650 
   8651     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
   8652         final Intent intent = res.key.requestIntent;
   8653         if (intent != null) {
   8654             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
   8655                     || res.lastTagPrefix.equals(prefix))) {
   8656                 return res.lastTag;
   8657             }
   8658             res.lastTagPrefix = prefix;
   8659             final StringBuilder sb = new StringBuilder(128);
   8660             if (prefix != null) {
   8661                 sb.append(prefix);
   8662             }
   8663             if (intent.getAction() != null) {
   8664                 sb.append(intent.getAction());
   8665             } else if (intent.getComponent() != null) {
   8666                 intent.getComponent().appendShortString(sb);
   8667             } else {
   8668                 sb.append("?");
   8669             }
   8670             return res.lastTag = sb.toString();
   8671         }
   8672         return null;
   8673     }
   8674 
   8675     @Override
   8676     public void setProcessLimit(int max) {
   8677         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   8678                 "setProcessLimit()");
   8679         synchronized (this) {
   8680             mConstants.setOverrideMaxCachedProcesses(max);
   8681         }
   8682         trimApplications();
   8683     }
   8684 
   8685     @Override
   8686     public int getProcessLimit() {
   8687         synchronized (this) {
   8688             return mConstants.getOverrideMaxCachedProcesses();
   8689         }
   8690     }
   8691 
   8692     void importanceTokenDied(ImportanceToken token) {
   8693         synchronized (ActivityManagerService.this) {
   8694             synchronized (mPidsSelfLocked) {
   8695                 ImportanceToken cur
   8696                     = mImportantProcesses.get(token.pid);
   8697                 if (cur != token) {
   8698                     return;
   8699                 }
   8700                 mImportantProcesses.remove(token.pid);
   8701                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
   8702                 if (pr == null) {
   8703                     return;
   8704                 }
   8705                 pr.forcingToImportant = null;
   8706                 updateProcessForegroundLocked(pr, false, false);
   8707             }
   8708             updateOomAdjLocked();
   8709         }
   8710     }
   8711 
   8712     @Override
   8713     public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
   8714         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   8715                 "setProcessImportant()");
   8716         synchronized(this) {
   8717             boolean changed = false;
   8718 
   8719             synchronized (mPidsSelfLocked) {
   8720                 ProcessRecord pr = mPidsSelfLocked.get(pid);
   8721                 if (pr == null && isForeground) {
   8722                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
   8723                     return;
   8724                 }
   8725                 ImportanceToken oldToken = mImportantProcesses.get(pid);
   8726                 if (oldToken != null) {
   8727                     oldToken.token.unlinkToDeath(oldToken, 0);
   8728                     mImportantProcesses.remove(pid);
   8729                     if (pr != null) {
   8730                         pr.forcingToImportant = null;
   8731                     }
   8732                     changed = true;
   8733                 }
   8734                 if (isForeground && token != null) {
   8735                     ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
   8736                         @Override
   8737                         public void binderDied() {
   8738                             importanceTokenDied(this);
   8739                         }
   8740                     };
   8741                     try {
   8742                         token.linkToDeath(newToken, 0);
   8743                         mImportantProcesses.put(pid, newToken);
   8744                         pr.forcingToImportant = newToken;
   8745                         changed = true;
   8746                     } catch (RemoteException e) {
   8747                         // If the process died while doing this, we will later
   8748                         // do the cleanup with the process death link.
   8749                     }
   8750                 }
   8751             }
   8752 
   8753             if (changed) {
   8754                 updateOomAdjLocked();
   8755             }
   8756         }
   8757     }
   8758 
   8759     @Override
   8760     public boolean isAppForeground(int uid) {
   8761         synchronized (this) {
   8762             UidRecord uidRec = mActiveUids.get(uid);
   8763             if (uidRec == null || uidRec.idle) {
   8764                 return false;
   8765             }
   8766             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   8767         }
   8768     }
   8769 
   8770     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
   8771     // be guarded by permission checking.
   8772     int getUidState(int uid) {
   8773         synchronized (this) {
   8774             return getUidStateLocked(uid);
   8775         }
   8776     }
   8777 
   8778     int getUidStateLocked(int uid) {
   8779         UidRecord uidRec = mActiveUids.get(uid);
   8780         return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
   8781     }
   8782 
   8783     @Override
   8784     public boolean isInMultiWindowMode(IBinder token) {
   8785         final long origId = Binder.clearCallingIdentity();
   8786         try {
   8787             synchronized(this) {
   8788                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   8789                 if (r == null) {
   8790                     return false;
   8791                 }
   8792                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
   8793                 return r.inMultiWindowMode();
   8794             }
   8795         } finally {
   8796             Binder.restoreCallingIdentity(origId);
   8797         }
   8798     }
   8799 
   8800     @Override
   8801     public boolean isInPictureInPictureMode(IBinder token) {
   8802         final long origId = Binder.clearCallingIdentity();
   8803         try {
   8804             synchronized(this) {
   8805                 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
   8806             }
   8807         } finally {
   8808             Binder.restoreCallingIdentity(origId);
   8809         }
   8810     }
   8811 
   8812     private boolean isInPictureInPictureMode(ActivityRecord r) {
   8813         if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
   8814                 || r.getStack().isInStackLocked(r) == null) {
   8815             return false;
   8816         }
   8817 
   8818         // If we are animating to fullscreen then we have already dispatched the PIP mode
   8819         // changed, so we should reflect that check here as well.
   8820         final PinnedActivityStack stack = r.getStack();
   8821         final PinnedStackWindowController windowController = stack.getWindowContainerController();
   8822         return !windowController.isAnimatingBoundsToFullscreen();
   8823     }
   8824 
   8825     @Override
   8826     public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
   8827         final long origId = Binder.clearCallingIdentity();
   8828         try {
   8829             synchronized(this) {
   8830                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
   8831                         "enterPictureInPictureMode", token, params);
   8832 
   8833                 // If the activity is already in picture in picture mode, then just return early
   8834                 if (isInPictureInPictureMode(r)) {
   8835                     return true;
   8836                 }
   8837 
   8838                 // Activity supports picture-in-picture, now check that we can enter PiP at this
   8839                 // point, if it is
   8840                 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
   8841                         false /* beforeStopping */)) {
   8842                     return false;
   8843                 }
   8844 
   8845                 final Runnable enterPipRunnable = () -> {
   8846                     // Only update the saved args from the args that are set
   8847                     r.pictureInPictureArgs.copyOnlySet(params);
   8848                     final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
   8849                     final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
   8850                     // Adjust the source bounds by the insets for the transition down
   8851                     final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
   8852                     mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
   8853                             "enterPictureInPictureMode");
   8854                     final PinnedActivityStack stack = r.getStack();
   8855                     stack.setPictureInPictureAspectRatio(aspectRatio);
   8856                     stack.setPictureInPictureActions(actions);
   8857                     MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
   8858                             r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
   8859                     logPictureInPictureArgs(params);
   8860                 };
   8861 
   8862                 if (isKeyguardLocked()) {
   8863                     // If the keyguard is showing or occluded, then try and dismiss it before
   8864                     // entering picture-in-picture (this will prompt the user to authenticate if the
   8865                     // device is currently locked).
   8866                     try {
   8867                         dismissKeyguard(token, new KeyguardDismissCallback() {
   8868                             @Override
   8869                             public void onDismissSucceeded() throws RemoteException {
   8870                                 mHandler.post(enterPipRunnable);
   8871                             }
   8872                         }, null /* message */);
   8873                     } catch (RemoteException e) {
   8874                         // Local call
   8875                     }
   8876                 } else {
   8877                     // Enter picture in picture immediately otherwise
   8878                     enterPipRunnable.run();
   8879                 }
   8880                 return true;
   8881             }
   8882         } finally {
   8883             Binder.restoreCallingIdentity(origId);
   8884         }
   8885     }
   8886 
   8887     @Override
   8888     public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
   8889         final long origId = Binder.clearCallingIdentity();
   8890         try {
   8891             synchronized(this) {
   8892                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
   8893                         "setPictureInPictureParams", token, params);
   8894 
   8895                 // Only update the saved args from the args that are set
   8896                 r.pictureInPictureArgs.copyOnlySet(params);
   8897                 if (r.inPinnedWindowingMode()) {
   8898                     // If the activity is already in picture-in-picture, update the pinned stack now
   8899                     // if it is not already expanding to fullscreen. Otherwise, the arguments will
   8900                     // be used the next time the activity enters PiP
   8901                     final PinnedActivityStack stack = r.getStack();
   8902                     if (!stack.isAnimatingBoundsToFullscreen()) {
   8903                         stack.setPictureInPictureAspectRatio(
   8904                                 r.pictureInPictureArgs.getAspectRatio());
   8905                         stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
   8906                     }
   8907                 }
   8908                 logPictureInPictureArgs(params);
   8909             }
   8910         } finally {
   8911             Binder.restoreCallingIdentity(origId);
   8912         }
   8913     }
   8914 
   8915     @Override
   8916     public int getMaxNumPictureInPictureActions(IBinder token) {
   8917         // Currently, this is a static constant, but later, we may change this to be dependent on
   8918         // the context of the activity
   8919         return 3;
   8920     }
   8921 
   8922     private void logPictureInPictureArgs(PictureInPictureParams params) {
   8923         if (params.hasSetActions()) {
   8924             MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
   8925                     params.getActions().size());
   8926         }
   8927         if (params.hasSetAspectRatio()) {
   8928             LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
   8929             lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
   8930             MetricsLogger.action(lm);
   8931         }
   8932     }
   8933 
   8934     /**
   8935      * Checks the state of the system and the activity associated with the given {@param token} to
   8936      * verify that picture-in-picture is supported for that activity.
   8937      *
   8938      * @return the activity record for the given {@param token} if all the checks pass.
   8939      */
   8940     private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
   8941             IBinder token, PictureInPictureParams params) {
   8942         if (!mSupportsPictureInPicture) {
   8943             throw new IllegalStateException(caller
   8944                     + ": Device doesn't support picture-in-picture mode.");
   8945         }
   8946 
   8947         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   8948         if (r == null) {
   8949             throw new IllegalStateException(caller
   8950                     + ": Can't find activity for token=" + token);
   8951         }
   8952 
   8953         if (!r.supportsPictureInPicture()) {
   8954             throw new IllegalStateException(caller
   8955                     + ": Current activity does not support picture-in-picture.");
   8956         }
   8957 
   8958         if (params.hasSetAspectRatio()
   8959                 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
   8960                         params.getAspectRatio())) {
   8961             final float minAspectRatio = mContext.getResources().getFloat(
   8962                     com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
   8963             final float maxAspectRatio = mContext.getResources().getFloat(
   8964                     com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
   8965             throw new IllegalArgumentException(String.format(caller
   8966                     + ": Aspect ratio is too extreme (must be between %f and %f).",
   8967                             minAspectRatio, maxAspectRatio));
   8968         }
   8969 
   8970         // Truncate the number of actions if necessary
   8971         params.truncateActions(getMaxNumPictureInPictureActions(token));
   8972 
   8973         return r;
   8974     }
   8975 
   8976     // =========================================================
   8977     // PROCESS INFO
   8978     // =========================================================
   8979 
   8980     static class ProcessInfoService extends IProcessInfoService.Stub {
   8981         final ActivityManagerService mActivityManagerService;
   8982         ProcessInfoService(ActivityManagerService activityManagerService) {
   8983             mActivityManagerService = activityManagerService;
   8984         }
   8985 
   8986         @Override
   8987         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
   8988             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
   8989                     /*in*/ pids, /*out*/ states, null);
   8990         }
   8991 
   8992         @Override
   8993         public void getProcessStatesAndOomScoresFromPids(
   8994                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
   8995             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
   8996                     /*in*/ pids, /*out*/ states, /*out*/ scores);
   8997         }
   8998     }
   8999 
   9000     /**
   9001      * For each PID in the given input array, write the current process state
   9002      * for that process into the states array, or -1 to indicate that no
   9003      * process with the given PID exists. If scores array is provided, write
   9004      * the oom score for the process into the scores array, with INVALID_ADJ
   9005      * indicating the PID doesn't exist.
   9006      */
   9007     public void getProcessStatesAndOomScoresForPIDs(
   9008             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
   9009         if (scores != null) {
   9010             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
   9011                     "getProcessStatesAndOomScoresForPIDs()");
   9012         }
   9013 
   9014         if (pids == null) {
   9015             throw new NullPointerException("pids");
   9016         } else if (states == null) {
   9017             throw new NullPointerException("states");
   9018         } else if (pids.length != states.length) {
   9019             throw new IllegalArgumentException("pids and states arrays have different lengths!");
   9020         } else if (scores != null && pids.length != scores.length) {
   9021             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
   9022         }
   9023 
   9024         synchronized (mPidsSelfLocked) {
   9025             for (int i = 0; i < pids.length; i++) {
   9026                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
   9027                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
   9028                         pr.curProcState;
   9029                 if (scores != null) {
   9030                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
   9031                 }
   9032             }
   9033         }
   9034     }
   9035 
   9036     // =========================================================
   9037     // PERMISSIONS
   9038     // =========================================================
   9039 
   9040     static class PermissionController extends IPermissionController.Stub {
   9041         ActivityManagerService mActivityManagerService;
   9042         PermissionController(ActivityManagerService activityManagerService) {
   9043             mActivityManagerService = activityManagerService;
   9044         }
   9045 
   9046         @Override
   9047         public boolean checkPermission(String permission, int pid, int uid) {
   9048             return mActivityManagerService.checkPermission(permission, pid,
   9049                     uid) == PackageManager.PERMISSION_GRANTED;
   9050         }
   9051 
   9052         @Override
   9053         public int noteOp(String op, int uid, String packageName) {
   9054             return mActivityManagerService.mAppOpsService
   9055                     .noteOperation(AppOpsManager.strOpToOp(op), uid, packageName);
   9056         }
   9057 
   9058         @Override
   9059         public String[] getPackagesForUid(int uid) {
   9060             return mActivityManagerService.mContext.getPackageManager()
   9061                     .getPackagesForUid(uid);
   9062         }
   9063 
   9064         @Override
   9065         public boolean isRuntimePermission(String permission) {
   9066             try {
   9067                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
   9068                         .getPermissionInfo(permission, 0);
   9069                 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
   9070                         == PermissionInfo.PROTECTION_DANGEROUS;
   9071             } catch (NameNotFoundException nnfe) {
   9072                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
   9073             }
   9074             return false;
   9075         }
   9076 
   9077         @Override
   9078         public int getPackageUid(String packageName, int flags) {
   9079             try {
   9080                 return mActivityManagerService.mContext.getPackageManager()
   9081                         .getPackageUid(packageName, flags);
   9082             } catch (NameNotFoundException nnfe) {
   9083                 return -1;
   9084             }
   9085         }
   9086     }
   9087 
   9088     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
   9089         @Override
   9090         public int checkComponentPermission(String permission, int pid, int uid,
   9091                 int owningUid, boolean exported) {
   9092             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
   9093                     owningUid, exported);
   9094         }
   9095 
   9096         @Override
   9097         public Object getAMSLock() {
   9098             return ActivityManagerService.this;
   9099         }
   9100     }
   9101 
   9102     int checkComponentPermission(String permission, int pid, int uid,
   9103             int owningUid, boolean exported) {
   9104         if (pid == MY_PID) {
   9105             return PackageManager.PERMISSION_GRANTED;
   9106         }
   9107         return ActivityManager.checkComponentPermission(permission, uid,
   9108                 owningUid, exported);
   9109     }
   9110 
   9111     /**
   9112      * As the only public entry point for permissions checking, this method
   9113      * can enforce the semantic that requesting a check on a null global
   9114      * permission is automatically denied.  (Internally a null permission
   9115      * string is used when calling {@link #checkComponentPermission} in cases
   9116      * when only uid-based security is needed.)
   9117      *
   9118      * This can be called with or without the global lock held.
   9119      */
   9120     @Override
   9121     public int checkPermission(String permission, int pid, int uid) {
   9122         if (permission == null) {
   9123             return PackageManager.PERMISSION_DENIED;
   9124         }
   9125         return checkComponentPermission(permission, pid, uid, -1, true);
   9126     }
   9127 
   9128     @Override
   9129     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
   9130         if (permission == null) {
   9131             return PackageManager.PERMISSION_DENIED;
   9132         }
   9133 
   9134         // We might be performing an operation on behalf of an indirect binder
   9135         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
   9136         // client identity accordingly before proceeding.
   9137         Identity tlsIdentity = sCallerIdentity.get();
   9138         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
   9139             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
   9140                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
   9141             uid = tlsIdentity.uid;
   9142             pid = tlsIdentity.pid;
   9143         }
   9144 
   9145         return checkComponentPermission(permission, pid, uid, -1, true);
   9146     }
   9147 
   9148     /**
   9149      * Binder IPC calls go through the public entry point.
   9150      * This can be called with or without the global lock held.
   9151      */
   9152     int checkCallingPermission(String permission) {
   9153         return checkPermission(permission,
   9154                 Binder.getCallingPid(),
   9155                 UserHandle.getAppId(Binder.getCallingUid()));
   9156     }
   9157 
   9158     /**
   9159      * This can be called with or without the global lock held.
   9160      */
   9161     void enforceCallingPermission(String permission, String func) {
   9162         if (checkCallingPermission(permission)
   9163                 == PackageManager.PERMISSION_GRANTED) {
   9164             return;
   9165         }
   9166 
   9167         String msg = "Permission Denial: " + func + " from pid="
   9168                 + Binder.getCallingPid()
   9169                 + ", uid=" + Binder.getCallingUid()
   9170                 + " requires " + permission;
   9171         Slog.w(TAG, msg);
   9172         throw new SecurityException(msg);
   9173     }
   9174 
   9175     /**
   9176      * This can be called with or without the global lock held.
   9177      */
   9178     void enforcePermission(String permission, int pid, int uid, String func) {
   9179         if (checkPermission(permission, pid, uid) == PackageManager.PERMISSION_GRANTED) {
   9180             return;
   9181         }
   9182 
   9183         String msg = "Permission Denial: " + func + " from pid=" + pid + ", uid=" + uid
   9184                 + " requires " + permission;
   9185         Slog.w(TAG, msg);
   9186         throw new SecurityException(msg);
   9187     }
   9188 
   9189     /**
   9190      * This can be called with or without the global lock held.
   9191      */
   9192     void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
   9193         if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) {
   9194             enforceCallingPermission(permission, func);
   9195         }
   9196     }
   9197 
   9198     /**
   9199      * Determine if UID is holding permissions required to access {@link Uri} in
   9200      * the given {@link ProviderInfo}. Final permission checking is always done
   9201      * in {@link ContentProvider}.
   9202      */
   9203     private final boolean checkHoldingPermissionsLocked(
   9204             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
   9205         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   9206                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
   9207         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
   9208             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
   9209                     != PERMISSION_GRANTED) {
   9210                 return false;
   9211             }
   9212         }
   9213         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
   9214     }
   9215 
   9216     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
   9217             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
   9218         if (pi.applicationInfo.uid == uid) {
   9219             return true;
   9220         } else if (!pi.exported) {
   9221             return false;
   9222         }
   9223 
   9224         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
   9225         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
   9226         try {
   9227             // check if target holds top-level <provider> permissions
   9228             if (!readMet && pi.readPermission != null && considerUidPermissions
   9229                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
   9230                 readMet = true;
   9231             }
   9232             if (!writeMet && pi.writePermission != null && considerUidPermissions
   9233                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
   9234                 writeMet = true;
   9235             }
   9236 
   9237             // track if unprotected read/write is allowed; any denied
   9238             // <path-permission> below removes this ability
   9239             boolean allowDefaultRead = pi.readPermission == null;
   9240             boolean allowDefaultWrite = pi.writePermission == null;
   9241 
   9242             // check if target holds any <path-permission> that match uri
   9243             final PathPermission[] pps = pi.pathPermissions;
   9244             if (pps != null) {
   9245                 final String path = grantUri.uri.getPath();
   9246                 int i = pps.length;
   9247                 while (i > 0 && (!readMet || !writeMet)) {
   9248                     i--;
   9249                     PathPermission pp = pps[i];
   9250                     if (pp.match(path)) {
   9251                         if (!readMet) {
   9252                             final String pprperm = pp.getReadPermission();
   9253                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   9254                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
   9255                                     + ": match=" + pp.match(path)
   9256                                     + " check=" + pm.checkUidPermission(pprperm, uid));
   9257                             if (pprperm != null) {
   9258                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
   9259                                         == PERMISSION_GRANTED) {
   9260                                     readMet = true;
   9261                                 } else {
   9262                                     allowDefaultRead = false;
   9263                                 }
   9264                             }
   9265                         }
   9266                         if (!writeMet) {
   9267                             final String ppwperm = pp.getWritePermission();
   9268                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   9269                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
   9270                                     + ": match=" + pp.match(path)
   9271                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
   9272                             if (ppwperm != null) {
   9273                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
   9274                                         == PERMISSION_GRANTED) {
   9275                                     writeMet = true;
   9276                                 } else {
   9277                                     allowDefaultWrite = false;
   9278                                 }
   9279                             }
   9280                         }
   9281                     }
   9282                 }
   9283             }
   9284 
   9285             // grant unprotected <provider> read/write, if not blocked by
   9286             // <path-permission> above
   9287             if (allowDefaultRead) readMet = true;
   9288             if (allowDefaultWrite) writeMet = true;
   9289 
   9290         } catch (RemoteException e) {
   9291             return false;
   9292         }
   9293 
   9294         return readMet && writeMet;
   9295     }
   9296 
   9297     public boolean isAppStartModeDisabled(int uid, String packageName) {
   9298         synchronized (this) {
   9299             return getAppStartModeLocked(uid, packageName, 0, -1, false, true, false)
   9300                     == ActivityManager.APP_START_MODE_DISABLED;
   9301         }
   9302     }
   9303 
   9304     // Unified app-op and target sdk check
   9305     int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
   9306         // Apps that target O+ are always subject to background check
   9307         if (packageTargetSdk >= Build.VERSION_CODES.O) {
   9308             if (DEBUG_BACKGROUND_CHECK) {
   9309                 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
   9310             }
   9311             return ActivityManager.APP_START_MODE_DELAYED_RIGID;
   9312         }
   9313         // ...and legacy apps get an AppOp check
   9314         int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
   9315                 uid, packageName);
   9316         if (DEBUG_BACKGROUND_CHECK) {
   9317             Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
   9318         }
   9319         switch (appop) {
   9320             case AppOpsManager.MODE_ALLOWED:
   9321                 // If force-background-check is enabled, restrict all apps that aren't whitelisted.
   9322                 if (mForceBackgroundCheck &&
   9323                         !UserHandle.isCore(uid) &&
   9324                         !isOnDeviceIdleWhitelistLocked(uid, /*allowExceptIdleToo=*/ true)) {
   9325                     if (DEBUG_BACKGROUND_CHECK) {
   9326                         Slog.i(TAG, "Force background check: " +
   9327                                 uid + "/" + packageName + " restricted");
   9328                     }
   9329                     return ActivityManager.APP_START_MODE_DELAYED;
   9330                 }
   9331                 return ActivityManager.APP_START_MODE_NORMAL;
   9332             case AppOpsManager.MODE_IGNORED:
   9333                 return ActivityManager.APP_START_MODE_DELAYED;
   9334             default:
   9335                 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
   9336         }
   9337     }
   9338 
   9339     // Service launch is available to apps with run-in-background exemptions but
   9340     // some other background operations are not.  If we're doing a check
   9341     // of service-launch policy, allow those callers to proceed unrestricted.
   9342     int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
   9343         // Persistent app?
   9344         if (mPackageManagerInt.isPackagePersistent(packageName)) {
   9345             if (DEBUG_BACKGROUND_CHECK) {
   9346                 Slog.i(TAG, "App " + uid + "/" + packageName
   9347                         + " is persistent; not restricted in background");
   9348             }
   9349             return ActivityManager.APP_START_MODE_NORMAL;
   9350         }
   9351 
   9352         // Non-persistent but background whitelisted?
   9353         if (uidOnBackgroundWhitelist(uid)) {
   9354             if (DEBUG_BACKGROUND_CHECK) {
   9355                 Slog.i(TAG, "App " + uid + "/" + packageName
   9356                         + " on background whitelist; not restricted in background");
   9357             }
   9358             return ActivityManager.APP_START_MODE_NORMAL;
   9359         }
   9360 
   9361         // Is this app on the battery whitelist?
   9362         if (isOnDeviceIdleWhitelistLocked(uid, /*allowExceptIdleToo=*/ false)) {
   9363             if (DEBUG_BACKGROUND_CHECK) {
   9364                 Slog.i(TAG, "App " + uid + "/" + packageName
   9365                         + " on idle whitelist; not restricted in background");
   9366             }
   9367             return ActivityManager.APP_START_MODE_NORMAL;
   9368         }
   9369 
   9370         // None of the service-policy criteria apply, so we apply the common criteria
   9371         return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
   9372     }
   9373 
   9374     int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
   9375             int callingPid, boolean alwaysRestrict, boolean disabledOnly, boolean forcedStandby) {
   9376         UidRecord uidRec = mActiveUids.get(uid);
   9377         if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
   9378                 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
   9379                 + (uidRec != null ? uidRec.idle : false));
   9380         if (uidRec == null || alwaysRestrict || forcedStandby || uidRec.idle) {
   9381             boolean ephemeral;
   9382             if (uidRec == null) {
   9383                 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
   9384                         UserHandle.getUserId(uid), packageName);
   9385             } else {
   9386                 ephemeral = uidRec.ephemeral;
   9387             }
   9388 
   9389             if (ephemeral) {
   9390                 // We are hard-core about ephemeral apps not running in the background.
   9391                 return ActivityManager.APP_START_MODE_DISABLED;
   9392             } else {
   9393                 if (disabledOnly) {
   9394                     // The caller is only interested in whether app starts are completely
   9395                     // disabled for the given package (that is, it is an instant app).  So
   9396                     // we don't need to go further, which is all just seeing if we should
   9397                     // apply a "delayed" mode for a regular app.
   9398                     return ActivityManager.APP_START_MODE_NORMAL;
   9399                 }
   9400                 final int startMode = (alwaysRestrict)
   9401                         ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
   9402                         : appServicesRestrictedInBackgroundLocked(uid, packageName,
   9403                                 packageTargetSdk);
   9404                 if (DEBUG_BACKGROUND_CHECK) {
   9405                     Slog.d(TAG, "checkAllowBackground: uid=" + uid
   9406                             + " pkg=" + packageName + " startMode=" + startMode
   9407                             + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid, false)
   9408                             + " onwhitelist(ei)=" + isOnDeviceIdleWhitelistLocked(uid, true));
   9409                 }
   9410                 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
   9411                     // This is an old app that has been forced into a "compatible as possible"
   9412                     // mode of background check.  To increase compatibility, we will allow other
   9413                     // foreground apps to cause its services to start.
   9414                     if (callingPid >= 0) {
   9415                         ProcessRecord proc;
   9416                         synchronized (mPidsSelfLocked) {
   9417                             proc = mPidsSelfLocked.get(callingPid);
   9418                         }
   9419                         if (proc != null &&
   9420                                 !ActivityManager.isProcStateBackground(proc.curProcState)) {
   9421                             // Whoever is instigating this is in the foreground, so we will allow it
   9422                             // to go through.
   9423                             return ActivityManager.APP_START_MODE_NORMAL;
   9424                         }
   9425                     }
   9426                 }
   9427                 return startMode;
   9428             }
   9429         }
   9430         return ActivityManager.APP_START_MODE_NORMAL;
   9431     }
   9432 
   9433     /**
   9434      * @return whether a UID is in the system, user or temp doze whitelist.
   9435      */
   9436     boolean isOnDeviceIdleWhitelistLocked(int uid, boolean allowExceptIdleToo) {
   9437         final int appId = UserHandle.getAppId(uid);
   9438 
   9439         final int[] whitelist = allowExceptIdleToo
   9440                 ? mDeviceIdleExceptIdleWhitelist
   9441                 : mDeviceIdleWhitelist;
   9442 
   9443         return Arrays.binarySearch(whitelist, appId) >= 0
   9444                 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
   9445                 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
   9446     }
   9447 
   9448     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
   9449         ProviderInfo pi = null;
   9450         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
   9451         if (cpr != null) {
   9452             pi = cpr.info;
   9453         } else {
   9454             try {
   9455                 pi = AppGlobals.getPackageManager().resolveContentProvider(
   9456                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
   9457                         userHandle);
   9458             } catch (RemoteException ex) {
   9459             }
   9460         }
   9461         return pi;
   9462     }
   9463 
   9464     void grantEphemeralAccessLocked(int userId, Intent intent,
   9465             int targetAppId, int ephemeralAppId) {
   9466         getPackageManagerInternalLocked().
   9467                 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
   9468     }
   9469 
   9470     @GuardedBy("this")
   9471     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
   9472         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
   9473         if (targetUris != null) {
   9474             return targetUris.get(grantUri);
   9475         }
   9476         return null;
   9477     }
   9478 
   9479     @GuardedBy("this")
   9480     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
   9481             String targetPkg, int targetUid, GrantUri grantUri) {
   9482         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
   9483         if (targetUris == null) {
   9484             targetUris = Maps.newArrayMap();
   9485             mGrantedUriPermissions.put(targetUid, targetUris);
   9486         }
   9487 
   9488         UriPermission perm = targetUris.get(grantUri);
   9489         if (perm == null) {
   9490             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
   9491             targetUris.put(grantUri, perm);
   9492         }
   9493 
   9494         return perm;
   9495     }
   9496 
   9497     @GuardedBy("this")
   9498     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
   9499             final int modeFlags) {
   9500         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
   9501         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
   9502                 : UriPermission.STRENGTH_OWNED;
   9503 
   9504         // Root gets to do everything.
   9505         if (uid == 0) {
   9506             return true;
   9507         }
   9508 
   9509         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   9510         if (perms == null) return false;
   9511 
   9512         // First look for exact match
   9513         final UriPermission exactPerm = perms.get(grantUri);
   9514         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
   9515             return true;
   9516         }
   9517 
   9518         // No exact match, look for prefixes
   9519         final int N = perms.size();
   9520         for (int i = 0; i < N; i++) {
   9521             final UriPermission perm = perms.valueAt(i);
   9522             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
   9523                     && perm.getStrength(modeFlags) >= minStrength) {
   9524                 return true;
   9525             }
   9526         }
   9527 
   9528         return false;
   9529     }
   9530 
   9531     /**
   9532      * @param uri This uri must NOT contain an embedded userId.
   9533      * @param userId The userId in which the uri is to be resolved.
   9534      */
   9535     @Override
   9536     public int checkUriPermission(Uri uri, int pid, int uid,
   9537             final int modeFlags, int userId, IBinder callerToken) {
   9538         enforceNotIsolatedCaller("checkUriPermission");
   9539 
   9540         // Another redirected-binder-call permissions check as in
   9541         // {@link checkPermissionWithToken}.
   9542         Identity tlsIdentity = sCallerIdentity.get();
   9543         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
   9544             uid = tlsIdentity.uid;
   9545             pid = tlsIdentity.pid;
   9546         }
   9547 
   9548         // Our own process gets to do everything.
   9549         if (pid == MY_PID) {
   9550             return PackageManager.PERMISSION_GRANTED;
   9551         }
   9552         synchronized (this) {
   9553             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
   9554                     ? PackageManager.PERMISSION_GRANTED
   9555                     : PackageManager.PERMISSION_DENIED;
   9556         }
   9557     }
   9558 
   9559     /**
   9560      * Check if the targetPkg can be granted permission to access uri by
   9561      * the callingUid using the given modeFlags.  Throws a security exception
   9562      * if callingUid is not allowed to do this.  Returns the uid of the target
   9563      * if the URI permission grant should be performed; returns -1 if it is not
   9564      * needed (for example targetPkg already has permission to access the URI).
   9565      * If you already know the uid of the target, you can supply it in
   9566      * lastTargetUid else set that to -1.
   9567      */
   9568     @GuardedBy("this")
   9569     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
   9570             final int modeFlags, int lastTargetUid) {
   9571         if (!Intent.isAccessUriMode(modeFlags)) {
   9572             return -1;
   9573         }
   9574 
   9575         if (targetPkg != null) {
   9576             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   9577                     "Checking grant " + targetPkg + " permission to " + grantUri);
   9578         }
   9579 
   9580         final IPackageManager pm = AppGlobals.getPackageManager();
   9581 
   9582         // If this is not a content: uri, we can't do anything with it.
   9583         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
   9584             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   9585                     "Can't grant URI permission for non-content URI: " + grantUri);
   9586             return -1;
   9587         }
   9588 
   9589         // Bail early if system is trying to hand out permissions directly; it
   9590         // must always grant permissions on behalf of someone explicit.
   9591         final int callingAppId = UserHandle.getAppId(callingUid);
   9592         if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
   9593             if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
   9594                 // Exempted authority for
   9595                 // 1. cropping user photos and sharing a generated license html
   9596                 //    file in Settings app
   9597                 // 2. sharing a generated license html file in TvSettings app
   9598             } else {
   9599                 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
   9600                         + " grant to " + grantUri + "; use startActivityAsCaller() instead");
   9601                 return -1;
   9602             }
   9603         }
   9604 
   9605         final String authority = grantUri.uri.getAuthority();
   9606         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
   9607                 MATCH_DEBUG_TRIAGED_MISSING);
   9608         if (pi == null) {
   9609             Slog.w(TAG, "No content provider found for permission check: " +
   9610                     grantUri.uri.toSafeString());
   9611             return -1;
   9612         }
   9613 
   9614         int targetUid = lastTargetUid;
   9615         if (targetUid < 0 && targetPkg != null) {
   9616             try {
   9617                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
   9618                         UserHandle.getUserId(callingUid));
   9619                 if (targetUid < 0) {
   9620                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   9621                             "Can't grant URI permission no uid for: " + targetPkg);
   9622                     return -1;
   9623                 }
   9624             } catch (RemoteException ex) {
   9625                 return -1;
   9626             }
   9627         }
   9628 
   9629         // If we're extending a persistable grant, then we always need to create
   9630         // the grant data structure so that take/release APIs work
   9631         if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
   9632             return targetUid;
   9633         }
   9634 
   9635         if (targetUid >= 0) {
   9636             // First...  does the target actually need this permission?
   9637             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
   9638                 // No need to grant the target this permission.
   9639                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   9640                         "Target " + targetPkg + " already has full permission to " + grantUri);
   9641                 return -1;
   9642             }
   9643         } else {
   9644             // First...  there is no target package, so can anyone access it?
   9645             boolean allowed = pi.exported;
   9646             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   9647                 if (pi.readPermission != null) {
   9648                     allowed = false;
   9649                 }
   9650             }
   9651             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   9652                 if (pi.writePermission != null) {
   9653                     allowed = false;
   9654                 }
   9655             }
   9656             if (pi.pathPermissions != null) {
   9657                 final int N = pi.pathPermissions.length;
   9658                 for (int i=0; i<N; i++) {
   9659                     if (pi.pathPermissions[i] != null
   9660                             && pi.pathPermissions[i].match(grantUri.uri.getPath())) {
   9661                         if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   9662                             if (pi.pathPermissions[i].getReadPermission() != null) {
   9663                                 allowed = false;
   9664                             }
   9665                         }
   9666                         if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   9667                             if (pi.pathPermissions[i].getWritePermission() != null) {
   9668                                 allowed = false;
   9669                             }
   9670                         }
   9671                         break;
   9672                     }
   9673                 }
   9674             }
   9675             if (allowed) {
   9676                 return -1;
   9677             }
   9678         }
   9679 
   9680         /* There is a special cross user grant if:
   9681          * - The target is on another user.
   9682          * - Apps on the current user can access the uri without any uid permissions.
   9683          * In this case, we grant a uri permission, even if the ContentProvider does not normally
   9684          * grant uri permissions.
   9685          */
   9686         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
   9687                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
   9688                 modeFlags, false /*without considering the uid permissions*/);
   9689 
   9690         // Second...  is the provider allowing granting of URI permissions?
   9691         if (!specialCrossUserGrant) {
   9692             if (!pi.grantUriPermissions) {
   9693                 throw new SecurityException("Provider " + pi.packageName
   9694                         + "/" + pi.name
   9695                         + " does not allow granting of Uri permissions (uri "
   9696                         + grantUri + ")");
   9697             }
   9698             if (pi.uriPermissionPatterns != null) {
   9699                 final int N = pi.uriPermissionPatterns.length;
   9700                 boolean allowed = false;
   9701                 for (int i=0; i<N; i++) {
   9702                     if (pi.uriPermissionPatterns[i] != null
   9703                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
   9704                         allowed = true;
   9705                         break;
   9706                     }
   9707                 }
   9708                 if (!allowed) {
   9709                     throw new SecurityException("Provider " + pi.packageName
   9710                             + "/" + pi.name
   9711                             + " does not allow granting of permission to path of Uri "
   9712                             + grantUri);
   9713                 }
   9714             }
   9715         }
   9716 
   9717         // Third...  does the caller itself have permission to access
   9718         // this uri?
   9719         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
   9720             // Require they hold a strong enough Uri permission
   9721             if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
   9722                 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
   9723                     throw new SecurityException(
   9724                             "UID " + callingUid + " does not have permission to " + grantUri
   9725                                     + "; you could obtain access using ACTION_OPEN_DOCUMENT "
   9726                                     + "or related APIs");
   9727                 } else {
   9728                     throw new SecurityException(
   9729                             "UID " + callingUid + " does not have permission to " + grantUri);
   9730                 }
   9731             }
   9732         }
   9733         return targetUid;
   9734     }
   9735 
   9736     /**
   9737      * @param uri This uri must NOT contain an embedded userId.
   9738      * @param userId The userId in which the uri is to be resolved.
   9739      */
   9740     @Override
   9741     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
   9742             final int modeFlags, int userId) {
   9743         enforceNotIsolatedCaller("checkGrantUriPermission");
   9744         synchronized(this) {
   9745             return checkGrantUriPermissionLocked(callingUid, targetPkg,
   9746                     new GrantUri(userId, uri, false), modeFlags, -1);
   9747         }
   9748     }
   9749 
   9750     @GuardedBy("this")
   9751     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
   9752             final int modeFlags, UriPermissionOwner owner) {
   9753         if (!Intent.isAccessUriMode(modeFlags)) {
   9754             return;
   9755         }
   9756 
   9757         // So here we are: the caller has the assumed permission
   9758         // to the uri, and the target doesn't.  Let's now give this to
   9759         // the target.
   9760 
   9761         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   9762                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
   9763 
   9764         final String authority = grantUri.uri.getAuthority();
   9765         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
   9766                 MATCH_DEBUG_TRIAGED_MISSING);
   9767         if (pi == null) {
   9768             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
   9769             return;
   9770         }
   9771 
   9772         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
   9773             grantUri.prefix = true;
   9774         }
   9775         final UriPermission perm = findOrCreateUriPermissionLocked(
   9776                 pi.packageName, targetPkg, targetUid, grantUri);
   9777         perm.grantModes(modeFlags, owner);
   9778     }
   9779 
   9780     @GuardedBy("this")
   9781     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
   9782             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
   9783         if (targetPkg == null) {
   9784             throw new NullPointerException("targetPkg");
   9785         }
   9786         int targetUid;
   9787         final IPackageManager pm = AppGlobals.getPackageManager();
   9788         try {
   9789             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
   9790         } catch (RemoteException ex) {
   9791             return;
   9792         }
   9793 
   9794         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
   9795                 targetUid);
   9796         if (targetUid < 0) {
   9797             return;
   9798         }
   9799 
   9800         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
   9801                 owner);
   9802     }
   9803 
   9804     static class NeededUriGrants extends ArrayList<GrantUri> {
   9805         final String targetPkg;
   9806         final int targetUid;
   9807         final int flags;
   9808 
   9809         NeededUriGrants(String targetPkg, int targetUid, int flags) {
   9810             this.targetPkg = targetPkg;
   9811             this.targetUid = targetUid;
   9812             this.flags = flags;
   9813         }
   9814 
   9815         void writeToProto(ProtoOutputStream proto, long fieldId) {
   9816             long token = proto.start(fieldId);
   9817             proto.write(NeededUriGrantsProto.TARGET_PACKAGE, targetPkg);
   9818             proto.write(NeededUriGrantsProto.TARGET_UID, targetUid);
   9819             proto.write(NeededUriGrantsProto.FLAGS, flags);
   9820 
   9821             final int N = this.size();
   9822             for (int i=0; i<N; i++) {
   9823                 this.get(i).writeToProto(proto, NeededUriGrantsProto.GRANTS);
   9824             }
   9825             proto.end(token);
   9826         }
   9827     }
   9828 
   9829     /**
   9830      * Like checkGrantUriPermissionLocked, but takes an Intent.
   9831      */
   9832     @GuardedBy("this")
   9833     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
   9834             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
   9835         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   9836                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
   9837                 + " clip=" + (intent != null ? intent.getClipData() : null)
   9838                 + " from " + intent + "; flags=0x"
   9839                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
   9840 
   9841         if (targetPkg == null) {
   9842             throw new NullPointerException("targetPkg");
   9843         }
   9844 
   9845         if (intent == null) {
   9846             return null;
   9847         }
   9848         Uri data = intent.getData();
   9849         ClipData clip = intent.getClipData();
   9850         if (data == null && clip == null) {
   9851             return null;
   9852         }
   9853         // Default userId for uris in the intent (if they don't specify it themselves)
   9854         int contentUserHint = intent.getContentUserHint();
   9855         if (contentUserHint == UserHandle.USER_CURRENT) {
   9856             contentUserHint = UserHandle.getUserId(callingUid);
   9857         }
   9858         final IPackageManager pm = AppGlobals.getPackageManager();
   9859         int targetUid;
   9860         if (needed != null) {
   9861             targetUid = needed.targetUid;
   9862         } else {
   9863             try {
   9864                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
   9865                         targetUserId);
   9866             } catch (RemoteException ex) {
   9867                 return null;
   9868             }
   9869             if (targetUid < 0) {
   9870                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   9871                         "Can't grant URI permission no uid for: " + targetPkg
   9872                         + " on user " + targetUserId);
   9873                 return null;
   9874             }
   9875         }
   9876         if (data != null) {
   9877             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
   9878             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
   9879                     targetUid);
   9880             if (targetUid > 0) {
   9881                 if (needed == null) {
   9882                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
   9883                 }
   9884                 needed.add(grantUri);
   9885             }
   9886         }
   9887         if (clip != null) {
   9888             for (int i=0; i<clip.getItemCount(); i++) {
   9889                 Uri uri = clip.getItemAt(i).getUri();
   9890                 if (uri != null) {
   9891                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
   9892                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
   9893                             targetUid);
   9894                     if (targetUid > 0) {
   9895                         if (needed == null) {
   9896                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
   9897                         }
   9898                         needed.add(grantUri);
   9899                     }
   9900                 } else {
   9901                     Intent clipIntent = clip.getItemAt(i).getIntent();
   9902                     if (clipIntent != null) {
   9903                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
   9904                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
   9905                         if (newNeeded != null) {
   9906                             needed = newNeeded;
   9907                         }
   9908                     }
   9909                 }
   9910             }
   9911         }
   9912 
   9913         return needed;
   9914     }
   9915 
   9916     /**
   9917      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
   9918      */
   9919     @GuardedBy("this")
   9920     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
   9921             UriPermissionOwner owner) {
   9922         if (needed != null) {
   9923             for (int i=0; i<needed.size(); i++) {
   9924                 GrantUri grantUri = needed.get(i);
   9925                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
   9926                         grantUri, needed.flags, owner);
   9927             }
   9928         }
   9929     }
   9930 
   9931     @GuardedBy("this")
   9932     void grantUriPermissionFromIntentLocked(int callingUid,
   9933             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
   9934         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
   9935                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
   9936         if (needed == null) {
   9937             return;
   9938         }
   9939 
   9940         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
   9941     }
   9942 
   9943     /**
   9944      * @param uri This uri must NOT contain an embedded userId.
   9945      * @param userId The userId in which the uri is to be resolved.
   9946      */
   9947     @Override
   9948     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
   9949             final int modeFlags, int userId) {
   9950         enforceNotIsolatedCaller("grantUriPermission");
   9951         GrantUri grantUri = new GrantUri(userId, uri, false);
   9952         synchronized(this) {
   9953             final ProcessRecord r = getRecordForAppLocked(caller);
   9954             if (r == null) {
   9955                 throw new SecurityException("Unable to find app for caller "
   9956                         + caller
   9957                         + " when granting permission to uri " + grantUri);
   9958             }
   9959             if (targetPkg == null) {
   9960                 throw new IllegalArgumentException("null target");
   9961             }
   9962             if (grantUri == null) {
   9963                 throw new IllegalArgumentException("null uri");
   9964             }
   9965 
   9966             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
   9967                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
   9968                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
   9969                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
   9970 
   9971             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
   9972                     UserHandle.getUserId(r.uid));
   9973         }
   9974     }
   9975 
   9976     @GuardedBy("this")
   9977     void removeUriPermissionIfNeededLocked(UriPermission perm) {
   9978         if (perm.modeFlags == 0) {
   9979             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
   9980                     perm.targetUid);
   9981             if (perms != null) {
   9982                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   9983                         "Removing " + perm.targetUid + " permission to " + perm.uri);
   9984 
   9985                 perms.remove(perm.uri);
   9986                 if (perms.isEmpty()) {
   9987                     mGrantedUriPermissions.remove(perm.targetUid);
   9988                 }
   9989             }
   9990         }
   9991     }
   9992 
   9993     @GuardedBy("this")
   9994     private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
   9995             final int modeFlags) {
   9996         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   9997                 "Revoking all granted permissions to " + grantUri);
   9998 
   9999         final IPackageManager pm = AppGlobals.getPackageManager();
   10000         final String authority = grantUri.uri.getAuthority();
   10001         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
   10002                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
   10003         if (pi == null) {
   10004             Slog.w(TAG, "No content provider found for permission revoke: "
   10005                     + grantUri.toSafeString());
   10006             return;
   10007         }
   10008 
   10009         // Does the caller have this permission on the URI?
   10010         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
   10011             // If they don't have direct access to the URI, then revoke any
   10012             // ownerless URI permissions that have been granted to them.
   10013             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   10014             if (perms != null) {
   10015                 boolean persistChanged = false;
   10016                 for (int i = perms.size()-1; i >= 0; i--) {
   10017                     final UriPermission perm = perms.valueAt(i);
   10018                     if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
   10019                         continue;
   10020                     }
   10021                     if (perm.uri.sourceUserId == grantUri.sourceUserId
   10022                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
   10023                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   10024                                 "Revoking non-owned " + perm.targetUid
   10025                                 + " permission to " + perm.uri);
   10026                         persistChanged |= perm.revokeModes(
   10027                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
   10028                         if (perm.modeFlags == 0) {
   10029                             perms.removeAt(i);
   10030                         }
   10031                     }
   10032                 }
   10033                 if (perms.isEmpty()) {
   10034                     mGrantedUriPermissions.remove(callingUid);
   10035                 }
   10036                 if (persistChanged) {
   10037                     schedulePersistUriGrants();
   10038                 }
   10039             }
   10040             return;
   10041         }
   10042 
   10043         boolean persistChanged = false;
   10044 
   10045         // Go through all of the permissions and remove any that match.
   10046         for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
   10047             final int targetUid = mGrantedUriPermissions.keyAt(i);
   10048             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   10049 
   10050             for (int j = perms.size()-1; j >= 0; j--) {
   10051                 final UriPermission perm = perms.valueAt(j);
   10052                 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
   10053                     continue;
   10054                 }
   10055                 if (perm.uri.sourceUserId == grantUri.sourceUserId
   10056                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
   10057                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   10058                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
   10059                     persistChanged |= perm.revokeModes(
   10060                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
   10061                             targetPackage == null);
   10062                     if (perm.modeFlags == 0) {
   10063                         perms.removeAt(j);
   10064                     }
   10065                 }
   10066             }
   10067 
   10068             if (perms.isEmpty()) {
   10069                 mGrantedUriPermissions.removeAt(i);
   10070             }
   10071         }
   10072 
   10073         if (persistChanged) {
   10074             schedulePersistUriGrants();
   10075         }
   10076     }
   10077 
   10078     /**
   10079      * @param uri This uri must NOT contain an embedded userId.
   10080      * @param userId The userId in which the uri is to be resolved.
   10081      */
   10082     @Override
   10083     public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
   10084             final int modeFlags, int userId) {
   10085         enforceNotIsolatedCaller("revokeUriPermission");
   10086         synchronized(this) {
   10087             final ProcessRecord r = getRecordForAppLocked(caller);
   10088             if (r == null) {
   10089                 throw new SecurityException("Unable to find app for caller "
   10090                         + caller
   10091                         + " when revoking permission to uri " + uri);
   10092             }
   10093             if (uri == null) {
   10094                 Slog.w(TAG, "revokeUriPermission: null uri");
   10095                 return;
   10096             }
   10097 
   10098             if (!Intent.isAccessUriMode(modeFlags)) {
   10099                 return;
   10100             }
   10101 
   10102             final String authority = uri.getAuthority();
   10103             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
   10104                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
   10105             if (pi == null) {
   10106                 Slog.w(TAG, "No content provider found for permission revoke: "
   10107                         + uri.toSafeString());
   10108                 return;
   10109             }
   10110 
   10111             revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
   10112                     modeFlags);
   10113         }
   10114     }
   10115 
   10116     /**
   10117      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
   10118      * given package.
   10119      *
   10120      * @param packageName Package name to match, or {@code null} to apply to all
   10121      *            packages.
   10122      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
   10123      *            to all users.
   10124      * @param persistable If persistable grants should be removed.
   10125      * @param targetOnly When {@code true}, only remove permissions where the app is the target,
   10126      * not source.
   10127      */
   10128     @GuardedBy("this")
   10129     private void removeUriPermissionsForPackageLocked(
   10130             String packageName, int userHandle, boolean persistable, boolean targetOnly) {
   10131         if (userHandle == UserHandle.USER_ALL && packageName == null) {
   10132             throw new IllegalArgumentException("Must narrow by either package or user");
   10133         }
   10134 
   10135         boolean persistChanged = false;
   10136 
   10137         int N = mGrantedUriPermissions.size();
   10138         for (int i = 0; i < N; i++) {
   10139             final int targetUid = mGrantedUriPermissions.keyAt(i);
   10140             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   10141 
   10142             // Only inspect grants matching user
   10143             if (userHandle == UserHandle.USER_ALL
   10144                     || userHandle == UserHandle.getUserId(targetUid)) {
   10145                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
   10146                     final UriPermission perm = it.next();
   10147 
   10148                     // Only inspect grants matching package
   10149                     if (packageName == null || (!targetOnly && perm.sourcePkg.equals(packageName))
   10150                             || perm.targetPkg.equals(packageName)) {
   10151                         // Hacky solution as part of fixing a security bug; ignore
   10152                         // grants associated with DownloadManager so we don't have
   10153                         // to immediately launch it to regrant the permissions
   10154                         if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
   10155                                 && !persistable) continue;
   10156 
   10157                         persistChanged |= perm.revokeModes(persistable
   10158                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
   10159 
   10160                         // Only remove when no modes remain; any persisted grants
   10161                         // will keep this alive.
   10162                         if (perm.modeFlags == 0) {
   10163                             it.remove();
   10164                         }
   10165                     }
   10166                 }
   10167 
   10168                 if (perms.isEmpty()) {
   10169                     mGrantedUriPermissions.remove(targetUid);
   10170                     N--;
   10171                     i--;
   10172                 }
   10173             }
   10174         }
   10175 
   10176         if (persistChanged) {
   10177             schedulePersistUriGrants();
   10178         }
   10179     }
   10180 
   10181     @Override
   10182     public IBinder newUriPermissionOwner(String name) {
   10183         enforceNotIsolatedCaller("newUriPermissionOwner");
   10184         synchronized(this) {
   10185             UriPermissionOwner owner = new UriPermissionOwner(this, name);
   10186             return owner.getExternalTokenLocked();
   10187         }
   10188     }
   10189 
   10190     @Override
   10191     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
   10192         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
   10193         synchronized(this) {
   10194             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
   10195             if (r == null) {
   10196                 throw new IllegalArgumentException("Activity does not exist; token="
   10197                         + activityToken);
   10198             }
   10199             return r.getUriPermissionsLocked().getExternalTokenLocked();
   10200         }
   10201     }
   10202     /**
   10203      * @param uri This uri must NOT contain an embedded userId.
   10204      * @param sourceUserId The userId in which the uri is to be resolved.
   10205      * @param targetUserId The userId of the app that receives the grant.
   10206      */
   10207     @Override
   10208     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
   10209             final int modeFlags, int sourceUserId, int targetUserId) {
   10210         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
   10211                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
   10212                 "grantUriPermissionFromOwner", null);
   10213         synchronized(this) {
   10214             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   10215             if (owner == null) {
   10216                 throw new IllegalArgumentException("Unknown owner: " + token);
   10217             }
   10218             if (fromUid != Binder.getCallingUid()) {
   10219                 if (Binder.getCallingUid() != myUid()) {
   10220                     // Only system code can grant URI permissions on behalf
   10221                     // of other users.
   10222                     throw new SecurityException("nice try");
   10223                 }
   10224             }
   10225             if (targetPkg == null) {
   10226                 throw new IllegalArgumentException("null target");
   10227             }
   10228             if (uri == null) {
   10229                 throw new IllegalArgumentException("null uri");
   10230             }
   10231 
   10232             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
   10233                     modeFlags, owner, targetUserId);
   10234         }
   10235     }
   10236 
   10237     /**
   10238      * @param uri This uri must NOT contain an embedded userId.
   10239      * @param userId The userId in which the uri is to be resolved.
   10240      */
   10241     @Override
   10242     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
   10243         synchronized(this) {
   10244             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   10245             if (owner == null) {
   10246                 throw new IllegalArgumentException("Unknown owner: " + token);
   10247             }
   10248 
   10249             if (uri == null) {
   10250                 owner.removeUriPermissionsLocked(mode);
   10251             } else {
   10252                 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
   10253                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
   10254             }
   10255         }
   10256     }
   10257 
   10258     private void schedulePersistUriGrants() {
   10259         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
   10260             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
   10261                     10 * DateUtils.SECOND_IN_MILLIS);
   10262         }
   10263     }
   10264 
   10265     private void writeGrantedUriPermissions() {
   10266         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
   10267 
   10268         final long startTime = SystemClock.uptimeMillis();
   10269 
   10270         // Snapshot permissions so we can persist without lock
   10271         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
   10272         synchronized (this) {
   10273             final int size = mGrantedUriPermissions.size();
   10274             for (int i = 0; i < size; i++) {
   10275                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   10276                 for (UriPermission perm : perms.values()) {
   10277                     if (perm.persistedModeFlags != 0) {
   10278                         persist.add(perm.snapshot());
   10279                     }
   10280                 }
   10281             }
   10282         }
   10283 
   10284         FileOutputStream fos = null;
   10285         try {
   10286             fos = mGrantFile.startWrite(startTime);
   10287 
   10288             XmlSerializer out = new FastXmlSerializer();
   10289             out.setOutput(fos, StandardCharsets.UTF_8.name());
   10290             out.startDocument(null, true);
   10291             out.startTag(null, TAG_URI_GRANTS);
   10292             for (UriPermission.Snapshot perm : persist) {
   10293                 out.startTag(null, TAG_URI_GRANT);
   10294                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
   10295                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
   10296                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
   10297                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
   10298                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
   10299                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
   10300                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
   10301                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
   10302                 out.endTag(null, TAG_URI_GRANT);
   10303             }
   10304             out.endTag(null, TAG_URI_GRANTS);
   10305             out.endDocument();
   10306 
   10307             mGrantFile.finishWrite(fos);
   10308         } catch (IOException e) {
   10309             if (fos != null) {
   10310                 mGrantFile.failWrite(fos);
   10311             }
   10312         }
   10313     }
   10314 
   10315     @GuardedBy("this")
   10316     private void readGrantedUriPermissionsLocked() {
   10317         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
   10318 
   10319         final long now = System.currentTimeMillis();
   10320 
   10321         FileInputStream fis = null;
   10322         try {
   10323             fis = mGrantFile.openRead();
   10324             final XmlPullParser in = Xml.newPullParser();
   10325             in.setInput(fis, StandardCharsets.UTF_8.name());
   10326 
   10327             int type;
   10328             while ((type = in.next()) != END_DOCUMENT) {
   10329                 final String tag = in.getName();
   10330                 if (type == START_TAG) {
   10331                     if (TAG_URI_GRANT.equals(tag)) {
   10332                         final int sourceUserId;
   10333                         final int targetUserId;
   10334                         final int userHandle = readIntAttribute(in,
   10335                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
   10336                         if (userHandle != UserHandle.USER_NULL) {
   10337                             // For backwards compatibility.
   10338                             sourceUserId = userHandle;
   10339                             targetUserId = userHandle;
   10340                         } else {
   10341                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
   10342                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
   10343                         }
   10344                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
   10345                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
   10346                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
   10347                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
   10348                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
   10349                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
   10350 
   10351                         // Sanity check that provider still belongs to source package
   10352                         // Both direct boot aware and unaware packages are fine as we
   10353                         // will do filtering at query time to avoid multiple parsing.
   10354                         final ProviderInfo pi = getProviderInfoLocked(
   10355                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
   10356                                         | MATCH_DIRECT_BOOT_UNAWARE);
   10357                         if (pi != null && sourcePkg.equals(pi.packageName)) {
   10358                             int targetUid = -1;
   10359                             try {
   10360                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
   10361                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
   10362                             } catch (RemoteException e) {
   10363                             }
   10364                             if (targetUid != -1) {
   10365                                 final UriPermission perm = findOrCreateUriPermissionLocked(
   10366                                         sourcePkg, targetPkg, targetUid,
   10367                                         new GrantUri(sourceUserId, uri, prefix));
   10368                                 perm.initPersistedModes(modeFlags, createdTime);
   10369                             }
   10370                         } else {
   10371                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
   10372                                     + " but instead found " + pi);
   10373                         }
   10374                     }
   10375                 }
   10376             }
   10377         } catch (FileNotFoundException e) {
   10378             // Missing grants is okay
   10379         } catch (IOException e) {
   10380             Slog.wtf(TAG, "Failed reading Uri grants", e);
   10381         } catch (XmlPullParserException e) {
   10382             Slog.wtf(TAG, "Failed reading Uri grants", e);
   10383         } finally {
   10384             IoUtils.closeQuietly(fis);
   10385         }
   10386     }
   10387 
   10388     /**
   10389      * @param uri This uri must NOT contain an embedded userId.
   10390      * @param toPackage Name of package whose uri is being granted to (if {@code null}, uses
   10391      * calling uid)
   10392      * @param userId The userId in which the uri is to be resolved.
   10393      */
   10394     @Override
   10395     public void takePersistableUriPermission(Uri uri, final int modeFlags,
   10396             @Nullable String toPackage, int userId) {
   10397         final int uid;
   10398         if (toPackage != null) {
   10399             enforceCallingPermission(android.Manifest.permission.FORCE_PERSISTABLE_URI_PERMISSIONS,
   10400                     "takePersistableUriPermission");
   10401             uid = mPackageManagerInt.getPackageUid(toPackage, 0, userId);
   10402         } else {
   10403             enforceNotIsolatedCaller("takePersistableUriPermission");
   10404             uid = Binder.getCallingUid();
   10405         }
   10406 
   10407         Preconditions.checkFlagsArgument(modeFlags,
   10408                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   10409 
   10410         synchronized (this) {
   10411             boolean persistChanged = false;
   10412             GrantUri grantUri = new GrantUri(userId, uri, false);
   10413 
   10414             UriPermission exactPerm = findUriPermissionLocked(uid, grantUri);
   10415             UriPermission prefixPerm = findUriPermissionLocked(uid,
   10416                     new GrantUri(userId, uri, true));
   10417 
   10418             final boolean exactValid = (exactPerm != null)
   10419                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
   10420             final boolean prefixValid = (prefixPerm != null)
   10421                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
   10422 
   10423             if (!(exactValid || prefixValid)) {
   10424                 throw new SecurityException("No persistable permission grants found for UID "
   10425                         + uid + " and Uri " + grantUri.toSafeString());
   10426             }
   10427 
   10428             if (exactValid) {
   10429                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
   10430             }
   10431             if (prefixValid) {
   10432                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
   10433             }
   10434 
   10435             persistChanged |= maybePrunePersistedUriGrantsLocked(uid);
   10436 
   10437             if (persistChanged) {
   10438                 schedulePersistUriGrants();
   10439             }
   10440         }
   10441     }
   10442 
   10443     /**
   10444      * @param uri This uri must NOT contain an embedded userId.
   10445      * @param toPackage Name of the target package whose uri is being released (if {@code null},
   10446      * uses calling uid)
   10447      * @param userId The userId in which the uri is to be resolved.
   10448      */
   10449     @Override
   10450     public void releasePersistableUriPermission(Uri uri, final int modeFlags,
   10451             @Nullable String toPackage, int userId) {
   10452 
   10453         final int uid;
   10454         if (toPackage != null) {
   10455             enforceCallingPermission(android.Manifest.permission.FORCE_PERSISTABLE_URI_PERMISSIONS,
   10456                     "releasePersistableUriPermission");
   10457             uid = mPackageManagerInt.getPackageUid(toPackage, 0, userId);
   10458         } else {
   10459             enforceNotIsolatedCaller("releasePersistableUriPermission");
   10460             uid = Binder.getCallingUid();
   10461         }
   10462 
   10463         Preconditions.checkFlagsArgument(modeFlags,
   10464                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   10465 
   10466         synchronized (this) {
   10467             boolean persistChanged = false;
   10468 
   10469             UriPermission exactPerm = findUriPermissionLocked(uid,
   10470                     new GrantUri(userId, uri, false));
   10471             UriPermission prefixPerm = findUriPermissionLocked(uid,
   10472                     new GrantUri(userId, uri, true));
   10473             if (exactPerm == null && prefixPerm == null && toPackage == null) {
   10474                 throw new SecurityException("No permission grants found for UID " + uid
   10475                         + " and Uri " + uri.toSafeString());
   10476             }
   10477 
   10478             if (exactPerm != null) {
   10479                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
   10480                 removeUriPermissionIfNeededLocked(exactPerm);
   10481             }
   10482             if (prefixPerm != null) {
   10483                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
   10484                 removeUriPermissionIfNeededLocked(prefixPerm);
   10485             }
   10486 
   10487             if (persistChanged) {
   10488                 schedulePersistUriGrants();
   10489             }
   10490         }
   10491     }
   10492 
   10493     /**
   10494      * Prune any older {@link UriPermission} for the given UID until outstanding
   10495      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
   10496      *
   10497      * @return if any mutations occured that require persisting.
   10498      */
   10499     @GuardedBy("this")
   10500     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
   10501         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   10502         if (perms == null) return false;
   10503         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
   10504 
   10505         final ArrayList<UriPermission> persisted = Lists.newArrayList();
   10506         for (UriPermission perm : perms.values()) {
   10507             if (perm.persistedModeFlags != 0) {
   10508                 persisted.add(perm);
   10509             }
   10510         }
   10511 
   10512         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
   10513         if (trimCount <= 0) return false;
   10514 
   10515         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
   10516         for (int i = 0; i < trimCount; i++) {
   10517             final UriPermission perm = persisted.get(i);
   10518 
   10519             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
   10520                     "Trimming grant created at " + perm.persistedCreateTime);
   10521 
   10522             perm.releasePersistableModes(~0);
   10523             removeUriPermissionIfNeededLocked(perm);
   10524         }
   10525 
   10526         return true;
   10527     }
   10528 
   10529     @Override
   10530     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
   10531             String packageName, boolean incoming) {
   10532         enforceNotIsolatedCaller("getPersistedUriPermissions");
   10533         Preconditions.checkNotNull(packageName, "packageName");
   10534 
   10535         final int callingUid = Binder.getCallingUid();
   10536         final int callingUserId = UserHandle.getUserId(callingUid);
   10537         final IPackageManager pm = AppGlobals.getPackageManager();
   10538         try {
   10539             final int packageUid = pm.getPackageUid(packageName,
   10540                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
   10541             if (packageUid != callingUid) {
   10542                 throw new SecurityException(
   10543                         "Package " + packageName + " does not belong to calling UID " + callingUid);
   10544             }
   10545         } catch (RemoteException e) {
   10546             throw new SecurityException("Failed to verify package name ownership");
   10547         }
   10548 
   10549         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
   10550         synchronized (this) {
   10551             if (incoming) {
   10552                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
   10553                         callingUid);
   10554                 if (perms == null) {
   10555                     Slog.w(TAG, "No permission grants found for " + packageName);
   10556                 } else {
   10557                     for (int j = 0; j < perms.size(); j++) {
   10558                         final UriPermission perm = perms.valueAt(j);
   10559                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
   10560                             result.add(perm.buildPersistedPublicApiObject());
   10561                         }
   10562                     }
   10563                 }
   10564             } else {
   10565                 final int size = mGrantedUriPermissions.size();
   10566                 for (int i = 0; i < size; i++) {
   10567                     final ArrayMap<GrantUri, UriPermission> perms =
   10568                             mGrantedUriPermissions.valueAt(i);
   10569                     for (int j = 0; j < perms.size(); j++) {
   10570                         final UriPermission perm = perms.valueAt(j);
   10571                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
   10572                             result.add(perm.buildPersistedPublicApiObject());
   10573                         }
   10574                     }
   10575                 }
   10576             }
   10577         }
   10578         return new ParceledListSlice<android.content.UriPermission>(result);
   10579     }
   10580 
   10581     @Override
   10582     public ParceledListSlice<GrantedUriPermission> getGrantedUriPermissions(
   10583             @Nullable String packageName, int userId) {
   10584         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
   10585                 "getGrantedUriPermissions");
   10586 
   10587         final List<GrantedUriPermission> result = new ArrayList<>();
   10588         synchronized (this) {
   10589             final int size = mGrantedUriPermissions.size();
   10590             for (int i = 0; i < size; i++) {
   10591                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   10592                 for (int j = 0; j < perms.size(); j++) {
   10593                     final UriPermission perm = perms.valueAt(j);
   10594                     if ((packageName == null || packageName.equals(perm.targetPkg))
   10595                             && perm.targetUserId == userId
   10596                             && perm.persistedModeFlags != 0) {
   10597                         result.add(perm.buildGrantedUriPermission());
   10598                     }
   10599                 }
   10600             }
   10601         }
   10602         return new ParceledListSlice<>(result);
   10603     }
   10604 
   10605     @Override
   10606     public void clearGrantedUriPermissions(String packageName, int userId) {
   10607         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
   10608                 "clearGrantedUriPermissions");
   10609         synchronized(this) {
   10610             removeUriPermissionsForPackageLocked(packageName, userId, true, true);
   10611         }
   10612     }
   10613 
   10614     @Override
   10615     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
   10616         synchronized (this) {
   10617             ProcessRecord app =
   10618                 who != null ? getRecordForAppLocked(who) : null;
   10619             if (app == null) return;
   10620 
   10621             Message msg = Message.obtain();
   10622             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
   10623             msg.obj = app;
   10624             msg.arg1 = waiting ? 1 : 0;
   10625             mUiHandler.sendMessage(msg);
   10626         }
   10627     }
   10628 
   10629     @Override
   10630     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
   10631         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
   10632         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
   10633         outInfo.availMem = getFreeMemory();
   10634         outInfo.totalMem = getTotalMemory();
   10635         outInfo.threshold = homeAppMem;
   10636         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
   10637         outInfo.hiddenAppThreshold = cachedAppMem;
   10638         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
   10639                 ProcessList.SERVICE_ADJ);
   10640         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
   10641                 ProcessList.VISIBLE_APP_ADJ);
   10642         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
   10643                 ProcessList.FOREGROUND_APP_ADJ);
   10644     }
   10645 
   10646     // =========================================================
   10647     // TASK MANAGEMENT
   10648     // =========================================================
   10649 
   10650     @Override
   10651     public List<IBinder> getAppTasks(String callingPackage) {
   10652         int callingUid = Binder.getCallingUid();
   10653         long ident = Binder.clearCallingIdentity();
   10654         try {
   10655             synchronized(this) {
   10656                 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
   10657             }
   10658         } finally {
   10659             Binder.restoreCallingIdentity(ident);
   10660         }
   10661     }
   10662 
   10663     @Override
   10664     public List<RunningTaskInfo> getTasks(int maxNum) {
   10665        return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
   10666     }
   10667 
   10668     @Override
   10669     public List<RunningTaskInfo> getFilteredTasks(int maxNum, @ActivityType int ignoreActivityType,
   10670             @WindowingMode int ignoreWindowingMode) {
   10671         final int callingUid = Binder.getCallingUid();
   10672         ArrayList<RunningTaskInfo> list = new ArrayList<>();
   10673 
   10674         synchronized(this) {
   10675             if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
   10676 
   10677             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
   10678                     callingUid);
   10679             mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
   10680                     ignoreWindowingMode, callingUid, allowed);
   10681         }
   10682 
   10683         return list;
   10684     }
   10685 
   10686     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
   10687         if (mRecentTasks.isCallerRecents(callingUid)) {
   10688             // Always allow the recents component to get tasks
   10689             return true;
   10690         }
   10691 
   10692         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
   10693                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
   10694         if (!allowed) {
   10695             if (checkPermission(android.Manifest.permission.GET_TASKS,
   10696                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
   10697                 // Temporary compatibility: some existing apps on the system image may
   10698                 // still be requesting the old permission and not switched to the new
   10699                 // one; if so, we'll still allow them full access.  This means we need
   10700                 // to see if they are holding the old permission and are a system app.
   10701                 try {
   10702                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
   10703                         allowed = true;
   10704                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
   10705                                 + " is using old GET_TASKS but privileged; allowing");
   10706                     }
   10707                 } catch (RemoteException e) {
   10708                 }
   10709             }
   10710         }
   10711         if (!allowed) {
   10712             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
   10713                     + " does not hold REAL_GET_TASKS; limiting output");
   10714         }
   10715         return allowed;
   10716     }
   10717 
   10718     @Override
   10719     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
   10720             int userId) {
   10721         final int callingUid = Binder.getCallingUid();
   10722         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
   10723                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
   10724         final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
   10725                 callingUid);
   10726         final boolean detailed = checkCallingPermission(
   10727                 android.Manifest.permission.GET_DETAILED_TASKS)
   10728                         == PackageManager.PERMISSION_GRANTED;
   10729 
   10730         synchronized (this) {
   10731             return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
   10732                     callingUid);
   10733         }
   10734     }
   10735 
   10736     @Override
   10737     public ActivityManager.TaskDescription getTaskDescription(int id) {
   10738         synchronized (this) {
   10739             enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
   10740             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
   10741                     MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
   10742             if (tr != null) {
   10743                 return tr.lastTaskDescription;
   10744             }
   10745         }
   10746         return null;
   10747     }
   10748 
   10749     @Override
   10750     public int addAppTask(IBinder activityToken, Intent intent,
   10751             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
   10752         final int callingUid = Binder.getCallingUid();
   10753         final long callingIdent = Binder.clearCallingIdentity();
   10754 
   10755         try {
   10756             synchronized (this) {
   10757                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
   10758                 if (r == null) {
   10759                     throw new IllegalArgumentException("Activity does not exist; token="
   10760                             + activityToken);
   10761                 }
   10762                 ComponentName comp = intent.getComponent();
   10763                 if (comp == null) {
   10764                     throw new IllegalArgumentException("Intent " + intent
   10765                             + " must specify explicit component");
   10766                 }
   10767                 if (thumbnail.getWidth() != mThumbnailWidth
   10768                         || thumbnail.getHeight() != mThumbnailHeight) {
   10769                     throw new IllegalArgumentException("Bad thumbnail size: got "
   10770                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
   10771                             + mThumbnailWidth + "x" + mThumbnailHeight);
   10772                 }
   10773                 if (intent.getSelector() != null) {
   10774                     intent.setSelector(null);
   10775                 }
   10776                 if (intent.getSourceBounds() != null) {
   10777                     intent.setSourceBounds(null);
   10778                 }
   10779                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
   10780                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
   10781                         // The caller has added this as an auto-remove task...  that makes no
   10782                         // sense, so turn off auto-remove.
   10783                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
   10784                     }
   10785                 }
   10786                 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
   10787                         STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
   10788                 if (ainfo.applicationInfo.uid != callingUid) {
   10789                     throw new SecurityException(
   10790                             "Can't add task for another application: target uid="
   10791                             + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
   10792                 }
   10793 
   10794                 final ActivityStack stack = r.getStack();
   10795                 final TaskRecord task = stack.createTaskRecord(
   10796                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
   10797                         null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
   10798                 if (!mRecentTasks.addToBottom(task)) {
   10799                     // The app has too many tasks already and we can't add any more
   10800                     stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
   10801                     return INVALID_TASK_ID;
   10802                 }
   10803                 task.lastTaskDescription.copyFrom(description);
   10804 
   10805                 // TODO: Send the thumbnail to WM to store it.
   10806 
   10807                 return task.taskId;
   10808             }
   10809         } finally {
   10810             Binder.restoreCallingIdentity(callingIdent);
   10811         }
   10812     }
   10813 
   10814     @Override
   10815     public Point getAppTaskThumbnailSize() {
   10816         synchronized (this) {
   10817             return new Point(mThumbnailWidth,  mThumbnailHeight);
   10818         }
   10819     }
   10820 
   10821     @Override
   10822     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
   10823         synchronized (this) {
   10824             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10825             if (r != null) {
   10826                 r.setTaskDescription(td);
   10827                 final TaskRecord task = r.getTask();
   10828                 task.updateTaskDescription();
   10829                 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
   10830             }
   10831         }
   10832     }
   10833 
   10834     @Override
   10835     public void setTaskResizeable(int taskId, int resizeableMode) {
   10836         synchronized (this) {
   10837             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
   10838                     taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
   10839             if (task == null) {
   10840                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
   10841                 return;
   10842             }
   10843             task.setResizeMode(resizeableMode);
   10844         }
   10845     }
   10846 
   10847     @Override
   10848     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
   10849         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
   10850         long ident = Binder.clearCallingIdentity();
   10851         try {
   10852             synchronized (this) {
   10853                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   10854                 if (task == null) {
   10855                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
   10856                     return;
   10857                 }
   10858                 // Place the task in the right stack if it isn't there already based on
   10859                 // the requested bounds.
   10860                 // The stack transition logic is:
   10861                 // - a null bounds on a freeform task moves that task to fullscreen
   10862                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
   10863                 //   that task to freeform
   10864                 // - otherwise the task is not moved
   10865                 ActivityStack stack = task.getStack();
   10866                 if (!task.getWindowConfiguration().canResizeTask()) {
   10867                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
   10868                 }
   10869                 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
   10870                     stack = stack.getDisplay().getOrCreateStack(
   10871                             WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
   10872                 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
   10873                     stack = stack.getDisplay().getOrCreateStack(
   10874                             WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
   10875                 }
   10876 
   10877                 // Reparent the task to the right stack if necessary
   10878                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
   10879                 if (stack != task.getStack()) {
   10880                     // Defer resume until the task is resized below
   10881                     task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
   10882                             DEFER_RESUME, "resizeTask");
   10883                     preserveWindow = false;
   10884                 }
   10885 
   10886                 // After reparenting (which only resizes the task to the stack bounds), resize the
   10887                 // task to the actual bounds provided
   10888                 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
   10889             }
   10890         } finally {
   10891             Binder.restoreCallingIdentity(ident);
   10892         }
   10893     }
   10894 
   10895     @Override
   10896     public Rect getTaskBounds(int taskId) {
   10897         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
   10898         long ident = Binder.clearCallingIdentity();
   10899         Rect rect = new Rect();
   10900         try {
   10901             synchronized (this) {
   10902                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
   10903                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
   10904                 if (task == null) {
   10905                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
   10906                     return rect;
   10907                 }
   10908                 if (task.getStack() != null) {
   10909                     // Return the bounds from window manager since it will be adjusted for various
   10910                     // things like the presense of a docked stack for tasks that aren't resizeable.
   10911                     task.getWindowContainerBounds(rect);
   10912                 } else {
   10913                     // Task isn't in window manager yet since it isn't associated with a stack.
   10914                     // Return the persist value from activity manager
   10915                     if (!task.matchParentBounds()) {
   10916                         rect.set(task.getBounds());
   10917                     } else if (task.mLastNonFullscreenBounds != null) {
   10918                         rect.set(task.mLastNonFullscreenBounds);
   10919                     }
   10920                 }
   10921             }
   10922         } finally {
   10923             Binder.restoreCallingIdentity(ident);
   10924         }
   10925         return rect;
   10926     }
   10927 
   10928     @Override
   10929     public void cancelTaskWindowTransition(int taskId) {
   10930         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
   10931                 "cancelTaskWindowTransition()");
   10932         final long ident = Binder.clearCallingIdentity();
   10933         try {
   10934             synchronized (this) {
   10935                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
   10936                         MATCH_TASK_IN_STACKS_ONLY);
   10937                 if (task == null) {
   10938                     Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
   10939                     return;
   10940                 }
   10941                 task.cancelWindowTransition();
   10942             }
   10943         } finally {
   10944             Binder.restoreCallingIdentity(ident);
   10945         }
   10946     }
   10947 
   10948     @Override
   10949     public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
   10950         enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
   10951         final long ident = Binder.clearCallingIdentity();
   10952         try {
   10953             final TaskRecord task;
   10954             synchronized (this) {
   10955                 task = mStackSupervisor.anyTaskForIdLocked(taskId,
   10956                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
   10957                 if (task == null) {
   10958                     Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
   10959                     return null;
   10960                 }
   10961             }
   10962             // Don't call this while holding the lock as this operation might hit the disk.
   10963             return task.getSnapshot(reducedResolution);
   10964         } finally {
   10965             Binder.restoreCallingIdentity(ident);
   10966         }
   10967     }
   10968 
   10969     @Override
   10970     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
   10971         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   10972                 userId, false, ALLOW_FULL_ONLY, "getTaskDescriptionIcon", null);
   10973 
   10974         final File passedIconFile = new File(filePath);
   10975         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
   10976                 passedIconFile.getName());
   10977         if (!legitIconFile.getPath().equals(filePath)
   10978                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
   10979             throw new IllegalArgumentException("Bad file path: " + filePath
   10980                     + " passed for userId " + userId);
   10981         }
   10982         return mRecentTasks.getTaskDescriptionIcon(filePath);
   10983     }
   10984 
   10985     @Override
   10986     public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
   10987             throws RemoteException {
   10988         final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
   10989         final ActivityOptions activityOptions = safeOptions != null
   10990                 ? safeOptions.getOptions(mStackSupervisor)
   10991                 : null;
   10992         if (activityOptions == null
   10993                 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
   10994                 || activityOptions.getCustomInPlaceResId() == 0) {
   10995             throw new IllegalArgumentException("Expected in-place ActivityOption " +
   10996                     "with valid animation");
   10997         }
   10998         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
   10999         mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
   11000                 activityOptions.getCustomInPlaceResId());
   11001         mWindowManager.executeAppTransition();
   11002     }
   11003 
   11004     @Override
   11005     public void removeStack(int stackId) {
   11006         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
   11007         synchronized (this) {
   11008             final long ident = Binder.clearCallingIdentity();
   11009             try {
   11010                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
   11011                 if (stack == null) {
   11012                     Slog.w(TAG, "removeStack: No stack with id=" + stackId);
   11013                     return;
   11014                 }
   11015                 if (!stack.isActivityTypeStandardOrUndefined()) {
   11016                     throw new IllegalArgumentException(
   11017                             "Removing non-standard stack is not allowed.");
   11018                 }
   11019                 mStackSupervisor.removeStack(stack);
   11020             } finally {
   11021                 Binder.restoreCallingIdentity(ident);
   11022             }
   11023         }
   11024     }
   11025 
   11026     /**
   11027      * Removes stacks in the input windowing modes from the system if they are of activity type
   11028      * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
   11029      */
   11030     @Override
   11031     public void removeStacksInWindowingModes(int[] windowingModes) {
   11032         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
   11033                 "removeStacksInWindowingModes()");
   11034         synchronized (this) {
   11035             final long ident = Binder.clearCallingIdentity();
   11036             try {
   11037                 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
   11038             } finally {
   11039                 Binder.restoreCallingIdentity(ident);
   11040             }
   11041         }
   11042     }
   11043 
   11044     @Override
   11045     public void removeStacksWithActivityTypes(int[] activityTypes) {
   11046         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
   11047                 "removeStacksWithActivityTypes()");
   11048         synchronized (this) {
   11049             final long ident = Binder.clearCallingIdentity();
   11050             try {
   11051                 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
   11052             } finally {
   11053                 Binder.restoreCallingIdentity(ident);
   11054             }
   11055         }
   11056     }
   11057 
   11058     @Override
   11059     public void moveStackToDisplay(int stackId, int displayId) {
   11060         enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
   11061 
   11062         synchronized (this) {
   11063             final long ident = Binder.clearCallingIdentity();
   11064             try {
   11065                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
   11066                         + " to displayId=" + displayId);
   11067                 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
   11068             } finally {
   11069                 Binder.restoreCallingIdentity(ident);
   11070             }
   11071         }
   11072     }
   11073 
   11074     @Override
   11075     public boolean removeTask(int taskId) {
   11076         enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
   11077         synchronized (this) {
   11078             final long ident = Binder.clearCallingIdentity();
   11079             try {
   11080                 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
   11081                         "remove-task");
   11082             } finally {
   11083                 Binder.restoreCallingIdentity(ident);
   11084             }
   11085         }
   11086     }
   11087 
   11088     /**
   11089      * TODO: Add mController hook
   11090      */
   11091     @Override
   11092     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
   11093         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
   11094 
   11095         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
   11096         synchronized(this) {
   11097             moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
   11098                     false /* fromRecents */);
   11099         }
   11100     }
   11101 
   11102     void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
   11103             boolean fromRecents) {
   11104 
   11105         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   11106                 Binder.getCallingUid(), -1, -1, "Task to front")) {
   11107             SafeActivityOptions.abort(options);
   11108             return;
   11109         }
   11110         final long origId = Binder.clearCallingIdentity();
   11111         try {
   11112             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   11113             if (task == null) {
   11114                 Slog.d(TAG, "Could not find task for id: "+ taskId);
   11115                 return;
   11116             }
   11117             if (mLockTaskController.isLockTaskModeViolation(task)) {
   11118                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
   11119                 return;
   11120             }
   11121             ActivityOptions realOptions = options != null
   11122                     ? options.getOptions(mStackSupervisor)
   11123                     : null;
   11124             mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
   11125                     false /* forceNonResizable */);
   11126 
   11127             final ActivityRecord topActivity = task.getTopActivity();
   11128             if (topActivity != null) {
   11129 
   11130                 // We are reshowing a task, use a starting window to hide the initial draw delay
   11131                 // so the transition can start earlier.
   11132                 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
   11133                         true /* taskSwitch */, fromRecents);
   11134             }
   11135         } finally {
   11136             Binder.restoreCallingIdentity(origId);
   11137         }
   11138         SafeActivityOptions.abort(options);
   11139     }
   11140 
   11141     /**
   11142      * Attempts to move a task backwards in z-order (the order of activities within the task is
   11143      * unchanged).
   11144      *
   11145      * There are several possible results of this call:
   11146      * - if the task is locked, then we will show the lock toast
   11147      * - if there is a task behind the provided task, then that task is made visible and resumed as
   11148      *   this task is moved to the back
   11149      * - otherwise, if there are no other tasks in the stack:
   11150      *     - if this task is in the pinned stack, then we remove the stack completely, which will
   11151      *       have the effect of moving the task to the top or bottom of the fullscreen stack
   11152      *       (depending on whether it is visible)
   11153      *     - otherwise, we simply return home and hide this task
   11154      *
   11155      * @param token A reference to the activity we wish to move
   11156      * @param nonRoot If false then this only works if the activity is the root
   11157      *                of a task; if true it will work for any activity in a task.
   11158      * @return Returns true if the move completed, false if not.
   11159      */
   11160     @Override
   11161     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
   11162         enforceNotIsolatedCaller("moveActivityTaskToBack");
   11163         synchronized(this) {
   11164             final long origId = Binder.clearCallingIdentity();
   11165             try {
   11166                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
   11167                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   11168                 if (task != null) {
   11169                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
   11170                 }
   11171             } finally {
   11172                 Binder.restoreCallingIdentity(origId);
   11173             }
   11174         }
   11175         return false;
   11176     }
   11177 
   11178     @Override
   11179     public void moveTaskBackwards(int task) {
   11180         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   11181                 "moveTaskBackwards()");
   11182 
   11183         synchronized(this) {
   11184             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   11185                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
   11186                 return;
   11187             }
   11188             final long origId = Binder.clearCallingIdentity();
   11189             moveTaskBackwardsLocked(task);
   11190             Binder.restoreCallingIdentity(origId);
   11191         }
   11192     }
   11193 
   11194     private final void moveTaskBackwardsLocked(int task) {
   11195         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
   11196     }
   11197 
   11198     @Override
   11199     public int createStackOnDisplay(int displayId) throws RemoteException {
   11200         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
   11201         synchronized (this) {
   11202             final ActivityDisplay display =
   11203                     mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
   11204             if (display == null) {
   11205                 return INVALID_STACK_ID;
   11206             }
   11207             // TODO(multi-display): Have the caller pass in the windowing mode and activity type.
   11208             final ActivityStack stack = display.createStack(
   11209                     WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
   11210                     ON_TOP);
   11211             return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
   11212         }
   11213     }
   11214 
   11215     @Override
   11216     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
   11217         synchronized (this) {
   11218             final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
   11219             if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
   11220                 return stack.mDisplayId;
   11221             }
   11222             return DEFAULT_DISPLAY;
   11223         }
   11224     }
   11225 
   11226     @Override
   11227     public void exitFreeformMode(IBinder token) throws RemoteException {
   11228         synchronized (this) {
   11229             long ident = Binder.clearCallingIdentity();
   11230             try {
   11231                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   11232                 if (r == null) {
   11233                     throw new IllegalArgumentException(
   11234                             "exitFreeformMode: No activity record matching token=" + token);
   11235                 }
   11236 
   11237                 final ActivityStack stack = r.getStack();
   11238                 if (stack == null || !stack.inFreeformWindowingMode()) {
   11239                     throw new IllegalStateException(
   11240                             "exitFreeformMode: You can only go fullscreen from freeform.");
   11241                 }
   11242 
   11243                 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
   11244             } finally {
   11245                 Binder.restoreCallingIdentity(ident);
   11246             }
   11247         }
   11248     }
   11249 
   11250     @Override
   11251     public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
   11252         if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
   11253             setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
   11254                     toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
   11255             return;
   11256         }
   11257         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
   11258         synchronized (this) {
   11259             final long ident = Binder.clearCallingIdentity();
   11260             try {
   11261                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   11262                 if (task == null) {
   11263                     Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
   11264                     return;
   11265                 }
   11266 
   11267                 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
   11268                         + " to windowingMode=" + windowingMode + " toTop=" + toTop);
   11269 
   11270                 if (!task.isActivityTypeStandardOrUndefined()) {
   11271                     throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
   11272                             + " non-standard task " + taskId + " to windowing mode="
   11273                             + windowingMode);
   11274                 }
   11275 
   11276                 final ActivityStack stack = task.getStack();
   11277                 if (toTop) {
   11278                     stack.moveToFront("setTaskWindowingMode", task);
   11279                 }
   11280                 stack.setWindowingMode(windowingMode);
   11281             } finally {
   11282                 Binder.restoreCallingIdentity(ident);
   11283             }
   11284         }
   11285     }
   11286 
   11287     /**
   11288      * Moves the specified task to the primary-split-screen stack.
   11289      *
   11290      * @param taskId Id of task to move.
   11291      * @param createMode The mode the primary split screen stack should be created in if it doesn't
   11292      *                   exist already. See
   11293      *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
   11294      *                   and
   11295      *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
   11296      * @param toTop If the task and stack should be moved to the top.
   11297      * @param animate Whether we should play an animation for the moving the task.
   11298      * @param initialBounds If the primary stack gets created, it will use these bounds for the
   11299      *                      stack. Pass {@code null} to use default bounds.
   11300      * @param showRecents If the recents activity should be shown on the other side of the task
   11301      *                    going into split-screen mode.
   11302      */
   11303     @Override
   11304     public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop,
   11305             boolean animate, Rect initialBounds, boolean showRecents) {
   11306         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
   11307                 "setTaskWindowingModeSplitScreenPrimary()");
   11308         synchronized (this) {
   11309             long ident = Binder.clearCallingIdentity();
   11310             try {
   11311                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   11312                 if (task == null) {
   11313                     Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
   11314                     return false;
   11315                 }
   11316                 if (DEBUG_STACK) Slog.d(TAG_STACK,
   11317                         "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
   11318                         + " to createMode=" + createMode + " toTop=" + toTop);
   11319                 if (!task.isActivityTypeStandardOrUndefined()) {
   11320                     throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
   11321                             + " non-standard task " + taskId + " to split-screen windowing mode");
   11322                 }
   11323 
   11324                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
   11325                 final int windowingMode = task.getWindowingMode();
   11326                 final ActivityStack stack = task.getStack();
   11327                 if (toTop) {
   11328                     stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
   11329                 }
   11330                 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
   11331                         false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
   11332                 return windowingMode != task.getWindowingMode();
   11333             } finally {
   11334                 Binder.restoreCallingIdentity(ident);
   11335             }
   11336         }
   11337     }
   11338 
   11339     @Override
   11340     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
   11341         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
   11342         synchronized (this) {
   11343             long ident = Binder.clearCallingIdentity();
   11344             try {
   11345                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   11346                 if (task == null) {
   11347                     Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
   11348                     return;
   11349                 }
   11350 
   11351                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
   11352                         + " to stackId=" + stackId + " toTop=" + toTop);
   11353 
   11354                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
   11355                 if (stack == null) {
   11356                     throw new IllegalStateException(
   11357                             "moveTaskToStack: No stack for stackId=" + stackId);
   11358                 }
   11359                 if (!stack.isActivityTypeStandardOrUndefined()) {
   11360                     throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
   11361                             + taskId + " to stack " + stackId);
   11362                 }
   11363                 if (stack.inSplitScreenPrimaryWindowingMode()) {
   11364                     mWindowManager.setDockedStackCreateState(
   11365                             SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
   11366                 }
   11367                 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
   11368                         "moveTaskToStack");
   11369             } finally {
   11370                 Binder.restoreCallingIdentity(ident);
   11371             }
   11372         }
   11373     }
   11374 
   11375     /**
   11376      * Dismisses split-screen multi-window mode.
   11377      * @param toTop If true the current primary split-screen stack will be placed or left on top.
   11378      */
   11379     @Override
   11380     public void dismissSplitScreenMode(boolean toTop) {
   11381         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
   11382         final long ident = Binder.clearCallingIdentity();
   11383         try {
   11384             synchronized (this) {
   11385                 final ActivityStack stack =
   11386                         mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
   11387                 if (stack == null) {
   11388                     Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
   11389                     return;
   11390                 }
   11391 
   11392                 if (toTop) {
   11393                     // Caller wants the current split-screen primary stack to be the top stack after
   11394                     // it goes fullscreen, so move it to the front.
   11395                     stack.moveToFront("dismissSplitScreenMode");
   11396                 } else if (mStackSupervisor.isFocusedStack(stack)) {
   11397                     // In this case the current split-screen primary stack shouldn't be the top
   11398                     // stack after it goes fullscreen, but it current has focus, so we move the
   11399                     // focus to the top-most split-screen secondary stack next to it.
   11400                     final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
   11401                             WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
   11402                     if (otherStack != null) {
   11403                         otherStack.moveToFront("dismissSplitScreenMode_other");
   11404                     }
   11405                 }
   11406 
   11407                 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
   11408             }
   11409         } finally {
   11410             Binder.restoreCallingIdentity(ident);
   11411         }
   11412     }
   11413 
   11414     /**
   11415      * Dismisses Pip
   11416      * @param animate True if the dismissal should be animated.
   11417      * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
   11418      *                          default animation duration should be used.
   11419      */
   11420     @Override
   11421     public void dismissPip(boolean animate, int animationDuration) {
   11422         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
   11423         final long ident = Binder.clearCallingIdentity();
   11424         try {
   11425             synchronized (this) {
   11426                 final PinnedActivityStack stack =
   11427                         mStackSupervisor.getDefaultDisplay().getPinnedStack();
   11428                 if (stack == null) {
   11429                     Slog.w(TAG, "dismissPip: pinned stack not found.");
   11430                     return;
   11431                 }
   11432                 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
   11433                     throw new IllegalArgumentException("Stack: " + stack
   11434                             + " doesn't support animated resize.");
   11435                 }
   11436                 if (animate) {
   11437                     stack.animateResizePinnedStack(null /* sourceHintBounds */,
   11438                             null /* destBounds */, animationDuration, false /* fromFullscreen */);
   11439                 } else {
   11440                     mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
   11441                 }
   11442             }
   11443         } finally {
   11444             Binder.restoreCallingIdentity(ident);
   11445         }
   11446     }
   11447 
   11448     /**
   11449      * Moves the top activity in the input stackId to the pinned stack.
   11450      *
   11451      * @param stackId Id of stack to move the top activity to pinned stack.
   11452      * @param bounds Bounds to use for pinned stack.
   11453      *
   11454      * @return True if the top activity of the input stack was successfully moved to the pinned
   11455      *          stack.
   11456      */
   11457     @Override
   11458     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
   11459         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
   11460                 "moveTopActivityToPinnedStack()");
   11461         synchronized (this) {
   11462             if (!mSupportsPictureInPicture) {
   11463                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
   11464                         + "Device doesn't support picture-in-picture mode");
   11465             }
   11466 
   11467             long ident = Binder.clearCallingIdentity();
   11468             try {
   11469                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
   11470             } finally {
   11471                 Binder.restoreCallingIdentity(ident);
   11472             }
   11473         }
   11474     }
   11475 
   11476     @Override
   11477     public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
   11478             boolean preserveWindows, boolean animate, int animationDuration) {
   11479         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
   11480         long ident = Binder.clearCallingIdentity();
   11481         try {
   11482             synchronized (this) {
   11483                 if (animate) {
   11484                     final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
   11485                     if (stack == null) {
   11486                         Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
   11487                         return;
   11488                     }
   11489                     if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
   11490                         throw new IllegalArgumentException("Stack: " + stackId
   11491                                 + " doesn't support animated resize.");
   11492                     }
   11493                     stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
   11494                             animationDuration, false /* fromFullscreen */);
   11495                 } else {
   11496                     final ActivityStack stack = mStackSupervisor.getStack(stackId);
   11497                     if (stack == null) {
   11498                         Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
   11499                         return;
   11500                     }
   11501                     mStackSupervisor.resizeStackLocked(stack, destBounds, null /* tempTaskBounds */,
   11502                             null /* tempTaskInsetBounds */, preserveWindows,
   11503                             allowResizeInDockedMode, !DEFER_RESUME);
   11504                 }
   11505             }
   11506         } finally {
   11507             Binder.restoreCallingIdentity(ident);
   11508         }
   11509     }
   11510 
   11511     @Override
   11512     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
   11513             Rect tempDockedTaskInsetBounds,
   11514             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
   11515         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
   11516         long ident = Binder.clearCallingIdentity();
   11517         try {
   11518             synchronized (this) {
   11519                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
   11520                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
   11521                         PRESERVE_WINDOWS);
   11522             }
   11523         } finally {
   11524             Binder.restoreCallingIdentity(ident);
   11525         }
   11526     }
   11527 
   11528     @Override
   11529     public void setSplitScreenResizing(boolean resizing) {
   11530         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
   11531         final long ident = Binder.clearCallingIdentity();
   11532         try {
   11533             synchronized (this) {
   11534                 mStackSupervisor.setSplitScreenResizing(resizing);
   11535             }
   11536         } finally {
   11537             Binder.restoreCallingIdentity(ident);
   11538         }
   11539     }
   11540 
   11541     @Override
   11542     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
   11543         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
   11544         final long ident = Binder.clearCallingIdentity();
   11545         try {
   11546             synchronized (this) {
   11547                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
   11548             }
   11549         } finally {
   11550             Binder.restoreCallingIdentity(ident);
   11551         }
   11552     }
   11553 
   11554     /**
   11555      * Try to place task to provided position. The final position might be different depending on
   11556      * current user and stacks state. The task will be moved to target stack if it's currently in
   11557      * different stack.
   11558      */
   11559     @Override
   11560     public void positionTaskInStack(int taskId, int stackId, int position) {
   11561         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
   11562         synchronized (this) {
   11563             long ident = Binder.clearCallingIdentity();
   11564             try {
   11565                 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
   11566                         + taskId + " in stackId=" + stackId + " at position=" + position);
   11567                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   11568                 if (task == null) {
   11569                     throw new IllegalArgumentException("positionTaskInStack: no task for id="
   11570                             + taskId);
   11571                 }
   11572 
   11573                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
   11574 
   11575                 if (stack == null) {
   11576                     throw new IllegalArgumentException("positionTaskInStack: no stack for id="
   11577                             + stackId);
   11578                 }
   11579                 if (!stack.isActivityTypeStandardOrUndefined()) {
   11580                     throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
   11581                             + " the position of task " + taskId + " in/to non-standard stack");
   11582                 }
   11583 
   11584                 // TODO: Have the callers of this API call a separate reparent method if that is
   11585                 // what they intended to do vs. having this method also do reparenting.
   11586                 if (task.getStack() == stack) {
   11587                     // Change position in current stack.
   11588                     stack.positionChildAt(task, position);
   11589                 } else {
   11590                     // Reparent to new stack.
   11591                     task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
   11592                             !DEFER_RESUME, "positionTaskInStack");
   11593                 }
   11594             } finally {
   11595                 Binder.restoreCallingIdentity(ident);
   11596             }
   11597         }
   11598     }
   11599 
   11600     @Override
   11601     public List<StackInfo> getAllStackInfos() {
   11602         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
   11603         long ident = Binder.clearCallingIdentity();
   11604         try {
   11605             synchronized (this) {
   11606                 return mStackSupervisor.getAllStackInfosLocked();
   11607             }
   11608         } finally {
   11609             Binder.restoreCallingIdentity(ident);
   11610         }
   11611     }
   11612 
   11613     @Override
   11614     public StackInfo getStackInfo(int windowingMode, int activityType) {
   11615         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
   11616         long ident = Binder.clearCallingIdentity();
   11617         try {
   11618             synchronized (this) {
   11619                 return mStackSupervisor.getStackInfo(windowingMode, activityType);
   11620             }
   11621         } finally {
   11622             Binder.restoreCallingIdentity(ident);
   11623         }
   11624     }
   11625 
   11626     @Override
   11627     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
   11628         synchronized(this) {
   11629             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
   11630         }
   11631     }
   11632 
   11633     @Override
   11634     public void updateDeviceOwner(String packageName) {
   11635         final int callingUid = Binder.getCallingUid();
   11636         if (callingUid != 0 && callingUid != SYSTEM_UID) {
   11637             throw new SecurityException("updateDeviceOwner called from non-system process");
   11638         }
   11639         synchronized (this) {
   11640             mDeviceOwnerName = packageName;
   11641         }
   11642     }
   11643 
   11644     @Override
   11645     public void updateLockTaskPackages(int userId, String[] packages) {
   11646         final int callingUid = Binder.getCallingUid();
   11647         if (callingUid != 0 && callingUid != SYSTEM_UID) {
   11648             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
   11649                     "updateLockTaskPackages()");
   11650         }
   11651         synchronized (this) {
   11652             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
   11653                     Arrays.toString(packages));
   11654             mLockTaskController.updateLockTaskPackages(userId, packages);
   11655         }
   11656     }
   11657 
   11658     @Override
   11659     public void updateLockTaskFeatures(int userId, int flags) {
   11660         final int callingUid = Binder.getCallingUid();
   11661         if (callingUid != 0 && callingUid != SYSTEM_UID) {
   11662             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
   11663                     "updateLockTaskFeatures()");
   11664         }
   11665         synchronized (this) {
   11666             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
   11667                     Integer.toHexString(flags));
   11668             mLockTaskController.updateLockTaskFeatures(userId, flags);
   11669         }
   11670     }
   11671 
   11672     private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
   11673         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
   11674         if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
   11675             return;
   11676         }
   11677 
   11678         final ActivityStack stack = mStackSupervisor.getFocusedStack();
   11679         if (stack == null || task != stack.topTask()) {
   11680             throw new IllegalArgumentException("Invalid task, not in foreground");
   11681         }
   11682 
   11683         // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
   11684         // system or a specific app.
   11685         // * System-initiated requests will only start the pinned mode (screen pinning)
   11686         // * App-initiated requests
   11687         //   - will put the device in fully locked mode (LockTask), if the app is whitelisted
   11688         //   - will start the pinned mode, otherwise
   11689         final int callingUid = Binder.getCallingUid();
   11690         long ident = Binder.clearCallingIdentity();
   11691         try {
   11692             // When a task is locked, dismiss the pinned stack if it exists
   11693             mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
   11694 
   11695             mLockTaskController.startLockTaskMode(task, isSystemCaller, callingUid);
   11696         } finally {
   11697             Binder.restoreCallingIdentity(ident);
   11698         }
   11699     }
   11700 
   11701     @Override
   11702     public void startLockTaskModeByToken(IBinder token) {
   11703         synchronized (this) {
   11704             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   11705             if (r == null) {
   11706                 return;
   11707             }
   11708             startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
   11709         }
   11710     }
   11711 
   11712     @Override
   11713     public void startSystemLockTaskMode(int taskId) throws RemoteException {
   11714         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
   11715         // This makes inner call to look as if it was initiated by system.
   11716         long ident = Binder.clearCallingIdentity();
   11717         try {
   11718             synchronized (this) {
   11719                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   11720 
   11721                 // When starting lock task mode the stack must be in front and focused
   11722                 task.getStack().moveToFront("startSystemLockTaskMode");
   11723                 startLockTaskModeLocked(task, true /* isSystemCaller */);
   11724             }
   11725         } finally {
   11726             Binder.restoreCallingIdentity(ident);
   11727         }
   11728     }
   11729 
   11730     @Override
   11731     public void stopLockTaskModeByToken(IBinder token) {
   11732         synchronized (this) {
   11733             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   11734             if (r == null) {
   11735                 return;
   11736             }
   11737             stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
   11738         }
   11739     }
   11740 
   11741     /**
   11742      * This API should be called by SystemUI only when user perform certain action to dismiss
   11743      * lock task mode. We should only dismiss pinned lock task mode in this case.
   11744      */
   11745     @Override
   11746     public void stopSystemLockTaskMode() throws RemoteException {
   11747         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
   11748         stopLockTaskModeInternal(null, true /* isSystemCaller */);
   11749     }
   11750 
   11751     private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
   11752         final int callingUid = Binder.getCallingUid();
   11753         long ident = Binder.clearCallingIdentity();
   11754         try {
   11755             synchronized (this) {
   11756                 mLockTaskController.stopLockTaskMode(task, isSystemCaller, callingUid);
   11757             }
   11758             // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
   11759             // task and jumping straight into a call in the case of emergency call back.
   11760             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
   11761             if (tm != null) {
   11762                 tm.showInCallScreen(false);
   11763             }
   11764         } finally {
   11765             Binder.restoreCallingIdentity(ident);
   11766         }
   11767     }
   11768 
   11769     @Override
   11770     public boolean isInLockTaskMode() {
   11771         return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
   11772     }
   11773 
   11774     @Override
   11775     public int getLockTaskModeState() {
   11776         synchronized (this) {
   11777             return mLockTaskController.getLockTaskModeState();
   11778         }
   11779     }
   11780 
   11781     @Override
   11782     public void showLockTaskEscapeMessage(IBinder token) {
   11783         synchronized (this) {
   11784             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   11785             if (r == null) {
   11786                 return;
   11787             }
   11788             mLockTaskController.showLockTaskToast();
   11789         }
   11790     }
   11791 
   11792     @Override
   11793     public void setDisablePreviewScreenshots(IBinder token, boolean disable)
   11794             throws RemoteException {
   11795         synchronized (this) {
   11796             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   11797             if (r == null) {
   11798                 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
   11799                         + token);
   11800                 return;
   11801             }
   11802             final long origId = Binder.clearCallingIdentity();
   11803             try {
   11804                 r.setDisablePreviewScreenshots(disable);
   11805             } finally {
   11806                 Binder.restoreCallingIdentity(origId);
   11807             }
   11808         }
   11809     }
   11810 
   11811     // =========================================================
   11812     // CONTENT PROVIDERS
   11813     // =========================================================
   11814 
   11815     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
   11816         List<ProviderInfo> providers = null;
   11817         try {
   11818             providers = AppGlobals.getPackageManager()
   11819                     .queryContentProviders(app.processName, app.uid,
   11820                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
   11821                                     | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
   11822                     .getList();
   11823         } catch (RemoteException ex) {
   11824         }
   11825         if (DEBUG_MU) Slog.v(TAG_MU,
   11826                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
   11827         int userId = app.userId;
   11828         if (providers != null) {
   11829             int N = providers.size();
   11830             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
   11831             for (int i=0; i<N; i++) {
   11832                 // TODO: keep logic in sync with installEncryptionUnawareProviders
   11833                 ProviderInfo cpi =
   11834                     (ProviderInfo)providers.get(i);
   11835                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   11836                         cpi.name, cpi.flags);
   11837                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
   11838                     // This is a singleton provider, but a user besides the
   11839                     // default user is asking to initialize a process it runs
   11840                     // in...  well, no, it doesn't actually run in this process,
   11841                     // it runs in the process of the default user.  Get rid of it.
   11842                     providers.remove(i);
   11843                     N--;
   11844                     i--;
   11845                     continue;
   11846                 }
   11847 
   11848                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   11849                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
   11850                 if (cpr == null) {
   11851                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
   11852                     mProviderMap.putProviderByClass(comp, cpr);
   11853                 }
   11854                 if (DEBUG_MU) Slog.v(TAG_MU,
   11855                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
   11856                 app.pubProviders.put(cpi.name, cpr);
   11857                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
   11858                     // Don't add this if it is a platform component that is marked
   11859                     // to run in multiple processes, because this is actually
   11860                     // part of the framework so doesn't make sense to track as a
   11861                     // separate apk in the process.
   11862                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
   11863                             mProcessStats);
   11864                 }
   11865                 notifyPackageUse(cpi.applicationInfo.packageName,
   11866                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
   11867             }
   11868         }
   11869         return providers;
   11870     }
   11871 
   11872     /**
   11873      * Check if the calling UID has a possible chance at accessing the provider
   11874      * at the given authority and user.
   11875      */
   11876     public String checkContentProviderAccess(String authority, int userId) {
   11877         if (userId == UserHandle.USER_ALL) {
   11878             mContext.enforceCallingOrSelfPermission(
   11879                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
   11880             userId = UserHandle.getCallingUserId();
   11881         }
   11882 
   11883         ProviderInfo cpi = null;
   11884         try {
   11885             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
   11886                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
   11887                             | PackageManager.MATCH_DISABLED_COMPONENTS
   11888                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
   11889                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
   11890                     userId);
   11891         } catch (RemoteException ignored) {
   11892         }
   11893         if (cpi == null) {
   11894             return "Failed to find provider " + authority + " for user " + userId
   11895                     + "; expected to find a valid ContentProvider for this authority";
   11896         }
   11897 
   11898         ProcessRecord r = null;
   11899         synchronized (mPidsSelfLocked) {
   11900             r = mPidsSelfLocked.get(Binder.getCallingPid());
   11901         }
   11902         if (r == null) {
   11903             return "Failed to find PID " + Binder.getCallingPid();
   11904         }
   11905 
   11906         synchronized (this) {
   11907             return checkContentProviderPermissionLocked(cpi, r, userId, true);
   11908         }
   11909     }
   11910 
   11911     /**
   11912      * Check if {@link ProcessRecord} has a possible chance at accessing the
   11913      * given {@link ProviderInfo}. Final permission checking is always done
   11914      * in {@link ContentProvider}.
   11915      */
   11916     private final String checkContentProviderPermissionLocked(
   11917             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
   11918         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
   11919         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
   11920         boolean checkedGrants = false;
   11921         if (checkUser) {
   11922             // Looking for cross-user grants before enforcing the typical cross-users permissions
   11923             int tmpTargetUserId = mUserController.unsafeConvertIncomingUser(userId);
   11924             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
   11925                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
   11926                     return null;
   11927                 }
   11928                 checkedGrants = true;
   11929             }
   11930             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
   11931                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
   11932             if (userId != tmpTargetUserId) {
   11933                 // When we actually went to determine the final targer user ID, this ended
   11934                 // up different than our initial check for the authority.  This is because
   11935                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
   11936                 // SELF.  So we need to re-check the grants again.
   11937                 checkedGrants = false;
   11938             }
   11939         }
   11940         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
   11941                 cpi.applicationInfo.uid, cpi.exported)
   11942                 == PackageManager.PERMISSION_GRANTED) {
   11943             return null;
   11944         }
   11945         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
   11946                 cpi.applicationInfo.uid, cpi.exported)
   11947                 == PackageManager.PERMISSION_GRANTED) {
   11948             return null;
   11949         }
   11950 
   11951         PathPermission[] pps = cpi.pathPermissions;
   11952         if (pps != null) {
   11953             int i = pps.length;
   11954             while (i > 0) {
   11955                 i--;
   11956                 PathPermission pp = pps[i];
   11957                 String pprperm = pp.getReadPermission();
   11958                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
   11959                         cpi.applicationInfo.uid, cpi.exported)
   11960                         == PackageManager.PERMISSION_GRANTED) {
   11961                     return null;
   11962                 }
   11963                 String ppwperm = pp.getWritePermission();
   11964                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
   11965                         cpi.applicationInfo.uid, cpi.exported)
   11966                         == PackageManager.PERMISSION_GRANTED) {
   11967                     return null;
   11968                 }
   11969             }
   11970         }
   11971         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
   11972             return null;
   11973         }
   11974 
   11975         final String suffix;
   11976         if (!cpi.exported) {
   11977             suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
   11978         } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
   11979             suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
   11980         } else {
   11981             suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
   11982         }
   11983         final String msg = "Permission Denial: opening provider " + cpi.name
   11984                 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   11985                 + ", uid=" + callingUid + ")" + suffix;
   11986         Slog.w(TAG, msg);
   11987         return msg;
   11988     }
   11989 
   11990     /**
   11991      * Returns if the ContentProvider has granted a uri to callingUid
   11992      */
   11993     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
   11994         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   11995         if (perms != null) {
   11996             for (int i=perms.size()-1; i>=0; i--) {
   11997                 GrantUri grantUri = perms.keyAt(i);
   11998                 if (grantUri.sourceUserId == userId || !checkUser) {
   11999                     if (matchesProvider(grantUri.uri, cpi)) {
   12000                         return true;
   12001                     }
   12002                 }
   12003             }
   12004         }
   12005         return false;
   12006     }
   12007 
   12008     /**
   12009      * Returns true if the uri authority is one of the authorities specified in the provider.
   12010      */
   12011     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
   12012         String uriAuth = uri.getAuthority();
   12013         String cpiAuth = cpi.authority;
   12014         if (cpiAuth.indexOf(';') == -1) {
   12015             return cpiAuth.equals(uriAuth);
   12016         }
   12017         String[] cpiAuths = cpiAuth.split(";");
   12018         int length = cpiAuths.length;
   12019         for (int i = 0; i < length; i++) {
   12020             if (cpiAuths[i].equals(uriAuth)) return true;
   12021         }
   12022         return false;
   12023     }
   12024 
   12025     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
   12026             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   12027         if (r != null) {
   12028             for (int i=0; i<r.conProviders.size(); i++) {
   12029                 ContentProviderConnection conn = r.conProviders.get(i);
   12030                 if (conn.provider == cpr) {
   12031                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
   12032                             "Adding provider requested by "
   12033                             + r.processName + " from process "
   12034                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   12035                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   12036                     if (stable) {
   12037                         conn.stableCount++;
   12038                         conn.numStableIncs++;
   12039                     } else {
   12040                         conn.unstableCount++;
   12041                         conn.numUnstableIncs++;
   12042                     }
   12043                     return conn;
   12044                 }
   12045             }
   12046             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
   12047             if (stable) {
   12048                 conn.stableCount = 1;
   12049                 conn.numStableIncs = 1;
   12050             } else {
   12051                 conn.unstableCount = 1;
   12052                 conn.numUnstableIncs = 1;
   12053             }
   12054             cpr.connections.add(conn);
   12055             r.conProviders.add(conn);
   12056             startAssociationLocked(r.uid, r.processName, r.curProcState,
   12057                     cpr.uid, cpr.name, cpr.info.processName);
   12058             return conn;
   12059         }
   12060         cpr.addExternalProcessHandleLocked(externalProcessToken);
   12061         return null;
   12062     }
   12063 
   12064     boolean decProviderCountLocked(ContentProviderConnection conn,
   12065             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   12066         if (conn != null) {
   12067             cpr = conn.provider;
   12068             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
   12069                     "Removing provider requested by "
   12070                     + conn.client.processName + " from process "
   12071                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   12072                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   12073             if (stable) {
   12074                 conn.stableCount--;
   12075             } else {
   12076                 conn.unstableCount--;
   12077             }
   12078             if (conn.stableCount == 0 && conn.unstableCount == 0) {
   12079                 cpr.connections.remove(conn);
   12080                 conn.client.conProviders.remove(conn);
   12081                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   12082                     // The client is more important than last activity -- note the time this
   12083                     // is happening, so we keep the old provider process around a bit as last
   12084                     // activity to avoid thrashing it.
   12085                     if (cpr.proc != null) {
   12086                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
   12087                     }
   12088                 }
   12089                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
   12090                 return true;
   12091             }
   12092             return false;
   12093         }
   12094         cpr.removeExternalProcessHandleLocked(externalProcessToken);
   12095         return false;
   12096     }
   12097 
   12098     private void checkTime(long startTime, String where) {
   12099         long now = SystemClock.uptimeMillis();
   12100         if ((now-startTime) > 50) {
   12101             // If we are taking more than 50ms, log about it.
   12102             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
   12103         }
   12104     }
   12105 
   12106     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
   12107             PROC_SPACE_TERM,
   12108             PROC_SPACE_TERM|PROC_PARENS,
   12109             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
   12110     };
   12111 
   12112     private final long[] mProcessStateStatsLongs = new long[1];
   12113 
   12114     private boolean isProcessAliveLocked(ProcessRecord proc) {
   12115         if (proc.pid <= 0) {
   12116             if (DEBUG_OOM_ADJ) Slog.d(TAG, "Process hasn't started yet: " + proc);
   12117             return false;
   12118         }
   12119         if (proc.procStatFile == null) {
   12120             proc.procStatFile = "/proc/" + proc.pid + "/stat";
   12121         }
   12122         mProcessStateStatsLongs[0] = 0;
   12123         if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
   12124                 mProcessStateStatsLongs, null)) {
   12125             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
   12126             return false;
   12127         }
   12128         final long state = mProcessStateStatsLongs[0];
   12129         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
   12130                 + (char)state);
   12131         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
   12132     }
   12133 
   12134     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
   12135             String name, IBinder token, boolean stable, int userId) {
   12136         ContentProviderRecord cpr;
   12137         ContentProviderConnection conn = null;
   12138         ProviderInfo cpi = null;
   12139 
   12140         synchronized(this) {
   12141             long startTime = SystemClock.uptimeMillis();
   12142 
   12143             ProcessRecord r = null;
   12144             if (caller != null) {
   12145                 r = getRecordForAppLocked(caller);
   12146                 if (r == null) {
   12147                     throw new SecurityException(
   12148                             "Unable to find app for caller " + caller
   12149                           + " (pid=" + Binder.getCallingPid()
   12150                           + ") when getting content provider " + name);
   12151                 }
   12152             }
   12153 
   12154             boolean checkCrossUser = true;
   12155 
   12156             checkTime(startTime, "getContentProviderImpl: getProviderByName");
   12157 
   12158             // First check if this content provider has been published...
   12159             cpr = mProviderMap.getProviderByName(name, userId);
   12160             // If that didn't work, check if it exists for user 0 and then
   12161             // verify that it's a singleton provider before using it.
   12162             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
   12163                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
   12164                 if (cpr != null) {
   12165                     cpi = cpr.info;
   12166                     if (isSingleton(cpi.processName, cpi.applicationInfo,
   12167                             cpi.name, cpi.flags)
   12168                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
   12169                         userId = UserHandle.USER_SYSTEM;
   12170                         checkCrossUser = false;
   12171                     } else {
   12172                         cpr = null;
   12173                         cpi = null;
   12174                     }
   12175                 }
   12176             }
   12177 
   12178             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
   12179             if (providerRunning) {
   12180                 cpi = cpr.info;
   12181                 String msg;
   12182                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
   12183                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
   12184                         != null) {
   12185                     throw new SecurityException(msg);
   12186                 }
   12187                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
   12188 
   12189                 if (r != null && cpr.canRunHere(r)) {
   12190                     // This provider has been published or is in the process
   12191                     // of being published...  but it is also allowed to run
   12192                     // in the caller's process, so don't make a connection
   12193                     // and just let the caller instantiate its own instance.
   12194                     ContentProviderHolder holder = cpr.newHolder(null);
   12195                     // don't give caller the provider object, it needs
   12196                     // to make its own.
   12197                     holder.provider = null;
   12198                     return holder;
   12199                 }
   12200                 // Don't expose providers between normal apps and instant apps
   12201                 try {
   12202                     if (AppGlobals.getPackageManager()
   12203                             .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
   12204                         return null;
   12205                     }
   12206                 } catch (RemoteException e) {
   12207                 }
   12208 
   12209                 final long origId = Binder.clearCallingIdentity();
   12210 
   12211                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
   12212 
   12213                 // In this case the provider instance already exists, so we can
   12214                 // return it right away.
   12215                 conn = incProviderCountLocked(r, cpr, token, stable);
   12216                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
   12217                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   12218                         // If this is a perceptible app accessing the provider,
   12219                         // make sure to count it as being accessed and thus
   12220                         // back up on the LRU list.  This is good because
   12221                         // content providers are often expensive to start.
   12222                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
   12223                         updateLruProcessLocked(cpr.proc, false, null);
   12224                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
   12225                     }
   12226                 }
   12227 
   12228                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
   12229                 final int verifiedAdj = cpr.proc.verifiedAdj;
   12230                 boolean success = updateOomAdjLocked(cpr.proc, true);
   12231                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
   12232                 // if the process has been successfully adjusted.  So to reduce races with
   12233                 // it, we will check whether the process still exists.  Note that this doesn't
   12234                 // completely get rid of races with LMK killing the process, but should make
   12235                 // them much smaller.
   12236                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
   12237                     success = false;
   12238                 }
   12239                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
   12240                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
   12241                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
   12242                 // NOTE: there is still a race here where a signal could be
   12243                 // pending on the process even though we managed to update its
   12244                 // adj level.  Not sure what to do about this, but at least
   12245                 // the race is now smaller.
   12246                 if (!success) {
   12247                     // Uh oh...  it looks like the provider's process
   12248                     // has been killed on us.  We need to wait for a new
   12249                     // process to be started, and make sure its death
   12250                     // doesn't kill our process.
   12251                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
   12252                             + " is crashing; detaching " + r);
   12253                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
   12254                     checkTime(startTime, "getContentProviderImpl: before appDied");
   12255                     appDiedLocked(cpr.proc);
   12256                     checkTime(startTime, "getContentProviderImpl: after appDied");
   12257                     if (!lastRef) {
   12258                         // This wasn't the last ref our process had on
   12259                         // the provider...  we have now been killed, bail.
   12260                         return null;
   12261                     }
   12262                     providerRunning = false;
   12263                     conn = null;
   12264                 } else {
   12265                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
   12266                 }
   12267 
   12268                 Binder.restoreCallingIdentity(origId);
   12269             }
   12270 
   12271             if (!providerRunning) {
   12272                 try {
   12273                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
   12274                     cpi = AppGlobals.getPackageManager().
   12275                         resolveContentProvider(name,
   12276                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
   12277                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
   12278                 } catch (RemoteException ex) {
   12279                 }
   12280                 if (cpi == null) {
   12281                     return null;
   12282                 }
   12283                 // If the provider is a singleton AND
   12284                 // (it's a call within the same user || the provider is a
   12285                 // privileged app)
   12286                 // Then allow connecting to the singleton provider
   12287                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   12288                         cpi.name, cpi.flags)
   12289                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
   12290                 if (singleton) {
   12291                     userId = UserHandle.USER_SYSTEM;
   12292                 }
   12293                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
   12294                 checkTime(startTime, "getContentProviderImpl: got app info for user");
   12295 
   12296                 String msg;
   12297                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
   12298                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
   12299                         != null) {
   12300                     throw new SecurityException(msg);
   12301                 }
   12302                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
   12303 
   12304                 if (!mProcessesReady
   12305                         && !cpi.processName.equals("system")) {
   12306                     // If this content provider does not run in the system
   12307                     // process, and the system is not yet ready to run other
   12308                     // processes, then fail fast instead of hanging.
   12309                     throw new IllegalArgumentException(
   12310                             "Attempt to launch content provider before system ready");
   12311                 }
   12312 
   12313                 // If system providers are not installed yet we aggressively crash to avoid
   12314                 // creating multiple instance of these providers and then bad things happen!
   12315                 if (!mSystemProvidersInstalled && cpi.applicationInfo.isSystemApp()
   12316                         && "system".equals(cpi.processName)) {
   12317                     throw new IllegalStateException("Cannot access system provider: '"
   12318                             + cpi.authority + "' before system providers are installed!");
   12319                 }
   12320 
   12321                 // Make sure that the user who owns this provider is running.  If not,
   12322                 // we don't want to allow it to run.
   12323                 if (!mUserController.isUserRunning(userId, 0)) {
   12324                     Slog.w(TAG, "Unable to launch app "
   12325                             + cpi.applicationInfo.packageName + "/"
   12326                             + cpi.applicationInfo.uid + " for provider "
   12327                             + name + ": user " + userId + " is stopped");
   12328                     return null;
   12329                 }
   12330 
   12331                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   12332                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
   12333                 cpr = mProviderMap.getProviderByClass(comp, userId);
   12334                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
   12335                 final boolean firstClass = cpr == null;
   12336                 if (firstClass) {
   12337                     final long ident = Binder.clearCallingIdentity();
   12338 
   12339                     // If permissions need a review before any of the app components can run,
   12340                     // we return no provider and launch a review activity if the calling app
   12341                     // is in the foreground.
   12342                     if (mPermissionReviewRequired) {
   12343                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
   12344                             return null;
   12345                         }
   12346                     }
   12347 
   12348                     try {
   12349                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
   12350                         ApplicationInfo ai =
   12351                             AppGlobals.getPackageManager().
   12352                                 getApplicationInfo(
   12353                                         cpi.applicationInfo.packageName,
   12354                                         STOCK_PM_FLAGS, userId);
   12355                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
   12356                         if (ai == null) {
   12357                             Slog.w(TAG, "No package info for content provider "
   12358                                     + cpi.name);
   12359                             return null;
   12360                         }
   12361                         ai = getAppInfoForUser(ai, userId);
   12362                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
   12363                     } catch (RemoteException ex) {
   12364                         // pm is in same process, this will never happen.
   12365                     } finally {
   12366                         Binder.restoreCallingIdentity(ident);
   12367                     }
   12368                 }
   12369 
   12370                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
   12371 
   12372                 if (r != null && cpr.canRunHere(r)) {
   12373                     // If this is a multiprocess provider, then just return its
   12374                     // info and allow the caller to instantiate it.  Only do
   12375                     // this if the provider is the same user as the caller's
   12376                     // process, or can run as root (so can be in any process).
   12377                     return cpr.newHolder(null);
   12378                 }
   12379 
   12380                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
   12381                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
   12382                             + cpr.info.name + " callers=" + Debug.getCallers(6));
   12383 
   12384                 // This is single process, and our app is now connecting to it.
   12385                 // See if we are already in the process of launching this
   12386                 // provider.
   12387                 final int N = mLaunchingProviders.size();
   12388                 int i;
   12389                 for (i = 0; i < N; i++) {
   12390                     if (mLaunchingProviders.get(i) == cpr) {
   12391                         break;
   12392                     }
   12393                 }
   12394 
   12395                 // If the provider is not already being launched, then get it
   12396                 // started.
   12397                 if (i >= N) {
   12398                     final long origId = Binder.clearCallingIdentity();
   12399 
   12400                     try {
   12401                         // Content provider is now in use, its package can't be stopped.
   12402                         try {
   12403                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
   12404                             AppGlobals.getPackageManager().setPackageStoppedState(
   12405                                     cpr.appInfo.packageName, false, userId);
   12406                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
   12407                         } catch (RemoteException e) {
   12408                         } catch (IllegalArgumentException e) {
   12409                             Slog.w(TAG, "Failed trying to unstop package "
   12410                                     + cpr.appInfo.packageName + ": " + e);
   12411                         }
   12412 
   12413                         // Use existing process if already started
   12414                         checkTime(startTime, "getContentProviderImpl: looking for process record");
   12415                         ProcessRecord proc = getProcessRecordLocked(
   12416                                 cpi.processName, cpr.appInfo.uid, false);
   12417                         if (proc != null && proc.thread != null && !proc.killed) {
   12418                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
   12419                                     "Installing in existing process " + proc);
   12420                             if (!proc.pubProviders.containsKey(cpi.name)) {
   12421                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
   12422                                 proc.pubProviders.put(cpi.name, cpr);
   12423                                 try {
   12424                                     proc.thread.scheduleInstallProvider(cpi);
   12425                                 } catch (RemoteException e) {
   12426                                 }
   12427                             }
   12428                         } else {
   12429                             checkTime(startTime, "getContentProviderImpl: before start process");
   12430                             proc = startProcessLocked(cpi.processName,
   12431                                     cpr.appInfo, false, 0, "content provider",
   12432                                     new ComponentName(cpi.applicationInfo.packageName,
   12433                                             cpi.name), false, false, false);
   12434                             checkTime(startTime, "getContentProviderImpl: after start process");
   12435                             if (proc == null) {
   12436                                 Slog.w(TAG, "Unable to launch app "
   12437                                         + cpi.applicationInfo.packageName + "/"
   12438                                         + cpi.applicationInfo.uid + " for provider "
   12439                                         + name + ": process is bad");
   12440                                 return null;
   12441                             }
   12442                         }
   12443                         cpr.launchingApp = proc;
   12444                         mLaunchingProviders.add(cpr);
   12445                     } finally {
   12446                         Binder.restoreCallingIdentity(origId);
   12447                     }
   12448                 }
   12449 
   12450                 checkTime(startTime, "getContentProviderImpl: updating data structures");
   12451 
   12452                 // Make sure the provider is published (the same provider class
   12453                 // may be published under multiple names).
   12454                 if (firstClass) {
   12455                     mProviderMap.putProviderByClass(comp, cpr);
   12456                 }
   12457 
   12458                 mProviderMap.putProviderByName(name, cpr);
   12459                 conn = incProviderCountLocked(r, cpr, token, stable);
   12460                 if (conn != null) {
   12461                     conn.waiting = true;
   12462                 }
   12463             }
   12464             checkTime(startTime, "getContentProviderImpl: done!");
   12465 
   12466             grantEphemeralAccessLocked(userId, null /*intent*/,
   12467                     cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
   12468         }
   12469 
   12470         // Wait for the provider to be published...
   12471         synchronized (cpr) {
   12472             while (cpr.provider == null) {
   12473                 if (cpr.launchingApp == null) {
   12474                     Slog.w(TAG, "Unable to launch app "
   12475                             + cpi.applicationInfo.packageName + "/"
   12476                             + cpi.applicationInfo.uid + " for provider "
   12477                             + name + ": launching app became null");
   12478                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
   12479                             UserHandle.getUserId(cpi.applicationInfo.uid),
   12480                             cpi.applicationInfo.packageName,
   12481                             cpi.applicationInfo.uid, name);
   12482                     return null;
   12483                 }
   12484                 try {
   12485                     if (DEBUG_MU) Slog.v(TAG_MU,
   12486                             "Waiting to start provider " + cpr
   12487                             + " launchingApp=" + cpr.launchingApp);
   12488                     if (conn != null) {
   12489                         conn.waiting = true;
   12490                     }
   12491                     cpr.wait();
   12492                 } catch (InterruptedException ex) {
   12493                 } finally {
   12494                     if (conn != null) {
   12495                         conn.waiting = false;
   12496                     }
   12497                 }
   12498             }
   12499         }
   12500         return cpr != null ? cpr.newHolder(conn) : null;
   12501     }
   12502 
   12503     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
   12504             ProcessRecord r, final int userId) {
   12505         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
   12506                 cpi.packageName, userId)) {
   12507 
   12508             final boolean callerForeground = r == null || r.setSchedGroup
   12509                     != ProcessList.SCHED_GROUP_BACKGROUND;
   12510 
   12511             // Show a permission review UI only for starting from a foreground app
   12512             if (!callerForeground) {
   12513                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
   12514                         + cpi.packageName + " requires a permissions review");
   12515                 return false;
   12516             }
   12517 
   12518             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
   12519             intent.addFlags(FLAG_ACTIVITY_NEW_TASK
   12520                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
   12521             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
   12522 
   12523             if (DEBUG_PERMISSIONS_REVIEW) {
   12524                 Slog.i(TAG, "u" + userId + " Launching permission review "
   12525                         + "for package " + cpi.packageName);
   12526             }
   12527 
   12528             final UserHandle userHandle = new UserHandle(userId);
   12529             mHandler.post(new Runnable() {
   12530                 @Override
   12531                 public void run() {
   12532                     mContext.startActivityAsUser(intent, userHandle);
   12533                 }
   12534             });
   12535 
   12536             return false;
   12537         }
   12538 
   12539         return true;
   12540     }
   12541 
   12542     /**
   12543      * Returns the PackageManager. Used by classes hosted by {@link ActivityManagerService}. The
   12544      * PackageManager could be unavailable at construction time and therefore needs to be accessed
   12545      * on demand.
   12546      */
   12547     IPackageManager getPackageManager() {
   12548         return AppGlobals.getPackageManager();
   12549     }
   12550 
   12551     ActivityStartController getActivityStartController() {
   12552         return mActivityStartController;
   12553     }
   12554 
   12555     LockTaskController getLockTaskController() {
   12556         return mLockTaskController;
   12557     }
   12558 
   12559     ClientLifecycleManager getLifecycleManager() {
   12560         return mLifecycleManager;
   12561     }
   12562 
   12563     PackageManagerInternal getPackageManagerInternalLocked() {
   12564         if (mPackageManagerInt == null) {
   12565             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
   12566         }
   12567         return mPackageManagerInt;
   12568     }
   12569 
   12570     @Override
   12571     public final ContentProviderHolder getContentProvider(
   12572             IApplicationThread caller, String name, int userId, boolean stable) {
   12573         enforceNotIsolatedCaller("getContentProvider");
   12574         if (caller == null) {
   12575             String msg = "null IApplicationThread when getting content provider "
   12576                     + name;
   12577             Slog.w(TAG, msg);
   12578             throw new SecurityException(msg);
   12579         }
   12580         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
   12581         // with cross-user grant.
   12582         return getContentProviderImpl(caller, name, null, stable, userId);
   12583     }
   12584 
   12585     public ContentProviderHolder getContentProviderExternal(
   12586             String name, int userId, IBinder token) {
   12587         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   12588             "Do not have permission in call getContentProviderExternal()");
   12589         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   12590                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
   12591         return getContentProviderExternalUnchecked(name, token, userId);
   12592     }
   12593 
   12594     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
   12595             IBinder token, int userId) {
   12596         return getContentProviderImpl(null, name, token, true, userId);
   12597     }
   12598 
   12599     /**
   12600      * Drop a content provider from a ProcessRecord's bookkeeping
   12601      */
   12602     public void removeContentProvider(IBinder connection, boolean stable) {
   12603         enforceNotIsolatedCaller("removeContentProvider");
   12604         long ident = Binder.clearCallingIdentity();
   12605         try {
   12606             synchronized (this) {
   12607                 ContentProviderConnection conn;
   12608                 try {
   12609                     conn = (ContentProviderConnection)connection;
   12610                 } catch (ClassCastException e) {
   12611                     String msg ="removeContentProvider: " + connection
   12612                             + " not a ContentProviderConnection";
   12613                     Slog.w(TAG, msg);
   12614                     throw new IllegalArgumentException(msg);
   12615                 }
   12616                 if (conn == null) {
   12617                     throw new NullPointerException("connection is null");
   12618                 }
   12619                 if (decProviderCountLocked(conn, null, null, stable)) {
   12620                     updateOomAdjLocked();
   12621                 }
   12622             }
   12623         } finally {
   12624             Binder.restoreCallingIdentity(ident);
   12625         }
   12626     }
   12627 
   12628     public void removeContentProviderExternal(String name, IBinder token) {
   12629         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   12630             "Do not have permission in call removeContentProviderExternal()");
   12631         int userId = UserHandle.getCallingUserId();
   12632         long ident = Binder.clearCallingIdentity();
   12633         try {
   12634             removeContentProviderExternalUnchecked(name, token, userId);
   12635         } finally {
   12636             Binder.restoreCallingIdentity(ident);
   12637         }
   12638     }
   12639 
   12640     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
   12641         synchronized (this) {
   12642             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
   12643             if(cpr == null) {
   12644                 //remove from mProvidersByClass
   12645                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
   12646                 return;
   12647             }
   12648 
   12649             //update content provider record entry info
   12650             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
   12651             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
   12652             if (localCpr.hasExternalProcessHandles()) {
   12653                 if (localCpr.removeExternalProcessHandleLocked(token)) {
   12654                     updateOomAdjLocked();
   12655                 } else {
   12656                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
   12657                             + " with no external reference for token: "
   12658                             + token + ".");
   12659                 }
   12660             } else {
   12661                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
   12662                         + " with no external references.");
   12663             }
   12664         }
   12665     }
   12666 
   12667     public final void publishContentProviders(IApplicationThread caller,
   12668             List<ContentProviderHolder> providers) {
   12669         if (providers == null) {
   12670             return;
   12671         }
   12672 
   12673         enforceNotIsolatedCaller("publishContentProviders");
   12674         synchronized (this) {
   12675             final ProcessRecord r = getRecordForAppLocked(caller);
   12676             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
   12677             if (r == null) {
   12678                 throw new SecurityException(
   12679                         "Unable to find app for caller " + caller
   12680                       + " (pid=" + Binder.getCallingPid()
   12681                       + ") when publishing content providers");
   12682             }
   12683 
   12684             final long origId = Binder.clearCallingIdentity();
   12685 
   12686             final int N = providers.size();
   12687             for (int i = 0; i < N; i++) {
   12688                 ContentProviderHolder src = providers.get(i);
   12689                 if (src == null || src.info == null || src.provider == null) {
   12690                     continue;
   12691                 }
   12692                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
   12693                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
   12694                 if (dst != null) {
   12695                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
   12696                     mProviderMap.putProviderByClass(comp, dst);
   12697                     String names[] = dst.info.authority.split(";");
   12698                     for (int j = 0; j < names.length; j++) {
   12699                         mProviderMap.putProviderByName(names[j], dst);
   12700                     }
   12701 
   12702                     int launchingCount = mLaunchingProviders.size();
   12703                     int j;
   12704                     boolean wasInLaunchingProviders = false;
   12705                     for (j = 0; j < launchingCount; j++) {
   12706                         if (mLaunchingProviders.get(j) == dst) {
   12707                             mLaunchingProviders.remove(j);
   12708                             wasInLaunchingProviders = true;
   12709                             j--;
   12710                             launchingCount--;
   12711                         }
   12712                     }
   12713                     if (wasInLaunchingProviders) {
   12714                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
   12715                     }
   12716                     synchronized (dst) {
   12717                         dst.provider = src.provider;
   12718                         dst.proc = r;
   12719                         dst.notifyAll();
   12720                     }
   12721                     updateOomAdjLocked(r, true);
   12722                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
   12723                             src.info.authority);
   12724                 }
   12725             }
   12726 
   12727             Binder.restoreCallingIdentity(origId);
   12728         }
   12729     }
   12730 
   12731     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
   12732         ContentProviderConnection conn;
   12733         try {
   12734             conn = (ContentProviderConnection)connection;
   12735         } catch (ClassCastException e) {
   12736             String msg ="refContentProvider: " + connection
   12737                     + " not a ContentProviderConnection";
   12738             Slog.w(TAG, msg);
   12739             throw new IllegalArgumentException(msg);
   12740         }
   12741         if (conn == null) {
   12742             throw new NullPointerException("connection is null");
   12743         }
   12744 
   12745         synchronized (this) {
   12746             if (stable > 0) {
   12747                 conn.numStableIncs += stable;
   12748             }
   12749             stable = conn.stableCount + stable;
   12750             if (stable < 0) {
   12751                 throw new IllegalStateException("stableCount < 0: " + stable);
   12752             }
   12753 
   12754             if (unstable > 0) {
   12755                 conn.numUnstableIncs += unstable;
   12756             }
   12757             unstable = conn.unstableCount + unstable;
   12758             if (unstable < 0) {
   12759                 throw new IllegalStateException("unstableCount < 0: " + unstable);
   12760             }
   12761 
   12762             if ((stable+unstable) <= 0) {
   12763                 throw new IllegalStateException("ref counts can't go to zero here: stable="
   12764                         + stable + " unstable=" + unstable);
   12765             }
   12766             conn.stableCount = stable;
   12767             conn.unstableCount = unstable;
   12768             return !conn.dead;
   12769         }
   12770     }
   12771 
   12772     public void unstableProviderDied(IBinder connection) {
   12773         ContentProviderConnection conn;
   12774         try {
   12775             conn = (ContentProviderConnection)connection;
   12776         } catch (ClassCastException e) {
   12777             String msg ="refContentProvider: " + connection
   12778                     + " not a ContentProviderConnection";
   12779             Slog.w(TAG, msg);
   12780             throw new IllegalArgumentException(msg);
   12781         }
   12782         if (conn == null) {
   12783             throw new NullPointerException("connection is null");
   12784         }
   12785 
   12786         // Safely retrieve the content provider associated with the connection.
   12787         IContentProvider provider;
   12788         synchronized (this) {
   12789             provider = conn.provider.provider;
   12790         }
   12791 
   12792         if (provider == null) {
   12793             // Um, yeah, we're way ahead of you.
   12794             return;
   12795         }
   12796 
   12797         // Make sure the caller is being honest with us.
   12798         if (provider.asBinder().pingBinder()) {
   12799             // Er, no, still looks good to us.
   12800             synchronized (this) {
   12801                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
   12802                         + " says " + conn + " died, but we don't agree");
   12803                 return;
   12804             }
   12805         }
   12806 
   12807         // Well look at that!  It's dead!
   12808         synchronized (this) {
   12809             if (conn.provider.provider != provider) {
   12810                 // But something changed...  good enough.
   12811                 return;
   12812             }
   12813 
   12814             ProcessRecord proc = conn.provider.proc;
   12815             if (proc == null || proc.thread == null) {
   12816                 // Seems like the process is already cleaned up.
   12817                 return;
   12818             }
   12819 
   12820             // As far as we're concerned, this is just like receiving a
   12821             // death notification...  just a bit prematurely.
   12822             reportUidInfoMessageLocked(TAG,
   12823                     "Process " + proc.processName + " (pid " + proc.pid
   12824                             + ") early provider death",
   12825                     proc.info.uid);
   12826             final long ident = Binder.clearCallingIdentity();
   12827             try {
   12828                 appDiedLocked(proc);
   12829             } finally {
   12830                 Binder.restoreCallingIdentity(ident);
   12831             }
   12832         }
   12833     }
   12834 
   12835     @Override
   12836     public void appNotRespondingViaProvider(IBinder connection) {
   12837         enforceCallingPermission(REMOVE_TASKS, "appNotRespondingViaProvider()");
   12838 
   12839         final ContentProviderConnection conn = (ContentProviderConnection) connection;
   12840         if (conn == null) {
   12841             Slog.w(TAG, "ContentProviderConnection is null");
   12842             return;
   12843         }
   12844 
   12845         final ProcessRecord host = conn.provider.proc;
   12846         if (host == null) {
   12847             Slog.w(TAG, "Failed to find hosting ProcessRecord");
   12848             return;
   12849         }
   12850 
   12851         mHandler.post(new Runnable() {
   12852             @Override
   12853             public void run() {
   12854                 mAppErrors.appNotResponding(host, null, null, false,
   12855                         "ContentProvider not responding");
   12856             }
   12857         });
   12858     }
   12859 
   12860     public final void installSystemProviders() {
   12861         List<ProviderInfo> providers;
   12862         synchronized (this) {
   12863             ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
   12864             providers = generateApplicationProvidersLocked(app);
   12865             if (providers != null) {
   12866                 for (int i=providers.size()-1; i>=0; i--) {
   12867                     ProviderInfo pi = (ProviderInfo)providers.get(i);
   12868                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   12869                         Slog.w(TAG, "Not installing system proc provider " + pi.name
   12870                                 + ": not system .apk");
   12871                         providers.remove(i);
   12872                     }
   12873                 }
   12874             }
   12875         }
   12876         if (providers != null) {
   12877             mSystemThread.installSystemProviders(providers);
   12878         }
   12879 
   12880         synchronized (this) {
   12881             mSystemProvidersInstalled = true;
   12882         }
   12883 
   12884         mConstants.start(mContext.getContentResolver());
   12885         mCoreSettingsObserver = new CoreSettingsObserver(this);
   12886         mFontScaleSettingObserver = new FontScaleSettingObserver();
   12887         mDevelopmentSettingsObserver = new DevelopmentSettingsObserver();
   12888         GlobalSettingsToPropertiesMapper.start(mContext.getContentResolver());
   12889 
   12890         // Now that the settings provider is published we can consider sending
   12891         // in a rescue party.
   12892         RescueParty.onSettingsProviderPublished(mContext);
   12893 
   12894         //mUsageStatsService.monitorPackages();
   12895     }
   12896 
   12897     void startPersistentApps(int matchFlags) {
   12898         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
   12899 
   12900         synchronized (this) {
   12901             try {
   12902                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
   12903                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
   12904                 for (ApplicationInfo app : apps) {
   12905                     if (!"android".equals(app.packageName)) {
   12906                         addAppLocked(app, null, false, null /* ABI override */);
   12907                     }
   12908                 }
   12909             } catch (RemoteException ex) {
   12910             }
   12911         }
   12912     }
   12913 
   12914     /**
   12915      * When a user is unlocked, we need to install encryption-unaware providers
   12916      * belonging to any running apps.
   12917      */
   12918     void installEncryptionUnawareProviders(int userId) {
   12919         // We're only interested in providers that are encryption unaware, and
   12920         // we don't care about uninstalled apps, since there's no way they're
   12921         // running at this point.
   12922         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
   12923 
   12924         synchronized (this) {
   12925             final int NP = mProcessNames.getMap().size();
   12926             for (int ip = 0; ip < NP; ip++) {
   12927                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   12928                 final int NA = apps.size();
   12929                 for (int ia = 0; ia < NA; ia++) {
   12930                     final ProcessRecord app = apps.valueAt(ia);
   12931                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
   12932 
   12933                     final int NG = app.pkgList.size();
   12934                     for (int ig = 0; ig < NG; ig++) {
   12935                         try {
   12936                             final String pkgName = app.pkgList.keyAt(ig);
   12937                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
   12938                                     .getPackageInfo(pkgName, matchFlags, userId);
   12939                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
   12940                                 for (ProviderInfo pi : pkgInfo.providers) {
   12941                                     // TODO: keep in sync with generateApplicationProvidersLocked
   12942                                     final boolean processMatch = Objects.equals(pi.processName,
   12943                                             app.processName) || pi.multiprocess;
   12944                                     final boolean userMatch = isSingleton(pi.processName,
   12945                                             pi.applicationInfo, pi.name, pi.flags)
   12946                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
   12947                                     if (processMatch && userMatch) {
   12948                                         Log.v(TAG, "Installing " + pi);
   12949                                         app.thread.scheduleInstallProvider(pi);
   12950                                     } else {
   12951                                         Log.v(TAG, "Skipping " + pi);
   12952                                     }
   12953                                 }
   12954                             }
   12955                         } catch (RemoteException ignored) {
   12956                         }
   12957                     }
   12958                 }
   12959             }
   12960         }
   12961     }
   12962 
   12963     /**
   12964      * Allows apps to retrieve the MIME type of a URI.
   12965      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
   12966      * users, then it does not need permission to access the ContentProvider.
   12967      * Either, it needs cross-user uri grants.
   12968      *
   12969      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
   12970      *
   12971      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
   12972      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
   12973      */
   12974     public String getProviderMimeType(Uri uri, int userId) {
   12975         enforceNotIsolatedCaller("getProviderMimeType");
   12976         final String name = uri.getAuthority();
   12977         int callingUid = Binder.getCallingUid();
   12978         int callingPid = Binder.getCallingPid();
   12979         long ident = 0;
   12980         boolean clearedIdentity = false;
   12981         userId = mUserController.unsafeConvertIncomingUser(userId);
   12982         if (canClearIdentity(callingPid, callingUid, userId)) {
   12983             clearedIdentity = true;
   12984             ident = Binder.clearCallingIdentity();
   12985         }
   12986         ContentProviderHolder holder = null;
   12987         try {
   12988             holder = getContentProviderExternalUnchecked(name, null, userId);
   12989             if (holder != null) {
   12990                 return holder.provider.getType(uri);
   12991             }
   12992         } catch (RemoteException e) {
   12993             Log.w(TAG, "Content provider dead retrieving " + uri, e);
   12994             return null;
   12995         } catch (Exception e) {
   12996             Log.w(TAG, "Exception while determining type of " + uri, e);
   12997             return null;
   12998         } finally {
   12999             // We need to clear the identity to call removeContentProviderExternalUnchecked
   13000             if (!clearedIdentity) {
   13001                 ident = Binder.clearCallingIdentity();
   13002             }
   13003             try {
   13004                 if (holder != null) {
   13005                     removeContentProviderExternalUnchecked(name, null, userId);
   13006                 }
   13007             } finally {
   13008                 Binder.restoreCallingIdentity(ident);
   13009             }
   13010         }
   13011 
   13012         return null;
   13013     }
   13014 
   13015     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
   13016         if (UserHandle.getUserId(callingUid) == userId) {
   13017             return true;
   13018         }
   13019         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
   13020                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
   13021                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
   13022                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
   13023                 return true;
   13024         }
   13025         return false;
   13026     }
   13027 
   13028     // =========================================================
   13029     // GLOBAL MANAGEMENT
   13030     // =========================================================
   13031 
   13032     @GuardedBy("this")
   13033     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
   13034             boolean isolated, int isolatedUid) {
   13035         String proc = customProcess != null ? customProcess : info.processName;
   13036         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   13037         final int userId = UserHandle.getUserId(info.uid);
   13038         int uid = info.uid;
   13039         if (isolated) {
   13040             if (isolatedUid == 0) {
   13041                 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
   13042                 while (true) {
   13043                     if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
   13044                             || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
   13045                         mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
   13046                     }
   13047                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
   13048                     mNextIsolatedProcessUid++;
   13049                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
   13050                         // No process for this uid, use it.
   13051                         break;
   13052                     }
   13053                     stepsLeft--;
   13054                     if (stepsLeft <= 0) {
   13055                         return null;
   13056                     }
   13057                 }
   13058             } else {
   13059                 // Special case for startIsolatedProcess (internal only), where
   13060                 // the uid of the isolated process is specified by the caller.
   13061                 uid = isolatedUid;
   13062             }
   13063             getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
   13064 
   13065             // Register the isolated UID with this application so BatteryStats knows to
   13066             // attribute resource usage to the application.
   13067             //
   13068             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
   13069             // about the process state of the isolated UID *before* it is registered with the
   13070             // owning application.
   13071             mBatteryStatsService.addIsolatedUid(uid, info.uid);
   13072         }
   13073         final ProcessRecord r = new ProcessRecord(this, stats, info, proc, uid);
   13074         if (!mBooted && !mBooting
   13075                 && userId == UserHandle.USER_SYSTEM
   13076                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
   13077             // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
   13078             r.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   13079             r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   13080             r.persistent = true;
   13081             r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
   13082         }
   13083         if (isolated && isolatedUid != 0) {
   13084             // Special case for startIsolatedProcess (internal only) - assume the process
   13085             // is required by the system server to prevent it being killed.
   13086             r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
   13087         }
   13088         addProcessNameLocked(r);
   13089         return r;
   13090     }
   13091 
   13092     private boolean uidOnBackgroundWhitelist(final int uid) {
   13093         final int appId = UserHandle.getAppId(uid);
   13094         final int[] whitelist = mBackgroundAppIdWhitelist;
   13095         final int N = whitelist.length;
   13096         for (int i = 0; i < N; i++) {
   13097             if (appId == whitelist[i]) {
   13098                 return true;
   13099             }
   13100         }
   13101         return false;
   13102     }
   13103 
   13104     @Override
   13105     public boolean isBackgroundRestricted(String packageName) {
   13106         final int callingUid = Binder.getCallingUid();
   13107         final IPackageManager pm = AppGlobals.getPackageManager();
   13108         try {
   13109             final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
   13110                     UserHandle.getUserId(callingUid));
   13111             if (packageUid != callingUid) {
   13112                 throw new IllegalArgumentException("Uid " + callingUid
   13113                         + " cannot query restriction state for package " + packageName);
   13114             }
   13115         } catch (RemoteException exc) {
   13116             // Ignore.
   13117         }
   13118         return isBackgroundRestrictedNoCheck(callingUid, packageName);
   13119     }
   13120 
   13121     boolean isBackgroundRestrictedNoCheck(final int uid, final String packageName) {
   13122         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND,
   13123                 uid, packageName);
   13124         return mode != AppOpsManager.MODE_ALLOWED;
   13125     }
   13126 
   13127     @Override
   13128     public void backgroundWhitelistUid(final int uid) {
   13129         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   13130             throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
   13131         }
   13132 
   13133         if (DEBUG_BACKGROUND_CHECK) {
   13134             Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
   13135         }
   13136         synchronized (this) {
   13137             final int N = mBackgroundAppIdWhitelist.length;
   13138             int[] newList = new int[N+1];
   13139             System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
   13140             newList[N] = UserHandle.getAppId(uid);
   13141             mBackgroundAppIdWhitelist = newList;
   13142         }
   13143     }
   13144 
   13145     @GuardedBy("this")
   13146     final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
   13147             String abiOverride) {
   13148         return addAppLocked(info, customProcess, isolated, false /* disableHiddenApiChecks */,
   13149                 abiOverride);
   13150     }
   13151 
   13152     final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
   13153             boolean disableHiddenApiChecks, String abiOverride) {
   13154         ProcessRecord app;
   13155         if (!isolated) {
   13156             app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
   13157                     info.uid, true);
   13158         } else {
   13159             app = null;
   13160         }
   13161 
   13162         if (app == null) {
   13163             app = newProcessRecordLocked(info, customProcess, isolated, 0);
   13164             updateLruProcessLocked(app, false, null);
   13165             updateOomAdjLocked();
   13166         }
   13167 
   13168         // This package really, really can not be stopped.
   13169         try {
   13170             AppGlobals.getPackageManager().setPackageStoppedState(
   13171                     info.packageName, false, UserHandle.getUserId(app.uid));
   13172         } catch (RemoteException e) {
   13173         } catch (IllegalArgumentException e) {
   13174             Slog.w(TAG, "Failed trying to unstop package "
   13175                     + info.packageName + ": " + e);
   13176         }
   13177 
   13178         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
   13179             app.persistent = true;
   13180             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
   13181         }
   13182         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
   13183             mPersistentStartingProcesses.add(app);
   13184             startProcessLocked(app, "added application",
   13185                     customProcess != null ? customProcess : app.processName, disableHiddenApiChecks,
   13186                     abiOverride);
   13187         }
   13188 
   13189         return app;
   13190     }
   13191 
   13192     public void unhandledBack() {
   13193         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
   13194                 "unhandledBack()");
   13195 
   13196         synchronized(this) {
   13197             final long origId = Binder.clearCallingIdentity();
   13198             try {
   13199                 getFocusedStack().unhandledBackLocked();
   13200             } finally {
   13201                 Binder.restoreCallingIdentity(origId);
   13202             }
   13203         }
   13204     }
   13205 
   13206     public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
   13207         enforceNotIsolatedCaller("openContentUri");
   13208         final int userId = UserHandle.getCallingUserId();
   13209         final Uri uri = Uri.parse(uriString);
   13210         String name = uri.getAuthority();
   13211         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
   13212         ParcelFileDescriptor pfd = null;
   13213         if (cph != null) {
   13214             // We record the binder invoker's uid in thread-local storage before
   13215             // going to the content provider to open the file.  Later, in the code
   13216             // that handles all permissions checks, we look for this uid and use
   13217             // that rather than the Activity Manager's own uid.  The effect is that
   13218             // we do the check against the caller's permissions even though it looks
   13219             // to the content provider like the Activity Manager itself is making
   13220             // the request.
   13221             Binder token = new Binder();
   13222             sCallerIdentity.set(new Identity(
   13223                     token, Binder.getCallingPid(), Binder.getCallingUid()));
   13224             try {
   13225                 pfd = cph.provider.openFile(null, uri, "r", null, token);
   13226             } catch (FileNotFoundException e) {
   13227                 // do nothing; pfd will be returned null
   13228             } finally {
   13229                 // Ensure that whatever happens, we clean up the identity state
   13230                 sCallerIdentity.remove();
   13231                 // Ensure we're done with the provider.
   13232                 removeContentProviderExternalUnchecked(name, null, userId);
   13233             }
   13234         } else {
   13235             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
   13236         }
   13237         return pfd;
   13238     }
   13239 
   13240     // Actually is sleeping or shutting down or whatever else in the future
   13241     // is an inactive state.
   13242     boolean isSleepingOrShuttingDownLocked() {
   13243         return isSleepingLocked() || mShuttingDown;
   13244     }
   13245 
   13246     boolean isShuttingDownLocked() {
   13247         return mShuttingDown;
   13248     }
   13249 
   13250     boolean isSleepingLocked() {
   13251         return mSleeping;
   13252     }
   13253 
   13254     void reportGlobalUsageEventLocked(int event) {
   13255         mUsageStatsService.reportEvent("android", mUserController.getCurrentUserId(), event);
   13256         int[] profiles = mUserController.getCurrentProfileIds();
   13257         if (profiles != null) {
   13258             for (int i = profiles.length - 1; i >= 0; i--) {
   13259                 mUsageStatsService.reportEvent((String)null, profiles[i], event);
   13260             }
   13261         }
   13262     }
   13263 
   13264     void reportCurWakefulnessUsageEventLocked() {
   13265         reportGlobalUsageEventLocked(mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE
   13266                 ? UsageEvents.Event.SCREEN_INTERACTIVE
   13267                 : UsageEvents.Event.SCREEN_NON_INTERACTIVE);
   13268     }
   13269 
   13270     void reportCurKeyguardUsageEventLocked() {
   13271         reportGlobalUsageEventLocked(mKeyguardShown
   13272                 ? UsageEvents.Event.KEYGUARD_SHOWN
   13273                 : UsageEvents.Event.KEYGUARD_HIDDEN);
   13274     }
   13275 
   13276     void onWakefulnessChanged(int wakefulness) {
   13277         synchronized(this) {
   13278             boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
   13279             boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
   13280             mWakefulness = wakefulness;
   13281 
   13282             if (wasAwake != isAwake) {
   13283                 // Also update state in a special way for running foreground services UI.
   13284                 mServices.updateScreenStateLocked(isAwake);
   13285                 reportCurWakefulnessUsageEventLocked();
   13286                 mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
   13287                         .sendToTarget();
   13288             }
   13289             updateOomAdjLocked();
   13290         }
   13291     }
   13292 
   13293     @GuardedBy("this")
   13294     void finishRunningVoiceLocked() {
   13295         if (mRunningVoice != null) {
   13296             mRunningVoice = null;
   13297             mVoiceWakeLock.release();
   13298             updateSleepIfNeededLocked();
   13299         }
   13300     }
   13301 
   13302     void startTimeTrackingFocusedActivityLocked() {
   13303         final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
   13304         if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
   13305             mCurAppTimeTracker.start(resumedActivity.packageName);
   13306         }
   13307     }
   13308 
   13309     @GuardedBy("this")
   13310     void updateSleepIfNeededLocked() {
   13311         final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
   13312         final boolean wasSleeping = mSleeping;
   13313 
   13314         if (!shouldSleep) {
   13315             // If wasSleeping is true, we need to wake up activity manager state from when
   13316             // we started sleeping. In either case, we need to apply the sleep tokens, which
   13317             // will wake up stacks or put them to sleep as appropriate.
   13318             if (wasSleeping) {
   13319                 mSleeping = false;
   13320                 startTimeTrackingFocusedActivityLocked();
   13321                 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
   13322                 mStackSupervisor.comeOutOfSleepIfNeededLocked();
   13323             }
   13324             mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
   13325             if (wasSleeping) {
   13326                 updateOomAdjLocked();
   13327             }
   13328         } else if (!mSleeping && shouldSleep) {
   13329             mSleeping = true;
   13330             if (mCurAppTimeTracker != null) {
   13331                 mCurAppTimeTracker.stop();
   13332             }
   13333             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
   13334             mStackSupervisor.goingToSleepLocked();
   13335             updateResumedAppTrace(null /* resumed */);
   13336             updateOomAdjLocked();
   13337         }
   13338     }
   13339 
   13340     /** Pokes the task persister. */
   13341     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
   13342         mRecentTasks.notifyTaskPersisterLocked(task, flush);
   13343     }
   13344 
   13345     /**
   13346      * Notifies all listeners when the pinned stack animation starts.
   13347      */
   13348     @Override
   13349     public void notifyPinnedStackAnimationStarted() {
   13350         mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
   13351     }
   13352 
   13353     /**
   13354      * Notifies all listeners when the pinned stack animation ends.
   13355      */
   13356     @Override
   13357     public void notifyPinnedStackAnimationEnded() {
   13358         mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
   13359     }
   13360 
   13361     @Override
   13362     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
   13363         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
   13364     }
   13365 
   13366     @Override
   13367     public boolean shutdown(int timeout) {
   13368         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
   13369                 != PackageManager.PERMISSION_GRANTED) {
   13370             throw new SecurityException("Requires permission "
   13371                     + android.Manifest.permission.SHUTDOWN);
   13372         }
   13373 
   13374         boolean timedout = false;
   13375 
   13376         synchronized(this) {
   13377             mShuttingDown = true;
   13378             mStackSupervisor.prepareForShutdownLocked();
   13379             updateEventDispatchingLocked();
   13380             timedout = mStackSupervisor.shutdownLocked(timeout);
   13381         }
   13382 
   13383         mAppOpsService.shutdown();
   13384         if (mUsageStatsService != null) {
   13385             mUsageStatsService.prepareShutdown();
   13386         }
   13387         mBatteryStatsService.shutdown();
   13388         synchronized (this) {
   13389             mProcessStats.shutdownLocked();
   13390             notifyTaskPersisterLocked(null, true);
   13391         }
   13392 
   13393         return timedout;
   13394     }
   13395 
   13396     public final void activitySlept(IBinder token) {
   13397         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
   13398 
   13399         final long origId = Binder.clearCallingIdentity();
   13400 
   13401         synchronized (this) {
   13402             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   13403             if (r != null) {
   13404                 mStackSupervisor.activitySleptLocked(r);
   13405             }
   13406         }
   13407 
   13408         Binder.restoreCallingIdentity(origId);
   13409     }
   13410 
   13411     @GuardedBy("this")
   13412     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
   13413         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
   13414         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
   13415         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
   13416             boolean wasRunningVoice = mRunningVoice != null;
   13417             mRunningVoice = session;
   13418             if (!wasRunningVoice) {
   13419                 mVoiceWakeLock.acquire();
   13420                 updateSleepIfNeededLocked();
   13421             }
   13422         }
   13423     }
   13424 
   13425     private void updateEventDispatchingLocked() {
   13426         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
   13427     }
   13428 
   13429     @Override
   13430     public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
   13431             int secondaryDisplayShowing) {
   13432         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   13433                 != PackageManager.PERMISSION_GRANTED) {
   13434             throw new SecurityException("Requires permission "
   13435                     + android.Manifest.permission.DEVICE_POWER);
   13436         }
   13437 
   13438         synchronized(this) {
   13439             long ident = Binder.clearCallingIdentity();
   13440             if (mKeyguardShown != keyguardShowing) {
   13441                 mKeyguardShown = keyguardShowing;
   13442                 reportCurKeyguardUsageEventLocked();
   13443             }
   13444             try {
   13445                 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
   13446                         secondaryDisplayShowing);
   13447             } finally {
   13448                 Binder.restoreCallingIdentity(ident);
   13449             }
   13450         }
   13451 
   13452         mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, keyguardShowing ? 1 : 0, 0)
   13453                 .sendToTarget();
   13454     }
   13455 
   13456     @Override
   13457     public void notifyLockedProfile(@UserIdInt int userId) {
   13458         try {
   13459             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
   13460                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
   13461             }
   13462         } catch (RemoteException ex) {
   13463             throw new SecurityException("Fail to check is caller a privileged app", ex);
   13464         }
   13465 
   13466         synchronized (this) {
   13467             final long ident = Binder.clearCallingIdentity();
   13468             try {
   13469                 if (mUserController.shouldConfirmCredentials(userId)) {
   13470                     if (mKeyguardController.isKeyguardLocked()) {
   13471                         // Showing launcher to avoid user entering credential twice.
   13472                         final int currentUserId = mUserController.getCurrentUserId();
   13473                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
   13474                     }
   13475                     mStackSupervisor.lockAllProfileTasks(userId);
   13476                 }
   13477             } finally {
   13478                 Binder.restoreCallingIdentity(ident);
   13479             }
   13480         }
   13481     }
   13482 
   13483     @Override
   13484     public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
   13485         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
   13486         synchronized (this) {
   13487             final long ident = Binder.clearCallingIdentity();
   13488             try {
   13489                 intent.addFlags(FLAG_ACTIVITY_NEW_TASK |
   13490                         FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
   13491                         FLAG_ACTIVITY_TASK_ON_HOME);
   13492                 ActivityOptions activityOptions = options != null
   13493                         ? new ActivityOptions(options)
   13494                         : ActivityOptions.makeBasic();
   13495                 activityOptions.setLaunchTaskId(
   13496                         mStackSupervisor.getHomeActivity().getTask().taskId);
   13497                 mContext.startActivityAsUser(intent, activityOptions.toBundle(),
   13498                         UserHandle.CURRENT);
   13499             } finally {
   13500                 Binder.restoreCallingIdentity(ident);
   13501             }
   13502         }
   13503     }
   13504 
   13505     @Override
   13506     public void stopAppSwitches() {
   13507         enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
   13508         synchronized(this) {
   13509             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
   13510                     + APP_SWITCH_DELAY_TIME;
   13511             mDidAppSwitch = false;
   13512             mActivityStartController.schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
   13513         }
   13514     }
   13515 
   13516     public void resumeAppSwitches() {
   13517         enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
   13518         synchronized(this) {
   13519             // Note that we don't execute any pending app switches... we will
   13520             // let those wait until either the timeout, or the next start
   13521             // activity request.
   13522             mAppSwitchesAllowedTime = 0;
   13523         }
   13524     }
   13525 
   13526     boolean checkAllowAppSwitchUid(int uid) {
   13527         ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
   13528         if (types != null) {
   13529             for (int i = types.size() - 1; i >= 0; i--) {
   13530                 if (types.valueAt(i).intValue() == uid) {
   13531                     return true;
   13532                 }
   13533             }
   13534         }
   13535         return false;
   13536     }
   13537 
   13538     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
   13539             int callingPid, int callingUid, String name) {
   13540         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
   13541             return true;
   13542         }
   13543 
   13544         if (mRecentTasks.isCallerRecents(sourceUid)) {
   13545             return true;
   13546         }
   13547 
   13548         int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
   13549         if (perm == PackageManager.PERMISSION_GRANTED) {
   13550             return true;
   13551         }
   13552         if (checkAllowAppSwitchUid(sourceUid)) {
   13553             return true;
   13554         }
   13555 
   13556         // If the actual IPC caller is different from the logical source, then
   13557         // also see if they are allowed to control app switches.
   13558         if (callingUid != -1 && callingUid != sourceUid) {
   13559             perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
   13560             if (perm == PackageManager.PERMISSION_GRANTED) {
   13561                 return true;
   13562             }
   13563             if (checkAllowAppSwitchUid(callingUid)) {
   13564                 return true;
   13565             }
   13566         }
   13567 
   13568         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
   13569         return false;
   13570     }
   13571 
   13572     public void setDebugApp(String packageName, boolean waitForDebugger,
   13573             boolean persistent) {
   13574         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   13575                 "setDebugApp()");
   13576 
   13577         long ident = Binder.clearCallingIdentity();
   13578         try {
   13579             // Note that this is not really thread safe if there are multiple
   13580             // callers into it at the same time, but that's not a situation we
   13581             // care about.
   13582             if (persistent) {
   13583                 final ContentResolver resolver = mContext.getContentResolver();
   13584                 Settings.Global.putString(
   13585                     resolver, Settings.Global.DEBUG_APP,
   13586                     packageName);
   13587                 Settings.Global.putInt(
   13588                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
   13589                     waitForDebugger ? 1 : 0);
   13590             }
   13591 
   13592             synchronized (this) {
   13593                 if (!persistent) {
   13594                     mOrigDebugApp = mDebugApp;
   13595                     mOrigWaitForDebugger = mWaitForDebugger;
   13596                 }
   13597                 mDebugApp = packageName;
   13598                 mWaitForDebugger = waitForDebugger;
   13599                 mDebugTransient = !persistent;
   13600                 if (packageName != null) {
   13601                     forceStopPackageLocked(packageName, -1, false, false, true, true,
   13602                             false, UserHandle.USER_ALL, "set debug app");
   13603                 }
   13604             }
   13605         } finally {
   13606             Binder.restoreCallingIdentity(ident);
   13607         }
   13608     }
   13609 
   13610     /**
   13611      * Set or remove an agent to be run whenever an app with the given process name starts.
   13612      *
   13613      * This method will not check whether the given process name matches a debuggable app. That
   13614      * would require scanning all current packages, and a rescan when new packages are installed
   13615      * or updated.
   13616      *
   13617      * Instead, do the check when an application is started and matched to a stored agent.
   13618      *
   13619      * @param packageName the process name of the app.
   13620      * @param agent the agent string to be used, or null to remove any previously set agent.
   13621      */
   13622     @Override
   13623     public void setAgentApp(@NonNull String packageName, @Nullable String agent) {
   13624         synchronized (this) {
   13625             // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   13626             // its own permission.
   13627             if (checkCallingPermission(
   13628                     android.Manifest.permission.SET_ACTIVITY_WATCHER) !=
   13629                         PackageManager.PERMISSION_GRANTED) {
   13630                 throw new SecurityException(
   13631                         "Requires permission " + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   13632             }
   13633 
   13634             if (agent == null) {
   13635                 if (mAppAgentMap != null) {
   13636                     mAppAgentMap.remove(packageName);
   13637                     if (mAppAgentMap.isEmpty()) {
   13638                         mAppAgentMap = null;
   13639                     }
   13640                 }
   13641             } else {
   13642                 if (mAppAgentMap == null) {
   13643                     mAppAgentMap = new HashMap<>();
   13644                 }
   13645                 if (mAppAgentMap.size() >= 100) {
   13646                     // Limit the size of the map, to avoid OOMEs.
   13647                     Slog.e(TAG, "App agent map has too many entries, cannot add " + packageName
   13648                             + "/" + agent);
   13649                     return;
   13650                 }
   13651                 mAppAgentMap.put(packageName, agent);
   13652             }
   13653         }
   13654     }
   13655 
   13656     void setTrackAllocationApp(ApplicationInfo app, String processName) {
   13657         synchronized (this) {
   13658             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   13659             if (!isDebuggable) {
   13660                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   13661                     throw new SecurityException("Process not debuggable: " + app.packageName);
   13662                 }
   13663             }
   13664 
   13665             mTrackAllocationApp = processName;
   13666         }
   13667     }
   13668 
   13669     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
   13670         synchronized (this) {
   13671             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   13672             if (!isDebuggable) {
   13673                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   13674                     throw new SecurityException("Process not debuggable: " + app.packageName);
   13675                 }
   13676             }
   13677             mProfileApp = processName;
   13678 
   13679             if (mProfilerInfo != null) {
   13680                 if (mProfilerInfo.profileFd != null) {
   13681                     try {
   13682                         mProfilerInfo.profileFd.close();
   13683                     } catch (IOException e) {
   13684                     }
   13685                 }
   13686             }
   13687             mProfilerInfo = new ProfilerInfo(profilerInfo);
   13688             mProfileType = 0;
   13689         }
   13690     }
   13691 
   13692     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
   13693         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   13694         if (!isDebuggable) {
   13695             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   13696                 throw new SecurityException("Process not debuggable: " + app.packageName);
   13697             }
   13698         }
   13699         mNativeDebuggingApp = processName;
   13700     }
   13701 
   13702     @Override
   13703     public void setAlwaysFinish(boolean enabled) {
   13704         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
   13705                 "setAlwaysFinish()");
   13706 
   13707         long ident = Binder.clearCallingIdentity();
   13708         try {
   13709             Settings.Global.putInt(
   13710                     mContext.getContentResolver(),
   13711                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
   13712 
   13713             synchronized (this) {
   13714                 mAlwaysFinishActivities = enabled;
   13715             }
   13716         } finally {
   13717             Binder.restoreCallingIdentity(ident);
   13718         }
   13719     }
   13720 
   13721     @Override
   13722     public void setActivityController(IActivityController controller, boolean imAMonkey) {
   13723         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   13724                 "setActivityController()");
   13725         synchronized (this) {
   13726             mController = controller;
   13727             mControllerIsAMonkey = imAMonkey;
   13728             Watchdog.getInstance().setActivityController(controller);
   13729         }
   13730     }
   13731 
   13732     @Override
   13733     public void setUserIsMonkey(boolean userIsMonkey) {
   13734         synchronized (this) {
   13735             synchronized (mPidsSelfLocked) {
   13736                 final int callingPid = Binder.getCallingPid();
   13737                 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
   13738                 if (proc == null) {
   13739                     throw new SecurityException("Unknown process: " + callingPid);
   13740                 }
   13741                 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
   13742                     throw new SecurityException("Only an instrumentation process "
   13743                             + "with a UiAutomation can call setUserIsMonkey");
   13744                 }
   13745             }
   13746             mUserIsMonkey = userIsMonkey;
   13747         }
   13748     }
   13749 
   13750     @Override
   13751     public boolean isUserAMonkey() {
   13752         synchronized (this) {
   13753             // If there is a controller also implies the user is a monkey.
   13754             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
   13755         }
   13756     }
   13757 
   13758     /**
   13759      * @deprecated This method is only used by a few internal components and it will soon be
   13760      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
   13761      * No new code should be calling it.
   13762      */
   13763     @Deprecated
   13764     @Override
   13765     public void requestBugReport(int bugreportType) {
   13766         String extraOptions = null;
   13767         switch (bugreportType) {
   13768             case ActivityManager.BUGREPORT_OPTION_FULL:
   13769                 // Default options.
   13770                 break;
   13771             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
   13772                 extraOptions = "bugreportplus";
   13773                 break;
   13774             case ActivityManager.BUGREPORT_OPTION_REMOTE:
   13775                 extraOptions = "bugreportremote";
   13776                 break;
   13777             case ActivityManager.BUGREPORT_OPTION_WEAR:
   13778                 extraOptions = "bugreportwear";
   13779                 break;
   13780             case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
   13781                 extraOptions = "bugreporttelephony";
   13782                 break;
   13783             case ActivityManager.BUGREPORT_OPTION_WIFI:
   13784                 extraOptions = "bugreportwifi";
   13785                 break;
   13786             default:
   13787                 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
   13788                         + bugreportType);
   13789         }
   13790         // Always log caller, even if it does not have permission to dump.
   13791         String type = extraOptions == null ? "bugreport" : extraOptions;
   13792         Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
   13793 
   13794         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
   13795         if (extraOptions != null) {
   13796             SystemProperties.set("dumpstate.options", extraOptions);
   13797         }
   13798         SystemProperties.set("ctl.start", "bugreport");
   13799     }
   13800 
   13801     /**
   13802      * @deprecated This method is only used by a few internal components and it will soon be
   13803      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
   13804      * No new code should be calling it.
   13805      */
   13806     @Deprecated
   13807     private void requestBugReportWithDescription(String shareTitle, String shareDescription,
   13808                                                  int bugreportType) {
   13809         if (!TextUtils.isEmpty(shareTitle)) {
   13810             if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
   13811                 String errorStr = "shareTitle should be less than " +
   13812                         MAX_BUGREPORT_TITLE_SIZE + " characters";
   13813                 throw new IllegalArgumentException(errorStr);
   13814             } else {
   13815                 if (!TextUtils.isEmpty(shareDescription)) {
   13816                     int length;
   13817                     try {
   13818                         length = shareDescription.getBytes("UTF-8").length;
   13819                     } catch (UnsupportedEncodingException e) {
   13820                         String errorStr = "shareDescription: UnsupportedEncodingException";
   13821                         throw new IllegalArgumentException(errorStr);
   13822                     }
   13823                     if (length > SystemProperties.PROP_VALUE_MAX) {
   13824                         String errorStr = "shareTitle should be less than " +
   13825                                 SystemProperties.PROP_VALUE_MAX + " bytes";
   13826                         throw new IllegalArgumentException(errorStr);
   13827                     } else {
   13828                         SystemProperties.set("dumpstate.options.description", shareDescription);
   13829                     }
   13830                 }
   13831                 SystemProperties.set("dumpstate.options.title", shareTitle);
   13832             }
   13833         }
   13834 
   13835         Slog.d(TAG, "Bugreport notification title " + shareTitle
   13836                 + " description " + shareDescription);
   13837         requestBugReport(bugreportType);
   13838     }
   13839 
   13840     /**
   13841      * @deprecated This method is only used by a few internal components and it will soon be
   13842      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
   13843      * No new code should be calling it.
   13844      */
   13845     @Deprecated
   13846     @Override
   13847     public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
   13848         requestBugReportWithDescription(shareTitle, shareDescription,
   13849                 ActivityManager.BUGREPORT_OPTION_TELEPHONY);
   13850     }
   13851 
   13852     /**
   13853      * @deprecated This method is only used by a few internal components and it will soon be
   13854      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
   13855      * No new code should be calling it.
   13856      */
   13857     @Deprecated
   13858     @Override
   13859     public void requestWifiBugReport(String shareTitle, String shareDescription) {
   13860         requestBugReportWithDescription(shareTitle, shareDescription,
   13861                 ActivityManager.BUGREPORT_OPTION_WIFI);
   13862     }
   13863 
   13864 
   13865     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
   13866         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
   13867     }
   13868 
   13869     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
   13870         if (r != null && (r.instr != null || r.usingWrapper)) {
   13871             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
   13872         }
   13873         return KEY_DISPATCHING_TIMEOUT;
   13874     }
   13875 
   13876     @Override
   13877     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
   13878         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   13879                 != PackageManager.PERMISSION_GRANTED) {
   13880             throw new SecurityException("Requires permission "
   13881                     + android.Manifest.permission.FILTER_EVENTS);
   13882         }
   13883         ProcessRecord proc;
   13884         long timeout;
   13885         synchronized (this) {
   13886             synchronized (mPidsSelfLocked) {
   13887                 proc = mPidsSelfLocked.get(pid);
   13888             }
   13889             timeout = getInputDispatchingTimeoutLocked(proc);
   13890         }
   13891 
   13892         if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
   13893             return -1;
   13894         }
   13895 
   13896         return timeout;
   13897     }
   13898 
   13899     /**
   13900      * Handle input dispatching timeouts.
   13901      * Returns whether input dispatching should be aborted or not.
   13902      */
   13903     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
   13904             final ActivityRecord activity, final ActivityRecord parent,
   13905             final boolean aboveSystem, String reason) {
   13906         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   13907                 != PackageManager.PERMISSION_GRANTED) {
   13908             throw new SecurityException("Requires permission "
   13909                     + android.Manifest.permission.FILTER_EVENTS);
   13910         }
   13911 
   13912         final String annotation;
   13913         if (reason == null) {
   13914             annotation = "Input dispatching timed out";
   13915         } else {
   13916             annotation = "Input dispatching timed out (" + reason + ")";
   13917         }
   13918 
   13919         if (proc != null) {
   13920             synchronized (this) {
   13921                 if (proc.debugging) {
   13922                     return false;
   13923                 }
   13924 
   13925                 if (proc.instr != null) {
   13926                     Bundle info = new Bundle();
   13927                     info.putString("shortMsg", "keyDispatchingTimedOut");
   13928                     info.putString("longMsg", annotation);
   13929                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
   13930                     return true;
   13931                 }
   13932             }
   13933             mHandler.post(new Runnable() {
   13934                 @Override
   13935                 public void run() {
   13936                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
   13937                 }
   13938             });
   13939         }
   13940 
   13941         return true;
   13942     }
   13943 
   13944     @Override
   13945     public Bundle getAssistContextExtras(int requestType) {
   13946         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
   13947                 null, null, true /* focused */, true /* newSessionId */,
   13948                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
   13949         if (pae == null) {
   13950             return null;
   13951         }
   13952         synchronized (pae) {
   13953             while (!pae.haveResult) {
   13954                 try {
   13955                     pae.wait();
   13956                 } catch (InterruptedException e) {
   13957                 }
   13958             }
   13959         }
   13960         synchronized (this) {
   13961             buildAssistBundleLocked(pae, pae.result);
   13962             mPendingAssistExtras.remove(pae);
   13963             mUiHandler.removeCallbacks(pae);
   13964         }
   13965         return pae.extras;
   13966     }
   13967 
   13968     @Override
   13969     public boolean isAssistDataAllowedOnCurrentActivity() {
   13970         int userId;
   13971         synchronized (this) {
   13972             final ActivityStack focusedStack = getFocusedStack();
   13973             if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
   13974                 return false;
   13975             }
   13976 
   13977             final ActivityRecord activity = focusedStack.getTopActivity();
   13978             if (activity == null) {
   13979                 return false;
   13980             }
   13981             userId = activity.userId;
   13982         }
   13983         return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
   13984     }
   13985 
   13986     @Override
   13987     public boolean showAssistFromActivity(IBinder token, Bundle args) {
   13988         long ident = Binder.clearCallingIdentity();
   13989         try {
   13990             synchronized (this) {
   13991                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
   13992                 ActivityRecord top = getFocusedStack().getTopActivity();
   13993                 if (top != caller) {
   13994                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
   13995                             + " is not current top " + top);
   13996                     return false;
   13997                 }
   13998                 if (!top.nowVisible) {
   13999                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
   14000                             + " is not visible");
   14001                     return false;
   14002                 }
   14003             }
   14004             return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
   14005                     token);
   14006         } finally {
   14007             Binder.restoreCallingIdentity(ident);
   14008         }
   14009     }
   14010 
   14011     @Override
   14012     public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
   14013             Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
   14014         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
   14015                 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
   14016                 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
   14017     }
   14018 
   14019     @Override
   14020     public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
   14021             IBinder activityToken, int flags) {
   14022         return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
   14023                 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
   14024                 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
   14025     }
   14026 
   14027     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
   14028             IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
   14029             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
   14030             int flags) {
   14031         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
   14032                 "enqueueAssistContext()");
   14033 
   14034         synchronized (this) {
   14035             ActivityRecord activity = getFocusedStack().getTopActivity();
   14036             if (activity == null) {
   14037                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
   14038                 return null;
   14039             }
   14040             if (activity.app == null || activity.app.thread == null) {
   14041                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
   14042                 return null;
   14043             }
   14044             if (focused) {
   14045                 if (activityToken != null) {
   14046                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
   14047                     if (activity != caller) {
   14048                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
   14049                                 + " is not current top " + activity);
   14050                         return null;
   14051                     }
   14052                 }
   14053             } else {
   14054                 activity = ActivityRecord.forTokenLocked(activityToken);
   14055                 if (activity == null) {
   14056                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
   14057                             + " couldn't be found");
   14058                     return null;
   14059                 }
   14060                 if (activity.app == null || activity.app.thread == null) {
   14061                     Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
   14062                     return null;
   14063                 }
   14064             }
   14065 
   14066             PendingAssistExtras pae;
   14067             Bundle extras = new Bundle();
   14068             if (args != null) {
   14069                 extras.putAll(args);
   14070             }
   14071             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
   14072             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
   14073 
   14074             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
   14075                     userHandle);
   14076             pae.isHome = activity.isActivityTypeHome();
   14077 
   14078             // Increment the sessionId if necessary
   14079             if (newSessionId) {
   14080                 mViSessionId++;
   14081             }
   14082             try {
   14083                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
   14084                         mViSessionId, flags);
   14085                 mPendingAssistExtras.add(pae);
   14086                 mUiHandler.postDelayed(pae, timeout);
   14087             } catch (RemoteException e) {
   14088                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
   14089                 return null;
   14090             }
   14091             return pae;
   14092         }
   14093     }
   14094 
   14095     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
   14096         IAssistDataReceiver receiver;
   14097         synchronized (this) {
   14098             mPendingAssistExtras.remove(pae);
   14099             receiver = pae.receiver;
   14100         }
   14101         if (receiver != null) {
   14102             // Caller wants result sent back to them.
   14103             Bundle sendBundle = new Bundle();
   14104             // At least return the receiver extras
   14105             sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
   14106             try {
   14107                 pae.receiver.onHandleAssistData(sendBundle);
   14108             } catch (RemoteException e) {
   14109             }
   14110         }
   14111     }
   14112 
   14113     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
   14114         if (result != null) {
   14115             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
   14116         }
   14117         if (pae.hint != null) {
   14118             pae.extras.putBoolean(pae.hint, true);
   14119         }
   14120     }
   14121 
   14122     /** Called from an app when assist data is ready. */
   14123     @Override
   14124     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
   14125             AssistContent content, Uri referrer) {
   14126         PendingAssistExtras pae = (PendingAssistExtras)token;
   14127         synchronized (pae) {
   14128             pae.result = extras;
   14129             pae.structure = structure;
   14130             pae.content = content;
   14131             if (referrer != null) {
   14132                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
   14133             }
   14134             if (structure != null) {
   14135                 structure.setHomeActivity(pae.isHome);
   14136             }
   14137             pae.haveResult = true;
   14138             pae.notifyAll();
   14139             if (pae.intent == null && pae.receiver == null) {
   14140                 // Caller is just waiting for the result.
   14141                 return;
   14142             }
   14143         }
   14144         // We are now ready to launch the assist activity.
   14145         IAssistDataReceiver sendReceiver = null;
   14146         Bundle sendBundle = null;
   14147         synchronized (this) {
   14148             buildAssistBundleLocked(pae, extras);
   14149             boolean exists = mPendingAssistExtras.remove(pae);
   14150             mUiHandler.removeCallbacks(pae);
   14151             if (!exists) {
   14152                 // Timed out.
   14153                 return;
   14154             }
   14155 
   14156             if ((sendReceiver=pae.receiver) != null) {
   14157                 // Caller wants result sent back to them.
   14158                 sendBundle = new Bundle();
   14159                 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
   14160                 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
   14161                 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
   14162                 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
   14163             }
   14164         }
   14165         if (sendReceiver != null) {
   14166             try {
   14167                 sendReceiver.onHandleAssistData(sendBundle);
   14168             } catch (RemoteException e) {
   14169             }
   14170             return;
   14171         }
   14172 
   14173         final long ident = Binder.clearCallingIdentity();
   14174         try {
   14175             if (TextUtils.equals(pae.intent.getAction(),
   14176                     android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
   14177                 pae.intent.putExtras(pae.extras);
   14178                 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
   14179             } else {
   14180                 pae.intent.replaceExtras(pae.extras);
   14181                 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
   14182                         | Intent.FLAG_ACTIVITY_SINGLE_TOP
   14183                         | Intent.FLAG_ACTIVITY_CLEAR_TOP);
   14184                 closeSystemDialogs("assist");
   14185 
   14186                 try {
   14187                     mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
   14188                 } catch (ActivityNotFoundException e) {
   14189                     Slog.w(TAG, "No activity to handle assist action.", e);
   14190                 }
   14191             }
   14192         } finally {
   14193             Binder.restoreCallingIdentity(ident);
   14194         }
   14195     }
   14196 
   14197     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
   14198             Bundle args) {
   14199         return enqueueAssistContext(requestType, intent, hint, null, null, null,
   14200                 true /* focused */, true /* newSessionId */, userHandle, args,
   14201                 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
   14202     }
   14203 
   14204     public void registerProcessObserver(IProcessObserver observer) {
   14205         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   14206                 "registerProcessObserver()");
   14207         synchronized (this) {
   14208             mProcessObservers.register(observer);
   14209         }
   14210     }
   14211 
   14212     @Override
   14213     public void unregisterProcessObserver(IProcessObserver observer) {
   14214         synchronized (this) {
   14215             mProcessObservers.unregister(observer);
   14216         }
   14217     }
   14218 
   14219     @Override
   14220     public int getUidProcessState(int uid, String callingPackage) {
   14221         if (!hasUsageStatsPermission(callingPackage)) {
   14222             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
   14223                     "getUidProcessState");
   14224         }
   14225 
   14226         synchronized (this) {
   14227             UidRecord uidRec = mActiveUids.get(uid);
   14228             return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
   14229         }
   14230     }
   14231 
   14232     @Override
   14233     public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
   14234             String callingPackage) {
   14235         if (!hasUsageStatsPermission(callingPackage)) {
   14236             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
   14237                     "registerUidObserver");
   14238         }
   14239         synchronized (this) {
   14240             mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
   14241                     callingPackage, which, cutpoint));
   14242         }
   14243     }
   14244 
   14245     @Override
   14246     public void unregisterUidObserver(IUidObserver observer) {
   14247         synchronized (this) {
   14248             mUidObservers.unregister(observer);
   14249         }
   14250     }
   14251 
   14252     @Override
   14253     public boolean isUidActive(int uid, String callingPackage) {
   14254         if (!hasUsageStatsPermission(callingPackage)) {
   14255             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
   14256                     "isUidActive");
   14257         }
   14258         synchronized (this) {
   14259             return isUidActiveLocked(uid);
   14260         }
   14261     }
   14262 
   14263     boolean isUidActiveLocked(int uid) {
   14264         final UidRecord uidRecord = mActiveUids.get(uid);
   14265         return uidRecord != null && !uidRecord.setIdle;
   14266     }
   14267 
   14268     @Override
   14269     public boolean convertFromTranslucent(IBinder token) {
   14270         final long origId = Binder.clearCallingIdentity();
   14271         try {
   14272             synchronized (this) {
   14273                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   14274                 if (r == null) {
   14275                     return false;
   14276                 }
   14277                 final boolean translucentChanged = r.changeWindowTranslucency(true);
   14278                 if (translucentChanged) {
   14279                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   14280                 }
   14281                 mWindowManager.setAppFullscreen(token, true);
   14282                 return translucentChanged;
   14283             }
   14284         } finally {
   14285             Binder.restoreCallingIdentity(origId);
   14286         }
   14287     }
   14288 
   14289     @Override
   14290     public boolean convertToTranslucent(IBinder token, Bundle options) {
   14291         SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
   14292         final long origId = Binder.clearCallingIdentity();
   14293         try {
   14294             synchronized (this) {
   14295                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   14296                 if (r == null) {
   14297                     return false;
   14298                 }
   14299                 final TaskRecord task = r.getTask();
   14300                 int index = task.mActivities.lastIndexOf(r);
   14301                 if (index > 0) {
   14302                     ActivityRecord under = task.mActivities.get(index - 1);
   14303                     under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
   14304                 }
   14305                 final boolean translucentChanged = r.changeWindowTranslucency(false);
   14306                 if (translucentChanged) {
   14307                     r.getStack().convertActivityToTranslucent(r);
   14308                 }
   14309                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   14310                 mWindowManager.setAppFullscreen(token, false);
   14311                 return translucentChanged;
   14312             }
   14313         } finally {
   14314             Binder.restoreCallingIdentity(origId);
   14315         }
   14316     }
   14317 
   14318     @Override
   14319     public Bundle getActivityOptions(IBinder token) {
   14320         final long origId = Binder.clearCallingIdentity();
   14321         try {
   14322             synchronized (this) {
   14323                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   14324                 if (r != null) {
   14325                     final ActivityOptions activityOptions = r.takeOptionsLocked();
   14326                     return activityOptions == null ? null : activityOptions.toBundle();
   14327                 }
   14328                 return null;
   14329             }
   14330         } finally {
   14331             Binder.restoreCallingIdentity(origId);
   14332         }
   14333     }
   14334 
   14335     @Override
   14336     public void setImmersive(IBinder token, boolean immersive) {
   14337         synchronized(this) {
   14338             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   14339             if (r == null) {
   14340                 throw new IllegalArgumentException();
   14341             }
   14342             r.immersive = immersive;
   14343 
   14344             // update associated state if we're frontmost
   14345             if (r == mStackSupervisor.getResumedActivityLocked()) {
   14346                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
   14347                 applyUpdateLockStateLocked(r);
   14348             }
   14349         }
   14350     }
   14351 
   14352     @Override
   14353     public boolean isImmersive(IBinder token) {
   14354         synchronized (this) {
   14355             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   14356             if (r == null) {
   14357                 throw new IllegalArgumentException();
   14358             }
   14359             return r.immersive;
   14360         }
   14361     }
   14362 
   14363     @Override
   14364     public void setVrThread(int tid) {
   14365         enforceSystemHasVrFeature();
   14366         synchronized (this) {
   14367             synchronized (mPidsSelfLocked) {
   14368                 final int pid = Binder.getCallingPid();
   14369                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
   14370                 mVrController.setVrThreadLocked(tid, pid, proc);
   14371             }
   14372         }
   14373     }
   14374 
   14375     @Override
   14376     public void setPersistentVrThread(int tid) {
   14377         if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
   14378             final String msg = "Permission Denial: setPersistentVrThread() from pid="
   14379                     + Binder.getCallingPid()
   14380                     + ", uid=" + Binder.getCallingUid()
   14381                     + " requires " + permission.RESTRICTED_VR_ACCESS;
   14382             Slog.w(TAG, msg);
   14383             throw new SecurityException(msg);
   14384         }
   14385         enforceSystemHasVrFeature();
   14386         synchronized (this) {
   14387             synchronized (mPidsSelfLocked) {
   14388                 final int pid = Binder.getCallingPid();
   14389                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
   14390                 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
   14391             }
   14392         }
   14393     }
   14394 
   14395     /**
   14396      * Schedule the given thread a normal scheduling priority.
   14397      *
   14398      * @param tid the tid of the thread to adjust the scheduling of.
   14399      * @param suppressLogs {@code true} if any error logging should be disabled.
   14400      *
   14401      * @return {@code true} if this succeeded.
   14402      */
   14403     static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
   14404         try {
   14405             Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
   14406             return true;
   14407         } catch (IllegalArgumentException e) {
   14408             if (!suppressLogs) {
   14409                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
   14410             }
   14411         } catch (SecurityException e) {
   14412             if (!suppressLogs) {
   14413                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
   14414             }
   14415         }
   14416         return false;
   14417     }
   14418 
   14419     /**
   14420      * Schedule the given thread an FIFO scheduling priority.
   14421      *
   14422      * @param tid the tid of the thread to adjust the scheduling of.
   14423      * @param suppressLogs {@code true} if any error logging should be disabled.
   14424      *
   14425      * @return {@code true} if this succeeded.
   14426      */
   14427     static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
   14428         try {
   14429             Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
   14430             return true;
   14431         } catch (IllegalArgumentException e) {
   14432             if (!suppressLogs) {
   14433                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
   14434             }
   14435         } catch (SecurityException e) {
   14436             if (!suppressLogs) {
   14437                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
   14438             }
   14439         }
   14440         return false;
   14441     }
   14442 
   14443     /**
   14444      * Check that we have the features required for VR-related API calls, and throw an exception if
   14445      * not.
   14446      */
   14447     private void enforceSystemHasVrFeature() {
   14448         if (!mContext.getPackageManager().hasSystemFeature(
   14449                 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
   14450             throw new UnsupportedOperationException("VR mode not supported on this device!");
   14451         }
   14452     }
   14453 
   14454     @Override
   14455     public void setRenderThread(int tid) {
   14456         synchronized (this) {
   14457             ProcessRecord proc;
   14458             int pid = Binder.getCallingPid();
   14459             if (pid == Process.myPid()) {
   14460                 demoteSystemServerRenderThread(tid);
   14461                 return;
   14462             }
   14463             synchronized (mPidsSelfLocked) {
   14464                 proc = mPidsSelfLocked.get(pid);
   14465                 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
   14466                     // ensure the tid belongs to the process
   14467                     if (!isThreadInProcess(pid, tid)) {
   14468                         throw new IllegalArgumentException(
   14469                             "Render thread does not belong to process");
   14470                     }
   14471                     proc.renderThreadTid = tid;
   14472                     if (DEBUG_OOM_ADJ) {
   14473                         Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
   14474                     }
   14475                     // promote to FIFO now
   14476                     if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
   14477                         if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
   14478                         if (mUseFifoUiScheduling) {
   14479                             setThreadScheduler(proc.renderThreadTid,
   14480                                 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
   14481                         } else {
   14482                             setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
   14483                         }
   14484                     }
   14485                 } else {
   14486                     if (DEBUG_OOM_ADJ) {
   14487                         Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
   14488                                "PID: " + pid + ", TID: " + tid + " FIFO: " +
   14489                                mUseFifoUiScheduling);
   14490                     }
   14491                 }
   14492             }
   14493         }
   14494     }
   14495 
   14496     /**
   14497      * We only use RenderThread in system_server to store task snapshots to the disk, which should
   14498      * happen in the background. Thus, demote render thread from system_server to a lower priority.
   14499      *
   14500      * @param tid the tid of the RenderThread
   14501      */
   14502     private void demoteSystemServerRenderThread(int tid) {
   14503         setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
   14504     }
   14505 
   14506     @Override
   14507     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
   14508         enforceSystemHasVrFeature();
   14509 
   14510         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
   14511 
   14512         ActivityRecord r;
   14513         synchronized (this) {
   14514             r = ActivityRecord.isInStackLocked(token);
   14515         }
   14516 
   14517         if (r == null) {
   14518             throw new IllegalArgumentException();
   14519         }
   14520 
   14521         int err;
   14522         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
   14523                 VrManagerInternal.NO_ERROR) {
   14524             return err;
   14525         }
   14526 
   14527         // Clear the binder calling uid since this path may call moveToTask().
   14528         final long callingId = Binder.clearCallingIdentity();
   14529         try {
   14530             synchronized(this) {
   14531                 r.requestedVrComponent = (enabled) ? packageName : null;
   14532 
   14533                 // Update associated state if this activity is currently focused
   14534                 if (r == mStackSupervisor.getResumedActivityLocked()) {
   14535                     applyUpdateVrModeLocked(r);
   14536                 }
   14537                 return 0;
   14538             }
   14539         } finally {
   14540             Binder.restoreCallingIdentity(callingId);
   14541         }
   14542     }
   14543 
   14544     @Override
   14545     public boolean isVrModePackageEnabled(ComponentName packageName) {
   14546         enforceSystemHasVrFeature();
   14547 
   14548         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
   14549 
   14550         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
   14551                 VrManagerInternal.NO_ERROR;
   14552     }
   14553 
   14554     public boolean isTopActivityImmersive() {
   14555         enforceNotIsolatedCaller("startActivity");
   14556         synchronized (this) {
   14557             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
   14558             return (r != null) ? r.immersive : false;
   14559         }
   14560     }
   14561 
   14562     /**
   14563      * @return whether the system should disable UI modes incompatible with VR mode.
   14564      */
   14565     boolean shouldDisableNonVrUiLocked() {
   14566         return mVrController.shouldDisableNonVrUiLocked();
   14567     }
   14568 
   14569     @Override
   14570     public boolean isTopOfTask(IBinder token) {
   14571         synchronized (this) {
   14572             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   14573             if (r == null) {
   14574                 throw new IllegalArgumentException();
   14575             }
   14576             return r.getTask().getTopActivity() == r;
   14577         }
   14578     }
   14579 
   14580     @Override
   14581     public void setHasTopUi(boolean hasTopUi) throws RemoteException {
   14582         if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
   14583             String msg = "Permission Denial: setHasTopUi() from pid="
   14584                     + Binder.getCallingPid()
   14585                     + ", uid=" + Binder.getCallingUid()
   14586                     + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
   14587             Slog.w(TAG, msg);
   14588             throw new SecurityException(msg);
   14589         }
   14590         final int pid = Binder.getCallingPid();
   14591         final long origId = Binder.clearCallingIdentity();
   14592         try {
   14593             synchronized (this) {
   14594                 boolean changed = false;
   14595                 ProcessRecord pr;
   14596                 synchronized (mPidsSelfLocked) {
   14597                     pr = mPidsSelfLocked.get(pid);
   14598                     if (pr == null) {
   14599                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
   14600                         return;
   14601                     }
   14602                     if (pr.hasTopUi != hasTopUi) {
   14603                         if (DEBUG_OOM_ADJ) {
   14604                             Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
   14605                         }
   14606                         pr.hasTopUi = hasTopUi;
   14607                         changed = true;
   14608                     }
   14609                 }
   14610                 if (changed) {
   14611                     updateOomAdjLocked(pr, true);
   14612                 }
   14613             }
   14614         } finally {
   14615             Binder.restoreCallingIdentity(origId);
   14616         }
   14617     }
   14618 
   14619     void setRunningRemoteAnimation(int pid, boolean runningRemoteAnimation) {
   14620         if (pid == Process.myPid()) {
   14621             Slog.wtf(TAG, "system can't run remote animation");
   14622             return;
   14623         }
   14624         synchronized (ActivityManagerService.this) {
   14625             final ProcessRecord pr;
   14626             synchronized (mPidsSelfLocked) {
   14627                 pr = mPidsSelfLocked.get(pid);
   14628                 if (pr == null) {
   14629                     Slog.w(TAG, "setRunningRemoteAnimation called on unknown pid: " + pid);
   14630                     return;
   14631                 }
   14632             }
   14633             if (pr.runningRemoteAnimation == runningRemoteAnimation) {
   14634                 return;
   14635             }
   14636             pr.runningRemoteAnimation = runningRemoteAnimation;
   14637             if (DEBUG_OOM_ADJ) {
   14638                 Slog.i(TAG, "Setting runningRemoteAnimation=" + pr.runningRemoteAnimation
   14639                         + " for pid=" + pid);
   14640             }
   14641             updateOomAdjLocked(pr, true);
   14642         }
   14643     }
   14644 
   14645     public final void enterSafeMode() {
   14646         synchronized(this) {
   14647             // It only makes sense to do this before the system is ready
   14648             // and started launching other packages.
   14649             if (!mSystemReady) {
   14650                 try {
   14651                     AppGlobals.getPackageManager().enterSafeMode();
   14652                 } catch (RemoteException e) {
   14653                 }
   14654             }
   14655 
   14656             mSafeMode = true;
   14657         }
   14658     }
   14659 
   14660     public final void showSafeModeOverlay() {
   14661         View v = LayoutInflater.from(mContext).inflate(
   14662                 com.android.internal.R.layout.safe_mode, null);
   14663         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
   14664         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
   14665         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
   14666         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
   14667         lp.gravity = Gravity.BOTTOM | Gravity.START;
   14668         lp.format = v.getBackground().getOpacity();
   14669         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
   14670                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
   14671         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
   14672         ((WindowManager)mContext.getSystemService(
   14673                 Context.WINDOW_SERVICE)).addView(v, lp);
   14674     }
   14675 
   14676     @Override
   14677     public void noteWakeupAlarm(IIntentSender sender, WorkSource workSource, int sourceUid,
   14678             String sourcePkg, String tag) {
   14679         if (workSource != null && workSource.isEmpty()) {
   14680             workSource = null;
   14681         }
   14682 
   14683         if (sourceUid <= 0 && workSource == null) {
   14684             // Try and derive a UID to attribute things to based on the caller.
   14685             if (sender != null) {
   14686                 if (!(sender instanceof PendingIntentRecord)) {
   14687                     return;
   14688                 }
   14689 
   14690                 final PendingIntentRecord rec = (PendingIntentRecord) sender;
   14691                 final int callerUid = Binder.getCallingUid();
   14692                 sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
   14693             } else {
   14694                 // TODO(narayan): Should we throw an exception in this case ? It means that we
   14695                 // haven't been able to derive a UID to attribute things to.
   14696                 return;
   14697             }
   14698         }
   14699 
   14700         if (DEBUG_POWER) {
   14701             Slog.w(TAG, "noteWakupAlarm[ sourcePkg=" + sourcePkg + ", sourceUid=" + sourceUid
   14702                     + ", workSource=" + workSource + ", tag=" + tag + "]");
   14703         }
   14704 
   14705         mBatteryStatsService.noteWakupAlarm(sourcePkg, sourceUid, workSource, tag);
   14706     }
   14707 
   14708     @Override
   14709     public void noteAlarmStart(IIntentSender sender, WorkSource workSource, int sourceUid,
   14710             String tag) {
   14711         if (workSource != null && workSource.isEmpty()) {
   14712             workSource = null;
   14713         }
   14714 
   14715         if (sourceUid <= 0 && workSource == null) {
   14716             // Try and derive a UID to attribute things to based on the caller.
   14717             if (sender != null) {
   14718                 if (!(sender instanceof PendingIntentRecord)) {
   14719                     return;
   14720                 }
   14721 
   14722                 final PendingIntentRecord rec = (PendingIntentRecord) sender;
   14723                 final int callerUid = Binder.getCallingUid();
   14724                 sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
   14725             } else {
   14726                 // TODO(narayan): Should we throw an exception in this case ? It means that we
   14727                 // haven't been able to derive a UID to attribute things to.
   14728                 return;
   14729             }
   14730         }
   14731 
   14732         if (DEBUG_POWER) {
   14733             Slog.w(TAG, "noteAlarmStart[sourceUid=" + sourceUid + ", workSource=" + workSource +
   14734                     ", tag=" + tag + "]");
   14735         }
   14736 
   14737         mBatteryStatsService.noteAlarmStart(tag, workSource, sourceUid);
   14738     }
   14739 
   14740     @Override
   14741     public void noteAlarmFinish(IIntentSender sender, WorkSource workSource, int sourceUid,
   14742             String tag) {
   14743         if (workSource != null && workSource.isEmpty()) {
   14744             workSource = null;
   14745         }
   14746 
   14747         if (sourceUid <= 0 && workSource == null) {
   14748             // Try and derive a UID to attribute things to based on the caller.
   14749             if (sender != null) {
   14750                 if (!(sender instanceof PendingIntentRecord)) {
   14751                     return;
   14752                 }
   14753 
   14754                 final PendingIntentRecord rec = (PendingIntentRecord) sender;
   14755                 final int callerUid = Binder.getCallingUid();
   14756                 sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
   14757             } else {
   14758                 // TODO(narayan): Should we throw an exception in this case ? It means that we
   14759                 // haven't been able to derive a UID to attribute things to.
   14760                 return;
   14761             }
   14762         }
   14763 
   14764         if (DEBUG_POWER) {
   14765             Slog.w(TAG, "noteAlarmFinish[sourceUid=" + sourceUid + ", workSource=" + workSource +
   14766                     ", tag=" + tag + "]");
   14767         }
   14768 
   14769         mBatteryStatsService.noteAlarmFinish(tag, workSource, sourceUid);
   14770     }
   14771 
   14772     public boolean killPids(int[] pids, String pReason, boolean secure) {
   14773         if (Binder.getCallingUid() != SYSTEM_UID) {
   14774             throw new SecurityException("killPids only available to the system");
   14775         }
   14776         String reason = (pReason == null) ? "Unknown" : pReason;
   14777         // XXX Note: don't acquire main activity lock here, because the window
   14778         // manager calls in with its locks held.
   14779 
   14780         boolean killed = false;
   14781         synchronized (mPidsSelfLocked) {
   14782             int worstType = 0;
   14783             for (int i=0; i<pids.length; i++) {
   14784                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   14785                 if (proc != null) {
   14786                     int type = proc.setAdj;
   14787                     if (type > worstType) {
   14788                         worstType = type;
   14789                     }
   14790                 }
   14791             }
   14792 
   14793             // If the worst oom_adj is somewhere in the cached proc LRU range,
   14794             // then constrain it so we will kill all cached procs.
   14795             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
   14796                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
   14797                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
   14798             }
   14799 
   14800             // If this is not a secure call, don't let it kill processes that
   14801             // are important.
   14802             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
   14803                 worstType = ProcessList.SERVICE_ADJ;
   14804             }
   14805 
   14806             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
   14807             for (int i=0; i<pids.length; i++) {
   14808                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   14809                 if (proc == null) {
   14810                     continue;
   14811                 }
   14812                 int adj = proc.setAdj;
   14813                 if (adj >= worstType && !proc.killedByAm) {
   14814                     proc.kill(reason, true);
   14815                     killed = true;
   14816                 }
   14817             }
   14818         }
   14819         return killed;
   14820     }
   14821 
   14822     @Override
   14823     public void killUid(int appId, int userId, String reason) {
   14824         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
   14825         synchronized (this) {
   14826             final long identity = Binder.clearCallingIdentity();
   14827             try {
   14828                 killPackageProcessesLocked(null, appId, userId,
   14829                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
   14830                         reason != null ? reason : "kill uid");
   14831             } finally {
   14832                 Binder.restoreCallingIdentity(identity);
   14833             }
   14834         }
   14835     }
   14836 
   14837     @Override
   14838     public boolean killProcessesBelowForeground(String reason) {
   14839         if (Binder.getCallingUid() != SYSTEM_UID) {
   14840             throw new SecurityException("killProcessesBelowForeground() only available to system");
   14841         }
   14842 
   14843         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
   14844     }
   14845 
   14846     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
   14847         if (Binder.getCallingUid() != SYSTEM_UID) {
   14848             throw new SecurityException("killProcessesBelowAdj() only available to system");
   14849         }
   14850 
   14851         boolean killed = false;
   14852         synchronized (mPidsSelfLocked) {
   14853             final int size = mPidsSelfLocked.size();
   14854             for (int i = 0; i < size; i++) {
   14855                 final int pid = mPidsSelfLocked.keyAt(i);
   14856                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   14857                 if (proc == null) continue;
   14858 
   14859                 final int adj = proc.setAdj;
   14860                 if (adj > belowAdj && !proc.killedByAm) {
   14861                     proc.kill(reason, true);
   14862                     killed = true;
   14863                 }
   14864             }
   14865         }
   14866         return killed;
   14867     }
   14868 
   14869     @Override
   14870     public void hang(final IBinder who, boolean allowRestart) {
   14871         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   14872                 != PackageManager.PERMISSION_GRANTED) {
   14873             throw new SecurityException("Requires permission "
   14874                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   14875         }
   14876 
   14877         final IBinder.DeathRecipient death = new DeathRecipient() {
   14878             @Override
   14879             public void binderDied() {
   14880                 synchronized (this) {
   14881                     notifyAll();
   14882                 }
   14883             }
   14884         };
   14885 
   14886         try {
   14887             who.linkToDeath(death, 0);
   14888         } catch (RemoteException e) {
   14889             Slog.w(TAG, "hang: given caller IBinder is already dead.");
   14890             return;
   14891         }
   14892 
   14893         synchronized (this) {
   14894             Watchdog.getInstance().setAllowRestart(allowRestart);
   14895             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
   14896             synchronized (death) {
   14897                 while (who.isBinderAlive()) {
   14898                     try {
   14899                         death.wait();
   14900                     } catch (InterruptedException e) {
   14901                     }
   14902                 }
   14903             }
   14904             Watchdog.getInstance().setAllowRestart(true);
   14905         }
   14906     }
   14907 
   14908     @Override
   14909     public void restart() {
   14910         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   14911                 != PackageManager.PERMISSION_GRANTED) {
   14912             throw new SecurityException("Requires permission "
   14913                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   14914         }
   14915 
   14916         Log.i(TAG, "Sending shutdown broadcast...");
   14917 
   14918         BroadcastReceiver br = new BroadcastReceiver() {
   14919             @Override public void onReceive(Context context, Intent intent) {
   14920                 // Now the broadcast is done, finish up the low-level shutdown.
   14921                 Log.i(TAG, "Shutting down activity manager...");
   14922                 shutdown(10000);
   14923                 Log.i(TAG, "Shutdown complete, restarting!");
   14924                 killProcess(myPid());
   14925                 System.exit(10);
   14926             }
   14927         };
   14928 
   14929         // First send the high-level shut down broadcast.
   14930         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
   14931         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   14932         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
   14933         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
   14934         mContext.sendOrderedBroadcastAsUser(intent,
   14935                 UserHandle.ALL, null, br, mHandler, 0, null, null);
   14936         */
   14937         br.onReceive(mContext, intent);
   14938     }
   14939 
   14940     private long getLowRamTimeSinceIdle(long now) {
   14941         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
   14942     }
   14943 
   14944     @Override
   14945     public void performIdleMaintenance() {
   14946         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   14947                 != PackageManager.PERMISSION_GRANTED) {
   14948             throw new SecurityException("Requires permission "
   14949                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   14950         }
   14951 
   14952         synchronized (this) {
   14953             final long now = SystemClock.uptimeMillis();
   14954             final long timeSinceLastIdle = now - mLastIdleTime;
   14955             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
   14956             mLastIdleTime = now;
   14957             mLowRamTimeSinceLastIdle = 0;
   14958             if (mLowRamStartTime != 0) {
   14959                 mLowRamStartTime = now;
   14960             }
   14961 
   14962             StringBuilder sb = new StringBuilder(128);
   14963             sb.append("Idle maintenance over ");
   14964             TimeUtils.formatDuration(timeSinceLastIdle, sb);
   14965             sb.append(" low RAM for ");
   14966             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
   14967             Slog.i(TAG, sb.toString());
   14968 
   14969             // If at least 1/3 of our time since the last idle period has been spent
   14970             // with RAM low, then we want to kill processes.
   14971             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
   14972 
   14973             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   14974                 ProcessRecord proc = mLruProcesses.get(i);
   14975                 if (proc.notCachedSinceIdle) {
   14976                     if (proc.setProcState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
   14977                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
   14978                         if (doKilling && proc.initialIdlePss != 0
   14979                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
   14980                             sb = new StringBuilder(128);
   14981                             sb.append("Kill");
   14982                             sb.append(proc.processName);
   14983                             sb.append(" in idle maint: pss=");
   14984                             sb.append(proc.lastPss);
   14985                             sb.append(", swapPss=");
   14986                             sb.append(proc.lastSwapPss);
   14987                             sb.append(", initialPss=");
   14988                             sb.append(proc.initialIdlePss);
   14989                             sb.append(", period=");
   14990                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
   14991                             sb.append(", lowRamPeriod=");
   14992                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
   14993                             Slog.wtfQuiet(TAG, sb.toString());
   14994                             proc.kill("idle maint (pss " + proc.lastPss
   14995                                     + " from " + proc.initialIdlePss + ")", true);
   14996                         }
   14997                     }
   14998                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
   14999                         && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
   15000                     proc.notCachedSinceIdle = true;
   15001                     proc.initialIdlePss = 0;
   15002                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, null,
   15003                             mTestPssMode, isSleepingLocked(), now);
   15004                 }
   15005             }
   15006         }
   15007     }
   15008 
   15009     @Override
   15010     public void sendIdleJobTrigger() {
   15011         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   15012                 != PackageManager.PERMISSION_GRANTED) {
   15013             throw new SecurityException("Requires permission "
   15014                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   15015         }
   15016 
   15017         final long ident = Binder.clearCallingIdentity();
   15018         try {
   15019             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
   15020                     .setPackage("android")
   15021                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   15022             broadcastIntent(null, intent, null, null, 0, null, null, null,
   15023                     OP_NONE, null, false, false, UserHandle.USER_ALL);
   15024         } finally {
   15025             Binder.restoreCallingIdentity(ident);
   15026         }
   15027     }
   15028 
   15029     private void retrieveSettings() {
   15030         final ContentResolver resolver = mContext.getContentResolver();
   15031         final boolean freeformWindowManagement =
   15032                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
   15033                         || Settings.Global.getInt(
   15034                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
   15035 
   15036         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
   15037         final boolean supportsPictureInPicture = supportsMultiWindow &&
   15038                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
   15039         final boolean supportsSplitScreenMultiWindow =
   15040                 ActivityManager.supportsSplitScreenMultiWindow(mContext);
   15041         final boolean supportsMultiDisplay = mContext.getPackageManager()
   15042                 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
   15043         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
   15044         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
   15045         final boolean alwaysFinishActivities =
   15046                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
   15047         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
   15048         final boolean forceResizable = Settings.Global.getInt(
   15049                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
   15050         final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
   15051                 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
   15052         final boolean supportsLeanbackOnly =
   15053                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
   15054         mHiddenApiBlacklist.registerObserver();
   15055 
   15056         // Transfer any global setting for forcing RTL layout, into a System Property
   15057         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
   15058 
   15059         final Configuration configuration = new Configuration();
   15060         Settings.System.getConfiguration(resolver, configuration);
   15061         if (forceRtl) {
   15062             // This will take care of setting the correct layout direction flags
   15063             configuration.setLayoutDirection(configuration.locale);
   15064         }
   15065 
   15066         synchronized (this) {
   15067             mDebugApp = mOrigDebugApp = debugApp;
   15068             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
   15069             mAlwaysFinishActivities = alwaysFinishActivities;
   15070             mSupportsLeanbackOnly = supportsLeanbackOnly;
   15071             mForceResizableActivities = forceResizable;
   15072             final boolean multiWindowFormEnabled = freeformWindowManagement
   15073                     || supportsSplitScreenMultiWindow
   15074                     || supportsPictureInPicture
   15075                     || supportsMultiDisplay;
   15076             if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
   15077                 mSupportsMultiWindow = true;
   15078                 mSupportsFreeformWindowManagement = freeformWindowManagement;
   15079                 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
   15080                 mSupportsPictureInPicture = supportsPictureInPicture;
   15081                 mSupportsMultiDisplay = supportsMultiDisplay;
   15082             } else {
   15083                 mSupportsMultiWindow = false;
   15084                 mSupportsFreeformWindowManagement = false;
   15085                 mSupportsSplitScreenMultiWindow = false;
   15086                 mSupportsPictureInPicture = false;
   15087                 mSupportsMultiDisplay = false;
   15088             }
   15089             mWindowManager.setForceResizableTasks(mForceResizableActivities);
   15090             mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
   15091             // This happens before any activities are started, so we can change global configuration
   15092             // in-place.
   15093             updateConfigurationLocked(configuration, null, true);
   15094             final Configuration globalConfig = getGlobalConfiguration();
   15095             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
   15096 
   15097             // Load resources only after the current configuration has been set.
   15098             final Resources res = mContext.getResources();
   15099             mThumbnailWidth = res.getDimensionPixelSize(
   15100                     com.android.internal.R.dimen.thumbnail_width);
   15101             mThumbnailHeight = res.getDimensionPixelSize(
   15102                     com.android.internal.R.dimen.thumbnail_height);
   15103             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
   15104                     com.android.internal.R.string.config_appsNotReportingCrashes));
   15105             mUserController.mUserSwitchUiEnabled = !res.getBoolean(
   15106                     com.android.internal.R.bool.config_customUserSwitchUi);
   15107             mUserController.mMaxRunningUsers = res.getInteger(
   15108                     com.android.internal.R.integer.config_multiuserMaxRunningUsers);
   15109 
   15110             if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
   15111                 mFullscreenThumbnailScale = (float) res
   15112                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
   15113                     (float) globalConfig.screenWidthDp;
   15114             } else {
   15115                 mFullscreenThumbnailScale = res.getFraction(
   15116                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
   15117             }
   15118             mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
   15119         }
   15120     }
   15121 
   15122     public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
   15123         traceLog.traceBegin("PhaseActivityManagerReady");
   15124         synchronized(this) {
   15125             if (mSystemReady) {
   15126                 // If we're done calling all the receivers, run the next "boot phase" passed in
   15127                 // by the SystemServer
   15128                 if (goingCallback != null) {
   15129                     goingCallback.run();
   15130                 }
   15131                 return;
   15132             }
   15133 
   15134             mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
   15135                     PackageManager.FEATURE_CANT_SAVE_STATE);
   15136             mLocalDeviceIdleController
   15137                     = LocalServices.getService(DeviceIdleController.LocalService.class);
   15138             mAssistUtils = new AssistUtils(mContext);
   15139             mVrController.onSystemReady();
   15140             // Make sure we have the current profile info, since it is needed for security checks.
   15141             mUserController.onSystemReady();
   15142             mRecentTasks.onSystemReadyLocked();
   15143             mAppOpsService.systemReady();
   15144             mSystemReady = true;
   15145         }
   15146 
   15147         try {
   15148             sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
   15149                     ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
   15150                     .getSerial();
   15151         } catch (RemoteException e) {}
   15152 
   15153         ArrayList<ProcessRecord> procsToKill = null;
   15154         synchronized(mPidsSelfLocked) {
   15155             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
   15156                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   15157                 if (!isAllowedWhileBooting(proc.info)){
   15158                     if (procsToKill == null) {
   15159                         procsToKill = new ArrayList<ProcessRecord>();
   15160                     }
   15161                     procsToKill.add(proc);
   15162                 }
   15163             }
   15164         }
   15165 
   15166         synchronized(this) {
   15167             if (procsToKill != null) {
   15168                 for (int i=procsToKill.size()-1; i>=0; i--) {
   15169                     ProcessRecord proc = procsToKill.get(i);
   15170                     Slog.i(TAG, "Removing system update proc: " + proc);
   15171                     removeProcessLocked(proc, true, false, "system update done");
   15172                 }
   15173             }
   15174 
   15175             // Now that we have cleaned up any update processes, we
   15176             // are ready to start launching real processes and know that
   15177             // we won't trample on them any more.
   15178             mProcessesReady = true;
   15179         }
   15180 
   15181         Slog.i(TAG, "System now ready");
   15182         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
   15183             SystemClock.uptimeMillis());
   15184 
   15185         synchronized(this) {
   15186             // Make sure we have no pre-ready processes sitting around.
   15187 
   15188             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   15189                 ResolveInfo ri = mContext.getPackageManager()
   15190                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
   15191                                 STOCK_PM_FLAGS);
   15192                 CharSequence errorMsg = null;
   15193                 if (ri != null) {
   15194                     ActivityInfo ai = ri.activityInfo;
   15195                     ApplicationInfo app = ai.applicationInfo;
   15196                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   15197                         mTopAction = Intent.ACTION_FACTORY_TEST;
   15198                         mTopData = null;
   15199                         mTopComponent = new ComponentName(app.packageName,
   15200                                 ai.name);
   15201                     } else {
   15202                         errorMsg = mContext.getResources().getText(
   15203                                 com.android.internal.R.string.factorytest_not_system);
   15204                     }
   15205                 } else {
   15206                     errorMsg = mContext.getResources().getText(
   15207                             com.android.internal.R.string.factorytest_no_action);
   15208                 }
   15209                 if (errorMsg != null) {
   15210                     mTopAction = null;
   15211                     mTopData = null;
   15212                     mTopComponent = null;
   15213                     Message msg = Message.obtain();
   15214                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
   15215                     msg.getData().putCharSequence("msg", errorMsg);
   15216                     mUiHandler.sendMessage(msg);
   15217                 }
   15218             }
   15219         }
   15220 
   15221         retrieveSettings();
   15222         final int currentUserId = mUserController.getCurrentUserId();
   15223         synchronized (this) {
   15224             readGrantedUriPermissionsLocked();
   15225         }
   15226 
   15227         final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
   15228         if (pmi != null) {
   15229             pmi.registerLowPowerModeObserver(ServiceType.FORCE_BACKGROUND_CHECK,
   15230                     state -> updateForceBackgroundCheck(state.batterySaverEnabled));
   15231             updateForceBackgroundCheck(
   15232                     pmi.getLowPowerState(ServiceType.FORCE_BACKGROUND_CHECK).batterySaverEnabled);
   15233         } else {
   15234             Slog.wtf(TAG, "PowerManagerInternal not found.");
   15235         }
   15236 
   15237         if (goingCallback != null) goingCallback.run();
   15238         traceLog.traceBegin("ActivityManagerStartApps");
   15239         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
   15240                 Integer.toString(currentUserId), currentUserId);
   15241         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
   15242                 Integer.toString(currentUserId), currentUserId);
   15243         mSystemServiceManager.startUser(currentUserId);
   15244 
   15245         synchronized (this) {
   15246             // Only start up encryption-aware persistent apps; once user is
   15247             // unlocked we'll come back around and start unaware apps
   15248             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
   15249 
   15250             // Start up initial activity.
   15251             mBooting = true;
   15252             // Enable home activity for system user, so that the system can always boot. We don't
   15253             // do this when the system user is not setup since the setup wizard should be the one
   15254             // to handle home activity in this case.
   15255             if (UserManager.isSplitSystemUser() &&
   15256                     Settings.Secure.getInt(mContext.getContentResolver(),
   15257                          Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
   15258                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
   15259                 try {
   15260                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
   15261                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
   15262                             UserHandle.USER_SYSTEM);
   15263                 } catch (RemoteException e) {
   15264                     throw e.rethrowAsRuntimeException();
   15265                 }
   15266             }
   15267             startHomeActivityLocked(currentUserId, "systemReady");
   15268 
   15269             try {
   15270                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
   15271                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
   15272                             + " data partition or your device will be unstable.");
   15273                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
   15274                 }
   15275             } catch (RemoteException e) {
   15276             }
   15277 
   15278             if (!Build.isBuildConsistent()) {
   15279                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
   15280                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
   15281             }
   15282 
   15283             long ident = Binder.clearCallingIdentity();
   15284             try {
   15285                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
   15286                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   15287                         | Intent.FLAG_RECEIVER_FOREGROUND);
   15288                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
   15289                 broadcastIntentLocked(null, null, intent,
   15290                         null, null, 0, null, null, null, OP_NONE,
   15291                         null, false, false, MY_PID, SYSTEM_UID,
   15292                         currentUserId);
   15293                 intent = new Intent(Intent.ACTION_USER_STARTING);
   15294                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   15295                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
   15296                 broadcastIntentLocked(null, null, intent,
   15297                         null, new IIntentReceiver.Stub() {
   15298                             @Override
   15299                             public void performReceive(Intent intent, int resultCode, String data,
   15300                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
   15301                                     throws RemoteException {
   15302                             }
   15303                         }, 0, null, null,
   15304                         new String[] {INTERACT_ACROSS_USERS}, OP_NONE,
   15305                         null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
   15306             } catch (Throwable t) {
   15307                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
   15308             } finally {
   15309                 Binder.restoreCallingIdentity(ident);
   15310             }
   15311             mStackSupervisor.resumeFocusedStackTopActivityLocked();
   15312             mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
   15313 
   15314             BinderInternal.nSetBinderProxyCountWatermarks(6000,5500);
   15315             BinderInternal.nSetBinderProxyCountEnabled(true);
   15316             BinderInternal.setBinderProxyCountCallback(
   15317                     new BinderInternal.BinderProxyLimitListener() {
   15318                         @Override
   15319                         public void onLimitReached(int uid) {
   15320                             Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
   15321                                     + Process.myUid());
   15322                             if (uid == Process.SYSTEM_UID) {
   15323                                 Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
   15324                             } else {
   15325                                 killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
   15326                                         "Too many Binders sent to SYSTEM");
   15327                             }
   15328                         }
   15329                     }, mHandler);
   15330 
   15331             traceLog.traceEnd(); // ActivityManagerStartApps
   15332             traceLog.traceEnd(); // PhaseActivityManagerReady
   15333         }
   15334     }
   15335 
   15336     private void updateForceBackgroundCheck(boolean enabled) {
   15337         synchronized (this) {
   15338             if (mForceBackgroundCheck != enabled) {
   15339                 mForceBackgroundCheck = enabled;
   15340 
   15341                 if (DEBUG_BACKGROUND_CHECK) {
   15342                     Slog.i(TAG, "Force background check " + (enabled ? "enabled" : "disabled"));
   15343                 }
   15344 
   15345                 if (mForceBackgroundCheck) {
   15346                     // Stop background services for idle UIDs.
   15347                     doStopUidForIdleUidsLocked();
   15348                 }
   15349             }
   15350         }
   15351     }
   15352 
   15353     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
   15354         synchronized (this) {
   15355             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
   15356         }
   15357     }
   15358 
   15359     void skipCurrentReceiverLocked(ProcessRecord app) {
   15360         for (BroadcastQueue queue : mBroadcastQueues) {
   15361             queue.skipCurrentReceiverLocked(app);
   15362         }
   15363     }
   15364 
   15365     /**
   15366      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
   15367      * The application process will exit immediately after this call returns.
   15368      * @param app object of the crashing app, null for the system server
   15369      * @param crashInfo describing the exception
   15370      */
   15371     public void handleApplicationCrash(IBinder app,
   15372             ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
   15373         ProcessRecord r = findAppProcess(app, "Crash");
   15374         final String processName = app == null ? "system_server"
   15375                 : (r == null ? "unknown" : r.processName);
   15376 
   15377         handleApplicationCrashInner("crash", r, processName, crashInfo);
   15378     }
   15379 
   15380     /* Native crash reporting uses this inner version because it needs to be somewhat
   15381      * decoupled from the AM-managed cleanup lifecycle
   15382      */
   15383     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
   15384             ApplicationErrorReport.CrashInfo crashInfo) {
   15385         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
   15386                 UserHandle.getUserId(Binder.getCallingUid()), processName,
   15387                 r == null ? -1 : r.info.flags,
   15388                 crashInfo.exceptionClassName,
   15389                 crashInfo.exceptionMessage,
   15390                 crashInfo.throwFileName,
   15391                 crashInfo.throwLineNumber);
   15392 
   15393         StatsLog.write(StatsLog.APP_CRASH_OCCURRED,
   15394                 Binder.getCallingUid(),
   15395                 eventType,
   15396                 processName,
   15397                 Binder.getCallingPid(),
   15398                 (r != null && r.info != null) ? r.info.packageName : "",
   15399                 (r != null && r.info != null) ? (r.info.isInstantApp()
   15400                         ? StatsLog.APP_CRASH_OCCURRED__IS_INSTANT_APP__TRUE
   15401                         : StatsLog.APP_CRASH_OCCURRED__IS_INSTANT_APP__FALSE)
   15402                         : StatsLog.APP_CRASH_OCCURRED__IS_INSTANT_APP__UNAVAILABLE,
   15403                 r != null ? (r.isInterestingToUserLocked()
   15404                         ? StatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__FOREGROUND
   15405                         : StatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__BACKGROUND)
   15406                         : StatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__UNKNOWN
   15407         );
   15408 
   15409         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
   15410 
   15411         mAppErrors.crashApplication(r, crashInfo);
   15412     }
   15413 
   15414     public void handleApplicationStrictModeViolation(
   15415             IBinder app,
   15416             int violationMask,
   15417             StrictMode.ViolationInfo info) {
   15418         // We're okay if the ProcessRecord is missing; it probably means that
   15419         // we're reporting a violation from the system process itself.
   15420         final ProcessRecord r = findAppProcess(app, "StrictMode");
   15421 
   15422         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
   15423             Integer stackFingerprint = info.hashCode();
   15424             boolean logIt = true;
   15425             synchronized (mAlreadyLoggedViolatedStacks) {
   15426                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
   15427                     logIt = false;
   15428                     // TODO: sub-sample into EventLog for these, with
   15429                     // the info.durationMillis?  Then we'd get
   15430                     // the relative pain numbers, without logging all
   15431                     // the stack traces repeatedly.  We'd want to do
   15432                     // likewise in the client code, which also does
   15433                     // dup suppression, before the Binder call.
   15434                 } else {
   15435                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
   15436                         mAlreadyLoggedViolatedStacks.clear();
   15437                     }
   15438                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
   15439                 }
   15440             }
   15441             if (logIt) {
   15442                 logStrictModeViolationToDropBox(r, info);
   15443             }
   15444         }
   15445 
   15446         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
   15447             AppErrorResult result = new AppErrorResult();
   15448             synchronized (this) {
   15449                 final long origId = Binder.clearCallingIdentity();
   15450 
   15451                 Message msg = Message.obtain();
   15452                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
   15453                 HashMap<String, Object> data = new HashMap<String, Object>();
   15454                 data.put("result", result);
   15455                 data.put("app", r);
   15456                 data.put("violationMask", violationMask);
   15457                 data.put("info", info);
   15458                 msg.obj = data;
   15459                 mUiHandler.sendMessage(msg);
   15460 
   15461                 Binder.restoreCallingIdentity(origId);
   15462             }
   15463             int res = result.get();
   15464             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
   15465         }
   15466     }
   15467 
   15468     // Depending on the policy in effect, there could be a bunch of
   15469     // these in quick succession so we try to batch these together to
   15470     // minimize disk writes, number of dropbox entries, and maximize
   15471     // compression, by having more fewer, larger records.
   15472     private void logStrictModeViolationToDropBox(
   15473             ProcessRecord process,
   15474             StrictMode.ViolationInfo info) {
   15475         if (info == null) {
   15476             return;
   15477         }
   15478         final boolean isSystemApp = process == null ||
   15479                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
   15480                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
   15481         final String processName = process == null ? "unknown" : process.processName;
   15482         final DropBoxManager dbox = (DropBoxManager)
   15483                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   15484 
   15485         // Exit early if the dropbox isn't configured to accept this report type.
   15486         final String dropboxTag = processClass(process) + "_strictmode";
   15487         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   15488 
   15489         final StringBuilder sb = new StringBuilder(1024);
   15490         synchronized (sb) {
   15491             appendDropBoxProcessHeaders(process, processName, sb);
   15492             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   15493             sb.append("System-App: ").append(isSystemApp).append("\n");
   15494             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
   15495             if (info.violationNumThisLoop != 0) {
   15496                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
   15497             }
   15498             if (info.numAnimationsRunning != 0) {
   15499                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
   15500             }
   15501             if (info.broadcastIntentAction != null) {
   15502                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
   15503             }
   15504             if (info.durationMillis != -1) {
   15505                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
   15506             }
   15507             if (info.numInstances != -1) {
   15508                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
   15509             }
   15510             if (info.tags != null) {
   15511                 for (String tag : info.tags) {
   15512                     sb.append("Span-Tag: ").append(tag).append("\n");
   15513                 }
   15514             }
   15515             sb.append("\n");
   15516             sb.append(info.getStackTrace());
   15517             sb.append("\n");
   15518             if (info.getViolationDetails() != null) {
   15519                 sb.append(info.getViolationDetails());
   15520                 sb.append("\n");
   15521             }
   15522         }
   15523 
   15524         final String res = sb.toString();
   15525         IoThread.getHandler().post(() -> {
   15526             dbox.addText(dropboxTag, res);
   15527         });
   15528     }
   15529 
   15530     /**
   15531      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
   15532      * @param app object of the crashing app, null for the system server
   15533      * @param tag reported by the caller
   15534      * @param system whether this wtf is coming from the system
   15535      * @param crashInfo describing the context of the error
   15536      * @return true if the process should exit immediately (WTF is fatal)
   15537      */
   15538     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
   15539             final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
   15540         final int callingUid = Binder.getCallingUid();
   15541         final int callingPid = Binder.getCallingPid();
   15542 
   15543         if (system) {
   15544             // If this is coming from the system, we could very well have low-level
   15545             // system locks held, so we want to do this all asynchronously.  And we
   15546             // never want this to become fatal, so there is that too.
   15547             mHandler.post(new Runnable() {
   15548                 @Override public void run() {
   15549                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
   15550                 }
   15551             });
   15552             return false;
   15553         }
   15554 
   15555         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
   15556                 crashInfo);
   15557 
   15558         final boolean isFatal = Build.IS_ENG || Settings.Global
   15559                 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
   15560         final boolean isSystem = (r == null) || r.persistent;
   15561 
   15562         if (isFatal && !isSystem) {
   15563             mAppErrors.crashApplication(r, crashInfo);
   15564             return true;
   15565         } else {
   15566             return false;
   15567         }
   15568     }
   15569 
   15570     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
   15571             final ApplicationErrorReport.CrashInfo crashInfo) {
   15572         final ProcessRecord r = findAppProcess(app, "WTF");
   15573         final String processName = app == null ? "system_server"
   15574                 : (r == null ? "unknown" : r.processName);
   15575 
   15576         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
   15577                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
   15578 
   15579         StatsLog.write(StatsLog.WTF_OCCURRED, callingUid, tag, processName,
   15580                 callingPid);
   15581 
   15582         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
   15583 
   15584         return r;
   15585     }
   15586 
   15587     /**
   15588      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
   15589      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
   15590      */
   15591     private ProcessRecord findAppProcess(IBinder app, String reason) {
   15592         if (app == null) {
   15593             return null;
   15594         }
   15595 
   15596         synchronized (this) {
   15597             final int NP = mProcessNames.getMap().size();
   15598             for (int ip=0; ip<NP; ip++) {
   15599                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   15600                 final int NA = apps.size();
   15601                 for (int ia=0; ia<NA; ia++) {
   15602                     ProcessRecord p = apps.valueAt(ia);
   15603                     if (p.thread != null && p.thread.asBinder() == app) {
   15604                         return p;
   15605                     }
   15606                 }
   15607             }
   15608 
   15609             Slog.w(TAG, "Can't find mystery application for " + reason
   15610                     + " from pid=" + Binder.getCallingPid()
   15611                     + " uid=" + Binder.getCallingUid() + ": " + app);
   15612             return null;
   15613         }
   15614     }
   15615 
   15616     /**
   15617      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
   15618      * to append various headers to the dropbox log text.
   15619      */
   15620     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
   15621             StringBuilder sb) {
   15622         // Watchdog thread ends up invoking this function (with
   15623         // a null ProcessRecord) to add the stack file to dropbox.
   15624         // Do not acquire a lock on this (am) in such cases, as it
   15625         // could cause a potential deadlock, if and when watchdog
   15626         // is invoked due to unavailability of lock on am and it
   15627         // would prevent watchdog from killing system_server.
   15628         if (process == null) {
   15629             sb.append("Process: ").append(processName).append("\n");
   15630             return;
   15631         }
   15632         // Note: ProcessRecord 'process' is guarded by the service
   15633         // instance.  (notably process.pkgList, which could otherwise change
   15634         // concurrently during execution of this method)
   15635         synchronized (this) {
   15636             sb.append("Process: ").append(processName).append("\n");
   15637             sb.append("PID: ").append(process.pid).append("\n");
   15638             int flags = process.info.flags;
   15639             IPackageManager pm = AppGlobals.getPackageManager();
   15640             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
   15641             for (int ip=0; ip<process.pkgList.size(); ip++) {
   15642                 String pkg = process.pkgList.keyAt(ip);
   15643                 sb.append("Package: ").append(pkg);
   15644                 try {
   15645                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
   15646                     if (pi != null) {
   15647                         sb.append(" v").append(pi.getLongVersionCode());
   15648                         if (pi.versionName != null) {
   15649                             sb.append(" (").append(pi.versionName).append(")");
   15650                         }
   15651                     }
   15652                 } catch (RemoteException e) {
   15653                     Slog.e(TAG, "Error getting package info: " + pkg, e);
   15654                 }
   15655                 sb.append("\n");
   15656             }
   15657             if (process.info.isInstantApp()) {
   15658                 sb.append("Instant-App: true\n");
   15659             }
   15660         }
   15661     }
   15662 
   15663     private static String processClass(ProcessRecord process) {
   15664         if (process == null || process.pid == MY_PID) {
   15665             return "system_server";
   15666         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   15667             return "system_app";
   15668         } else {
   15669             return "data_app";
   15670         }
   15671     }
   15672 
   15673     private volatile long mWtfClusterStart;
   15674     private volatile int mWtfClusterCount;
   15675 
   15676     /**
   15677      * Write a description of an error (crash, WTF, ANR) to the drop box.
   15678      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
   15679      * @param process which caused the error, null means the system server
   15680      * @param activity which triggered the error, null if unknown
   15681      * @param parent activity related to the error, null if unknown
   15682      * @param subject line related to the error, null if absent
   15683      * @param report in long form describing the error, null if absent
   15684      * @param dataFile text file to include in the report, null if none
   15685      * @param crashInfo giving an application stack trace, null if absent
   15686      */
   15687     public void addErrorToDropBox(String eventType,
   15688             ProcessRecord process, String processName, ActivityRecord activity,
   15689             ActivityRecord parent, String subject,
   15690             final String report, final File dataFile,
   15691             final ApplicationErrorReport.CrashInfo crashInfo) {
   15692         // NOTE -- this must never acquire the ActivityManagerService lock,
   15693         // otherwise the watchdog may be prevented from resetting the system.
   15694 
   15695         // Bail early if not published yet
   15696         if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
   15697         final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
   15698 
   15699         // Exit early if the dropbox isn't configured to accept this report type.
   15700         final String dropboxTag = processClass(process) + "_" + eventType;
   15701         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   15702 
   15703         // Rate-limit how often we're willing to do the heavy lifting below to
   15704         // collect and record logs; currently 5 logs per 10 second period.
   15705         final long now = SystemClock.elapsedRealtime();
   15706         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
   15707             mWtfClusterStart = now;
   15708             mWtfClusterCount = 1;
   15709         } else {
   15710             if (mWtfClusterCount++ >= 5) return;
   15711         }
   15712 
   15713         final StringBuilder sb = new StringBuilder(1024);
   15714         appendDropBoxProcessHeaders(process, processName, sb);
   15715         if (process != null) {
   15716             sb.append("Foreground: ")
   15717                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
   15718                     .append("\n");
   15719         }
   15720         if (activity != null) {
   15721             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
   15722         }
   15723         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
   15724             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
   15725         }
   15726         if (parent != null && parent != activity) {
   15727             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
   15728         }
   15729         if (subject != null) {
   15730             sb.append("Subject: ").append(subject).append("\n");
   15731         }
   15732         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   15733         if (Debug.isDebuggerConnected()) {
   15734             sb.append("Debugger: Connected\n");
   15735         }
   15736         sb.append("\n");
   15737 
   15738         // Do the rest in a worker thread to avoid blocking the caller on I/O
   15739         // (After this point, we shouldn't access AMS internal data structures.)
   15740         Thread worker = new Thread("Error dump: " + dropboxTag) {
   15741             @Override
   15742             public void run() {
   15743                 if (report != null) {
   15744                     sb.append(report);
   15745                 }
   15746 
   15747                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
   15748                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
   15749                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
   15750                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
   15751 
   15752                 if (dataFile != null && maxDataFileSize > 0) {
   15753                     try {
   15754                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
   15755                                     "\n\n[[TRUNCATED]]"));
   15756                     } catch (IOException e) {
   15757                         Slog.e(TAG, "Error reading " + dataFile, e);
   15758                     }
   15759                 }
   15760                 if (crashInfo != null && crashInfo.stackTrace != null) {
   15761                     sb.append(crashInfo.stackTrace);
   15762                 }
   15763 
   15764                 if (lines > 0) {
   15765                     sb.append("\n");
   15766 
   15767                     // Merge several logcat streams, and take the last N lines
   15768                     InputStreamReader input = null;
   15769                     try {
   15770                         java.lang.Process logcat = new ProcessBuilder(
   15771                                 "/system/bin/timeout", "-k", "15s", "10s",
   15772                                 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
   15773                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
   15774                                         .redirectErrorStream(true).start();
   15775 
   15776                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
   15777                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
   15778                         input = new InputStreamReader(logcat.getInputStream());
   15779 
   15780                         int num;
   15781                         char[] buf = new char[8192];
   15782                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
   15783                     } catch (IOException e) {
   15784                         Slog.e(TAG, "Error running logcat", e);
   15785                     } finally {
   15786                         if (input != null) try { input.close(); } catch (IOException e) {}
   15787                     }
   15788                 }
   15789 
   15790                 dbox.addText(dropboxTag, sb.toString());
   15791             }
   15792         };
   15793 
   15794         if (process == null) {
   15795             // If process is null, we are being called from some internal code
   15796             // and may be about to die -- run this synchronously.
   15797             final int oldMask = StrictMode.allowThreadDiskWritesMask();
   15798             try {
   15799                 worker.run();
   15800             } finally {
   15801                 StrictMode.setThreadPolicyMask(oldMask);
   15802             }
   15803         } else {
   15804             worker.start();
   15805         }
   15806     }
   15807 
   15808     @Override
   15809     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
   15810         enforceNotIsolatedCaller("getProcessesInErrorState");
   15811         // assume our apps are happy - lazy create the list
   15812         List<ActivityManager.ProcessErrorStateInfo> errList = null;
   15813 
   15814         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
   15815                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
   15816         int userId = UserHandle.getUserId(Binder.getCallingUid());
   15817 
   15818         synchronized (this) {
   15819 
   15820             // iterate across all processes
   15821             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   15822                 ProcessRecord app = mLruProcesses.get(i);
   15823                 if (!allUsers && app.userId != userId) {
   15824                     continue;
   15825                 }
   15826                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
   15827                     // This one's in trouble, so we'll generate a report for it
   15828                     // crashes are higher priority (in case there's a crash *and* an anr)
   15829                     ActivityManager.ProcessErrorStateInfo report = null;
   15830                     if (app.crashing) {
   15831                         report = app.crashingReport;
   15832                     } else if (app.notResponding) {
   15833                         report = app.notRespondingReport;
   15834                     }
   15835 
   15836                     if (report != null) {
   15837                         if (errList == null) {
   15838                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
   15839                         }
   15840                         errList.add(report);
   15841                     } else {
   15842                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
   15843                                 " crashing = " + app.crashing +
   15844                                 " notResponding = " + app.notResponding);
   15845                     }
   15846                 }
   15847             }
   15848         }
   15849 
   15850         return errList;
   15851     }
   15852 
   15853     static int procStateToImportance(int procState, int memAdj,
   15854             ActivityManager.RunningAppProcessInfo currApp,
   15855             int clientTargetSdk) {
   15856         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
   15857                 procState, clientTargetSdk);
   15858         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
   15859             currApp.lru = memAdj;
   15860         } else {
   15861             currApp.lru = 0;
   15862         }
   15863         return imp;
   15864     }
   15865 
   15866     private void fillInProcMemInfo(ProcessRecord app,
   15867             ActivityManager.RunningAppProcessInfo outInfo,
   15868             int clientTargetSdk) {
   15869         outInfo.pid = app.pid;
   15870         outInfo.uid = app.info.uid;
   15871         if (mHeavyWeightProcess == app) {
   15872             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
   15873         }
   15874         if (app.persistent) {
   15875             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
   15876         }
   15877         if (app.activities.size() > 0) {
   15878             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
   15879         }
   15880         outInfo.lastTrimLevel = app.trimMemoryLevel;
   15881         int adj = app.curAdj;
   15882         int procState = app.curProcState;
   15883         outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
   15884         outInfo.importanceReasonCode = app.adjTypeCode;
   15885         outInfo.processState = app.curProcState;
   15886     }
   15887 
   15888     @Override
   15889     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
   15890         enforceNotIsolatedCaller("getRunningAppProcesses");
   15891 
   15892         final int callingUid = Binder.getCallingUid();
   15893         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
   15894 
   15895         // Lazy instantiation of list
   15896         List<ActivityManager.RunningAppProcessInfo> runList = null;
   15897         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
   15898                 callingUid) == PackageManager.PERMISSION_GRANTED;
   15899         final int userId = UserHandle.getUserId(callingUid);
   15900         final boolean allUids = isGetTasksAllowed(
   15901                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
   15902 
   15903         synchronized (this) {
   15904             // Iterate across all processes
   15905             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   15906                 ProcessRecord app = mLruProcesses.get(i);
   15907                 if ((!allUsers && app.userId != userId)
   15908                         || (!allUids && app.uid != callingUid)) {
   15909                     continue;
   15910                 }
   15911                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
   15912                     // Generate process state info for running application
   15913                     ActivityManager.RunningAppProcessInfo currApp =
   15914                         new ActivityManager.RunningAppProcessInfo(app.processName,
   15915                                 app.pid, app.getPackageList());
   15916                     fillInProcMemInfo(app, currApp, clientTargetSdk);
   15917                     if (app.adjSource instanceof ProcessRecord) {
   15918                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
   15919                         currApp.importanceReasonImportance =
   15920                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
   15921                                         app.adjSourceProcState);
   15922                     } else if (app.adjSource instanceof ActivityRecord) {
   15923                         ActivityRecord r = (ActivityRecord)app.adjSource;
   15924                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
   15925                     }
   15926                     if (app.adjTarget instanceof ComponentName) {
   15927                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
   15928                     }
   15929                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
   15930                     //        + " lru=" + currApp.lru);
   15931                     if (runList == null) {
   15932                         runList = new ArrayList<>();
   15933                     }
   15934                     runList.add(currApp);
   15935                 }
   15936             }
   15937         }
   15938         return runList;
   15939     }
   15940 
   15941     @Override
   15942     public List<ApplicationInfo> getRunningExternalApplications() {
   15943         enforceNotIsolatedCaller("getRunningExternalApplications");
   15944         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
   15945         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
   15946         if (runningApps != null && runningApps.size() > 0) {
   15947             Set<String> extList = new HashSet<String>();
   15948             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
   15949                 if (app.pkgList != null) {
   15950                     for (String pkg : app.pkgList) {
   15951                         extList.add(pkg);
   15952                     }
   15953                 }
   15954             }
   15955             IPackageManager pm = AppGlobals.getPackageManager();
   15956             for (String pkg : extList) {
   15957                 try {
   15958                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
   15959                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
   15960                         retList.add(info);
   15961                     }
   15962                 } catch (RemoteException e) {
   15963                 }
   15964             }
   15965         }
   15966         return retList;
   15967     }
   15968 
   15969     @Override
   15970     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outState) {
   15971         if (outState == null) {
   15972             throw new IllegalArgumentException("outState is null");
   15973         }
   15974         enforceNotIsolatedCaller("getMyMemoryState");
   15975 
   15976         final int callingUid = Binder.getCallingUid();
   15977         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
   15978 
   15979         synchronized (this) {
   15980             ProcessRecord proc;
   15981             synchronized (mPidsSelfLocked) {
   15982                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   15983             }
   15984             if (proc != null) {
   15985                 fillInProcMemInfo(proc, outState, clientTargetSdk);
   15986             }
   15987         }
   15988     }
   15989 
   15990     @Override
   15991     public int getMemoryTrimLevel() {
   15992         enforceNotIsolatedCaller("getMyMemoryState");
   15993         synchronized (this) {
   15994             return mLastMemoryLevel;
   15995         }
   15996     }
   15997 
   15998     @Override
   15999     public void onShellCommand(FileDescriptor in, FileDescriptor out,
   16000             FileDescriptor err, String[] args, ShellCallback callback,
   16001             ResultReceiver resultReceiver) {
   16002         (new ActivityManagerShellCommand(this, false)).exec(
   16003                 this, in, out, err, args, callback, resultReceiver);
   16004     }
   16005 
   16006     SleepToken acquireSleepToken(String tag, int displayId) {
   16007         synchronized (this) {
   16008             final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
   16009             updateSleepIfNeededLocked();
   16010             return token;
   16011         }
   16012     }
   16013 
   16014     @Override
   16015     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   16016         PriorityDump.dump(mPriorityDumper, fd, pw, args);
   16017     }
   16018 
   16019     /**
   16020      * Wrapper function to print out debug data filtered by specified arguments.
   16021     */
   16022     private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
   16023         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
   16024 
   16025         boolean dumpAll = false;
   16026         boolean dumpClient = false;
   16027         boolean dumpCheckin = false;
   16028         boolean dumpCheckinFormat = false;
   16029         boolean dumpNormalPriority = false;
   16030         boolean dumpVisibleStacksOnly = false;
   16031         boolean dumpFocusedStackOnly = false;
   16032         String dumpPackage = null;
   16033 
   16034         int opti = 0;
   16035         while (opti < args.length) {
   16036             String opt = args[opti];
   16037             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   16038                 break;
   16039             }
   16040             opti++;
   16041             if ("-a".equals(opt)) {
   16042                 dumpAll = true;
   16043             } else if ("-c".equals(opt)) {
   16044                 dumpClient = true;
   16045             } else if ("-v".equals(opt)) {
   16046                 dumpVisibleStacksOnly = true;
   16047             } else if ("-f".equals(opt)) {
   16048                 dumpFocusedStackOnly = true;
   16049             } else if ("-p".equals(opt)) {
   16050                 if (opti < args.length) {
   16051                     dumpPackage = args[opti];
   16052                     opti++;
   16053                 } else {
   16054                     pw.println("Error: -p option requires package argument");
   16055                     return;
   16056                 }
   16057                 dumpClient = true;
   16058             } else if ("--checkin".equals(opt)) {
   16059                 dumpCheckin = dumpCheckinFormat = true;
   16060             } else if ("-C".equals(opt)) {
   16061                 dumpCheckinFormat = true;
   16062             } else if ("--normal-priority".equals(opt)) {
   16063                 dumpNormalPriority = true;
   16064             } else if ("-h".equals(opt)) {
   16065                 ActivityManagerShellCommand.dumpHelp(pw, true);
   16066                 return;
   16067             } else {
   16068                 pw.println("Unknown argument: " + opt + "; use -h for help");
   16069             }
   16070         }
   16071 
   16072         long origId = Binder.clearCallingIdentity();
   16073 
   16074         if (useProto) {
   16075             final ProtoOutputStream proto = new ProtoOutputStream(fd);
   16076             String cmd = opti < args.length ? args[opti] : "";
   16077             opti++;
   16078 
   16079             if ("activities".equals(cmd) || "a".equals(cmd)) {
   16080                 // output proto is ActivityManagerServiceDumpActivitiesProto
   16081                 synchronized (this) {
   16082                     writeActivitiesToProtoLocked(proto);
   16083                 }
   16084             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
   16085                 // output proto is ActivityManagerServiceDumpBroadcastsProto
   16086                 synchronized (this) {
   16087                     writeBroadcastsToProtoLocked(proto);
   16088                 }
   16089             } else if ("provider".equals(cmd)) {
   16090                 String[] newArgs;
   16091                 String name;
   16092                 if (opti >= args.length) {
   16093                     name = null;
   16094                     newArgs = EMPTY_STRING_ARRAY;
   16095                 } else {
   16096                     name = args[opti];
   16097                     opti++;
   16098                     newArgs = new String[args.length - opti];
   16099                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   16100                             args.length - opti);
   16101                 }
   16102                 if (!dumpProviderProto(fd, pw, name, newArgs)) {
   16103                     pw.println("No providers match: " + name);
   16104                     pw.println("Use -h for help.");
   16105                 }
   16106             } else if ("service".equals(cmd)) {
   16107                 // output proto is ActivityManagerServiceDumpServicesProto
   16108                 mServices.writeToProto(proto, ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
   16109             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
   16110                 if (opti < args.length) {
   16111                     dumpPackage = args[opti];
   16112                     opti++;
   16113                 }
   16114                 // output proto is ProcessProto
   16115                 synchronized (this) {
   16116                     writeProcessesToProtoLocked(proto, dumpPackage);
   16117                 }
   16118             } else {
   16119                 // default option, dump everything, output is ActivityManagerServiceProto
   16120                 synchronized (this) {
   16121                     long activityToken = proto.start(ActivityManagerServiceProto.ACTIVITIES);
   16122                     writeActivitiesToProtoLocked(proto);
   16123                     proto.end(activityToken);
   16124 
   16125                     long broadcastToken = proto.start(ActivityManagerServiceProto.BROADCASTS);
   16126                     writeBroadcastsToProtoLocked(proto);
   16127                     proto.end(broadcastToken);
   16128 
   16129                     long serviceToken = proto.start(ActivityManagerServiceProto.SERVICES);
   16130                     mServices.writeToProto(proto, ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
   16131                     proto.end(serviceToken);
   16132 
   16133                     long processToken = proto.start(ActivityManagerServiceProto.PROCESSES);
   16134                     writeProcessesToProtoLocked(proto, dumpPackage);
   16135                     proto.end(processToken);
   16136                 }
   16137             }
   16138             proto.flush();
   16139             Binder.restoreCallingIdentity(origId);
   16140             return;
   16141         }
   16142 
   16143         int dumpAppId = getAppId(dumpPackage);
   16144         boolean more = false;
   16145         // Is the caller requesting to dump a particular piece of data?
   16146         if (opti < args.length) {
   16147             String cmd = args[opti];
   16148             opti++;
   16149             if ("activities".equals(cmd) || "a".equals(cmd)) {
   16150                 synchronized (this) {
   16151                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
   16152                 }
   16153             } else if ("lastanr".equals(cmd)) {
   16154                 synchronized (this) {
   16155                     dumpLastANRLocked(pw);
   16156                 }
   16157             } else if ("starter".equals(cmd)) {
   16158                 synchronized (this) {
   16159                     dumpActivityStarterLocked(pw, dumpPackage);
   16160                 }
   16161             } else if ("containers".equals(cmd)) {
   16162                 synchronized (this) {
   16163                     dumpActivityContainersLocked(pw);
   16164                 }
   16165             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
   16166                 synchronized (this) {
   16167                     if (mRecentTasks != null) {
   16168                         mRecentTasks.dump(pw, true /* dumpAll */, dumpPackage);
   16169                     }
   16170                 }
   16171             } else if ("binder-proxies".equals(cmd)) {
   16172                 if (opti >= args.length) {
   16173                     dumpBinderProxiesCounts(pw, BinderInternal.nGetBinderProxyPerUidCounts(),
   16174                             "Counts of Binder Proxies held by SYSTEM");
   16175                 } else {
   16176                     String uid = args[opti];
   16177                     opti++;
   16178                     // Ensure Binder Proxy Count is as up to date as possible
   16179                     System.gc();
   16180                     System.runFinalization();
   16181                     System.gc();
   16182                     pw.println(BinderInternal.nGetBinderProxyCount(Integer.parseInt(uid)));
   16183                 }
   16184             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
   16185                 if (opti < args.length) {
   16186                     dumpPackage = args[opti];
   16187                     opti++;
   16188                 }
   16189                 synchronized (this) {
   16190                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
   16191                 }
   16192             } else if ("broadcast-stats".equals(cmd)) {
   16193                 if (opti < args.length) {
   16194                     dumpPackage = args[opti];
   16195                     opti++;
   16196                 }
   16197                 synchronized (this) {
   16198                     if (dumpCheckinFormat) {
   16199                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
   16200                                 dumpPackage);
   16201                     } else {
   16202                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
   16203                     }
   16204                 }
   16205             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
   16206                 if (opti < args.length) {
   16207                     dumpPackage = args[opti];
   16208                     opti++;
   16209                 }
   16210                 synchronized (this) {
   16211                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
   16212                 }
   16213             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
   16214                 if (opti < args.length) {
   16215                     dumpPackage = args[opti];
   16216                     opti++;
   16217                 }
   16218                 synchronized (this) {
   16219                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage, dumpAppId);
   16220                 }
   16221             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
   16222                 synchronized (this) {
   16223                     dumpOomLocked(fd, pw, args, opti, true);
   16224                 }
   16225             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
   16226                 synchronized (this) {
   16227                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
   16228                 }
   16229             } else if ("provider".equals(cmd)) {
   16230                 String[] newArgs;
   16231                 String name;
   16232                 if (opti >= args.length) {
   16233                     name = null;
   16234                     newArgs = EMPTY_STRING_ARRAY;
   16235                 } else {
   16236                     name = args[opti];
   16237                     opti++;
   16238                     newArgs = new String[args.length - opti];
   16239                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   16240                 }
   16241                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
   16242                     pw.println("No providers match: " + name);
   16243                     pw.println("Use -h for help.");
   16244                 }
   16245             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
   16246                 synchronized (this) {
   16247                     dumpProvidersLocked(fd, pw, args, opti, true, null);
   16248                 }
   16249             } else if ("service".equals(cmd)) {
   16250                 String[] newArgs;
   16251                 String name;
   16252                 if (opti >= args.length) {
   16253                     name = null;
   16254                     newArgs = EMPTY_STRING_ARRAY;
   16255                 } else {
   16256                     name = args[opti];
   16257                     opti++;
   16258                     newArgs = new String[args.length - opti];
   16259                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   16260                             args.length - opti);
   16261                 }
   16262                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
   16263                     pw.println("No services match: " + name);
   16264                     pw.println("Use -h for help.");
   16265                 }
   16266             } else if ("package".equals(cmd)) {
   16267                 String[] newArgs;
   16268                 if (opti >= args.length) {
   16269                     pw.println("package: no package name specified");
   16270                     pw.println("Use -h for help.");
   16271                 } else {
   16272                     dumpPackage = args[opti];
   16273                     opti++;
   16274                     newArgs = new String[args.length - opti];
   16275                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   16276                             args.length - opti);
   16277                     args = newArgs;
   16278                     opti = 0;
   16279                     more = true;
   16280                 }
   16281             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
   16282                 synchronized (this) {
   16283                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
   16284                 }
   16285             } else if ("settings".equals(cmd)) {
   16286                 synchronized (this) {
   16287                     mConstants.dump(pw);
   16288                 }
   16289             } else if ("services".equals(cmd) || "s".equals(cmd)) {
   16290                 if (dumpClient) {
   16291                     ActiveServices.ServiceDumper dumper;
   16292                     synchronized (this) {
   16293                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
   16294                                 dumpPackage);
   16295                     }
   16296                     dumper.dumpWithClient();
   16297                 } else {
   16298                     synchronized (this) {
   16299                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
   16300                                 dumpPackage).dumpLocked();
   16301                     }
   16302                 }
   16303             } else if ("locks".equals(cmd)) {
   16304                 LockGuard.dump(fd, pw, args);
   16305             } else {
   16306                 // Dumping a single activity?
   16307                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
   16308                         dumpFocusedStackOnly)) {
   16309                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
   16310                     int res = shell.exec(this, null, fd, null, args, null,
   16311                             new ResultReceiver(null));
   16312                     if (res < 0) {
   16313                         pw.println("Bad activity command, or no activities match: " + cmd);
   16314                         pw.println("Use -h for help.");
   16315                     }
   16316                 }
   16317             }
   16318             if (!more) {
   16319                 Binder.restoreCallingIdentity(origId);
   16320                 return;
   16321             }
   16322         }
   16323 
   16324         // No piece of data specified, dump everything.
   16325         if (dumpCheckinFormat) {
   16326             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
   16327         } else if (dumpClient) {
   16328             ActiveServices.ServiceDumper sdumper;
   16329             synchronized (this) {
   16330                 mConstants.dump(pw);
   16331                 pw.println();
   16332                 if (dumpAll) {
   16333                     pw.println("-------------------------------------------------------------------------------");
   16334                 }
   16335                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   16336                 pw.println();
   16337                 if (dumpAll) {
   16338                     pw.println("-------------------------------------------------------------------------------");
   16339                 }
   16340                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   16341                 pw.println();
   16342                 if (dumpAll) {
   16343                     pw.println("-------------------------------------------------------------------------------");
   16344                 }
   16345                 if (dumpAll || dumpPackage != null) {
   16346                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   16347                     pw.println();
   16348                     if (dumpAll) {
   16349                         pw.println("-------------------------------------------------------------------------------");
   16350                     }
   16351                 }
   16352                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   16353                 pw.println();
   16354                 if (dumpAll) {
   16355                     pw.println("-------------------------------------------------------------------------------");
   16356                 }
   16357                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   16358                 pw.println();
   16359                 if (dumpAll) {
   16360                     pw.println("-------------------------------------------------------------------------------");
   16361                 }
   16362                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
   16363                         dumpPackage);
   16364             }
   16365             sdumper.dumpWithClient();
   16366             pw.println();
   16367             synchronized (this) {
   16368                 if (dumpAll) {
   16369                     pw.println("-------------------------------------------------------------------------------");
   16370                 }
   16371                 if (mRecentTasks != null) {
   16372                     mRecentTasks.dump(pw, dumpAll, dumpPackage);
   16373                 }
   16374                 pw.println();
   16375                 if (dumpAll) {
   16376                     pw.println("-------------------------------------------------------------------------------");
   16377                 }
   16378                 dumpLastANRLocked(pw);
   16379                 pw.println();
   16380                 if (dumpAll) {
   16381                     pw.println("-------------------------------------------------------------------------------");
   16382                 }
   16383                 dumpActivityStarterLocked(pw, dumpPackage);
   16384                 pw.println();
   16385                 if (dumpAll) {
   16386                     pw.println("-------------------------------------------------------------------------------");
   16387                 }
   16388                 dumpActivityContainersLocked(pw);
   16389                 pw.println();
   16390                 if (dumpAll) {
   16391                     pw.println("-------------------------------------------------------------------------------");
   16392                 }
   16393                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   16394                 if (mAssociations.size() > 0) {
   16395                     pw.println();
   16396                     if (dumpAll) {
   16397                         pw.println("-------------------------------------------------------------------------------");
   16398                     }
   16399                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   16400                 }
   16401                 pw.println();
   16402                 if (dumpAll) {
   16403                     pw.println("-------------------------------------------------------------------------------");
   16404                 }
   16405                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
   16406             }
   16407 
   16408         } else {
   16409             synchronized (this) {
   16410                 mConstants.dump(pw);
   16411                 pw.println();
   16412                 if (dumpAll) {
   16413                     pw.println("-------------------------------------------------------------------------------");
   16414                 }
   16415                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   16416                 pw.println();
   16417                 if (dumpAll) {
   16418                     pw.println("-------------------------------------------------------------------------------");
   16419                 }
   16420                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   16421                 pw.println();
   16422                 if (dumpAll) {
   16423                     pw.println("-------------------------------------------------------------------------------");
   16424                 }
   16425                 if (dumpAll || dumpPackage != null) {
   16426                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   16427                     pw.println();
   16428                     if (dumpAll) {
   16429                         pw.println("-------------------------------------------------------------------------------");
   16430                     }
   16431                 }
   16432                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   16433                 pw.println();
   16434                 if (dumpAll) {
   16435                     pw.println("-------------------------------------------------------------------------------");
   16436                 }
   16437                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   16438                 pw.println();
   16439                 if (dumpAll) {
   16440                     pw.println("-------------------------------------------------------------------------------");
   16441                 }
   16442                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
   16443                         .dumpLocked();
   16444                 pw.println();
   16445                 if (dumpAll) {
   16446                     pw.println("-------------------------------------------------------------------------------");
   16447                 }
   16448                 if (mRecentTasks != null) {
   16449                     mRecentTasks.dump(pw, dumpAll, dumpPackage);
   16450                 }
   16451                 pw.println();
   16452                 if (dumpAll) {
   16453                     pw.println("-------------------------------------------------------------------------------");
   16454                 }
   16455                 dumpLastANRLocked(pw);
   16456                 pw.println();
   16457                 if (dumpAll) {
   16458                     pw.println("-------------------------------------------------------------------------------");
   16459                 }
   16460                 dumpActivityStarterLocked(pw, dumpPackage);
   16461                 pw.println();
   16462                 if (dumpAll) {
   16463                     pw.println("-------------------------------------------------------------------------------");
   16464                 }
   16465                 dumpActivityContainersLocked(pw);
   16466                 // Activities section is dumped as part of the Critical priority dump. Exclude the
   16467                 // section if priority is Normal.
   16468                 if (!dumpNormalPriority){
   16469                     pw.println();
   16470                     if (dumpAll) {
   16471                         pw.println("-------------------------------------------------------------------------------");
   16472                     }
   16473                     dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   16474                 }
   16475                 if (mAssociations.size() > 0) {
   16476                     pw.println();
   16477                     if (dumpAll) {
   16478                         pw.println("-------------------------------------------------------------------------------");
   16479                     }
   16480                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   16481                 }
   16482                 pw.println();
   16483                 if (dumpAll) {
   16484                     pw.println("-------------------------------------------------------------------------------");
   16485                 }
   16486                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
   16487             }
   16488         }
   16489         Binder.restoreCallingIdentity(origId);
   16490     }
   16491 
   16492     private void writeActivitiesToProtoLocked(ProtoOutputStream proto) {
   16493         // The output proto of "activity --proto activities" is ActivityManagerServiceDumpActivitiesProto
   16494         mStackSupervisor.writeToProto(proto, ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
   16495     }
   16496 
   16497     private void dumpLastANRLocked(PrintWriter pw) {
   16498         pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
   16499         if (mLastANRState == null) {
   16500             pw.println("  <no ANR has occurred since boot>");
   16501         } else {
   16502             pw.println(mLastANRState);
   16503         }
   16504     }
   16505 
   16506     private void dumpActivityContainersLocked(PrintWriter pw) {
   16507         pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
   16508         mStackSupervisor.dumpChildrenNames(pw, " ");
   16509         pw.println(" ");
   16510     }
   16511 
   16512     private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
   16513         pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
   16514         mActivityStartController.dump(pw, "", dumpPackage);
   16515     }
   16516 
   16517     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   16518             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   16519         dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
   16520                 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
   16521     }
   16522 
   16523     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   16524             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
   16525         pw.println(header);
   16526 
   16527         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
   16528                 dumpPackage);
   16529         boolean needSep = printedAnything;
   16530 
   16531         boolean printed = ActivityStackSupervisor.printThisActivity(pw,
   16532                 mStackSupervisor.getResumedActivityLocked(),
   16533                 dumpPackage, needSep, "  ResumedActivity: ");
   16534         if (printed) {
   16535             printedAnything = true;
   16536             needSep = false;
   16537         }
   16538 
   16539         if (dumpPackage == null) {
   16540             if (needSep) {
   16541                 pw.println();
   16542             }
   16543             printedAnything = true;
   16544             mStackSupervisor.dump(pw, "  ");
   16545         }
   16546 
   16547         if (!printedAnything) {
   16548             pw.println("  (nothing)");
   16549         }
   16550     }
   16551 
   16552     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   16553             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   16554         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
   16555 
   16556         int dumpUid = 0;
   16557         if (dumpPackage != null) {
   16558             IPackageManager pm = AppGlobals.getPackageManager();
   16559             try {
   16560                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
   16561             } catch (RemoteException e) {
   16562             }
   16563         }
   16564 
   16565         boolean printedAnything = false;
   16566 
   16567         final long now = SystemClock.uptimeMillis();
   16568 
   16569         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
   16570             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
   16571                     = mAssociations.valueAt(i1);
   16572             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
   16573                 SparseArray<ArrayMap<String, Association>> sourceUids
   16574                         = targetComponents.valueAt(i2);
   16575                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
   16576                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
   16577                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
   16578                         Association ass = sourceProcesses.valueAt(i4);
   16579                         if (dumpPackage != null) {
   16580                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
   16581                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
   16582                                 continue;
   16583                             }
   16584                         }
   16585                         printedAnything = true;
   16586                         pw.print("  ");
   16587                         pw.print(ass.mTargetProcess);
   16588                         pw.print("/");
   16589                         UserHandle.formatUid(pw, ass.mTargetUid);
   16590                         pw.print(" <- ");
   16591                         pw.print(ass.mSourceProcess);
   16592                         pw.print("/");
   16593                         UserHandle.formatUid(pw, ass.mSourceUid);
   16594                         pw.println();
   16595                         pw.print("    via ");
   16596                         pw.print(ass.mTargetComponent.flattenToShortString());
   16597                         pw.println();
   16598                         pw.print("    ");
   16599                         long dur = ass.mTime;
   16600                         if (ass.mNesting > 0) {
   16601                             dur += now - ass.mStartTime;
   16602                         }
   16603                         TimeUtils.formatDuration(dur, pw);
   16604                         pw.print(" (");
   16605                         pw.print(ass.mCount);
   16606                         pw.print(" times)");
   16607                         pw.print("  ");
   16608                         for (int i=0; i<ass.mStateTimes.length; i++) {
   16609                             long amt = ass.mStateTimes[i];
   16610                             if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
   16611                                 amt += now - ass.mLastStateUptime;
   16612                             }
   16613                             if (amt != 0) {
   16614                                 pw.print(" ");
   16615                                 pw.print(ProcessList.makeProcStateString(
   16616                                             i + ActivityManager.MIN_PROCESS_STATE));
   16617                                 pw.print("=");
   16618                                 TimeUtils.formatDuration(amt, pw);
   16619                                 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
   16620                                     pw.print("*");
   16621                                 }
   16622                             }
   16623                         }
   16624                         pw.println();
   16625                         if (ass.mNesting > 0) {
   16626                             pw.print("    Currently active: ");
   16627                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
   16628                             pw.println();
   16629                         }
   16630                     }
   16631                 }
   16632             }
   16633 
   16634         }
   16635 
   16636         if (!printedAnything) {
   16637             pw.println("  (nothing)");
   16638         }
   16639     }
   16640 
   16641     private int getAppId(String dumpPackage) {
   16642         if (dumpPackage != null) {
   16643             try {
   16644                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
   16645                         dumpPackage, 0);
   16646                 return UserHandle.getAppId(info.uid);
   16647             } catch (NameNotFoundException e) {
   16648                 e.printStackTrace();
   16649             }
   16650         }
   16651         return -1;
   16652     }
   16653 
   16654     boolean dumpUids(PrintWriter pw, String dumpPackage, int dumpAppId, SparseArray<UidRecord> uids,
   16655                 String header, boolean needSep) {
   16656         boolean printed = false;
   16657         for (int i=0; i<uids.size(); i++) {
   16658             UidRecord uidRec = uids.valueAt(i);
   16659             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != dumpAppId) {
   16660                 continue;
   16661             }
   16662             if (!printed) {
   16663                 printed = true;
   16664                 if (needSep) {
   16665                     pw.println();
   16666                 }
   16667                 pw.print("  ");
   16668                 pw.println(header);
   16669                 needSep = true;
   16670             }
   16671             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
   16672             pw.print(": "); pw.println(uidRec);
   16673         }
   16674         return printed;
   16675     }
   16676 
   16677     boolean dumpBinderProxiesCounts(PrintWriter pw, SparseIntArray counts, String header) {
   16678         if(counts != null) {
   16679             pw.println(header);
   16680             for (int i = 0; i < counts.size(); i++) {
   16681                 final int uid = counts.keyAt(i);
   16682                 final int binderCount = counts.valueAt(i);
   16683                 pw.print("    UID ");
   16684                 pw.print(uid);
   16685                 pw.print(", binder count = ");
   16686                 pw.print(binderCount);
   16687                 pw.print(", package(s)= ");
   16688                 final String[] pkgNames = mContext.getPackageManager().getPackagesForUid(uid);
   16689                 if (pkgNames != null) {
   16690                     for (int j = 0; j < pkgNames.length; j++) {
   16691                         pw.print(pkgNames[j]);
   16692                         pw.print("; ");
   16693                     }
   16694                 } else {
   16695                     pw.print("NO PACKAGE NAME FOUND");
   16696                 }
   16697                 pw.println();
   16698             }
   16699             pw.println();
   16700             return true;
   16701         }
   16702         return false;
   16703     }
   16704 
   16705     @GuardedBy("this")
   16706     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   16707             int opti, boolean dumpAll, String dumpPackage, int dumpAppId) {
   16708         boolean needSep = false;
   16709         int numPers = 0;
   16710 
   16711         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
   16712 
   16713         if (dumpAll) {
   16714             final int NP = mProcessNames.getMap().size();
   16715             for (int ip=0; ip<NP; ip++) {
   16716                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
   16717                 final int NA = procs.size();
   16718                 for (int ia=0; ia<NA; ia++) {
   16719                     ProcessRecord r = procs.valueAt(ia);
   16720                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   16721                         continue;
   16722                     }
   16723                     if (!needSep) {
   16724                         pw.println("  All known processes:");
   16725                         needSep = true;
   16726                     }
   16727                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
   16728                         pw.print(" UID "); pw.print(procs.keyAt(ia));
   16729                         pw.print(" "); pw.println(r);
   16730                     r.dump(pw, "    ");
   16731                     if (r.persistent) {
   16732                         numPers++;
   16733                     }
   16734                 }
   16735             }
   16736         }
   16737 
   16738         if (mIsolatedProcesses.size() > 0) {
   16739             boolean printed = false;
   16740             for (int i=0; i<mIsolatedProcesses.size(); i++) {
   16741                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
   16742                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   16743                     continue;
   16744                 }
   16745                 if (!printed) {
   16746                     if (needSep) {
   16747                         pw.println();
   16748                     }
   16749                     pw.println("  Isolated process list (sorted by uid):");
   16750                     printed = true;
   16751                     needSep = true;
   16752                 }
   16753                 pw.print("    Isolated #"); pw.print(i); pw.print(": ");
   16754                 pw.println(r);
   16755             }
   16756         }
   16757 
   16758         if (mActiveInstrumentation.size() > 0) {
   16759             boolean printed = false;
   16760             for (int i=0; i<mActiveInstrumentation.size(); i++) {
   16761                 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
   16762                 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
   16763                         && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
   16764                     continue;
   16765                 }
   16766                 if (!printed) {
   16767                     if (needSep) {
   16768                         pw.println();
   16769                     }
   16770                     pw.println("  Active instrumentation:");
   16771                     printed = true;
   16772                     needSep = true;
   16773                 }
   16774                 pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
   16775                 pw.println(ai);
   16776                 ai.dump(pw, "      ");
   16777             }
   16778         }
   16779 
   16780         if (mActiveUids.size() > 0) {
   16781             if (dumpUids(pw, dumpPackage, dumpAppId, mActiveUids, "UID states:", needSep)) {
   16782                 needSep = true;
   16783             }
   16784         }
   16785         if (dumpAll) {
   16786             if (mValidateUids.size() > 0) {
   16787                 if (dumpUids(pw, dumpPackage, dumpAppId, mValidateUids, "UID validation:",
   16788                         needSep)) {
   16789                     needSep = true;
   16790                 }
   16791             }
   16792         }
   16793 
   16794         if (mLruProcesses.size() > 0) {
   16795             if (needSep) {
   16796                 pw.println();
   16797             }
   16798             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
   16799                     pw.print(" total, non-act at ");
   16800                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   16801                     pw.print(", non-svc at ");
   16802                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   16803                     pw.println("):");
   16804             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
   16805             needSep = true;
   16806         }
   16807 
   16808         if (dumpAll || dumpPackage != null) {
   16809             synchronized (mPidsSelfLocked) {
   16810                 boolean printed = false;
   16811                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   16812                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
   16813                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   16814                         continue;
   16815                     }
   16816                     if (!printed) {
   16817                         if (needSep) pw.println();
   16818                         needSep = true;
   16819                         pw.println("  PID mappings:");
   16820                         printed = true;
   16821                     }
   16822                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
   16823                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
   16824                 }
   16825             }
   16826         }
   16827 
   16828         if (mImportantProcesses.size() > 0) {
   16829             synchronized (mPidsSelfLocked) {
   16830                 boolean printed = false;
   16831                 for (int i = 0; i< mImportantProcesses.size(); i++) {
   16832                     ProcessRecord r = mPidsSelfLocked.get(
   16833                             mImportantProcesses.valueAt(i).pid);
   16834                     if (dumpPackage != null && (r == null
   16835                             || !r.pkgList.containsKey(dumpPackage))) {
   16836                         continue;
   16837                     }
   16838                     if (!printed) {
   16839                         if (needSep) pw.println();
   16840                         needSep = true;
   16841                         pw.println("  Foreground Processes:");
   16842                         printed = true;
   16843                     }
   16844                     pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
   16845                             pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
   16846                 }
   16847             }
   16848         }
   16849 
   16850         if (mPersistentStartingProcesses.size() > 0) {
   16851             if (needSep) pw.println();
   16852             needSep = true;
   16853             pw.println("  Persisent processes that are starting:");
   16854             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
   16855                     "Starting Norm", "Restarting PERS", dumpPackage);
   16856         }
   16857 
   16858         if (mRemovedProcesses.size() > 0) {
   16859             if (needSep) pw.println();
   16860             needSep = true;
   16861             pw.println("  Processes that are being removed:");
   16862             dumpProcessList(pw, this, mRemovedProcesses, "    ",
   16863                     "Removed Norm", "Removed PERS", dumpPackage);
   16864         }
   16865 
   16866         if (mProcessesOnHold.size() > 0) {
   16867             if (needSep) pw.println();
   16868             needSep = true;
   16869             pw.println("  Processes that are on old until the system is ready:");
   16870             dumpProcessList(pw, this, mProcessesOnHold, "    ",
   16871                     "OnHold Norm", "OnHold PERS", dumpPackage);
   16872         }
   16873 
   16874         needSep = dumpProcessesToGc(pw, needSep, dumpPackage);
   16875 
   16876         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
   16877 
   16878         if (dumpPackage == null) {
   16879             pw.println();
   16880             needSep = false;
   16881             mUserController.dump(pw, dumpAll);
   16882         }
   16883         if (mHomeProcess != null && (dumpPackage == null
   16884                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
   16885             if (needSep) {
   16886                 pw.println();
   16887                 needSep = false;
   16888             }
   16889             pw.println("  mHomeProcess: " + mHomeProcess);
   16890         }
   16891         if (mPreviousProcess != null && (dumpPackage == null
   16892                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
   16893             if (needSep) {
   16894                 pw.println();
   16895                 needSep = false;
   16896             }
   16897             pw.println("  mPreviousProcess: " + mPreviousProcess);
   16898         }
   16899         if (dumpAll && (mPreviousProcess == null || dumpPackage == null
   16900                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
   16901             StringBuilder sb = new StringBuilder(128);
   16902             sb.append("  mPreviousProcessVisibleTime: ");
   16903             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
   16904             pw.println(sb);
   16905         }
   16906         if (mHeavyWeightProcess != null && (dumpPackage == null
   16907                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
   16908             if (needSep) {
   16909                 pw.println();
   16910                 needSep = false;
   16911             }
   16912             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   16913         }
   16914         if (dumpAll && mPendingStarts.size() > 0) {
   16915             if (needSep) pw.println();
   16916             needSep = true;
   16917             pw.println("  mPendingStarts: ");
   16918             for (int i = 0, len = mPendingStarts.size(); i < len; ++i ) {
   16919                 pw.println("    " + mPendingStarts.keyAt(i) + ": " + mPendingStarts.valueAt(i));
   16920             }
   16921         }
   16922         if (dumpPackage == null) {
   16923             pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
   16924             mStackSupervisor.dumpDisplayConfigs(pw, "  ");
   16925         }
   16926         if (dumpAll) {
   16927             if (dumpPackage == null) {
   16928                 pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
   16929             }
   16930             if (mCompatModePackages.getPackages().size() > 0) {
   16931                 boolean printed = false;
   16932                 for (Map.Entry<String, Integer> entry
   16933                         : mCompatModePackages.getPackages().entrySet()) {
   16934                     String pkg = entry.getKey();
   16935                     int mode = entry.getValue();
   16936                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
   16937                         continue;
   16938                     }
   16939                     if (!printed) {
   16940                         pw.println("  mScreenCompatPackages:");
   16941                         printed = true;
   16942                     }
   16943                     pw.print("    "); pw.print(pkg); pw.print(": ");
   16944                             pw.print(mode); pw.println();
   16945                 }
   16946             }
   16947             final int NI = mUidObservers.getRegisteredCallbackCount();
   16948             boolean printed = false;
   16949             for (int i=0; i<NI; i++) {
   16950                 final UidObserverRegistration reg = (UidObserverRegistration)
   16951                         mUidObservers.getRegisteredCallbackCookie(i);
   16952                 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
   16953                     if (!printed) {
   16954                         pw.println("  mUidObservers:");
   16955                         printed = true;
   16956                     }
   16957                     pw.print("    "); UserHandle.formatUid(pw, reg.uid);
   16958                     pw.print(" "); pw.print(reg.pkg); pw.print(":");
   16959                     if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
   16960                         pw.print(" IDLE");
   16961                     }
   16962                     if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
   16963                         pw.print(" ACT" );
   16964                     }
   16965                     if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
   16966                         pw.print(" GONE");
   16967                     }
   16968                     if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
   16969                         pw.print(" STATE");
   16970                         pw.print(" (cut="); pw.print(reg.cutpoint);
   16971                         pw.print(")");
   16972                     }
   16973                     pw.println();
   16974                     if (reg.lastProcStates != null) {
   16975                         final int NJ = reg.lastProcStates.size();
   16976                         for (int j=0; j<NJ; j++) {
   16977                             pw.print("      Last ");
   16978                             UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
   16979                             pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
   16980                         }
   16981                     }
   16982                 }
   16983             }
   16984             pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
   16985             pw.println("  mDeviceIdleExceptIdleWhitelist="
   16986                     + Arrays.toString(mDeviceIdleExceptIdleWhitelist));
   16987             pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
   16988             if (mPendingTempWhitelist.size() > 0) {
   16989                 pw.println("  mPendingTempWhitelist:");
   16990                 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
   16991                     PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
   16992                     pw.print("    ");
   16993                     UserHandle.formatUid(pw, ptw.targetUid);
   16994                     pw.print(": ");
   16995                     TimeUtils.formatDuration(ptw.duration, pw);
   16996                     pw.print(" ");
   16997                     pw.println(ptw.tag);
   16998                 }
   16999             }
   17000         }
   17001         if (dumpPackage == null) {
   17002             pw.println("  mWakefulness="
   17003                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
   17004             pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
   17005             pw.println("  mSleeping=" + mSleeping);
   17006             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
   17007             if (mRunningVoice != null) {
   17008                 pw.println("  mRunningVoice=" + mRunningVoice);
   17009                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
   17010             }
   17011             pw.println("  mVrController=" + mVrController);
   17012         }
   17013         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
   17014                 || mOrigWaitForDebugger) {
   17015             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
   17016                     || dumpPackage.equals(mOrigDebugApp)) {
   17017                 if (needSep) {
   17018                     pw.println();
   17019                     needSep = false;
   17020                 }
   17021                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
   17022                         + " mDebugTransient=" + mDebugTransient
   17023                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
   17024             }
   17025         }
   17026         if (mCurAppTimeTracker != null) {
   17027             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
   17028         }
   17029         if (mMemWatchProcesses.getMap().size() > 0) {
   17030             pw.println("  Mem watch processes:");
   17031             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
   17032                     = mMemWatchProcesses.getMap();
   17033             for (int i=0; i<procs.size(); i++) {
   17034                 final String proc = procs.keyAt(i);
   17035                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
   17036                 for (int j=0; j<uids.size(); j++) {
   17037                     if (needSep) {
   17038                         pw.println();
   17039                         needSep = false;
   17040                     }
   17041                     StringBuilder sb = new StringBuilder();
   17042                     sb.append("    ").append(proc).append('/');
   17043                     UserHandle.formatUid(sb, uids.keyAt(j));
   17044                     Pair<Long, String> val = uids.valueAt(j);
   17045                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
   17046                     if (val.second != null) {
   17047                         sb.append(", report to ").append(val.second);
   17048                     }
   17049                     pw.println(sb.toString());
   17050                 }
   17051             }
   17052             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
   17053             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
   17054             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
   17055                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
   17056         }
   17057         if (mTrackAllocationApp != null) {
   17058             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
   17059                 if (needSep) {
   17060                     pw.println();
   17061                     needSep = false;
   17062                 }
   17063                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
   17064             }
   17065         }
   17066         if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
   17067                 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
   17068             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
   17069                 if (needSep) {
   17070                     pw.println();
   17071                     needSep = false;
   17072                 }
   17073                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
   17074                 if (mProfilerInfo != null) {
   17075                     pw.println("  mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
   17076                             mProfilerInfo.profileFd);
   17077                     pw.println("  mSamplingInterval=" + mProfilerInfo.samplingInterval +
   17078                             " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
   17079                             " mStreamingOutput=" + mProfilerInfo.streamingOutput);
   17080                     pw.println("  mProfileType=" + mProfileType);
   17081                 }
   17082             }
   17083         }
   17084         if (mNativeDebuggingApp != null) {
   17085             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
   17086                 if (needSep) {
   17087                     pw.println();
   17088                     needSep = false;
   17089                 }
   17090                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
   17091             }
   17092         }
   17093         if (mAllowAppSwitchUids.size() > 0) {
   17094             boolean printed = false;
   17095             for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
   17096                 ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
   17097                 for (int j = 0; j < types.size(); j++) {
   17098                     if (dumpPackage == null ||
   17099                             UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
   17100                         if (needSep) {
   17101                             pw.println();
   17102                             needSep = false;
   17103                         }
   17104                         if (!printed) {
   17105                             pw.println("  mAllowAppSwitchUids:");
   17106                             printed = true;
   17107                         }
   17108                         pw.print("    User ");
   17109                         pw.print(mAllowAppSwitchUids.keyAt(i));
   17110                         pw.print(": Type ");
   17111                         pw.print(types.keyAt(j));
   17112                         pw.print(" = ");
   17113                         UserHandle.formatUid(pw, types.valueAt(j).intValue());
   17114                         pw.println();
   17115                     }
   17116                 }
   17117             }
   17118         }
   17119         if (dumpPackage == null) {
   17120             if (mAlwaysFinishActivities) {
   17121                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
   17122             }
   17123             if (mController != null) {
   17124                 pw.println("  mController=" + mController
   17125                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
   17126             }
   17127             if (dumpAll) {
   17128                 pw.println("  Total persistent processes: " + numPers);
   17129                 pw.println("  mProcessesReady=" + mProcessesReady
   17130                         + " mSystemReady=" + mSystemReady
   17131                         + " mBooted=" + mBooted
   17132                         + " mFactoryTest=" + mFactoryTest);
   17133                 pw.println("  mBooting=" + mBooting
   17134                         + " mCallFinishBooting=" + mCallFinishBooting
   17135                         + " mBootAnimationComplete=" + mBootAnimationComplete);
   17136                 pw.print("  mLastPowerCheckUptime=");
   17137                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
   17138                         pw.println("");
   17139                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
   17140                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
   17141                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
   17142                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
   17143                         + " (" + mLruProcesses.size() + " total)"
   17144                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
   17145                         + " mNumServiceProcs=" + mNumServiceProcs
   17146                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
   17147                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
   17148                         + " mLastMemoryLevel=" + mLastMemoryLevel
   17149                         + " mLastNumProcesses=" + mLastNumProcesses);
   17150                 long now = SystemClock.uptimeMillis();
   17151                 pw.print("  mLastIdleTime=");
   17152                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
   17153                         pw.print(" mLowRamSinceLastIdle=");
   17154                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
   17155                         pw.println();
   17156                 pw.println();
   17157                 pw.print("  mUidChangeDispatchCount=");
   17158                 pw.print(mUidChangeDispatchCount);
   17159                 pw.println();
   17160 
   17161                 pw.println("  Slow UID dispatches:");
   17162                 final int N = mUidObservers.beginBroadcast();
   17163                 for (int i = 0; i < N; i++) {
   17164                     UidObserverRegistration r =
   17165                             (UidObserverRegistration) mUidObservers.getBroadcastCookie(i);
   17166                     pw.print("    ");
   17167                     pw.print(mUidObservers.getBroadcastItem(i).getClass().getTypeName());
   17168                     pw.print(": ");
   17169                     pw.print(r.mSlowDispatchCount);
   17170                     pw.print(" / Max ");
   17171                     pw.print(r.mMaxDispatchTime);
   17172                     pw.println("ms");
   17173                 }
   17174                 mUidObservers.finishBroadcast();
   17175 
   17176                 pw.println();
   17177                 pw.println("  ServiceManager statistics:");
   17178                 ServiceManager.sStatLogger.dump(pw, "    ");
   17179                 pw.println();
   17180             }
   17181         }
   17182         pw.println("  mForceBackgroundCheck=" + mForceBackgroundCheck);
   17183     }
   17184 
   17185     @GuardedBy("this")
   17186     void writeProcessesToProtoLocked(ProtoOutputStream proto, String dumpPackage) {
   17187         int numPers = 0;
   17188 
   17189         final int NP = mProcessNames.getMap().size();
   17190         for (int ip=0; ip<NP; ip++) {
   17191             SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
   17192             final int NA = procs.size();
   17193             for (int ia = 0; ia<NA; ia++) {
   17194                 ProcessRecord r = procs.valueAt(ia);
   17195                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   17196                     continue;
   17197                 }
   17198                 r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PROCS);
   17199                 if (r.persistent) {
   17200                     numPers++;
   17201                 }
   17202             }
   17203         }
   17204 
   17205         for (int i=0; i<mIsolatedProcesses.size(); i++) {
   17206             ProcessRecord r = mIsolatedProcesses.valueAt(i);
   17207             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   17208                 continue;
   17209             }
   17210             r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ISOLATED_PROCS);
   17211         }
   17212 
   17213         for (int i=0; i<mActiveInstrumentation.size(); i++) {
   17214             ActiveInstrumentation ai = mActiveInstrumentation.get(i);
   17215             if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
   17216                     && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
   17217                 continue;
   17218             }
   17219             ai.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_INSTRUMENTATIONS);
   17220         }
   17221 
   17222         int whichAppId = getAppId(dumpPackage);
   17223         for (int i=0; i<mActiveUids.size(); i++) {
   17224             UidRecord uidRec = mActiveUids.valueAt(i);
   17225             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
   17226                 continue;
   17227             }
   17228             uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_UIDS);
   17229         }
   17230 
   17231         for (int i=0; i<mValidateUids.size(); i++) {
   17232             UidRecord uidRec = mValidateUids.valueAt(i);
   17233             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
   17234                 continue;
   17235             }
   17236             uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VALIDATE_UIDS);
   17237         }
   17238 
   17239         if (mLruProcesses.size() > 0) {
   17240             long lruToken = proto.start(ActivityManagerServiceDumpProcessesProto.LRU_PROCS);
   17241             int total = mLruProcesses.size();
   17242             proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.SIZE, total);
   17243             proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_ACT_AT, total-mLruProcessActivityStart);
   17244             proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_SVC_AT, total-mLruProcessServiceStart);
   17245             writeProcessOomListToProto(proto, ActivityManagerServiceDumpProcessesProto.LruProcesses.LIST, this,
   17246                     mLruProcesses,false, dumpPackage);
   17247             proto.end(lruToken);
   17248         }
   17249 
   17250         if (dumpPackage != null) {
   17251             synchronized (mPidsSelfLocked) {
   17252                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   17253                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
   17254                     if (!r.pkgList.containsKey(dumpPackage)) {
   17255                         continue;
   17256                     }
   17257                     r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PIDS_SELF_LOCKED);
   17258                 }
   17259             }
   17260         }
   17261 
   17262         if (mImportantProcesses.size() > 0) {
   17263             synchronized (mPidsSelfLocked) {
   17264                 for (int i=0; i<mImportantProcesses.size(); i++) {
   17265                     ImportanceToken it = mImportantProcesses.valueAt(i);
   17266                     ProcessRecord r = mPidsSelfLocked.get(it.pid);
   17267                     if (dumpPackage != null && (r == null
   17268                             || !r.pkgList.containsKey(dumpPackage))) {
   17269                         continue;
   17270                     }
   17271                     it.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.IMPORTANT_PROCS);
   17272                 }
   17273             }
   17274         }
   17275 
   17276         for (int i=0; i<mPersistentStartingProcesses.size(); i++) {
   17277             ProcessRecord r = mPersistentStartingProcesses.get(i);
   17278             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   17279                 continue;
   17280             }
   17281             r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PERSISTENT_STARTING_PROCS);
   17282         }
   17283 
   17284         for (int i=0; i<mRemovedProcesses.size(); i++) {
   17285             ProcessRecord r = mRemovedProcesses.get(i);
   17286             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   17287                 continue;
   17288             }
   17289             r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.REMOVED_PROCS);
   17290         }
   17291 
   17292         for (int i=0; i<mProcessesOnHold.size(); i++) {
   17293             ProcessRecord r = mProcessesOnHold.get(i);
   17294             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   17295                 continue;
   17296             }
   17297             r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ON_HOLD_PROCS);
   17298         }
   17299 
   17300         writeProcessesToGcToProto(proto, ActivityManagerServiceDumpProcessesProto.GC_PROCS, dumpPackage);
   17301         mAppErrors.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.APP_ERRORS, dumpPackage);
   17302 
   17303         if (dumpPackage == null) {
   17304             mUserController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.USER_CONTROLLER);
   17305             getGlobalConfiguration().writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GLOBAL_CONFIGURATION);
   17306             proto.write(ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE, getFocusedStack().mConfigWillChange);
   17307         }
   17308 
   17309         if (mHomeProcess != null && (dumpPackage == null
   17310                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
   17311             mHomeProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HOME_PROC);
   17312         }
   17313 
   17314         if (mPreviousProcess != null && (dumpPackage == null
   17315                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
   17316             mPreviousProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC);
   17317             proto.write(ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
   17318         }
   17319 
   17320         if (mHeavyWeightProcess != null && (dumpPackage == null
   17321                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
   17322             mHeavyWeightProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HEAVY_WEIGHT_PROC);
   17323         }
   17324 
   17325         for (Map.Entry<String, Integer> entry : mCompatModePackages.getPackages().entrySet()) {
   17326             String pkg = entry.getKey();
   17327             int mode = entry.getValue();
   17328             if (dumpPackage == null || dumpPackage.equals(pkg)) {
   17329                 long compatToken = proto.start(ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES);
   17330                 proto.write(ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.PACKAGE, pkg);
   17331                 proto.write(ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.MODE, mode);
   17332                 proto.end(compatToken);
   17333             }
   17334         }
   17335 
   17336         final int NI = mUidObservers.getRegisteredCallbackCount();
   17337         for (int i=0; i<NI; i++) {
   17338             final UidObserverRegistration reg = (UidObserverRegistration)
   17339                     mUidObservers.getRegisteredCallbackCookie(i);
   17340             if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
   17341                 reg.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.UID_OBSERVERS);
   17342             }
   17343         }
   17344 
   17345         for (int v : mDeviceIdleWhitelist) {
   17346             proto.write(ActivityManagerServiceDumpProcessesProto.DEVICE_IDLE_WHITELIST, v);
   17347         }
   17348 
   17349         for (int v : mDeviceIdleTempWhitelist) {
   17350             proto.write(ActivityManagerServiceDumpProcessesProto.DEVICE_IDLE_TEMP_WHITELIST, v);
   17351         }
   17352 
   17353         if (mPendingTempWhitelist.size() > 0) {
   17354             for (int i=0; i < mPendingTempWhitelist.size(); i++) {
   17355                 mPendingTempWhitelist.valueAt(i).writeToProto(proto,
   17356                         ActivityManagerServiceDumpProcessesProto.PENDING_TEMP_WHITELIST);
   17357             }
   17358         }
   17359 
   17360         if (dumpPackage == null) {
   17361             final long sleepToken = proto.start(ActivityManagerServiceDumpProcessesProto.SLEEP_STATUS);
   17362             proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.WAKEFULNESS,
   17363                     PowerManagerInternal.wakefulnessToProtoEnum(mWakefulness));
   17364             for (SleepToken st : mStackSupervisor.mSleepTokens) {
   17365                 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS, st.toString());
   17366             }
   17367             proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
   17368             proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN, mShuttingDown);
   17369             proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.TEST_PSS_MODE, mTestPssMode);
   17370             proto.end(sleepToken);
   17371 
   17372             if (mRunningVoice != null) {
   17373                 final long vrToken = proto.start(ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
   17374                 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION, mRunningVoice.toString());
   17375                 mVoiceWakeLock.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
   17376                 proto.end(vrToken);
   17377             }
   17378 
   17379             mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
   17380         }
   17381 
   17382         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
   17383                 || mOrigWaitForDebugger) {
   17384             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
   17385                     || dumpPackage.equals(mOrigDebugApp)) {
   17386                 final long debugAppToken = proto.start(ActivityManagerServiceDumpProcessesProto.DEBUG);
   17387                 proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.DEBUG_APP, mDebugApp);
   17388                 proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.ORIG_DEBUG_APP, mOrigDebugApp);
   17389                 proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.DEBUG_TRANSIENT, mDebugTransient);
   17390                 proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.ORIG_WAIT_FOR_DEBUGGER, mOrigWaitForDebugger);
   17391                 proto.end(debugAppToken);
   17392             }
   17393         }
   17394 
   17395         if (mCurAppTimeTracker != null) {
   17396             mCurAppTimeTracker.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.CURRENT_TRACKER, true);
   17397         }
   17398 
   17399         if (mMemWatchProcesses.getMap().size() > 0) {
   17400             final long token = proto.start(ActivityManagerServiceDumpProcessesProto.MEM_WATCH_PROCESSES);
   17401             ArrayMap<String, SparseArray<Pair<Long, String>>> procs = mMemWatchProcesses.getMap();
   17402             for (int i=0; i<procs.size(); i++) {
   17403                 final String proc = procs.keyAt(i);
   17404                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
   17405                 final long ptoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.PROCS);
   17406                 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.NAME, proc);
   17407                 for (int j=0; j<uids.size(); j++) {
   17408                     final long utoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MEM_STATS);
   17409                     Pair<Long, String> val = uids.valueAt(j);
   17410                     proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.UID, uids.keyAt(j));
   17411                     proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.SIZE,
   17412                             DebugUtils.sizeValueToString(val.first, new StringBuilder()));
   17413                     proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.REPORT_TO, val.second);
   17414                     proto.end(utoken);
   17415                 }
   17416                 proto.end(ptoken);
   17417             }
   17418 
   17419             final long dtoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.DUMP);
   17420             proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PROC_NAME, mMemWatchDumpProcName);
   17421             proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.FILE, mMemWatchDumpFile);
   17422             proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PID, mMemWatchDumpPid);
   17423             proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.UID, mMemWatchDumpUid);
   17424             proto.end(dtoken);
   17425 
   17426             proto.end(token);
   17427         }
   17428 
   17429         if (mTrackAllocationApp != null) {
   17430             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
   17431                 proto.write(ActivityManagerServiceDumpProcessesProto.TRACK_ALLOCATION_APP, mTrackAllocationApp);
   17432             }
   17433         }
   17434 
   17435         if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
   17436                 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
   17437             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
   17438                 final long token = proto.start(ActivityManagerServiceDumpProcessesProto.PROFILE);
   17439                 proto.write(ActivityManagerServiceDumpProcessesProto.Profile.APP_NAME, mProfileApp);
   17440                 mProfileProc.writeToProto(proto,ActivityManagerServiceDumpProcessesProto.Profile.PROC);
   17441                 if (mProfilerInfo != null) {
   17442                     mProfilerInfo.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.Profile.INFO);
   17443                     proto.write(ActivityManagerServiceDumpProcessesProto.Profile.TYPE, mProfileType);
   17444                 }
   17445                 proto.end(token);
   17446             }
   17447         }
   17448 
   17449         if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
   17450             proto.write(ActivityManagerServiceDumpProcessesProto.NATIVE_DEBUGGING_APP, mNativeDebuggingApp);
   17451         }
   17452 
   17453         if (dumpPackage == null) {
   17454             proto.write(ActivityManagerServiceDumpProcessesProto.ALWAYS_FINISH_ACTIVITIES, mAlwaysFinishActivities);
   17455             if (mController != null) {
   17456                 final long token = proto.start(ActivityManagerServiceDumpProcessesProto.CONTROLLER);
   17457                 proto.write(ActivityManagerServiceDumpProcessesProto.Controller.CONTROLLER, mController.toString());
   17458                 proto.write(ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY, mControllerIsAMonkey);
   17459                 proto.end(token);
   17460             }
   17461             proto.write(ActivityManagerServiceDumpProcessesProto.TOTAL_PERSISTENT_PROCS, numPers);
   17462             proto.write(ActivityManagerServiceDumpProcessesProto.PROCESSES_READY, mProcessesReady);
   17463             proto.write(ActivityManagerServiceDumpProcessesProto.SYSTEM_READY, mSystemReady);
   17464             proto.write(ActivityManagerServiceDumpProcessesProto.BOOTED, mBooted);
   17465             proto.write(ActivityManagerServiceDumpProcessesProto.FACTORY_TEST, mFactoryTest);
   17466             proto.write(ActivityManagerServiceDumpProcessesProto.BOOTING, mBooting);
   17467             proto.write(ActivityManagerServiceDumpProcessesProto.CALL_FINISH_BOOTING, mCallFinishBooting);
   17468             proto.write(ActivityManagerServiceDumpProcessesProto.BOOT_ANIMATION_COMPLETE, mBootAnimationComplete);
   17469             proto.write(ActivityManagerServiceDumpProcessesProto.LAST_POWER_CHECK_UPTIME_MS, mLastPowerCheckUptime);
   17470             mStackSupervisor.mGoingToSleep.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GOING_TO_SLEEP);
   17471             mStackSupervisor.mLaunchingActivity.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.LAUNCHING_ACTIVITY);
   17472             proto.write(ActivityManagerServiceDumpProcessesProto.ADJ_SEQ, mAdjSeq);
   17473             proto.write(ActivityManagerServiceDumpProcessesProto.LRU_SEQ, mLruSeq);
   17474             proto.write(ActivityManagerServiceDumpProcessesProto.NUM_NON_CACHED_PROCS, mNumNonCachedProcs);
   17475             proto.write(ActivityManagerServiceDumpProcessesProto.NUM_SERVICE_PROCS, mNumServiceProcs);
   17476             proto.write(ActivityManagerServiceDumpProcessesProto.NEW_NUM_SERVICE_PROCS, mNewNumServiceProcs);
   17477             proto.write(ActivityManagerServiceDumpProcessesProto.ALLOW_LOWER_MEM_LEVEL, mAllowLowerMemLevel);
   17478             proto.write(ActivityManagerServiceDumpProcessesProto.LAST_MEMORY_LEVEL, mLastMemoryLevel);
   17479             proto.write(ActivityManagerServiceDumpProcessesProto.LAST_NUM_PROCESSES, mLastNumProcesses);
   17480             long now = SystemClock.uptimeMillis();
   17481             ProtoUtils.toDuration(proto, ActivityManagerServiceDumpProcessesProto.LAST_IDLE_TIME, mLastIdleTime, now);
   17482             proto.write(ActivityManagerServiceDumpProcessesProto.LOW_RAM_SINCE_LAST_IDLE_MS, getLowRamTimeSinceIdle(now));
   17483         }
   17484 
   17485     }
   17486 
   17487     void writeProcessesToGcToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) {
   17488         if (mProcessesToGc.size() > 0) {
   17489             long now = SystemClock.uptimeMillis();
   17490             for (int i=0; i<mProcessesToGc.size(); i++) {
   17491                 ProcessRecord r = mProcessesToGc.get(i);
   17492                 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   17493                     continue;
   17494                 }
   17495                 final long token = proto.start(fieldId);
   17496                 r.writeToProto(proto, ProcessToGcProto.PROC);
   17497                 proto.write(ProcessToGcProto.REPORT_LOW_MEMORY, r.reportLowMemory);
   17498                 proto.write(ProcessToGcProto.NOW_UPTIME_MS, now);
   17499                 proto.write(ProcessToGcProto.LAST_GCED_MS, r.lastRequestedGc);
   17500                 proto.write(ProcessToGcProto.LAST_LOW_MEMORY_MS, r.lastLowMemory);
   17501                 proto.end(token);
   17502             }
   17503         }
   17504     }
   17505 
   17506     boolean dumpProcessesToGc(PrintWriter pw, boolean needSep, String dumpPackage) {
   17507         if (mProcessesToGc.size() > 0) {
   17508             boolean printed = false;
   17509             long now = SystemClock.uptimeMillis();
   17510             for (int i=0; i<mProcessesToGc.size(); i++) {
   17511                 ProcessRecord proc = mProcessesToGc.get(i);
   17512                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
   17513                     continue;
   17514                 }
   17515                 if (!printed) {
   17516                     if (needSep) pw.println();
   17517                     needSep = true;
   17518                     pw.println("  Processes that are waiting to GC:");
   17519                     printed = true;
   17520                 }
   17521                 pw.print("    Process "); pw.println(proc);
   17522                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
   17523                         pw.print(", last gced=");
   17524                         pw.print(now-proc.lastRequestedGc);
   17525                         pw.print(" ms ago, last lowMem=");
   17526                         pw.print(now-proc.lastLowMemory);
   17527                         pw.println(" ms ago");
   17528 
   17529             }
   17530         }
   17531         return needSep;
   17532     }
   17533 
   17534     void printOomLevel(PrintWriter pw, String name, int adj) {
   17535         pw.print("    ");
   17536         if (adj >= 0) {
   17537             pw.print(' ');
   17538             if (adj < 10) pw.print(' ');
   17539         } else {
   17540             if (adj > -10) pw.print(' ');
   17541         }
   17542         pw.print(adj);
   17543         pw.print(": ");
   17544         pw.print(name);
   17545         pw.print(" (");
   17546         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
   17547         pw.println(")");
   17548     }
   17549 
   17550     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   17551             int opti, boolean dumpAll) {
   17552         boolean needSep = false;
   17553 
   17554         if (mLruProcesses.size() > 0) {
   17555             if (needSep) pw.println();
   17556             needSep = true;
   17557             pw.println("  OOM levels:");
   17558             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
   17559             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
   17560             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
   17561             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
   17562             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
   17563             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
   17564             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
   17565             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
   17566             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
   17567             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
   17568             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
   17569             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
   17570             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
   17571             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
   17572 
   17573             if (needSep) pw.println();
   17574             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
   17575                     pw.print(" total, non-act at ");
   17576                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   17577                     pw.print(", non-svc at ");
   17578                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   17579                     pw.println("):");
   17580             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
   17581             needSep = true;
   17582         }
   17583 
   17584         dumpProcessesToGc(pw, needSep, null);
   17585 
   17586         pw.println();
   17587         pw.println("  mHomeProcess: " + mHomeProcess);
   17588         pw.println("  mPreviousProcess: " + mPreviousProcess);
   17589         if (mHeavyWeightProcess != null) {
   17590             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   17591         }
   17592 
   17593         return true;
   17594     }
   17595 
   17596     /**
   17597      * There are three ways to call this:
   17598      *  - no provider specified: dump all the providers
   17599      *  - a flattened component name that matched an existing provider was specified as the
   17600      *    first arg: dump that one provider
   17601      *  - the first arg isn't the flattened component name of an existing provider:
   17602      *    dump all providers whose component contains the first arg as a substring
   17603      */
   17604     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   17605             int opti, boolean dumpAll) {
   17606         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
   17607     }
   17608 
   17609     /**
   17610      * Similar to the dumpProvider, but only dumps the first matching provider.
   17611      * The provider is responsible for dumping as proto.
   17612      */
   17613     protected boolean dumpProviderProto(FileDescriptor fd, PrintWriter pw, String name,
   17614             String[] args) {
   17615         return mProviderMap.dumpProviderProto(fd, pw, name, args);
   17616     }
   17617 
   17618     static class ItemMatcher {
   17619         ArrayList<ComponentName> components;
   17620         ArrayList<String> strings;
   17621         ArrayList<Integer> objects;
   17622         boolean all;
   17623 
   17624         ItemMatcher() {
   17625             all = true;
   17626         }
   17627 
   17628         void build(String name) {
   17629             ComponentName componentName = ComponentName.unflattenFromString(name);
   17630             if (componentName != null) {
   17631                 if (components == null) {
   17632                     components = new ArrayList<ComponentName>();
   17633                 }
   17634                 components.add(componentName);
   17635                 all = false;
   17636             } else {
   17637                 int objectId = 0;
   17638                 // Not a '/' separated full component name; maybe an object ID?
   17639                 try {
   17640                     objectId = Integer.parseInt(name, 16);
   17641                     if (objects == null) {
   17642                         objects = new ArrayList<Integer>();
   17643                     }
   17644                     objects.add(objectId);
   17645                     all = false;
   17646                 } catch (RuntimeException e) {
   17647                     // Not an integer; just do string match.
   17648                     if (strings == null) {
   17649                         strings = new ArrayList<String>();
   17650                     }
   17651                     strings.add(name);
   17652                     all = false;
   17653                 }
   17654             }
   17655         }
   17656 
   17657         int build(String[] args, int opti) {
   17658             for (; opti<args.length; opti++) {
   17659                 String name = args[opti];
   17660                 if ("--".equals(name)) {
   17661                     return opti+1;
   17662                 }
   17663                 build(name);
   17664             }
   17665             return opti;
   17666         }
   17667 
   17668         boolean match(Object object, ComponentName comp) {
   17669             if (all) {
   17670                 return true;
   17671             }
   17672             if (components != null) {
   17673                 for (int i=0; i<components.size(); i++) {
   17674                     if (components.get(i).equals(comp)) {
   17675                         return true;
   17676                     }
   17677                 }
   17678             }
   17679             if (objects != null) {
   17680                 for (int i=0; i<objects.size(); i++) {
   17681                     if (System.identityHashCode(object) == objects.get(i)) {
   17682                         return true;
   17683                     }
   17684                 }
   17685             }
   17686             if (strings != null) {
   17687                 String flat = comp.flattenToString();
   17688                 for (int i=0; i<strings.size(); i++) {
   17689                     if (flat.contains(strings.get(i))) {
   17690                         return true;
   17691                     }
   17692                 }
   17693             }
   17694             return false;
   17695         }
   17696     }
   17697 
   17698     /**
   17699      * There are three things that cmd can be:
   17700      *  - a flattened component name that matches an existing activity
   17701      *  - the cmd arg isn't the flattened component name of an existing activity:
   17702      *    dump all activity whose component contains the cmd as a substring
   17703      *  - A hex number of the ActivityRecord object instance.
   17704      *
   17705      *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
   17706      *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
   17707      */
   17708     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   17709             int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
   17710         ArrayList<ActivityRecord> activities;
   17711 
   17712         synchronized (this) {
   17713             activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
   17714                     dumpFocusedStackOnly);
   17715         }
   17716 
   17717         if (activities.size() <= 0) {
   17718             return false;
   17719         }
   17720 
   17721         String[] newArgs = new String[args.length - opti];
   17722         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   17723 
   17724         TaskRecord lastTask = null;
   17725         boolean needSep = false;
   17726         for (int i=activities.size()-1; i>=0; i--) {
   17727             ActivityRecord r = activities.get(i);
   17728             if (needSep) {
   17729                 pw.println();
   17730             }
   17731             needSep = true;
   17732             synchronized (this) {
   17733                 final TaskRecord task = r.getTask();
   17734                 if (lastTask != task) {
   17735                     lastTask = task;
   17736                     pw.print("TASK "); pw.print(lastTask.affinity);
   17737                             pw.print(" id="); pw.print(lastTask.taskId);
   17738                             pw.print(" userId="); pw.println(lastTask.userId);
   17739                     if (dumpAll) {
   17740                         lastTask.dump(pw, "  ");
   17741                     }
   17742                 }
   17743             }
   17744             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
   17745         }
   17746         return true;
   17747     }
   17748 
   17749     /**
   17750      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
   17751      * there is a thread associated with the activity.
   17752      */
   17753     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
   17754             final ActivityRecord r, String[] args, boolean dumpAll) {
   17755         String innerPrefix = prefix + "  ";
   17756         synchronized (this) {
   17757             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
   17758                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
   17759                     pw.print(" pid=");
   17760                     if (r.app != null) pw.println(r.app.pid);
   17761                     else pw.println("(not running)");
   17762             if (dumpAll) {
   17763                 r.dump(pw, innerPrefix);
   17764             }
   17765         }
   17766         if (r.app != null && r.app.thread != null) {
   17767             // flush anything that is already in the PrintWriter since the thread is going
   17768             // to write to the file descriptor directly
   17769             pw.flush();
   17770             try {
   17771                 TransferPipe tp = new TransferPipe();
   17772                 try {
   17773                     r.app.thread.dumpActivity(tp.getWriteFd(),
   17774                             r.appToken, innerPrefix, args);
   17775                     tp.go(fd);
   17776                 } finally {
   17777                     tp.kill();
   17778                 }
   17779             } catch (IOException e) {
   17780                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   17781             } catch (RemoteException e) {
   17782                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   17783             }
   17784         }
   17785     }
   17786 
   17787     void writeBroadcastsToProtoLocked(ProtoOutputStream proto) {
   17788         if (mRegisteredReceivers.size() > 0) {
   17789             Iterator it = mRegisteredReceivers.values().iterator();
   17790             while (it.hasNext()) {
   17791                 ReceiverList r = (ReceiverList)it.next();
   17792                 r.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_LIST);
   17793             }
   17794         }
   17795         mReceiverResolver.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_RESOLVER);
   17796         for (BroadcastQueue q : mBroadcastQueues) {
   17797             q.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.BROADCAST_QUEUE);
   17798         }
   17799         for (int user=0; user<mStickyBroadcasts.size(); user++) {
   17800             long token = proto.start(ActivityManagerServiceDumpBroadcastsProto.STICKY_BROADCASTS);
   17801             proto.write(StickyBroadcastProto.USER, mStickyBroadcasts.keyAt(user));
   17802             for (Map.Entry<String, ArrayList<Intent>> ent
   17803                     : mStickyBroadcasts.valueAt(user).entrySet()) {
   17804                 long actionToken = proto.start(StickyBroadcastProto.ACTIONS);
   17805                 proto.write(StickyBroadcastProto.StickyAction.NAME, ent.getKey());
   17806                 for (Intent intent : ent.getValue()) {
   17807                     intent.writeToProto(proto, StickyBroadcastProto.StickyAction.INTENTS,
   17808                             false, true, true, false);
   17809                 }
   17810                 proto.end(actionToken);
   17811             }
   17812             proto.end(token);
   17813         }
   17814 
   17815         long handlerToken = proto.start(ActivityManagerServiceDumpBroadcastsProto.HANDLER);
   17816         proto.write(ActivityManagerServiceDumpBroadcastsProto.MainHandler.HANDLER, mHandler.toString());
   17817         mHandler.getLooper().writeToProto(proto,
   17818             ActivityManagerServiceDumpBroadcastsProto.MainHandler.LOOPER);
   17819         proto.end(handlerToken);
   17820     }
   17821 
   17822     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   17823             int opti, boolean dumpAll, String dumpPackage) {
   17824         boolean needSep = false;
   17825         boolean onlyHistory = false;
   17826         boolean printedAnything = false;
   17827 
   17828         if ("history".equals(dumpPackage)) {
   17829             if (opti < args.length && "-s".equals(args[opti])) {
   17830                 dumpAll = false;
   17831             }
   17832             onlyHistory = true;
   17833             dumpPackage = null;
   17834         }
   17835 
   17836         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
   17837         if (!onlyHistory && dumpAll) {
   17838             if (mRegisteredReceivers.size() > 0) {
   17839                 boolean printed = false;
   17840                 Iterator it = mRegisteredReceivers.values().iterator();
   17841                 while (it.hasNext()) {
   17842                     ReceiverList r = (ReceiverList)it.next();
   17843                     if (dumpPackage != null && (r.app == null ||
   17844                             !dumpPackage.equals(r.app.info.packageName))) {
   17845                         continue;
   17846                     }
   17847                     if (!printed) {
   17848                         pw.println("  Registered Receivers:");
   17849                         needSep = true;
   17850                         printed = true;
   17851                         printedAnything = true;
   17852                     }
   17853                     pw.print("  * "); pw.println(r);
   17854                     r.dump(pw, "    ");
   17855                 }
   17856             }
   17857 
   17858             if (mReceiverResolver.dump(pw, needSep ?
   17859                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
   17860                     "    ", dumpPackage, false, false)) {
   17861                 needSep = true;
   17862                 printedAnything = true;
   17863             }
   17864         }
   17865 
   17866         for (BroadcastQueue q : mBroadcastQueues) {
   17867             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
   17868             printedAnything |= needSep;
   17869         }
   17870 
   17871         needSep = true;
   17872 
   17873         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
   17874             for (int user=0; user<mStickyBroadcasts.size(); user++) {
   17875                 if (needSep) {
   17876                     pw.println();
   17877                 }
   17878                 needSep = true;
   17879                 printedAnything = true;
   17880                 pw.print("  Sticky broadcasts for user ");
   17881                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
   17882                 StringBuilder sb = new StringBuilder(128);
   17883                 for (Map.Entry<String, ArrayList<Intent>> ent
   17884                         : mStickyBroadcasts.valueAt(user).entrySet()) {
   17885                     pw.print("  * Sticky action "); pw.print(ent.getKey());
   17886                     if (dumpAll) {
   17887                         pw.println(":");
   17888                         ArrayList<Intent> intents = ent.getValue();
   17889                         final int N = intents.size();
   17890                         for (int i=0; i<N; i++) {
   17891                             sb.setLength(0);
   17892                             sb.append("    Intent: ");
   17893                             intents.get(i).toShortString(sb, false, true, false, false);
   17894                             pw.println(sb.toString());
   17895                             Bundle bundle = intents.get(i).getExtras();
   17896                             if (bundle != null) {
   17897                                 pw.print("      ");
   17898                                 pw.println(bundle.toString());
   17899                             }
   17900                         }
   17901                     } else {
   17902                         pw.println("");
   17903                     }
   17904                 }
   17905             }
   17906         }
   17907 
   17908         if (!onlyHistory && dumpAll) {
   17909             pw.println();
   17910             for (BroadcastQueue queue : mBroadcastQueues) {
   17911                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
   17912                         + queue.mBroadcastsScheduled);
   17913             }
   17914             pw.println("  mHandler:");
   17915             mHandler.dump(new PrintWriterPrinter(pw), "    ");
   17916             needSep = true;
   17917             printedAnything = true;
   17918         }
   17919 
   17920         if (!printedAnything) {
   17921             pw.println("  (nothing)");
   17922         }
   17923     }
   17924 
   17925     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   17926             int opti, boolean dumpAll, String dumpPackage) {
   17927         if (mCurBroadcastStats == null) {
   17928             return;
   17929         }
   17930 
   17931         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
   17932         final long now = SystemClock.elapsedRealtime();
   17933         if (mLastBroadcastStats != null) {
   17934             pw.print("  Last stats (from ");
   17935             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
   17936             pw.print(" to ");
   17937             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
   17938             pw.print(", ");
   17939             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
   17940                     - mLastBroadcastStats.mStartUptime, pw);
   17941             pw.println(" uptime):");
   17942             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
   17943                 pw.println("    (nothing)");
   17944             }
   17945             pw.println();
   17946         }
   17947         pw.print("  Current stats (from ");
   17948         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
   17949         pw.print(" to now, ");
   17950         TimeUtils.formatDuration(SystemClock.uptimeMillis()
   17951                 - mCurBroadcastStats.mStartUptime, pw);
   17952         pw.println(" uptime):");
   17953         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
   17954             pw.println("    (nothing)");
   17955         }
   17956     }
   17957 
   17958     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   17959             int opti, boolean fullCheckin, String dumpPackage) {
   17960         if (mCurBroadcastStats == null) {
   17961             return;
   17962         }
   17963 
   17964         if (mLastBroadcastStats != null) {
   17965             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
   17966             if (fullCheckin) {
   17967                 mLastBroadcastStats = null;
   17968                 return;
   17969             }
   17970         }
   17971         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
   17972         if (fullCheckin) {
   17973             mCurBroadcastStats = null;
   17974         }
   17975     }
   17976 
   17977     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   17978             int opti, boolean dumpAll, String dumpPackage) {
   17979         boolean needSep;
   17980         boolean printedAnything = false;
   17981 
   17982         ItemMatcher matcher = new ItemMatcher();
   17983         matcher.build(args, opti);
   17984 
   17985         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
   17986 
   17987         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
   17988         printedAnything |= needSep;
   17989 
   17990         if (mLaunchingProviders.size() > 0) {
   17991             boolean printed = false;
   17992             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
   17993                 ContentProviderRecord r = mLaunchingProviders.get(i);
   17994                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
   17995                     continue;
   17996                 }
   17997                 if (!printed) {
   17998                     if (needSep) pw.println();
   17999                     needSep = true;
   18000                     pw.println("  Launching content providers:");
   18001                     printed = true;
   18002                     printedAnything = true;
   18003                 }
   18004                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
   18005                         pw.println(r);
   18006             }
   18007         }
   18008 
   18009         if (!printedAnything) {
   18010             pw.println("  (nothing)");
   18011         }
   18012     }
   18013 
   18014     @GuardedBy("this")
   18015     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   18016             int opti, boolean dumpAll, String dumpPackage) {
   18017         boolean needSep = false;
   18018         boolean printedAnything = false;
   18019 
   18020         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
   18021 
   18022         if (mGrantedUriPermissions.size() > 0) {
   18023             boolean printed = false;
   18024             int dumpUid = -2;
   18025             if (dumpPackage != null) {
   18026                 try {
   18027                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
   18028                             MATCH_ANY_USER, 0);
   18029                 } catch (NameNotFoundException e) {
   18030                     dumpUid = -1;
   18031                 }
   18032             }
   18033             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
   18034                 int uid = mGrantedUriPermissions.keyAt(i);
   18035                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
   18036                     continue;
   18037                 }
   18038                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   18039                 if (!printed) {
   18040                     if (needSep) pw.println();
   18041                     needSep = true;
   18042                     pw.println("  Granted Uri Permissions:");
   18043                     printed = true;
   18044                     printedAnything = true;
   18045                 }
   18046                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
   18047                 for (UriPermission perm : perms.values()) {
   18048                     pw.print("    "); pw.println(perm);
   18049                     if (dumpAll) {
   18050                         perm.dump(pw, "      ");
   18051                     }
   18052                 }
   18053             }
   18054         }
   18055 
   18056         if (!printedAnything) {
   18057             pw.println("  (nothing)");
   18058         }
   18059     }
   18060 
   18061     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   18062             int opti, boolean dumpAll, String dumpPackage) {
   18063         boolean printed = false;
   18064 
   18065         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
   18066 
   18067         if (mIntentSenderRecords.size() > 0) {
   18068             // Organize these by package name, so they are easier to read.
   18069             final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
   18070             final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
   18071             final Iterator<WeakReference<PendingIntentRecord>> it
   18072                     = mIntentSenderRecords.values().iterator();
   18073             while (it.hasNext()) {
   18074                 WeakReference<PendingIntentRecord> ref = it.next();
   18075                 PendingIntentRecord rec = ref != null ? ref.get() : null;
   18076                 if (rec == null) {
   18077                     weakRefs.add(ref);
   18078                     continue;
   18079                 }
   18080                 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
   18081                     continue;
   18082                 }
   18083                 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
   18084                 if (list == null) {
   18085                     list = new ArrayList<>();
   18086                     byPackage.put(rec.key.packageName, list);
   18087                 }
   18088                 list.add(rec);
   18089             }
   18090             for (int i = 0; i < byPackage.size(); i++) {
   18091                 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
   18092                 printed = true;
   18093                 pw.print("  * "); pw.print(byPackage.keyAt(i));
   18094                 pw.print(": "); pw.print(intents.size()); pw.println(" items");
   18095                 for (int j = 0; j < intents.size(); j++) {
   18096                     pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
   18097                     if (dumpAll) {
   18098                         intents.get(j).dump(pw, "      ");
   18099                     }
   18100                 }
   18101             }
   18102             if (weakRefs.size() > 0) {
   18103                 printed = true;
   18104                 pw.println("  * WEAK REFS:");
   18105                 for (int i = 0; i < weakRefs.size(); i++) {
   18106                     pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
   18107                 }
   18108             }
   18109         }
   18110 
   18111         if (!printed) {
   18112             pw.println("  (nothing)");
   18113         }
   18114     }
   18115 
   18116     private static final int dumpProcessList(PrintWriter pw,
   18117             ActivityManagerService service, List list,
   18118             String prefix, String normalLabel, String persistentLabel,
   18119             String dumpPackage) {
   18120         int numPers = 0;
   18121         final int N = list.size()-1;
   18122         for (int i=N; i>=0; i--) {
   18123             ProcessRecord r = (ProcessRecord)list.get(i);
   18124             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   18125                 continue;
   18126             }
   18127             pw.println(String.format("%s%s #%2d: %s",
   18128                     prefix, (r.persistent ? persistentLabel : normalLabel),
   18129                     i, r.toString()));
   18130             if (r.persistent) {
   18131                 numPers++;
   18132             }
   18133         }
   18134         return numPers;
   18135     }
   18136 
   18137     private static final ArrayList<Pair<ProcessRecord, Integer>>
   18138         sortProcessOomList(List<ProcessRecord> origList, String dumpPackage) {
   18139         ArrayList<Pair<ProcessRecord, Integer>> list
   18140                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
   18141         for (int i=0; i<origList.size(); i++) {
   18142             ProcessRecord r = origList.get(i);
   18143             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   18144                 continue;
   18145             }
   18146             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
   18147         }
   18148 
   18149         Comparator<Pair<ProcessRecord, Integer>> comparator
   18150                 = new Comparator<Pair<ProcessRecord, Integer>>() {
   18151             @Override
   18152             public int compare(Pair<ProcessRecord, Integer> object1,
   18153                     Pair<ProcessRecord, Integer> object2) {
   18154                 if (object1.first.setAdj != object2.first.setAdj) {
   18155                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
   18156                 }
   18157                 if (object1.first.setProcState != object2.first.setProcState) {
   18158                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
   18159                 }
   18160                 if (object1.second.intValue() != object2.second.intValue()) {
   18161                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
   18162                 }
   18163                 return 0;
   18164             }
   18165         };
   18166 
   18167         Collections.sort(list, comparator);
   18168         return list;
   18169     }
   18170 
   18171     private static final boolean writeProcessOomListToProto(ProtoOutputStream proto, long fieldId,
   18172             ActivityManagerService service, List<ProcessRecord> origList,
   18173             boolean inclDetails, String dumpPackage) {
   18174         ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
   18175         if (list.isEmpty()) return false;
   18176 
   18177         final long curUptime = SystemClock.uptimeMillis();
   18178 
   18179         for (int i = list.size() - 1; i >= 0; i--) {
   18180             ProcessRecord r = list.get(i).first;
   18181             long token = proto.start(fieldId);
   18182             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
   18183             proto.write(ProcessOomProto.PERSISTENT, r.persistent);
   18184             proto.write(ProcessOomProto.NUM, (origList.size()-1)-list.get(i).second);
   18185             proto.write(ProcessOomProto.OOM_ADJ, oomAdj);
   18186             int schedGroup = ProcessOomProto.SCHED_GROUP_UNKNOWN;
   18187             switch (r.setSchedGroup) {
   18188                 case ProcessList.SCHED_GROUP_BACKGROUND:
   18189                     schedGroup = ProcessOomProto.SCHED_GROUP_BACKGROUND;
   18190                     break;
   18191                 case ProcessList.SCHED_GROUP_DEFAULT:
   18192                     schedGroup = ProcessOomProto.SCHED_GROUP_DEFAULT;
   18193                     break;
   18194                 case ProcessList.SCHED_GROUP_TOP_APP:
   18195                     schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP;
   18196                     break;
   18197                 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
   18198                     schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP_BOUND;
   18199                     break;
   18200             }
   18201             if (schedGroup != ProcessOomProto.SCHED_GROUP_UNKNOWN) {
   18202                 proto.write(ProcessOomProto.SCHED_GROUP, schedGroup);
   18203             }
   18204             if (r.foregroundActivities) {
   18205                 proto.write(ProcessOomProto.ACTIVITIES, true);
   18206             } else if (r.foregroundServices) {
   18207                 proto.write(ProcessOomProto.SERVICES, true);
   18208             }
   18209             proto.write(ProcessOomProto.STATE, ProcessList.makeProcStateProtoEnum(r.curProcState));
   18210             proto.write(ProcessOomProto.TRIM_MEMORY_LEVEL, r.trimMemoryLevel);
   18211             r.writeToProto(proto, ProcessOomProto.PROC);
   18212             proto.write(ProcessOomProto.ADJ_TYPE, r.adjType);
   18213             if (r.adjSource != null || r.adjTarget != null) {
   18214                 if (r.adjTarget instanceof  ComponentName) {
   18215                     ComponentName cn = (ComponentName) r.adjTarget;
   18216                     cn.writeToProto(proto, ProcessOomProto.ADJ_TARGET_COMPONENT_NAME);
   18217                 } else if (r.adjTarget != null) {
   18218                     proto.write(ProcessOomProto.ADJ_TARGET_OBJECT, r.adjTarget.toString());
   18219                 }
   18220                 if (r.adjSource instanceof ProcessRecord) {
   18221                     ProcessRecord p = (ProcessRecord) r.adjSource;
   18222                     p.writeToProto(proto, ProcessOomProto.ADJ_SOURCE_PROC);
   18223                 } else if (r.adjSource != null) {
   18224                     proto.write(ProcessOomProto.ADJ_SOURCE_OBJECT, r.adjSource.toString());
   18225                 }
   18226             }
   18227             if (inclDetails) {
   18228                 long detailToken = proto.start(ProcessOomProto.DETAIL);
   18229                 proto.write(ProcessOomProto.Detail.MAX_ADJ, r.maxAdj);
   18230                 proto.write(ProcessOomProto.Detail.CUR_RAW_ADJ, r.curRawAdj);
   18231                 proto.write(ProcessOomProto.Detail.SET_RAW_ADJ, r.setRawAdj);
   18232                 proto.write(ProcessOomProto.Detail.CUR_ADJ, r.curAdj);
   18233                 proto.write(ProcessOomProto.Detail.SET_ADJ, r.setAdj);
   18234                 proto.write(ProcessOomProto.Detail.CURRENT_STATE,
   18235                         ProcessList.makeProcStateProtoEnum(r.curProcState));
   18236                 proto.write(ProcessOomProto.Detail.SET_STATE,
   18237                         ProcessList.makeProcStateProtoEnum(r.setProcState));
   18238                 proto.write(ProcessOomProto.Detail.LAST_PSS, DebugUtils.sizeValueToString(
   18239                         r.lastPss*1024, new StringBuilder()));
   18240                 proto.write(ProcessOomProto.Detail.LAST_SWAP_PSS, DebugUtils.sizeValueToString(
   18241                         r.lastSwapPss*1024, new StringBuilder()));
   18242                 proto.write(ProcessOomProto.Detail.LAST_CACHED_PSS, DebugUtils.sizeValueToString(
   18243                         r.lastCachedPss*1024, new StringBuilder()));
   18244                 proto.write(ProcessOomProto.Detail.CACHED, r.cached);
   18245                 proto.write(ProcessOomProto.Detail.EMPTY, r.empty);
   18246                 proto.write(ProcessOomProto.Detail.HAS_ABOVE_CLIENT, r.hasAboveClient);
   18247 
   18248                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
   18249                     if (r.lastCpuTime != 0) {
   18250                         long uptimeSince = curUptime - service.mLastPowerCheckUptime;
   18251                         long timeUsed = r.curCpuTime - r.lastCpuTime;
   18252                         long cpuTimeToken = proto.start(ProcessOomProto.Detail.SERVICE_RUN_TIME);
   18253                         proto.write(ProcessOomProto.Detail.CpuRunTime.OVER_MS, uptimeSince);
   18254                         proto.write(ProcessOomProto.Detail.CpuRunTime.USED_MS, timeUsed);
   18255                         proto.write(ProcessOomProto.Detail.CpuRunTime.ULTILIZATION,
   18256                                 (100.0*timeUsed)/uptimeSince);
   18257                         proto.end(cpuTimeToken);
   18258                     }
   18259                 }
   18260                 proto.end(detailToken);
   18261             }
   18262             proto.end(token);
   18263         }
   18264 
   18265         return true;
   18266     }
   18267 
   18268     private static final boolean dumpProcessOomList(PrintWriter pw,
   18269             ActivityManagerService service, List<ProcessRecord> origList,
   18270             String prefix, String normalLabel, String persistentLabel,
   18271             boolean inclDetails, String dumpPackage) {
   18272 
   18273         ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
   18274         if (list.isEmpty()) return false;
   18275 
   18276         final long curUptime = SystemClock.uptimeMillis();
   18277         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
   18278 
   18279         for (int i=list.size()-1; i>=0; i--) {
   18280             ProcessRecord r = list.get(i).first;
   18281             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
   18282             char schedGroup;
   18283             switch (r.setSchedGroup) {
   18284                 case ProcessList.SCHED_GROUP_BACKGROUND:
   18285                     schedGroup = 'B';
   18286                     break;
   18287                 case ProcessList.SCHED_GROUP_DEFAULT:
   18288                     schedGroup = 'F';
   18289                     break;
   18290                 case ProcessList.SCHED_GROUP_TOP_APP:
   18291                     schedGroup = 'T';
   18292                     break;
   18293                 case ProcessList.SCHED_GROUP_RESTRICTED:
   18294                     schedGroup = 'R';
   18295                     break;
   18296                 default:
   18297                     schedGroup = '?';
   18298                     break;
   18299             }
   18300             char foreground;
   18301             if (r.foregroundActivities) {
   18302                 foreground = 'A';
   18303             } else if (r.foregroundServices) {
   18304                 foreground = 'S';
   18305             } else {
   18306                 foreground = ' ';
   18307             }
   18308             String procState = ProcessList.makeProcStateString(r.curProcState);
   18309             pw.print(prefix);
   18310             pw.print(r.persistent ? persistentLabel : normalLabel);
   18311             pw.print(" #");
   18312             int num = (origList.size()-1)-list.get(i).second;
   18313             if (num < 10) pw.print(' ');
   18314             pw.print(num);
   18315             pw.print(": ");
   18316             pw.print(oomAdj);
   18317             pw.print(' ');
   18318             pw.print(schedGroup);
   18319             pw.print('/');
   18320             pw.print(foreground);
   18321             pw.print('/');
   18322             pw.print(procState);
   18323             pw.print(" trm:");
   18324             if (r.trimMemoryLevel < 10) pw.print(' ');
   18325             pw.print(r.trimMemoryLevel);
   18326             pw.print(' ');
   18327             pw.print(r.toShortString());
   18328             pw.print(" (");
   18329             pw.print(r.adjType);
   18330             pw.println(')');
   18331             if (r.adjSource != null || r.adjTarget != null) {
   18332                 pw.print(prefix);
   18333                 pw.print("    ");
   18334                 if (r.adjTarget instanceof ComponentName) {
   18335                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
   18336                 } else if (r.adjTarget != null) {
   18337                     pw.print(r.adjTarget.toString());
   18338                 } else {
   18339                     pw.print("{null}");
   18340                 }
   18341                 pw.print("<=");
   18342                 if (r.adjSource instanceof ProcessRecord) {
   18343                     pw.print("Proc{");
   18344                     pw.print(((ProcessRecord)r.adjSource).toShortString());
   18345                     pw.println("}");
   18346                 } else if (r.adjSource != null) {
   18347                     pw.println(r.adjSource.toString());
   18348                 } else {
   18349                     pw.println("{null}");
   18350                 }
   18351             }
   18352             if (inclDetails) {
   18353                 pw.print(prefix);
   18354                 pw.print("    ");
   18355                 pw.print("oom: max="); pw.print(r.maxAdj);
   18356                 pw.print(" curRaw="); pw.print(r.curRawAdj);
   18357                 pw.print(" setRaw="); pw.print(r.setRawAdj);
   18358                 pw.print(" cur="); pw.print(r.curAdj);
   18359                 pw.print(" set="); pw.println(r.setAdj);
   18360                 pw.print(prefix);
   18361                 pw.print("    ");
   18362                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
   18363                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
   18364                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
   18365                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
   18366                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
   18367                 pw.println();
   18368                 pw.print(prefix);
   18369                 pw.print("    ");
   18370                 pw.print("cached="); pw.print(r.cached);
   18371                 pw.print(" empty="); pw.print(r.empty);
   18372                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
   18373 
   18374                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
   18375                     if (r.lastCpuTime != 0) {
   18376                         long timeUsed = r.curCpuTime - r.lastCpuTime;
   18377                         pw.print(prefix);
   18378                         pw.print("    ");
   18379                         pw.print("run cpu over ");
   18380                         TimeUtils.formatDuration(uptimeSince, pw);
   18381                         pw.print(" used ");
   18382                         TimeUtils.formatDuration(timeUsed, pw);
   18383                         pw.print(" (");
   18384                         pw.print((timeUsed*100)/uptimeSince);
   18385                         pw.println("%)");
   18386                     }
   18387                 }
   18388             }
   18389         }
   18390         return true;
   18391     }
   18392 
   18393     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
   18394             String[] args) {
   18395         ArrayList<ProcessRecord> procs;
   18396         synchronized (this) {
   18397             if (args != null && args.length > start
   18398                     && args[start].charAt(0) != '-') {
   18399                 procs = new ArrayList<ProcessRecord>();
   18400                 int pid = -1;
   18401                 try {
   18402                     pid = Integer.parseInt(args[start]);
   18403                 } catch (NumberFormatException e) {
   18404                 }
   18405                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   18406                     ProcessRecord proc = mLruProcesses.get(i);
   18407                     if (proc.pid > 0 && proc.pid == pid) {
   18408                         procs.add(proc);
   18409                     } else if (allPkgs && proc.pkgList != null
   18410                             && proc.pkgList.containsKey(args[start])) {
   18411                         procs.add(proc);
   18412                     } else if (proc.processName.equals(args[start])) {
   18413                         procs.add(proc);
   18414                     }
   18415                 }
   18416                 if (procs.size() <= 0) {
   18417                     return null;
   18418                 }
   18419             } else {
   18420                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
   18421             }
   18422         }
   18423         return procs;
   18424     }
   18425 
   18426     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
   18427             PrintWriter pw, String[] args) {
   18428         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
   18429         if (procs == null) {
   18430             pw.println("No process found for: " + args[0]);
   18431             return;
   18432         }
   18433 
   18434         long uptime = SystemClock.uptimeMillis();
   18435         long realtime = SystemClock.elapsedRealtime();
   18436         pw.println("Applications Graphics Acceleration Info:");
   18437         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   18438 
   18439         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   18440             ProcessRecord r = procs.get(i);
   18441             if (r.thread != null) {
   18442                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
   18443                 pw.flush();
   18444                 try {
   18445                     TransferPipe tp = new TransferPipe();
   18446                     try {
   18447                         r.thread.dumpGfxInfo(tp.getWriteFd(), args);
   18448                         tp.go(fd);
   18449                     } finally {
   18450                         tp.kill();
   18451                     }
   18452                 } catch (IOException e) {
   18453                     pw.println("Failure while dumping the app: " + r);
   18454                     pw.flush();
   18455                 } catch (RemoteException e) {
   18456                     pw.println("Got a RemoteException while dumping the app " + r);
   18457                     pw.flush();
   18458                 }
   18459             }
   18460         }
   18461     }
   18462 
   18463     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
   18464         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
   18465         if (procs == null) {
   18466             pw.println("No process found for: " + args[0]);
   18467             return;
   18468         }
   18469 
   18470         pw.println("Applications Database Info:");
   18471 
   18472         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   18473             ProcessRecord r = procs.get(i);
   18474             if (r.thread != null) {
   18475                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
   18476                 pw.flush();
   18477                 try {
   18478                     TransferPipe tp = new TransferPipe();
   18479                     try {
   18480                         r.thread.dumpDbInfo(tp.getWriteFd(), args);
   18481                         tp.go(fd);
   18482                     } finally {
   18483                         tp.kill();
   18484                     }
   18485                 } catch (IOException e) {
   18486                     pw.println("Failure while dumping the app: " + r);
   18487                     pw.flush();
   18488                 } catch (RemoteException e) {
   18489                     pw.println("Got a RemoteException while dumping the app " + r);
   18490                     pw.flush();
   18491                 }
   18492             }
   18493         }
   18494     }
   18495 
   18496     final static class MemItem {
   18497         final boolean isProc;
   18498         final String label;
   18499         final String shortLabel;
   18500         final long pss;
   18501         final long swapPss;
   18502         final int id;
   18503         final boolean hasActivities;
   18504         ArrayList<MemItem> subitems;
   18505 
   18506         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
   18507                 boolean _hasActivities) {
   18508             isProc = true;
   18509             label = _label;
   18510             shortLabel = _shortLabel;
   18511             pss = _pss;
   18512             swapPss = _swapPss;
   18513             id = _id;
   18514             hasActivities = _hasActivities;
   18515         }
   18516 
   18517         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
   18518             isProc = false;
   18519             label = _label;
   18520             shortLabel = _shortLabel;
   18521             pss = _pss;
   18522             swapPss = _swapPss;
   18523             id = _id;
   18524             hasActivities = false;
   18525         }
   18526     }
   18527 
   18528     private static void sortMemItems(List<MemItem> items) {
   18529         Collections.sort(items, new Comparator<MemItem>() {
   18530             @Override
   18531             public int compare(MemItem lhs, MemItem rhs) {
   18532                 if (lhs.pss < rhs.pss) {
   18533                     return 1;
   18534                 } else if (lhs.pss > rhs.pss) {
   18535                     return -1;
   18536                 }
   18537                 return 0;
   18538             }
   18539         });
   18540     }
   18541 
   18542     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
   18543             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
   18544         if (sort && !isCompact) {
   18545             sortMemItems(items);
   18546         }
   18547 
   18548         for (int i=0; i<items.size(); i++) {
   18549             MemItem mi = items.get(i);
   18550             if (!isCompact) {
   18551                 if (dumpSwapPss) {
   18552                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
   18553                             mi.label, stringifyKBSize(mi.swapPss));
   18554                 } else {
   18555                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
   18556                 }
   18557             } else if (mi.isProc) {
   18558                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
   18559                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
   18560                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
   18561                 pw.println(mi.hasActivities ? ",a" : ",e");
   18562             } else {
   18563                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
   18564                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
   18565             }
   18566             if (mi.subitems != null) {
   18567                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
   18568                         true, isCompact, dumpSwapPss);
   18569             }
   18570         }
   18571     }
   18572 
   18573     static final void dumpMemItems(ProtoOutputStream proto, long fieldId, String tag,
   18574             ArrayList<MemItem> items, boolean sort, boolean dumpSwapPss) {
   18575         if (sort) {
   18576             sortMemItems(items);
   18577         }
   18578 
   18579         for (int i=0; i<items.size(); i++) {
   18580             MemItem mi = items.get(i);
   18581             final long token = proto.start(fieldId);
   18582 
   18583             proto.write(MemInfoDumpProto.MemItem.TAG, tag);
   18584             proto.write(MemInfoDumpProto.MemItem.LABEL, mi.shortLabel);
   18585             proto.write(MemInfoDumpProto.MemItem.IS_PROC, mi.isProc);
   18586             proto.write(MemInfoDumpProto.MemItem.ID, mi.id);
   18587             proto.write(MemInfoDumpProto.MemItem.HAS_ACTIVITIES, mi.hasActivities);
   18588             proto.write(MemInfoDumpProto.MemItem.PSS_KB, mi.pss);
   18589             if (dumpSwapPss) {
   18590                 proto.write(MemInfoDumpProto.MemItem.SWAP_PSS_KB, mi.swapPss);
   18591             }
   18592             if (mi.subitems != null) {
   18593                 dumpMemItems(proto, MemInfoDumpProto.MemItem.SUB_ITEMS, mi.shortLabel, mi.subitems,
   18594                         true, dumpSwapPss);
   18595             }
   18596             proto.end(token);
   18597         }
   18598     }
   18599 
   18600     // These are in KB.
   18601     static final long[] DUMP_MEM_BUCKETS = new long[] {
   18602         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
   18603         120*1024, 160*1024, 200*1024,
   18604         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
   18605         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
   18606     };
   18607 
   18608     static final void appendMemBucket(StringBuilder out, long memKB, String label,
   18609             boolean stackLike) {
   18610         int start = label.lastIndexOf('.');
   18611         if (start >= 0) start++;
   18612         else start = 0;
   18613         int end = label.length();
   18614         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
   18615             if (DUMP_MEM_BUCKETS[i] >= memKB) {
   18616                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
   18617                 out.append(bucket);
   18618                 out.append(stackLike ? "MB." : "MB ");
   18619                 out.append(label, start, end);
   18620                 return;
   18621             }
   18622         }
   18623         out.append(memKB/1024);
   18624         out.append(stackLike ? "MB." : "MB ");
   18625         out.append(label, start, end);
   18626     }
   18627 
   18628     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
   18629             ProcessList.NATIVE_ADJ,
   18630             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
   18631             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
   18632             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
   18633             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
   18634             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
   18635             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
   18636     };
   18637     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
   18638             "Native",
   18639             "System", "Persistent", "Persistent Service", "Foreground",
   18640             "Visible", "Perceptible",
   18641             "Heavy Weight", "Backup",
   18642             "A Services", "Home",
   18643             "Previous", "B Services", "Cached"
   18644     };
   18645     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
   18646             "native",
   18647             "sys", "pers", "persvc", "fore",
   18648             "vis", "percept",
   18649             "heavy", "backup",
   18650             "servicea", "home",
   18651             "prev", "serviceb", "cached"
   18652     };
   18653 
   18654     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
   18655             long realtime, boolean isCheckinRequest, boolean isCompact) {
   18656         if (isCompact) {
   18657             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
   18658         }
   18659         if (isCheckinRequest || isCompact) {
   18660             // short checkin version
   18661             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
   18662         } else {
   18663             pw.println("Applications Memory Usage (in Kilobytes):");
   18664             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   18665         }
   18666     }
   18667 
   18668     private static final int KSM_SHARED = 0;
   18669     private static final int KSM_SHARING = 1;
   18670     private static final int KSM_UNSHARED = 2;
   18671     private static final int KSM_VOLATILE = 3;
   18672 
   18673     private final long[] getKsmInfo() {
   18674         long[] longOut = new long[4];
   18675         final int[] SINGLE_LONG_FORMAT = new int[] {
   18676             PROC_SPACE_TERM| PROC_OUT_LONG
   18677         };
   18678         long[] longTmp = new long[1];
   18679         readProcFile("/sys/kernel/mm/ksm/pages_shared",
   18680                 SINGLE_LONG_FORMAT, null, longTmp, null);
   18681         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   18682         longTmp[0] = 0;
   18683         readProcFile("/sys/kernel/mm/ksm/pages_sharing",
   18684                 SINGLE_LONG_FORMAT, null, longTmp, null);
   18685         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   18686         longTmp[0] = 0;
   18687         readProcFile("/sys/kernel/mm/ksm/pages_unshared",
   18688                 SINGLE_LONG_FORMAT, null, longTmp, null);
   18689         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   18690         longTmp[0] = 0;
   18691         readProcFile("/sys/kernel/mm/ksm/pages_volatile",
   18692                 SINGLE_LONG_FORMAT, null, longTmp, null);
   18693         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   18694         return longOut;
   18695     }
   18696 
   18697     private static String stringifySize(long size, int order) {
   18698         Locale locale = Locale.US;
   18699         switch (order) {
   18700             case 1:
   18701                 return String.format(locale, "%,13d", size);
   18702             case 1024:
   18703                 return String.format(locale, "%,9dK", size / 1024);
   18704             case 1024 * 1024:
   18705                 return String.format(locale, "%,5dM", size / 1024 / 1024);
   18706             case 1024 * 1024 * 1024:
   18707                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
   18708             default:
   18709                 throw new IllegalArgumentException("Invalid size order");
   18710         }
   18711     }
   18712 
   18713     private static String stringifyKBSize(long size) {
   18714         return stringifySize(size * 1024, 1024);
   18715     }
   18716 
   18717     // Update this version number if you change the 'compact' format.
   18718     private static final int MEMINFO_COMPACT_VERSION = 1;
   18719 
   18720     private static class MemoryUsageDumpOptions {
   18721         boolean dumpDetails;
   18722         boolean dumpFullDetails;
   18723         boolean dumpDalvik;
   18724         boolean dumpSummaryOnly;
   18725         boolean dumpUnreachable;
   18726         boolean oomOnly;
   18727         boolean isCompact;
   18728         boolean localOnly;
   18729         boolean packages;
   18730         boolean isCheckinRequest;
   18731         boolean dumpSwapPss;
   18732         boolean dumpProto;
   18733     }
   18734 
   18735     final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
   18736             String[] args, boolean brief, PrintWriter categoryPw, boolean asProto) {
   18737         MemoryUsageDumpOptions opts = new MemoryUsageDumpOptions();
   18738         opts.dumpDetails = false;
   18739         opts.dumpFullDetails = false;
   18740         opts.dumpDalvik = false;
   18741         opts.dumpSummaryOnly = false;
   18742         opts.dumpUnreachable = false;
   18743         opts.oomOnly = false;
   18744         opts.isCompact = false;
   18745         opts.localOnly = false;
   18746         opts.packages = false;
   18747         opts.isCheckinRequest = false;
   18748         opts.dumpSwapPss = false;
   18749         opts.dumpProto = asProto;
   18750 
   18751         int opti = 0;
   18752         while (opti < args.length) {
   18753             String opt = args[opti];
   18754             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   18755                 break;
   18756             }
   18757             opti++;
   18758             if ("-a".equals(opt)) {
   18759                 opts.dumpDetails = true;
   18760                 opts.dumpFullDetails = true;
   18761                 opts.dumpDalvik = true;
   18762                 opts.dumpSwapPss = true;
   18763             } else if ("-d".equals(opt)) {
   18764                 opts.dumpDalvik = true;
   18765             } else if ("-c".equals(opt)) {
   18766                 opts.isCompact = true;
   18767             } else if ("-s".equals(opt)) {
   18768                 opts.dumpDetails = true;
   18769                 opts.dumpSummaryOnly = true;
   18770             } else if ("-S".equals(opt)) {
   18771                 opts.dumpSwapPss = true;
   18772             } else if ("--unreachable".equals(opt)) {
   18773                 opts.dumpUnreachable = true;
   18774             } else if ("--oom".equals(opt)) {
   18775                 opts.oomOnly = true;
   18776             } else if ("--local".equals(opt)) {
   18777                 opts.localOnly = true;
   18778             } else if ("--package".equals(opt)) {
   18779                 opts.packages = true;
   18780             } else if ("--checkin".equals(opt)) {
   18781                 opts.isCheckinRequest = true;
   18782             } else if ("--proto".equals(opt)) {
   18783                 opts.dumpProto = true;
   18784 
   18785             } else if ("-h".equals(opt)) {
   18786                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
   18787                 pw.println("  -a: include all available information for each process.");
   18788                 pw.println("  -d: include dalvik details.");
   18789                 pw.println("  -c: dump in a compact machine-parseable representation.");
   18790                 pw.println("  -s: dump only summary of application memory usage.");
   18791                 pw.println("  -S: dump also SwapPss.");
   18792                 pw.println("  --oom: only show processes organized by oom adj.");
   18793                 pw.println("  --local: only collect details locally, don't call process.");
   18794                 pw.println("  --package: interpret process arg as package, dumping all");
   18795                 pw.println("             processes that have loaded that package.");
   18796                 pw.println("  --checkin: dump data for a checkin");
   18797                 pw.println("  --proto: dump data to proto");
   18798                 pw.println("If [process] is specified it can be the name or ");
   18799                 pw.println("pid of a specific process to dump.");
   18800                 return;
   18801             } else {
   18802                 pw.println("Unknown argument: " + opt + "; use -h for help");
   18803             }
   18804         }
   18805 
   18806         String[] innerArgs = new String[args.length-opti];
   18807         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
   18808 
   18809         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, opts.packages, args);
   18810         if (opts.dumpProto) {
   18811             dumpApplicationMemoryUsage(fd, opts, innerArgs, brief, procs);
   18812         } else {
   18813             dumpApplicationMemoryUsage(fd, pw, prefix, opts, innerArgs, brief, procs, categoryPw);
   18814         }
   18815     }
   18816 
   18817     private final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
   18818             MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
   18819             ArrayList<ProcessRecord> procs, PrintWriter categoryPw) {
   18820         long uptime = SystemClock.uptimeMillis();
   18821         long realtime = SystemClock.elapsedRealtime();
   18822         final long[] tmpLong = new long[1];
   18823 
   18824         if (procs == null) {
   18825             // No Java processes.  Maybe they want to print a native process.
   18826             String proc = "N/A";
   18827             if (innerArgs.length > 0) {
   18828                 proc = innerArgs[0];
   18829                 if (proc.charAt(0) != '-') {
   18830                     ArrayList<ProcessCpuTracker.Stats> nativeProcs
   18831                             = new ArrayList<ProcessCpuTracker.Stats>();
   18832                     updateCpuStatsNow();
   18833                     int findPid = -1;
   18834                     try {
   18835                         findPid = Integer.parseInt(innerArgs[0]);
   18836                     } catch (NumberFormatException e) {
   18837                     }
   18838                     synchronized (mProcessCpuTracker) {
   18839                         final int N = mProcessCpuTracker.countStats();
   18840                         for (int i=0; i<N; i++) {
   18841                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   18842                             if (st.pid == findPid || (st.baseName != null
   18843                                     && st.baseName.equals(innerArgs[0]))) {
   18844                                 nativeProcs.add(st);
   18845                             }
   18846                         }
   18847                     }
   18848                     if (nativeProcs.size() > 0) {
   18849                         dumpApplicationMemoryUsageHeader(pw, uptime, realtime,
   18850                                 opts.isCheckinRequest, opts.isCompact);
   18851                         Debug.MemoryInfo mi = null;
   18852                         for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
   18853                             final ProcessCpuTracker.Stats r = nativeProcs.get(i);
   18854                             final int pid = r.pid;
   18855                             if (!opts.isCheckinRequest && opts.dumpDetails) {
   18856                                 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
   18857                             }
   18858                             if (mi == null) {
   18859                                 mi = new Debug.MemoryInfo();
   18860                             }
   18861                             if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
   18862                                 Debug.getMemoryInfo(pid, mi);
   18863                             } else {
   18864                                 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
   18865                                 mi.dalvikPrivateDirty = (int)tmpLong[0];
   18866                             }
   18867                             ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest,
   18868                                     opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
   18869                                     pid, r.baseName, 0, 0, 0, 0, 0, 0);
   18870                             if (opts.isCheckinRequest) {
   18871                                 pw.println();
   18872                             }
   18873                         }
   18874                         return;
   18875                     }
   18876                 }
   18877             }
   18878             pw.println("No process found for: " + proc);
   18879             return;
   18880         }
   18881 
   18882         if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
   18883             opts.dumpDetails = true;
   18884         }
   18885 
   18886         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, opts.isCheckinRequest, opts.isCompact);
   18887 
   18888         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
   18889         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
   18890         long nativePss = 0;
   18891         long nativeSwapPss = 0;
   18892         long dalvikPss = 0;
   18893         long dalvikSwapPss = 0;
   18894         long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
   18895                 EmptyArray.LONG;
   18896         long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
   18897                 EmptyArray.LONG;
   18898         long otherPss = 0;
   18899         long otherSwapPss = 0;
   18900         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   18901         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   18902 
   18903         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   18904         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   18905         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
   18906                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
   18907 
   18908         long totalPss = 0;
   18909         long totalSwapPss = 0;
   18910         long cachedPss = 0;
   18911         long cachedSwapPss = 0;
   18912         boolean hasSwapPss = false;
   18913 
   18914         Debug.MemoryInfo mi = null;
   18915         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   18916             final ProcessRecord r = procs.get(i);
   18917             final IApplicationThread thread;
   18918             final int pid;
   18919             final int oomAdj;
   18920             final boolean hasActivities;
   18921             synchronized (this) {
   18922                 thread = r.thread;
   18923                 pid = r.pid;
   18924                 oomAdj = r.getSetAdjWithServices();
   18925                 hasActivities = r.activities.size() > 0;
   18926             }
   18927             if (thread != null) {
   18928                 if (!opts.isCheckinRequest && opts.dumpDetails) {
   18929                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
   18930                 }
   18931                 if (mi == null) {
   18932                     mi = new Debug.MemoryInfo();
   18933                 }
   18934                 final int reportType;
   18935                 final long startTime;
   18936                 final long endTime;
   18937                 if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
   18938                     reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
   18939                     startTime = SystemClock.currentThreadTimeMillis();
   18940                     Debug.getMemoryInfo(pid, mi);
   18941                     endTime = SystemClock.currentThreadTimeMillis();
   18942                     hasSwapPss = mi.hasSwappedOutPss;
   18943                 } else {
   18944                     reportType = ProcessStats.ADD_PSS_EXTERNAL;
   18945                     startTime = SystemClock.currentThreadTimeMillis();
   18946                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
   18947                     endTime = SystemClock.currentThreadTimeMillis();
   18948                     mi.dalvikPrivateDirty = (int)tmpLong[0];
   18949                 }
   18950                 if (opts.dumpDetails) {
   18951                     if (opts.localOnly) {
   18952                         ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails,
   18953                                 opts.dumpDalvik, opts.dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
   18954                         if (opts.isCheckinRequest) {
   18955                             pw.println();
   18956                         }
   18957                     } else {
   18958                         pw.flush();
   18959                         try {
   18960                             TransferPipe tp = new TransferPipe();
   18961                             try {
   18962                                 thread.dumpMemInfo(tp.getWriteFd(),
   18963                                         mi, opts.isCheckinRequest, opts.dumpFullDetails,
   18964                                         opts.dumpDalvik, opts.dumpSummaryOnly, opts.dumpUnreachable, innerArgs);
   18965                                 tp.go(fd, opts.dumpUnreachable ? 30000 : 5000);
   18966                             } finally {
   18967                                 tp.kill();
   18968                             }
   18969                         } catch (IOException e) {
   18970                             if (!opts.isCheckinRequest) {
   18971                                 pw.println("Got IoException! " + e);
   18972                                 pw.flush();
   18973                             }
   18974                         } catch (RemoteException e) {
   18975                             if (!opts.isCheckinRequest) {
   18976                                 pw.println("Got RemoteException! " + e);
   18977                                 pw.flush();
   18978                             }
   18979                         }
   18980                     }
   18981                 }
   18982 
   18983                 final long myTotalPss = mi.getTotalPss();
   18984                 final long myTotalUss = mi.getTotalUss();
   18985                 final long myTotalRss = mi.getTotalRss();
   18986                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
   18987 
   18988                 synchronized (this) {
   18989                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
   18990                         // Record this for posterity if the process has been stable.
   18991                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
   18992                                 reportType, endTime-startTime, r.pkgList);
   18993                     }
   18994                 }
   18995 
   18996                 if (!opts.isCheckinRequest && mi != null) {
   18997                     totalPss += myTotalPss;
   18998                     totalSwapPss += myTotalSwapPss;
   18999                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
   19000                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
   19001                             myTotalSwapPss, pid, hasActivities);
   19002                     procMems.add(pssItem);
   19003                     procMemsMap.put(pid, pssItem);
   19004 
   19005                     nativePss += mi.nativePss;
   19006                     nativeSwapPss += mi.nativeSwappedOutPss;
   19007                     dalvikPss += mi.dalvikPss;
   19008                     dalvikSwapPss += mi.dalvikSwappedOutPss;
   19009                     for (int j=0; j<dalvikSubitemPss.length; j++) {
   19010                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   19011                         dalvikSubitemSwapPss[j] +=
   19012                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   19013                     }
   19014                     otherPss += mi.otherPss;
   19015                     otherSwapPss += mi.otherSwappedOutPss;
   19016                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   19017                         long mem = mi.getOtherPss(j);
   19018                         miscPss[j] += mem;
   19019                         otherPss -= mem;
   19020                         mem = mi.getOtherSwappedOutPss(j);
   19021                         miscSwapPss[j] += mem;
   19022                         otherSwapPss -= mem;
   19023                     }
   19024 
   19025                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   19026                         cachedPss += myTotalPss;
   19027                         cachedSwapPss += myTotalSwapPss;
   19028                     }
   19029 
   19030                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
   19031                         if (oomIndex == (oomPss.length - 1)
   19032                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
   19033                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
   19034                             oomPss[oomIndex] += myTotalPss;
   19035                             oomSwapPss[oomIndex] += myTotalSwapPss;
   19036                             if (oomProcs[oomIndex] == null) {
   19037                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
   19038                             }
   19039                             oomProcs[oomIndex].add(pssItem);
   19040                             break;
   19041                         }
   19042                     }
   19043                 }
   19044             }
   19045         }
   19046 
   19047         long nativeProcTotalPss = 0;
   19048 
   19049         if (!opts.isCheckinRequest && procs.size() > 1 && !opts.packages) {
   19050             // If we are showing aggregations, also look for native processes to
   19051             // include so that our aggregations are more accurate.
   19052             updateCpuStatsNow();
   19053             mi = null;
   19054             synchronized (mProcessCpuTracker) {
   19055                 final int N = mProcessCpuTracker.countStats();
   19056                 for (int i=0; i<N; i++) {
   19057                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   19058                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
   19059                         if (mi == null) {
   19060                             mi = new Debug.MemoryInfo();
   19061                         }
   19062                         if (!brief && !opts.oomOnly) {
   19063                             Debug.getMemoryInfo(st.pid, mi);
   19064                         } else {
   19065                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
   19066                             mi.nativePrivateDirty = (int)tmpLong[0];
   19067                         }
   19068 
   19069                         final long myTotalPss = mi.getTotalPss();
   19070                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
   19071                         totalPss += myTotalPss;
   19072                         totalSwapPss += myTotalSwapPss;
   19073                         nativeProcTotalPss += myTotalPss;
   19074 
   19075                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
   19076                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
   19077                         procMems.add(pssItem);
   19078 
   19079                         nativePss += mi.nativePss;
   19080                         nativeSwapPss += mi.nativeSwappedOutPss;
   19081                         dalvikPss += mi.dalvikPss;
   19082                         dalvikSwapPss += mi.dalvikSwappedOutPss;
   19083                         for (int j=0; j<dalvikSubitemPss.length; j++) {
   19084                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   19085                             dalvikSubitemSwapPss[j] +=
   19086                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   19087                         }
   19088                         otherPss += mi.otherPss;
   19089                         otherSwapPss += mi.otherSwappedOutPss;
   19090                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   19091                             long mem = mi.getOtherPss(j);
   19092                             miscPss[j] += mem;
   19093                             otherPss -= mem;
   19094                             mem = mi.getOtherSwappedOutPss(j);
   19095                             miscSwapPss[j] += mem;
   19096                             otherSwapPss -= mem;
   19097                         }
   19098                         oomPss[0] += myTotalPss;
   19099                         oomSwapPss[0] += myTotalSwapPss;
   19100                         if (oomProcs[0] == null) {
   19101                             oomProcs[0] = new ArrayList<MemItem>();
   19102                         }
   19103                         oomProcs[0].add(pssItem);
   19104                     }
   19105                 }
   19106             }
   19107 
   19108             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
   19109 
   19110             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
   19111             final int dalvikId = -2;
   19112             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
   19113             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
   19114             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   19115                 String label = Debug.MemoryInfo.getOtherLabel(j);
   19116                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
   19117             }
   19118             if (dalvikSubitemPss.length > 0) {
   19119                 // Add dalvik subitems.
   19120                 for (MemItem memItem : catMems) {
   19121                     int memItemStart = 0, memItemEnd = 0;
   19122                     if (memItem.id == dalvikId) {
   19123                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
   19124                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
   19125                     } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
   19126                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
   19127                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
   19128                     } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
   19129                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
   19130                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
   19131                     } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
   19132                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
   19133                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
   19134                     } else {
   19135                         continue;  // No subitems, continue.
   19136                     }
   19137                     memItem.subitems = new ArrayList<MemItem>();
   19138                     for (int j=memItemStart; j<=memItemEnd; j++) {
   19139                         final String name = Debug.MemoryInfo.getOtherLabel(
   19140                                 Debug.MemoryInfo.NUM_OTHER_STATS + j);
   19141                         memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
   19142                                 dalvikSubitemSwapPss[j], j));
   19143                     }
   19144                 }
   19145             }
   19146 
   19147             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
   19148             for (int j=0; j<oomPss.length; j++) {
   19149                 if (oomPss[j] != 0) {
   19150                     String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
   19151                             : DUMP_MEM_OOM_LABEL[j];
   19152                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
   19153                             DUMP_MEM_OOM_ADJ[j]);
   19154                     item.subitems = oomProcs[j];
   19155                     oomMems.add(item);
   19156                 }
   19157             }
   19158 
   19159             opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
   19160             if (!brief && !opts.oomOnly && !opts.isCompact) {
   19161                 pw.println();
   19162                 pw.println("Total PSS by process:");
   19163                 dumpMemItems(pw, "  ", "proc", procMems, true, opts.isCompact, opts.dumpSwapPss);
   19164                 pw.println();
   19165             }
   19166             if (!opts.isCompact) {
   19167                 pw.println("Total PSS by OOM adjustment:");
   19168             }
   19169             dumpMemItems(pw, "  ", "oom", oomMems, false, opts.isCompact, opts.dumpSwapPss);
   19170             if (!brief && !opts.oomOnly) {
   19171                 PrintWriter out = categoryPw != null ? categoryPw : pw;
   19172                 if (!opts.isCompact) {
   19173                     out.println();
   19174                     out.println("Total PSS by category:");
   19175                 }
   19176                 dumpMemItems(out, "  ", "cat", catMems, true, opts.isCompact, opts.dumpSwapPss);
   19177             }
   19178             if (!opts.isCompact) {
   19179                 pw.println();
   19180             }
   19181             MemInfoReader memInfo = new MemInfoReader();
   19182             memInfo.readMemInfo();
   19183             if (nativeProcTotalPss > 0) {
   19184                 synchronized (this) {
   19185                     final long cachedKb = memInfo.getCachedSizeKb();
   19186                     final long freeKb = memInfo.getFreeSizeKb();
   19187                     final long zramKb = memInfo.getZramTotalSizeKb();
   19188                     final long kernelKb = memInfo.getKernelUsedSizeKb();
   19189                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
   19190                             kernelKb*1024, nativeProcTotalPss*1024);
   19191                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
   19192                             nativeProcTotalPss);
   19193                 }
   19194             }
   19195             if (!brief) {
   19196                 if (!opts.isCompact) {
   19197                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
   19198                     pw.print(" (status ");
   19199                     switch (mLastMemoryLevel) {
   19200                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
   19201                             pw.println("normal)");
   19202                             break;
   19203                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
   19204                             pw.println("moderate)");
   19205                             break;
   19206                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
   19207                             pw.println("low)");
   19208                             break;
   19209                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
   19210                             pw.println("critical)");
   19211                             break;
   19212                         default:
   19213                             pw.print(mLastMemoryLevel);
   19214                             pw.println(")");
   19215                             break;
   19216                     }
   19217                     pw.print(" Free RAM: ");
   19218                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
   19219                             + memInfo.getFreeSizeKb()));
   19220                     pw.print(" (");
   19221                     pw.print(stringifyKBSize(cachedPss));
   19222                     pw.print(" cached pss + ");
   19223                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
   19224                     pw.print(" cached kernel + ");
   19225                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
   19226                     pw.println(" free)");
   19227                 } else {
   19228                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
   19229                     pw.print(cachedPss + memInfo.getCachedSizeKb()
   19230                             + memInfo.getFreeSizeKb()); pw.print(",");
   19231                     pw.println(totalPss - cachedPss);
   19232                 }
   19233             }
   19234             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
   19235                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
   19236                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
   19237             if (!opts.isCompact) {
   19238                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
   19239                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
   19240                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
   19241                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
   19242                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
   19243             } else {
   19244                 pw.print("lostram,"); pw.println(lostRAM);
   19245             }
   19246             if (!brief) {
   19247                 if (memInfo.getZramTotalSizeKb() != 0) {
   19248                     if (!opts.isCompact) {
   19249                         pw.print("     ZRAM: ");
   19250                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
   19251                                 pw.print(" physical used for ");
   19252                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
   19253                                         - memInfo.getSwapFreeSizeKb()));
   19254                                 pw.print(" in swap (");
   19255                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
   19256                                 pw.println(" total swap)");
   19257                     } else {
   19258                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
   19259                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
   19260                                 pw.println(memInfo.getSwapFreeSizeKb());
   19261                     }
   19262                 }
   19263                 final long[] ksm = getKsmInfo();
   19264                 if (!opts.isCompact) {
   19265                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
   19266                             || ksm[KSM_VOLATILE] != 0) {
   19267                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
   19268                                 pw.print(" saved from shared ");
   19269                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
   19270                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
   19271                                 pw.print(" unshared; ");
   19272                                 pw.print(stringifyKBSize(
   19273                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
   19274                     }
   19275                     pw.print("   Tuning: ");
   19276                     pw.print(ActivityManager.staticGetMemoryClass());
   19277                     pw.print(" (large ");
   19278                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   19279                     pw.print("), oom ");
   19280                     pw.print(stringifySize(
   19281                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
   19282                     pw.print(", restore limit ");
   19283                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
   19284                     if (ActivityManager.isLowRamDeviceStatic()) {
   19285                         pw.print(" (low-ram)");
   19286                     }
   19287                     if (ActivityManager.isHighEndGfx()) {
   19288                         pw.print(" (high-end-gfx)");
   19289                     }
   19290                     pw.println();
   19291                 } else {
   19292                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
   19293                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
   19294                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
   19295                     pw.print("tuning,");
   19296                     pw.print(ActivityManager.staticGetMemoryClass());
   19297                     pw.print(',');
   19298                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   19299                     pw.print(',');
   19300                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
   19301                     if (ActivityManager.isLowRamDeviceStatic()) {
   19302                         pw.print(",low-ram");
   19303                     }
   19304                     if (ActivityManager.isHighEndGfx()) {
   19305                         pw.print(",high-end-gfx");
   19306                     }
   19307                     pw.println();
   19308                 }
   19309             }
   19310         }
   19311     }
   19312 
   19313     private final void dumpApplicationMemoryUsage(FileDescriptor fd,
   19314             MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
   19315             ArrayList<ProcessRecord> procs) {
   19316         final long uptimeMs = SystemClock.uptimeMillis();
   19317         final long realtimeMs = SystemClock.elapsedRealtime();
   19318         final long[] tmpLong = new long[1];
   19319 
   19320         if (procs == null) {
   19321             // No Java processes.  Maybe they want to print a native process.
   19322             String proc = "N/A";
   19323             if (innerArgs.length > 0) {
   19324                 proc = innerArgs[0];
   19325                 if (proc.charAt(0) != '-') {
   19326                     ArrayList<ProcessCpuTracker.Stats> nativeProcs
   19327                             = new ArrayList<ProcessCpuTracker.Stats>();
   19328                     updateCpuStatsNow();
   19329                     int findPid = -1;
   19330                     try {
   19331                         findPid = Integer.parseInt(innerArgs[0]);
   19332                     } catch (NumberFormatException e) {
   19333                     }
   19334                     synchronized (mProcessCpuTracker) {
   19335                         final int N = mProcessCpuTracker.countStats();
   19336                         for (int i=0; i<N; i++) {
   19337                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   19338                             if (st.pid == findPid || (st.baseName != null
   19339                                     && st.baseName.equals(innerArgs[0]))) {
   19340                                 nativeProcs.add(st);
   19341                             }
   19342                         }
   19343                     }
   19344                     if (nativeProcs.size() > 0) {
   19345                         ProtoOutputStream proto = new ProtoOutputStream(fd);
   19346 
   19347                         proto.write(MemInfoDumpProto.UPTIME_DURATION_MS, uptimeMs);
   19348                         proto.write(MemInfoDumpProto.ELAPSED_REALTIME_MS, realtimeMs);
   19349                         Debug.MemoryInfo mi = null;
   19350                         for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
   19351                             final ProcessCpuTracker.Stats r = nativeProcs.get(i);
   19352                             final int pid = r.pid;
   19353                             final long nToken = proto.start(MemInfoDumpProto.NATIVE_PROCESSES);
   19354 
   19355                             proto.write(MemInfoDumpProto.ProcessMemory.PID, pid);
   19356                             proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.baseName);
   19357 
   19358                             if (mi == null) {
   19359                                 mi = new Debug.MemoryInfo();
   19360                             }
   19361                             if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
   19362                                 Debug.getMemoryInfo(pid, mi);
   19363                             } else {
   19364                                 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
   19365                                 mi.dalvikPrivateDirty = (int)tmpLong[0];
   19366                             }
   19367                             ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
   19368                                     opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
   19369 
   19370                             proto.end(nToken);
   19371                         }
   19372 
   19373                         proto.flush();
   19374                         return;
   19375                     }
   19376                 }
   19377             }
   19378             Log.d(TAG, "No process found for: " + innerArgs[0]);
   19379             return;
   19380         }
   19381 
   19382         if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
   19383             opts.dumpDetails = true;
   19384         }
   19385 
   19386         ProtoOutputStream proto = new ProtoOutputStream(fd);
   19387 
   19388         proto.write(MemInfoDumpProto.UPTIME_DURATION_MS, uptimeMs);
   19389         proto.write(MemInfoDumpProto.ELAPSED_REALTIME_MS, realtimeMs);
   19390 
   19391         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
   19392         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
   19393         long nativePss = 0;
   19394         long nativeSwapPss = 0;
   19395         long dalvikPss = 0;
   19396         long dalvikSwapPss = 0;
   19397         long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
   19398                 EmptyArray.LONG;
   19399         long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
   19400                 EmptyArray.LONG;
   19401         long otherPss = 0;
   19402         long otherSwapPss = 0;
   19403         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   19404         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   19405 
   19406         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   19407         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   19408         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
   19409                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
   19410 
   19411         long totalPss = 0;
   19412         long totalSwapPss = 0;
   19413         long cachedPss = 0;
   19414         long cachedSwapPss = 0;
   19415         boolean hasSwapPss = false;
   19416 
   19417         Debug.MemoryInfo mi = null;
   19418         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   19419             final ProcessRecord r = procs.get(i);
   19420             final IApplicationThread thread;
   19421             final int pid;
   19422             final int oomAdj;
   19423             final boolean hasActivities;
   19424             synchronized (this) {
   19425                 thread = r.thread;
   19426                 pid = r.pid;
   19427                 oomAdj = r.getSetAdjWithServices();
   19428                 hasActivities = r.activities.size() > 0;
   19429             }
   19430             if (thread == null) {
   19431                 continue;
   19432             }
   19433             if (mi == null) {
   19434                 mi = new Debug.MemoryInfo();
   19435             }
   19436             final int reportType;
   19437             final long startTime;
   19438             final long endTime;
   19439             if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
   19440                 reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
   19441                 startTime = SystemClock.currentThreadTimeMillis();
   19442                 Debug.getMemoryInfo(pid, mi);
   19443                 endTime = SystemClock.currentThreadTimeMillis();
   19444                 hasSwapPss = mi.hasSwappedOutPss;
   19445             } else {
   19446                 reportType = ProcessStats.ADD_PSS_EXTERNAL;
   19447                 startTime = SystemClock.currentThreadTimeMillis();
   19448                 mi.dalvikPss = (int) Debug.getPss(pid, tmpLong, null);
   19449                 endTime = SystemClock.currentThreadTimeMillis();
   19450                 mi.dalvikPrivateDirty = (int) tmpLong[0];
   19451             }
   19452             if (opts.dumpDetails) {
   19453                 if (opts.localOnly) {
   19454                     final long aToken = proto.start(MemInfoDumpProto.APP_PROCESSES);
   19455                     final long mToken = proto.start(MemInfoDumpProto.AppData.PROCESS_MEMORY);
   19456                     proto.write(MemInfoDumpProto.ProcessMemory.PID, pid);
   19457                     proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.processName);
   19458                     ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
   19459                             opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
   19460                     proto.end(mToken);
   19461                     proto.end(aToken);
   19462                 } else {
   19463                     try {
   19464                         ByteTransferPipe tp = new ByteTransferPipe();
   19465                         try {
   19466                             thread.dumpMemInfoProto(tp.getWriteFd(),
   19467                                 mi, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
   19468                                 opts.dumpUnreachable, innerArgs);
   19469                             proto.write(MemInfoDumpProto.APP_PROCESSES, tp.get());
   19470                         } finally {
   19471                             tp.kill();
   19472                         }
   19473                     } catch (IOException e) {
   19474                         Log.e(TAG, "Got IOException!", e);
   19475                     } catch (RemoteException e) {
   19476                         Log.e(TAG, "Got RemoteException!", e);
   19477                     }
   19478                 }
   19479             }
   19480 
   19481             final long myTotalPss = mi.getTotalPss();
   19482             final long myTotalUss = mi.getTotalUss();
   19483             final long myTotalRss = mi.getTotalRss();
   19484             final long myTotalSwapPss = mi.getTotalSwappedOutPss();
   19485 
   19486             synchronized (this) {
   19487                 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
   19488                     // Record this for posterity if the process has been stable.
   19489                     r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
   19490                             reportType, endTime-startTime, r.pkgList);
   19491                 }
   19492             }
   19493 
   19494             if (!opts.isCheckinRequest && mi != null) {
   19495                 totalPss += myTotalPss;
   19496                 totalSwapPss += myTotalSwapPss;
   19497                 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
   19498                         (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
   19499                         myTotalSwapPss, pid, hasActivities);
   19500                 procMems.add(pssItem);
   19501                 procMemsMap.put(pid, pssItem);
   19502 
   19503                 nativePss += mi.nativePss;
   19504                 nativeSwapPss += mi.nativeSwappedOutPss;
   19505                 dalvikPss += mi.dalvikPss;
   19506                 dalvikSwapPss += mi.dalvikSwappedOutPss;
   19507                 for (int j=0; j<dalvikSubitemPss.length; j++) {
   19508                     dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   19509                     dalvikSubitemSwapPss[j] +=
   19510                             mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   19511                 }
   19512                 otherPss += mi.otherPss;
   19513                 otherSwapPss += mi.otherSwappedOutPss;
   19514                 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   19515                     long mem = mi.getOtherPss(j);
   19516                     miscPss[j] += mem;
   19517                     otherPss -= mem;
   19518                     mem = mi.getOtherSwappedOutPss(j);
   19519                     miscSwapPss[j] += mem;
   19520                     otherSwapPss -= mem;
   19521                 }
   19522 
   19523                 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   19524                     cachedPss += myTotalPss;
   19525                     cachedSwapPss += myTotalSwapPss;
   19526                 }
   19527 
   19528                 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
   19529                     if (oomIndex == (oomPss.length - 1)
   19530                             || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
   19531                                     && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
   19532                         oomPss[oomIndex] += myTotalPss;
   19533                         oomSwapPss[oomIndex] += myTotalSwapPss;
   19534                         if (oomProcs[oomIndex] == null) {
   19535                             oomProcs[oomIndex] = new ArrayList<MemItem>();
   19536                         }
   19537                         oomProcs[oomIndex].add(pssItem);
   19538                         break;
   19539                     }
   19540                 }
   19541             }
   19542         }
   19543 
   19544         long nativeProcTotalPss = 0;
   19545 
   19546         if (procs.size() > 1 && !opts.packages) {
   19547             // If we are showing aggregations, also look for native processes to
   19548             // include so that our aggregations are more accurate.
   19549             updateCpuStatsNow();
   19550             mi = null;
   19551             synchronized (mProcessCpuTracker) {
   19552                 final int N = mProcessCpuTracker.countStats();
   19553                 for (int i=0; i<N; i++) {
   19554                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   19555                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
   19556                         if (mi == null) {
   19557                             mi = new Debug.MemoryInfo();
   19558                         }
   19559                         if (!brief && !opts.oomOnly) {
   19560                             Debug.getMemoryInfo(st.pid, mi);
   19561                         } else {
   19562                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
   19563                             mi.nativePrivateDirty = (int)tmpLong[0];
   19564                         }
   19565 
   19566                         final long myTotalPss = mi.getTotalPss();
   19567                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
   19568                         totalPss += myTotalPss;
   19569                         nativeProcTotalPss += myTotalPss;
   19570 
   19571                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
   19572                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
   19573                         procMems.add(pssItem);
   19574 
   19575                         nativePss += mi.nativePss;
   19576                         nativeSwapPss += mi.nativeSwappedOutPss;
   19577                         dalvikPss += mi.dalvikPss;
   19578                         dalvikSwapPss += mi.dalvikSwappedOutPss;
   19579                         for (int j=0; j<dalvikSubitemPss.length; j++) {
   19580                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   19581                             dalvikSubitemSwapPss[j] +=
   19582                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
   19583                         }
   19584                         otherPss += mi.otherPss;
   19585                         otherSwapPss += mi.otherSwappedOutPss;
   19586                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   19587                             long mem = mi.getOtherPss(j);
   19588                             miscPss[j] += mem;
   19589                             otherPss -= mem;
   19590                             mem = mi.getOtherSwappedOutPss(j);
   19591                             miscSwapPss[j] += mem;
   19592                             otherSwapPss -= mem;
   19593                         }
   19594                         oomPss[0] += myTotalPss;
   19595                         oomSwapPss[0] += myTotalSwapPss;
   19596                         if (oomProcs[0] == null) {
   19597                             oomProcs[0] = new ArrayList<MemItem>();
   19598                         }
   19599                         oomProcs[0].add(pssItem);
   19600                     }
   19601                 }
   19602             }
   19603 
   19604             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
   19605 
   19606             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
   19607             final int dalvikId = -2;
   19608             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
   19609             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
   19610             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   19611                 String label = Debug.MemoryInfo.getOtherLabel(j);
   19612                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
   19613             }
   19614             if (dalvikSubitemPss.length > 0) {
   19615                 // Add dalvik subitems.
   19616                 for (MemItem memItem : catMems) {
   19617                     int memItemStart = 0, memItemEnd = 0;
   19618                     if (memItem.id == dalvikId) {
   19619                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
   19620                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
   19621                     } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
   19622                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
   19623                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
   19624                     } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
   19625                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
   19626                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
   19627                     } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
   19628                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
   19629                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
   19630                     } else {
   19631                         continue;  // No subitems, continue.
   19632                     }
   19633                     memItem.subitems = new ArrayList<MemItem>();
   19634                     for (int j=memItemStart; j<=memItemEnd; j++) {
   19635                         final String name = Debug.MemoryInfo.getOtherLabel(
   19636                                 Debug.MemoryInfo.NUM_OTHER_STATS + j);
   19637                         memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
   19638                                 dalvikSubitemSwapPss[j], j));
   19639                     }
   19640                 }
   19641             }
   19642 
   19643             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
   19644             for (int j=0; j<oomPss.length; j++) {
   19645                 if (oomPss[j] != 0) {
   19646                     String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
   19647                             : DUMP_MEM_OOM_LABEL[j];
   19648                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
   19649                             DUMP_MEM_OOM_ADJ[j]);
   19650                     item.subitems = oomProcs[j];
   19651                     oomMems.add(item);
   19652                 }
   19653             }
   19654 
   19655             opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
   19656             if (!opts.oomOnly) {
   19657                 dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_PROCESS, "proc",
   19658                         procMems, true, opts.dumpSwapPss);
   19659             }
   19660             dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_OOM_ADJUSTMENT, "oom",
   19661                     oomMems, false, opts.dumpSwapPss);
   19662             if (!brief && !opts.oomOnly) {
   19663                 dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_CATEGORY, "cat",
   19664                         catMems, true, opts.dumpSwapPss);
   19665             }
   19666             MemInfoReader memInfo = new MemInfoReader();
   19667             memInfo.readMemInfo();
   19668             if (nativeProcTotalPss > 0) {
   19669                 synchronized (this) {
   19670                     final long cachedKb = memInfo.getCachedSizeKb();
   19671                     final long freeKb = memInfo.getFreeSizeKb();
   19672                     final long zramKb = memInfo.getZramTotalSizeKb();
   19673                     final long kernelKb = memInfo.getKernelUsedSizeKb();
   19674                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
   19675                             kernelKb*1024, nativeProcTotalPss*1024);
   19676                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
   19677                             nativeProcTotalPss);
   19678                 }
   19679             }
   19680             if (!brief) {
   19681                 proto.write(MemInfoDumpProto.TOTAL_RAM_KB, memInfo.getTotalSizeKb());
   19682                 proto.write(MemInfoDumpProto.STATUS, mLastMemoryLevel);
   19683                 proto.write(MemInfoDumpProto.CACHED_PSS_KB, cachedPss);
   19684                 proto.write(MemInfoDumpProto.CACHED_KERNEL_KB, memInfo.getCachedSizeKb());
   19685                 proto.write(MemInfoDumpProto.FREE_KB, memInfo.getFreeSizeKb());
   19686             }
   19687             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
   19688                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
   19689                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
   19690             proto.write(MemInfoDumpProto.USED_PSS_KB, totalPss - cachedPss);
   19691             proto.write(MemInfoDumpProto.USED_KERNEL_KB, memInfo.getKernelUsedSizeKb());
   19692             proto.write(MemInfoDumpProto.LOST_RAM_KB, lostRAM);
   19693             if (!brief) {
   19694                 if (memInfo.getZramTotalSizeKb() != 0) {
   19695                     proto.write(MemInfoDumpProto.TOTAL_ZRAM_KB, memInfo.getZramTotalSizeKb());
   19696                     proto.write(MemInfoDumpProto.ZRAM_PHYSICAL_USED_IN_SWAP_KB,
   19697                             memInfo.getSwapTotalSizeKb() - memInfo.getSwapFreeSizeKb());
   19698                     proto.write(MemInfoDumpProto.TOTAL_ZRAM_SWAP_KB, memInfo.getSwapTotalSizeKb());
   19699                 }
   19700                 final long[] ksm = getKsmInfo();
   19701                 proto.write(MemInfoDumpProto.KSM_SHARING_KB, ksm[KSM_SHARING]);
   19702                 proto.write(MemInfoDumpProto.KSM_SHARED_KB, ksm[KSM_SHARED]);
   19703                 proto.write(MemInfoDumpProto.KSM_UNSHARED_KB, ksm[KSM_UNSHARED]);
   19704                 proto.write(MemInfoDumpProto.KSM_VOLATILE_KB, ksm[KSM_VOLATILE]);
   19705 
   19706                 proto.write(MemInfoDumpProto.TUNING_MB, ActivityManager.staticGetMemoryClass());
   19707                 proto.write(MemInfoDumpProto.TUNING_LARGE_MB, ActivityManager.staticGetLargeMemoryClass());
   19708                 proto.write(MemInfoDumpProto.OOM_KB,
   19709                         mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024);
   19710                 proto.write(MemInfoDumpProto.RESTORE_LIMIT_KB,
   19711                         mProcessList.getCachedRestoreThresholdKb());
   19712 
   19713                 proto.write(MemInfoDumpProto.IS_LOW_RAM_DEVICE, ActivityManager.isLowRamDeviceStatic());
   19714                 proto.write(MemInfoDumpProto.IS_HIGH_END_GFX, ActivityManager.isHighEndGfx());
   19715             }
   19716         }
   19717 
   19718         proto.flush();
   19719     }
   19720 
   19721     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
   19722             long memtrack, String name) {
   19723         sb.append("  ");
   19724         sb.append(ProcessList.makeOomAdjString(oomAdj));
   19725         sb.append(' ');
   19726         sb.append(ProcessList.makeProcStateString(procState));
   19727         sb.append(' ');
   19728         ProcessList.appendRamKb(sb, pss);
   19729         sb.append(": ");
   19730         sb.append(name);
   19731         if (memtrack > 0) {
   19732             sb.append(" (");
   19733             sb.append(stringifyKBSize(memtrack));
   19734             sb.append(" memtrack)");
   19735         }
   19736     }
   19737 
   19738     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
   19739         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
   19740         sb.append(" (pid ");
   19741         sb.append(mi.pid);
   19742         sb.append(") ");
   19743         sb.append(mi.adjType);
   19744         sb.append('\n');
   19745         if (mi.adjReason != null) {
   19746             sb.append("                      ");
   19747             sb.append(mi.adjReason);
   19748             sb.append('\n');
   19749         }
   19750     }
   19751 
   19752     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
   19753         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
   19754         for (int i=0, N=memInfos.size(); i<N; i++) {
   19755             ProcessMemInfo mi = memInfos.get(i);
   19756             infoMap.put(mi.pid, mi);
   19757         }
   19758         updateCpuStatsNow();
   19759         long[] memtrackTmp = new long[1];
   19760         final List<ProcessCpuTracker.Stats> stats;
   19761         // Get a list of Stats that have vsize > 0
   19762         synchronized (mProcessCpuTracker) {
   19763             stats = mProcessCpuTracker.getStats((st) -> {
   19764                 return st.vsize > 0;
   19765             });
   19766         }
   19767         final int statsCount = stats.size();
   19768         for (int i = 0; i < statsCount; i++) {
   19769             ProcessCpuTracker.Stats st = stats.get(i);
   19770             long pss = Debug.getPss(st.pid, null, memtrackTmp);
   19771             if (pss > 0) {
   19772                 if (infoMap.indexOfKey(st.pid) < 0) {
   19773                     ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
   19774                             ProcessList.NATIVE_ADJ, -1, "native", null);
   19775                     mi.pss = pss;
   19776                     mi.memtrack = memtrackTmp[0];
   19777                     memInfos.add(mi);
   19778                 }
   19779             }
   19780         }
   19781 
   19782         long totalPss = 0;
   19783         long totalMemtrack = 0;
   19784         for (int i=0, N=memInfos.size(); i<N; i++) {
   19785             ProcessMemInfo mi = memInfos.get(i);
   19786             if (mi.pss == 0) {
   19787                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
   19788                 mi.memtrack = memtrackTmp[0];
   19789             }
   19790             totalPss += mi.pss;
   19791             totalMemtrack += mi.memtrack;
   19792         }
   19793         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
   19794             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
   19795                 if (lhs.oomAdj != rhs.oomAdj) {
   19796                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
   19797                 }
   19798                 if (lhs.pss != rhs.pss) {
   19799                     return lhs.pss < rhs.pss ? 1 : -1;
   19800                 }
   19801                 return 0;
   19802             }
   19803         });
   19804 
   19805         StringBuilder tag = new StringBuilder(128);
   19806         StringBuilder stack = new StringBuilder(128);
   19807         tag.append("Low on memory -- ");
   19808         appendMemBucket(tag, totalPss, "total", false);
   19809         appendMemBucket(stack, totalPss, "total", true);
   19810 
   19811         StringBuilder fullNativeBuilder = new StringBuilder(1024);
   19812         StringBuilder shortNativeBuilder = new StringBuilder(1024);
   19813         StringBuilder fullJavaBuilder = new StringBuilder(1024);
   19814 
   19815         boolean firstLine = true;
   19816         int lastOomAdj = Integer.MIN_VALUE;
   19817         long extraNativeRam = 0;
   19818         long extraNativeMemtrack = 0;
   19819         long cachedPss = 0;
   19820         for (int i=0, N=memInfos.size(); i<N; i++) {
   19821             ProcessMemInfo mi = memInfos.get(i);
   19822 
   19823             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   19824                 cachedPss += mi.pss;
   19825             }
   19826 
   19827             if (mi.oomAdj != ProcessList.NATIVE_ADJ
   19828                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
   19829                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
   19830                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
   19831                 if (lastOomAdj != mi.oomAdj) {
   19832                     lastOomAdj = mi.oomAdj;
   19833                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   19834                         tag.append(" / ");
   19835                     }
   19836                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
   19837                         if (firstLine) {
   19838                             stack.append(":");
   19839                             firstLine = false;
   19840                         }
   19841                         stack.append("\n\t at ");
   19842                     } else {
   19843                         stack.append("$");
   19844                     }
   19845                 } else {
   19846                     tag.append(" ");
   19847                     stack.append("$");
   19848                 }
   19849                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   19850                     appendMemBucket(tag, mi.pss, mi.name, false);
   19851                 }
   19852                 appendMemBucket(stack, mi.pss, mi.name, true);
   19853                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
   19854                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
   19855                     stack.append("(");
   19856                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
   19857                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
   19858                             stack.append(DUMP_MEM_OOM_LABEL[k]);
   19859                             stack.append(":");
   19860                             stack.append(DUMP_MEM_OOM_ADJ[k]);
   19861                         }
   19862                     }
   19863                     stack.append(")");
   19864                 }
   19865             }
   19866 
   19867             appendMemInfo(fullNativeBuilder, mi);
   19868             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
   19869                 // The short form only has native processes that are >= 512K.
   19870                 if (mi.pss >= 512) {
   19871                     appendMemInfo(shortNativeBuilder, mi);
   19872                 } else {
   19873                     extraNativeRam += mi.pss;
   19874                     extraNativeMemtrack += mi.memtrack;
   19875                 }
   19876             } else {
   19877                 // Short form has all other details, but if we have collected RAM
   19878                 // from smaller native processes let's dump a summary of that.
   19879                 if (extraNativeRam > 0) {
   19880                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
   19881                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
   19882                     shortNativeBuilder.append('\n');
   19883                     extraNativeRam = 0;
   19884                 }
   19885                 appendMemInfo(fullJavaBuilder, mi);
   19886             }
   19887         }
   19888 
   19889         fullJavaBuilder.append("           ");
   19890         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
   19891         fullJavaBuilder.append(": TOTAL");
   19892         if (totalMemtrack > 0) {
   19893             fullJavaBuilder.append(" (");
   19894             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
   19895             fullJavaBuilder.append(" memtrack)");
   19896         } else {
   19897         }
   19898         fullJavaBuilder.append("\n");
   19899 
   19900         MemInfoReader memInfo = new MemInfoReader();
   19901         memInfo.readMemInfo();
   19902         final long[] infos = memInfo.getRawInfo();
   19903 
   19904         StringBuilder memInfoBuilder = new StringBuilder(1024);
   19905         Debug.getMemInfo(infos);
   19906         memInfoBuilder.append("  MemInfo: ");
   19907         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
   19908         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
   19909         memInfoBuilder.append(stringifyKBSize(
   19910                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
   19911         memInfoBuilder.append(stringifyKBSize(
   19912                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
   19913         memInfoBuilder.append(stringifyKBSize(
   19914                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
   19915         memInfoBuilder.append("           ");
   19916         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
   19917         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
   19918         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
   19919         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
   19920         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
   19921             memInfoBuilder.append("  ZRAM: ");
   19922             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
   19923             memInfoBuilder.append(" RAM, ");
   19924             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
   19925             memInfoBuilder.append(" swap total, ");
   19926             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
   19927             memInfoBuilder.append(" swap free\n");
   19928         }
   19929         final long[] ksm = getKsmInfo();
   19930         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
   19931                 || ksm[KSM_VOLATILE] != 0) {
   19932             memInfoBuilder.append("  KSM: ");
   19933             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
   19934             memInfoBuilder.append(" saved from shared ");
   19935             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
   19936             memInfoBuilder.append("\n       ");
   19937             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
   19938             memInfoBuilder.append(" unshared; ");
   19939             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
   19940             memInfoBuilder.append(" volatile\n");
   19941         }
   19942         memInfoBuilder.append("  Free RAM: ");
   19943         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
   19944                 + memInfo.getFreeSizeKb()));
   19945         memInfoBuilder.append("\n");
   19946         memInfoBuilder.append("  Used RAM: ");
   19947         memInfoBuilder.append(stringifyKBSize(
   19948                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
   19949         memInfoBuilder.append("\n");
   19950         memInfoBuilder.append("  Lost RAM: ");
   19951         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
   19952                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
   19953                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
   19954         memInfoBuilder.append("\n");
   19955         Slog.i(TAG, "Low on memory:");
   19956         Slog.i(TAG, shortNativeBuilder.toString());
   19957         Slog.i(TAG, fullJavaBuilder.toString());
   19958         Slog.i(TAG, memInfoBuilder.toString());
   19959 
   19960         StringBuilder dropBuilder = new StringBuilder(1024);
   19961         /*
   19962         StringWriter oomSw = new StringWriter();
   19963         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
   19964         StringWriter catSw = new StringWriter();
   19965         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
   19966         String[] emptyArgs = new String[] { };
   19967         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
   19968         oomPw.flush();
   19969         String oomString = oomSw.toString();
   19970         */
   19971         dropBuilder.append("Low on memory:");
   19972         dropBuilder.append(stack);
   19973         dropBuilder.append('\n');
   19974         dropBuilder.append(fullNativeBuilder);
   19975         dropBuilder.append(fullJavaBuilder);
   19976         dropBuilder.append('\n');
   19977         dropBuilder.append(memInfoBuilder);
   19978         dropBuilder.append('\n');
   19979         /*
   19980         dropBuilder.append(oomString);
   19981         dropBuilder.append('\n');
   19982         */
   19983         StringWriter catSw = new StringWriter();
   19984         synchronized (ActivityManagerService.this) {
   19985             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
   19986             String[] emptyArgs = new String[] { };
   19987             catPw.println();
   19988             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null, -1);
   19989             catPw.println();
   19990             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
   19991                     false, null).dumpLocked();
   19992             catPw.println();
   19993             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
   19994             catPw.flush();
   19995         }
   19996         dropBuilder.append(catSw.toString());
   19997         StatsLog.write(StatsLog.LOW_MEM_REPORTED);
   19998         addErrorToDropBox("lowmem", null, "system_server", null,
   19999                 null, tag.toString(), dropBuilder.toString(), null, null);
   20000         //Slog.i(TAG, "Sent to dropbox:");
   20001         //Slog.i(TAG, dropBuilder.toString());
   20002         synchronized (ActivityManagerService.this) {
   20003             long now = SystemClock.uptimeMillis();
   20004             if (mLastMemUsageReportTime < now) {
   20005                 mLastMemUsageReportTime = now;
   20006             }
   20007         }
   20008     }
   20009 
   20010     /**
   20011      * Searches array of arguments for the specified string
   20012      * @param args array of argument strings
   20013      * @param value value to search for
   20014      * @return true if the value is contained in the array
   20015      */
   20016     private static boolean scanArgs(String[] args, String value) {
   20017         if (args != null) {
   20018             for (String arg : args) {
   20019                 if (value.equals(arg)) {
   20020                     return true;
   20021                 }
   20022             }
   20023         }
   20024         return false;
   20025     }
   20026 
   20027     private final boolean removeDyingProviderLocked(ProcessRecord proc,
   20028             ContentProviderRecord cpr, boolean always) {
   20029         final boolean inLaunching = mLaunchingProviders.contains(cpr);
   20030 
   20031         if (!inLaunching || always) {
   20032             synchronized (cpr) {
   20033                 cpr.launchingApp = null;
   20034                 cpr.notifyAll();
   20035             }
   20036             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
   20037             String names[] = cpr.info.authority.split(";");
   20038             for (int j = 0; j < names.length; j++) {
   20039                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
   20040             }
   20041         }
   20042 
   20043         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
   20044             ContentProviderConnection conn = cpr.connections.get(i);
   20045             if (conn.waiting) {
   20046                 // If this connection is waiting for the provider, then we don't
   20047                 // need to mess with its process unless we are always removing
   20048                 // or for some reason the provider is not currently launching.
   20049                 if (inLaunching && !always) {
   20050                     continue;
   20051                 }
   20052             }
   20053             ProcessRecord capp = conn.client;
   20054             conn.dead = true;
   20055             if (conn.stableCount > 0) {
   20056                 if (!capp.persistent && capp.thread != null
   20057                         && capp.pid != 0
   20058                         && capp.pid != MY_PID) {
   20059                     capp.kill("depends on provider "
   20060                             + cpr.name.flattenToShortString()
   20061                             + " in dying proc " + (proc != null ? proc.processName : "??")
   20062                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
   20063                 }
   20064             } else if (capp.thread != null && conn.provider.provider != null) {
   20065                 try {
   20066                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
   20067                 } catch (RemoteException e) {
   20068                 }
   20069                 // In the protocol here, we don't expect the client to correctly
   20070                 // clean up this connection, we'll just remove it.
   20071                 cpr.connections.remove(i);
   20072                 if (conn.client.conProviders.remove(conn)) {
   20073                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
   20074                 }
   20075             }
   20076         }
   20077 
   20078         if (inLaunching && always) {
   20079             mLaunchingProviders.remove(cpr);
   20080         }
   20081         return inLaunching;
   20082     }
   20083 
   20084     /**
   20085      * Main code for cleaning up a process when it has gone away.  This is
   20086      * called both as a result of the process dying, or directly when stopping
   20087      * a process when running in single process mode.
   20088      *
   20089      * @return Returns true if the given process has been restarted, so the
   20090      * app that was passed in must remain on the process lists.
   20091      */
   20092     @GuardedBy("this")
   20093     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
   20094             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
   20095         if (index >= 0) {
   20096             removeLruProcessLocked(app);
   20097             ProcessList.remove(app.pid);
   20098         }
   20099 
   20100         mProcessesToGc.remove(app);
   20101         mPendingPssProcesses.remove(app);
   20102         ProcessList.abortNextPssTime(app.procStateMemTracker);
   20103 
   20104         // Dismiss any open dialogs.
   20105         if (app.crashDialog != null && !app.forceCrashReport) {
   20106             app.crashDialog.dismiss();
   20107             app.crashDialog = null;
   20108         }
   20109         if (app.anrDialog != null) {
   20110             app.anrDialog.dismiss();
   20111             app.anrDialog = null;
   20112         }
   20113         if (app.waitDialog != null) {
   20114             app.waitDialog.dismiss();
   20115             app.waitDialog = null;
   20116         }
   20117 
   20118         app.crashing = false;
   20119         app.notResponding = false;
   20120 
   20121         app.resetPackageList(mProcessStats);
   20122         app.unlinkDeathRecipient();
   20123         app.makeInactive(mProcessStats);
   20124         app.waitingToKill = null;
   20125         app.forcingToImportant = null;
   20126         updateProcessForegroundLocked(app, false, false);
   20127         app.foregroundActivities = false;
   20128         app.hasShownUi = false;
   20129         app.treatLikeActivity = false;
   20130         app.hasAboveClient = false;
   20131         app.hasClientActivities = false;
   20132 
   20133         mServices.killServicesLocked(app, allowRestart);
   20134 
   20135         boolean restart = false;
   20136 
   20137         // Remove published content providers.
   20138         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
   20139             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
   20140             final boolean always = app.bad || !allowRestart;
   20141             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
   20142             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
   20143                 // We left the provider in the launching list, need to
   20144                 // restart it.
   20145                 restart = true;
   20146             }
   20147 
   20148             cpr.provider = null;
   20149             cpr.proc = null;
   20150         }
   20151         app.pubProviders.clear();
   20152 
   20153         // Take care of any launching providers waiting for this process.
   20154         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
   20155             restart = true;
   20156         }
   20157 
   20158         // Unregister from connected content providers.
   20159         if (!app.conProviders.isEmpty()) {
   20160             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
   20161                 ContentProviderConnection conn = app.conProviders.get(i);
   20162                 conn.provider.connections.remove(conn);
   20163                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
   20164                         conn.provider.name);
   20165             }
   20166             app.conProviders.clear();
   20167         }
   20168 
   20169         // At this point there may be remaining entries in mLaunchingProviders
   20170         // where we were the only one waiting, so they are no longer of use.
   20171         // Look for these and clean up if found.
   20172         // XXX Commented out for now.  Trying to figure out a way to reproduce
   20173         // the actual situation to identify what is actually going on.
   20174         if (false) {
   20175             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
   20176                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
   20177                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
   20178                     synchronized (cpr) {
   20179                         cpr.launchingApp = null;
   20180                         cpr.notifyAll();
   20181                     }
   20182                 }
   20183             }
   20184         }
   20185 
   20186         skipCurrentReceiverLocked(app);
   20187 
   20188         // Unregister any receivers.
   20189         for (int i = app.receivers.size() - 1; i >= 0; i--) {
   20190             removeReceiverLocked(app.receivers.valueAt(i));
   20191         }
   20192         app.receivers.clear();
   20193 
   20194         // If the app is undergoing backup, tell the backup manager about it
   20195         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
   20196             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
   20197                     + mBackupTarget.appInfo + " died during backup");
   20198             mHandler.post(new Runnable() {
   20199                 @Override
   20200                 public void run(){
   20201                     try {
   20202                         IBackupManager bm = IBackupManager.Stub.asInterface(
   20203                                 ServiceManager.getService(Context.BACKUP_SERVICE));
   20204                         bm.agentDisconnected(app.info.packageName);
   20205                     } catch (RemoteException e) {
   20206                         // can't happen; backup manager is local
   20207                     }
   20208                 }
   20209             });
   20210         }
   20211 
   20212         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
   20213             ProcessChangeItem item = mPendingProcessChanges.get(i);
   20214             if (app.pid > 0 && item.pid == app.pid) {
   20215                 mPendingProcessChanges.remove(i);
   20216                 mAvailProcessChanges.add(item);
   20217             }
   20218         }
   20219         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
   20220                 null).sendToTarget();
   20221 
   20222         // If the caller is restarting this app, then leave it in its
   20223         // current lists and let the caller take care of it.
   20224         if (restarting) {
   20225             return false;
   20226         }
   20227 
   20228         if (!app.persistent || app.isolated) {
   20229             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
   20230                     "Removing non-persistent process during cleanup: " + app);
   20231             if (!replacingPid) {
   20232                 removeProcessNameLocked(app.processName, app.uid, app);
   20233             }
   20234             if (mHeavyWeightProcess == app) {
   20235                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   20236                         mHeavyWeightProcess.userId, 0));
   20237                 mHeavyWeightProcess = null;
   20238             }
   20239         } else if (!app.removed) {
   20240             // This app is persistent, so we need to keep its record around.
   20241             // If it is not already on the pending app list, add it there
   20242             // and start a new process for it.
   20243             if (mPersistentStartingProcesses.indexOf(app) < 0) {
   20244                 mPersistentStartingProcesses.add(app);
   20245                 restart = true;
   20246             }
   20247         }
   20248         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
   20249                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
   20250         mProcessesOnHold.remove(app);
   20251 
   20252         if (app == mHomeProcess) {
   20253             mHomeProcess = null;
   20254         }
   20255         if (app == mPreviousProcess) {
   20256             mPreviousProcess = null;
   20257         }
   20258 
   20259         if (restart && !app.isolated) {
   20260             // We have components that still need to be running in the
   20261             // process, so re-launch it.
   20262             if (index < 0) {
   20263                 ProcessList.remove(app.pid);
   20264             }
   20265             addProcessNameLocked(app);
   20266             app.pendingStart = false;
   20267             startProcessLocked(app, "restart", app.processName);
   20268             return true;
   20269         } else if (app.pid > 0 && app.pid != MY_PID) {
   20270             // Goodbye!
   20271             boolean removed;
   20272             synchronized (mPidsSelfLocked) {
   20273                 mPidsSelfLocked.remove(app.pid);
   20274                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   20275             }
   20276             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   20277             if (app.isolated) {
   20278                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   20279             }
   20280             app.setPid(0);
   20281         }
   20282         return false;
   20283     }
   20284 
   20285     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
   20286         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
   20287             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   20288             if (cpr.launchingApp == app) {
   20289                 return true;
   20290             }
   20291         }
   20292         return false;
   20293     }
   20294 
   20295     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
   20296         // Look through the content providers we are waiting to have launched,
   20297         // and if any run in this process then either schedule a restart of
   20298         // the process or kill the client waiting for it if this process has
   20299         // gone bad.
   20300         boolean restart = false;
   20301         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
   20302             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   20303             if (cpr.launchingApp == app) {
   20304                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
   20305                     restart = true;
   20306                 } else {
   20307                     removeDyingProviderLocked(app, cpr, true);
   20308                 }
   20309             }
   20310         }
   20311         return restart;
   20312     }
   20313 
   20314     // =========================================================
   20315     // SERVICES
   20316     // =========================================================
   20317 
   20318     @Override
   20319     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) {
   20320         enforceNotIsolatedCaller("getServices");
   20321 
   20322         final int callingUid = Binder.getCallingUid();
   20323         final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
   20324             INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
   20325         final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
   20326             callingUid);
   20327         synchronized (this) {
   20328             return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
   20329                 allowed, canInteractAcrossUsers);
   20330         }
   20331     }
   20332 
   20333     @Override
   20334     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
   20335         enforceNotIsolatedCaller("getRunningServiceControlPanel");
   20336         synchronized (this) {
   20337             return mServices.getRunningServiceControlPanelLocked(name);
   20338         }
   20339     }
   20340 
   20341     @Override
   20342     public ComponentName startService(IApplicationThread caller, Intent service,
   20343             String resolvedType, boolean requireForeground, String callingPackage, int userId)
   20344             throws TransactionTooLargeException {
   20345         enforceNotIsolatedCaller("startService");
   20346         // Refuse possible leaked file descriptors
   20347         if (service != null && service.hasFileDescriptors() == true) {
   20348             throw new IllegalArgumentException("File descriptors passed in Intent");
   20349         }
   20350 
   20351         if (callingPackage == null) {
   20352             throw new IllegalArgumentException("callingPackage cannot be null");
   20353         }
   20354 
   20355         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
   20356                 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
   20357         synchronized(this) {
   20358             final int callingPid = Binder.getCallingPid();
   20359             final int callingUid = Binder.getCallingUid();
   20360             final long origId = Binder.clearCallingIdentity();
   20361             ComponentName res;
   20362             try {
   20363                 res = mServices.startServiceLocked(caller, service,
   20364                         resolvedType, callingPid, callingUid,
   20365                         requireForeground, callingPackage, userId);
   20366             } finally {
   20367                 Binder.restoreCallingIdentity(origId);
   20368             }
   20369             return res;
   20370         }
   20371     }
   20372 
   20373     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
   20374             boolean fgRequired, String callingPackage, int userId)
   20375             throws TransactionTooLargeException {
   20376         synchronized(this) {
   20377             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
   20378                     "startServiceInPackage: " + service + " type=" + resolvedType);
   20379             final long origId = Binder.clearCallingIdentity();
   20380             ComponentName res;
   20381             try {
   20382                 res = mServices.startServiceLocked(null, service,
   20383                         resolvedType, -1, uid, fgRequired, callingPackage, userId);
   20384             } finally {
   20385                 Binder.restoreCallingIdentity(origId);
   20386             }
   20387             return res;
   20388         }
   20389     }
   20390 
   20391     @Override
   20392     public int stopService(IApplicationThread caller, Intent service,
   20393             String resolvedType, int userId) {
   20394         enforceNotIsolatedCaller("stopService");
   20395         // Refuse possible leaked file descriptors
   20396         if (service != null && service.hasFileDescriptors() == true) {
   20397             throw new IllegalArgumentException("File descriptors passed in Intent");
   20398         }
   20399 
   20400         synchronized(this) {
   20401             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
   20402         }
   20403     }
   20404 
   20405     @Override
   20406     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
   20407         enforceNotIsolatedCaller("peekService");
   20408         // Refuse possible leaked file descriptors
   20409         if (service != null && service.hasFileDescriptors() == true) {
   20410             throw new IllegalArgumentException("File descriptors passed in Intent");
   20411         }
   20412 
   20413         if (callingPackage == null) {
   20414             throw new IllegalArgumentException("callingPackage cannot be null");
   20415         }
   20416 
   20417         synchronized(this) {
   20418             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
   20419         }
   20420     }
   20421 
   20422     @Override
   20423     public boolean stopServiceToken(ComponentName className, IBinder token,
   20424             int startId) {
   20425         synchronized(this) {
   20426             return mServices.stopServiceTokenLocked(className, token, startId);
   20427         }
   20428     }
   20429 
   20430     @Override
   20431     public void setServiceForeground(ComponentName className, IBinder token,
   20432             int id, Notification notification, int flags) {
   20433         synchronized(this) {
   20434             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
   20435         }
   20436     }
   20437 
   20438     @Override
   20439     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
   20440             boolean requireFull, String name, String callerPackage) {
   20441         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
   20442                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
   20443     }
   20444 
   20445     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
   20446             String className, int flags) {
   20447         boolean result = false;
   20448         // For apps that don't have pre-defined UIDs, check for permission
   20449         if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
   20450             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
   20451                 if (ActivityManager.checkUidPermission(
   20452                         INTERACT_ACROSS_USERS,
   20453                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
   20454                     ComponentName comp = new ComponentName(aInfo.packageName, className);
   20455                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
   20456                             + " requests FLAG_SINGLE_USER, but app does not hold "
   20457                             + INTERACT_ACROSS_USERS;
   20458                     Slog.w(TAG, msg);
   20459                     throw new SecurityException(msg);
   20460                 }
   20461                 // Permission passed
   20462                 result = true;
   20463             }
   20464         } else if ("system".equals(componentProcessName)) {
   20465             result = true;
   20466         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
   20467             // Phone app and persistent apps are allowed to export singleuser providers.
   20468             result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
   20469                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
   20470         }
   20471         if (DEBUG_MU) Slog.v(TAG_MU,
   20472                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
   20473                 + Integer.toHexString(flags) + ") = " + result);
   20474         return result;
   20475     }
   20476 
   20477     /**
   20478      * Checks to see if the caller is in the same app as the singleton
   20479      * component, or the component is in a special app. It allows special apps
   20480      * to export singleton components but prevents exporting singleton
   20481      * components for regular apps.
   20482      */
   20483     boolean isValidSingletonCall(int callingUid, int componentUid) {
   20484         int componentAppId = UserHandle.getAppId(componentUid);
   20485         return UserHandle.isSameApp(callingUid, componentUid)
   20486                 || componentAppId == SYSTEM_UID
   20487                 || componentAppId == PHONE_UID
   20488                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
   20489                         == PackageManager.PERMISSION_GRANTED;
   20490     }
   20491 
   20492     public int bindService(IApplicationThread caller, IBinder token, Intent service,
   20493             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
   20494             int userId) throws TransactionTooLargeException {
   20495         enforceNotIsolatedCaller("bindService");
   20496 
   20497         // Refuse possible leaked file descriptors
   20498         if (service != null && service.hasFileDescriptors() == true) {
   20499             throw new IllegalArgumentException("File descriptors passed in Intent");
   20500         }
   20501 
   20502         if (callingPackage == null) {
   20503             throw new IllegalArgumentException("callingPackage cannot be null");
   20504         }
   20505 
   20506         synchronized(this) {
   20507             return mServices.bindServiceLocked(caller, token, service,
   20508                     resolvedType, connection, flags, callingPackage, userId);
   20509         }
   20510     }
   20511 
   20512     public boolean unbindService(IServiceConnection connection) {
   20513         synchronized (this) {
   20514             return mServices.unbindServiceLocked(connection);
   20515         }
   20516     }
   20517 
   20518     public void publishService(IBinder token, Intent intent, IBinder service) {
   20519         // Refuse possible leaked file descriptors
   20520         if (intent != null && intent.hasFileDescriptors() == true) {
   20521             throw new IllegalArgumentException("File descriptors passed in Intent");
   20522         }
   20523 
   20524         synchronized(this) {
   20525             if (!(token instanceof ServiceRecord)) {
   20526                 throw new IllegalArgumentException("Invalid service token");
   20527             }
   20528             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
   20529         }
   20530     }
   20531 
   20532     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
   20533         // Refuse possible leaked file descriptors
   20534         if (intent != null && intent.hasFileDescriptors() == true) {
   20535             throw new IllegalArgumentException("File descriptors passed in Intent");
   20536         }
   20537 
   20538         synchronized(this) {
   20539             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
   20540         }
   20541     }
   20542 
   20543     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
   20544         synchronized(this) {
   20545             if (!(token instanceof ServiceRecord)) {
   20546                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
   20547                 throw new IllegalArgumentException("Invalid service token");
   20548             }
   20549             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
   20550         }
   20551     }
   20552 
   20553     // =========================================================
   20554     // BACKUP AND RESTORE
   20555     // =========================================================
   20556 
   20557     // Cause the target app to be launched if necessary and its backup agent
   20558     // instantiated.  The backup agent will invoke backupAgentCreated() on the
   20559     // activity manager to announce its creation.
   20560     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
   20561         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
   20562         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
   20563 
   20564         IPackageManager pm = AppGlobals.getPackageManager();
   20565         ApplicationInfo app = null;
   20566         try {
   20567             app = pm.getApplicationInfo(packageName, STOCK_PM_FLAGS, userId);
   20568         } catch (RemoteException e) {
   20569             // can't happen; package manager is process-local
   20570         }
   20571         if (app == null) {
   20572             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
   20573             return false;
   20574         }
   20575 
   20576         int oldBackupUid;
   20577         int newBackupUid;
   20578 
   20579         synchronized(this) {
   20580             // !!! TODO: currently no check here that we're already bound
   20581             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   20582             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   20583             synchronized (stats) {
   20584                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
   20585             }
   20586 
   20587             // Backup agent is now in use, its package can't be stopped.
   20588             try {
   20589                 AppGlobals.getPackageManager().setPackageStoppedState(
   20590                         app.packageName, false, UserHandle.getUserId(app.uid));
   20591             } catch (RemoteException e) {
   20592             } catch (IllegalArgumentException e) {
   20593                 Slog.w(TAG, "Failed trying to unstop package "
   20594                         + app.packageName + ": " + e);
   20595             }
   20596 
   20597             BackupRecord r = new BackupRecord(ss, app, backupMode);
   20598             ComponentName hostingName =
   20599                     (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
   20600                             ? new ComponentName(app.packageName, app.backupAgentName)
   20601                             : new ComponentName("android", "FullBackupAgent");
   20602             // startProcessLocked() returns existing proc's record if it's already running
   20603             ProcessRecord proc = startProcessLocked(app.processName, app,
   20604                     false, 0, "backup", hostingName, false, false, false);
   20605             if (proc == null) {
   20606                 Slog.e(TAG, "Unable to start backup agent process " + r);
   20607                 return false;
   20608             }
   20609 
   20610             // If the app is a regular app (uid >= 10000) and not the system server or phone
   20611             // process, etc, then mark it as being in full backup so that certain calls to the
   20612             // process can be blocked. This is not reset to false anywhere because we kill the
   20613             // process after the full backup is done and the ProcessRecord will vaporize anyway.
   20614             if (UserHandle.isApp(app.uid) &&
   20615                     backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
   20616                 proc.inFullBackup = true;
   20617             }
   20618             r.app = proc;
   20619             oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
   20620             newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
   20621             mBackupTarget = r;
   20622             mBackupAppName = app.packageName;
   20623 
   20624             // Try not to kill the process during backup
   20625             updateOomAdjLocked(proc, true);
   20626 
   20627             // If the process is already attached, schedule the creation of the backup agent now.
   20628             // If it is not yet live, this will be done when it attaches to the framework.
   20629             if (proc.thread != null) {
   20630                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
   20631                 try {
   20632                     proc.thread.scheduleCreateBackupAgent(app,
   20633                             compatibilityInfoForPackageLocked(app), backupMode);
   20634                 } catch (RemoteException e) {
   20635                     // Will time out on the backup manager side
   20636                 }
   20637             } else {
   20638                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
   20639             }
   20640             // Invariants: at this point, the target app process exists and the application
   20641             // is either already running or in the process of coming up.  mBackupTarget and
   20642             // mBackupAppName describe the app, so that when it binds back to the AM we
   20643             // know that it's scheduled for a backup-agent operation.
   20644         }
   20645 
   20646         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
   20647         if (oldBackupUid != -1) {
   20648             js.removeBackingUpUid(oldBackupUid);
   20649         }
   20650         if (newBackupUid != -1) {
   20651             js.addBackingUpUid(newBackupUid);
   20652         }
   20653 
   20654         return true;
   20655     }
   20656 
   20657     @Override
   20658     public void clearPendingBackup() {
   20659         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
   20660         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
   20661 
   20662         synchronized (this) {
   20663             mBackupTarget = null;
   20664             mBackupAppName = null;
   20665         }
   20666 
   20667         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
   20668         js.clearAllBackingUpUids();
   20669     }
   20670 
   20671     // A backup agent has just come up
   20672     public void backupAgentCreated(String agentPackageName, IBinder agent) {
   20673         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
   20674                 + " = " + agent);
   20675 
   20676         synchronized(this) {
   20677             if (!agentPackageName.equals(mBackupAppName)) {
   20678                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
   20679                 return;
   20680             }
   20681         }
   20682 
   20683         long oldIdent = Binder.clearCallingIdentity();
   20684         try {
   20685             IBackupManager bm = IBackupManager.Stub.asInterface(
   20686                     ServiceManager.getService(Context.BACKUP_SERVICE));
   20687             bm.agentConnected(agentPackageName, agent);
   20688         } catch (RemoteException e) {
   20689             // can't happen; the backup manager service is local
   20690         } catch (Exception e) {
   20691             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
   20692             e.printStackTrace();
   20693         } finally {
   20694             Binder.restoreCallingIdentity(oldIdent);
   20695         }
   20696     }
   20697 
   20698     // done with this agent
   20699     public void unbindBackupAgent(ApplicationInfo appInfo) {
   20700         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
   20701         if (appInfo == null) {
   20702             Slog.w(TAG, "unbind backup agent for null app");
   20703             return;
   20704         }
   20705 
   20706         int oldBackupUid;
   20707 
   20708         synchronized(this) {
   20709             try {
   20710                 if (mBackupAppName == null) {
   20711                     Slog.w(TAG, "Unbinding backup agent with no active backup");
   20712                     return;
   20713                 }
   20714 
   20715                 if (!mBackupAppName.equals(appInfo.packageName)) {
   20716                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
   20717                     return;
   20718                 }
   20719 
   20720                 // Not backing this app up any more; reset its OOM adjustment
   20721                 final ProcessRecord proc = mBackupTarget.app;
   20722                 updateOomAdjLocked(proc, true);
   20723                 proc.inFullBackup = false;
   20724 
   20725                 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
   20726 
   20727                 // If the app crashed during backup, 'thread' will be null here
   20728                 if (proc.thread != null) {
   20729                     try {
   20730                         proc.thread.scheduleDestroyBackupAgent(appInfo,
   20731                                 compatibilityInfoForPackageLocked(appInfo));
   20732                     } catch (Exception e) {
   20733                         Slog.e(TAG, "Exception when unbinding backup agent:");
   20734                         e.printStackTrace();
   20735                     }
   20736                 }
   20737             } finally {
   20738                 mBackupTarget = null;
   20739                 mBackupAppName = null;
   20740             }
   20741         }
   20742 
   20743         if (oldBackupUid != -1) {
   20744             JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
   20745             js.removeBackingUpUid(oldBackupUid);
   20746         }
   20747     }
   20748 
   20749     // =========================================================
   20750     // BROADCASTS
   20751     // =========================================================
   20752 
   20753     private boolean isInstantApp(ProcessRecord record, @Nullable String callerPackage, int uid) {
   20754         if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
   20755             return false;
   20756         }
   20757         // Easy case -- we have the app's ProcessRecord.
   20758         if (record != null) {
   20759             return record.info.isInstantApp();
   20760         }
   20761         // Otherwise check with PackageManager.
   20762         IPackageManager pm = AppGlobals.getPackageManager();
   20763         try {
   20764             if (callerPackage == null) {
   20765                 final String[] packageNames = pm.getPackagesForUid(uid);
   20766                 if (packageNames == null || packageNames.length == 0) {
   20767                     throw new IllegalArgumentException("Unable to determine caller package name");
   20768                 }
   20769                 // Instant Apps can't use shared uids, so its safe to only check the first package.
   20770                 callerPackage = packageNames[0];
   20771             }
   20772             mAppOpsService.checkPackage(uid, callerPackage);
   20773             return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
   20774         } catch (RemoteException e) {
   20775             Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
   20776             return true;
   20777         }
   20778     }
   20779 
   20780     boolean isPendingBroadcastProcessLocked(int pid) {
   20781         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
   20782                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
   20783     }
   20784 
   20785     void skipPendingBroadcastLocked(int pid) {
   20786             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   20787             for (BroadcastQueue queue : mBroadcastQueues) {
   20788                 queue.skipPendingBroadcastLocked(pid);
   20789             }
   20790     }
   20791 
   20792     // The app just attached; send any pending broadcasts that it should receive
   20793     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
   20794         boolean didSomething = false;
   20795         for (BroadcastQueue queue : mBroadcastQueues) {
   20796             didSomething |= queue.sendPendingBroadcastsLocked(app);
   20797         }
   20798         return didSomething;
   20799     }
   20800 
   20801     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
   20802             IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
   20803             int flags) {
   20804         enforceNotIsolatedCaller("registerReceiver");
   20805         ArrayList<Intent> stickyIntents = null;
   20806         ProcessRecord callerApp = null;
   20807         final boolean visibleToInstantApps
   20808                 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
   20809         int callingUid;
   20810         int callingPid;
   20811         boolean instantApp;
   20812         synchronized(this) {
   20813             if (caller != null) {
   20814                 callerApp = getRecordForAppLocked(caller);
   20815                 if (callerApp == null) {
   20816                     throw new SecurityException(
   20817                             "Unable to find app for caller " + caller
   20818                             + " (pid=" + Binder.getCallingPid()
   20819                             + ") when registering receiver " + receiver);
   20820                 }
   20821                 if (callerApp.info.uid != SYSTEM_UID &&
   20822                         !callerApp.pkgList.containsKey(callerPackage) &&
   20823                         !"android".equals(callerPackage)) {
   20824                     throw new SecurityException("Given caller package " + callerPackage
   20825                             + " is not running in process " + callerApp);
   20826                 }
   20827                 callingUid = callerApp.info.uid;
   20828                 callingPid = callerApp.pid;
   20829             } else {
   20830                 callerPackage = null;
   20831                 callingUid = Binder.getCallingUid();
   20832                 callingPid = Binder.getCallingPid();
   20833             }
   20834 
   20835             instantApp = isInstantApp(callerApp, callerPackage, callingUid);
   20836             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
   20837                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
   20838 
   20839             Iterator<String> actions = filter.actionsIterator();
   20840             if (actions == null) {
   20841                 ArrayList<String> noAction = new ArrayList<String>(1);
   20842                 noAction.add(null);
   20843                 actions = noAction.iterator();
   20844             }
   20845 
   20846             // Collect stickies of users
   20847             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
   20848             while (actions.hasNext()) {
   20849                 String action = actions.next();
   20850                 for (int id : userIds) {
   20851                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
   20852                     if (stickies != null) {
   20853                         ArrayList<Intent> intents = stickies.get(action);
   20854                         if (intents != null) {
   20855                             if (stickyIntents == null) {
   20856                                 stickyIntents = new ArrayList<Intent>();
   20857                             }
   20858                             stickyIntents.addAll(intents);
   20859                         }
   20860                     }
   20861                 }
   20862             }
   20863         }
   20864 
   20865         ArrayList<Intent> allSticky = null;
   20866         if (stickyIntents != null) {
   20867             final ContentResolver resolver = mContext.getContentResolver();
   20868             // Look for any matching sticky broadcasts...
   20869             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
   20870                 Intent intent = stickyIntents.get(i);
   20871                 // Don't provided intents that aren't available to instant apps.
   20872                 if (instantApp &&
   20873                         (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
   20874                     continue;
   20875                 }
   20876                 // If intent has scheme "content", it will need to acccess
   20877                 // provider that needs to lock mProviderMap in ActivityThread
   20878                 // and also it may need to wait application response, so we
   20879                 // cannot lock ActivityManagerService here.
   20880                 if (filter.match(resolver, intent, true, TAG) >= 0) {
   20881                     if (allSticky == null) {
   20882                         allSticky = new ArrayList<Intent>();
   20883                     }
   20884                     allSticky.add(intent);
   20885                 }
   20886             }
   20887         }
   20888 
   20889         // The first sticky in the list is returned directly back to the client.
   20890         Intent sticky = allSticky != null ? allSticky.get(0) : null;
   20891         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
   20892         if (receiver == null) {
   20893             return sticky;
   20894         }
   20895 
   20896         synchronized (this) {
   20897             if (callerApp != null && (callerApp.thread == null
   20898                     || callerApp.thread.asBinder() != caller.asBinder())) {
   20899                 // Original caller already died
   20900                 return null;
   20901             }
   20902             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
   20903             if (rl == null) {
   20904                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
   20905                         userId, receiver);
   20906                 if (rl.app != null) {
   20907                     final int totalReceiversForApp = rl.app.receivers.size();
   20908                     if (totalReceiversForApp >= MAX_RECEIVERS_ALLOWED_PER_APP) {
   20909                         throw new IllegalStateException("Too many receivers, total of "
   20910                                 + totalReceiversForApp + ", registered for pid: "
   20911                                 + rl.pid + ", callerPackage: " + callerPackage);
   20912                     }
   20913                     rl.app.receivers.add(rl);
   20914                 } else {
   20915                     try {
   20916                         receiver.asBinder().linkToDeath(rl, 0);
   20917                     } catch (RemoteException e) {
   20918                         return sticky;
   20919                     }
   20920                     rl.linkedToDeath = true;
   20921                 }
   20922                 mRegisteredReceivers.put(receiver.asBinder(), rl);
   20923             } else if (rl.uid != callingUid) {
   20924                 throw new IllegalArgumentException(
   20925                         "Receiver requested to register for uid " + callingUid
   20926                         + " was previously registered for uid " + rl.uid
   20927                         + " callerPackage is " + callerPackage);
   20928             } else if (rl.pid != callingPid) {
   20929                 throw new IllegalArgumentException(
   20930                         "Receiver requested to register for pid " + callingPid
   20931                         + " was previously registered for pid " + rl.pid
   20932                         + " callerPackage is " + callerPackage);
   20933             } else if (rl.userId != userId) {
   20934                 throw new IllegalArgumentException(
   20935                         "Receiver requested to register for user " + userId
   20936                         + " was previously registered for user " + rl.userId
   20937                         + " callerPackage is " + callerPackage);
   20938             }
   20939             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
   20940                     permission, callingUid, userId, instantApp, visibleToInstantApps);
   20941             if (rl.containsFilter(filter)) {
   20942                 Slog.w(TAG, "Receiver with filter " + filter
   20943                         + " already registered for pid " + rl.pid
   20944                         + ", callerPackage is " + callerPackage);
   20945             } else {
   20946                 rl.add(bf);
   20947                 if (!bf.debugCheck()) {
   20948                     Slog.w(TAG, "==> For Dynamic broadcast");
   20949                 }
   20950                 mReceiverResolver.addFilter(bf);
   20951             }
   20952 
   20953             // Enqueue broadcasts for all existing stickies that match
   20954             // this filter.
   20955             if (allSticky != null) {
   20956                 ArrayList receivers = new ArrayList();
   20957                 receivers.add(bf);
   20958 
   20959                 final int stickyCount = allSticky.size();
   20960                 for (int i = 0; i < stickyCount; i++) {
   20961                     Intent intent = allSticky.get(i);
   20962                     BroadcastQueue queue = broadcastQueueForIntent(intent);
   20963                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
   20964                             null, -1, -1, false, null, null, OP_NONE, null, receivers,
   20965                             null, 0, null, null, false, true, true, -1);
   20966                     queue.enqueueParallelBroadcastLocked(r);
   20967                     queue.scheduleBroadcastsLocked();
   20968                 }
   20969             }
   20970 
   20971             return sticky;
   20972         }
   20973     }
   20974 
   20975     public void unregisterReceiver(IIntentReceiver receiver) {
   20976         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
   20977 
   20978         final long origId = Binder.clearCallingIdentity();
   20979         try {
   20980             boolean doTrim = false;
   20981 
   20982             synchronized(this) {
   20983                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
   20984                 if (rl != null) {
   20985                     final BroadcastRecord r = rl.curBroadcast;
   20986                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
   20987                         final boolean doNext = r.queue.finishReceiverLocked(
   20988                                 r, r.resultCode, r.resultData, r.resultExtras,
   20989                                 r.resultAbort, false);
   20990                         if (doNext) {
   20991                             doTrim = true;
   20992                             r.queue.processNextBroadcast(false);
   20993                         }
   20994                     }
   20995 
   20996                     if (rl.app != null) {
   20997                         rl.app.receivers.remove(rl);
   20998                     }
   20999                     removeReceiverLocked(rl);
   21000                     if (rl.linkedToDeath) {
   21001                         rl.linkedToDeath = false;
   21002                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
   21003                     }
   21004                 }
   21005             }
   21006 
   21007             // If we actually concluded any broadcasts, we might now be able
   21008             // to trim the recipients' apps from our working set
   21009             if (doTrim) {
   21010                 trimApplications();
   21011                 return;
   21012             }
   21013 
   21014         } finally {
   21015             Binder.restoreCallingIdentity(origId);
   21016         }
   21017     }
   21018 
   21019     void removeReceiverLocked(ReceiverList rl) {
   21020         mRegisteredReceivers.remove(rl.receiver.asBinder());
   21021         for (int i = rl.size() - 1; i >= 0; i--) {
   21022             mReceiverResolver.removeFilter(rl.get(i));
   21023         }
   21024     }
   21025 
   21026     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
   21027         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   21028             ProcessRecord r = mLruProcesses.get(i);
   21029             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
   21030                 try {
   21031                     r.thread.dispatchPackageBroadcast(cmd, packages);
   21032                 } catch (RemoteException ex) {
   21033                 }
   21034             }
   21035         }
   21036     }
   21037 
   21038     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
   21039             int callingUid, int[] users) {
   21040         // TODO: come back and remove this assumption to triage all broadcasts
   21041         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
   21042 
   21043         List<ResolveInfo> receivers = null;
   21044         try {
   21045             HashSet<ComponentName> singleUserReceivers = null;
   21046             boolean scannedFirstReceivers = false;
   21047             for (int user : users) {
   21048                 // Skip users that have Shell restrictions, with exception of always permitted
   21049                 // Shell broadcasts
   21050                 if (callingUid == SHELL_UID
   21051                         && mUserController.hasUserRestriction(
   21052                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
   21053                         && !isPermittedShellBroadcast(intent)) {
   21054                     continue;
   21055                 }
   21056                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
   21057                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
   21058                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
   21059                     // If this is not the system user, we need to check for
   21060                     // any receivers that should be filtered out.
   21061                     for (int i=0; i<newReceivers.size(); i++) {
   21062                         ResolveInfo ri = newReceivers.get(i);
   21063                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
   21064                             newReceivers.remove(i);
   21065                             i--;
   21066                         }
   21067                     }
   21068                 }
   21069                 if (newReceivers != null && newReceivers.size() == 0) {
   21070                     newReceivers = null;
   21071                 }
   21072                 if (receivers == null) {
   21073                     receivers = newReceivers;
   21074                 } else if (newReceivers != null) {
   21075                     // We need to concatenate the additional receivers
   21076                     // found with what we have do far.  This would be easy,
   21077                     // but we also need to de-dup any receivers that are
   21078                     // singleUser.
   21079                     if (!scannedFirstReceivers) {
   21080                         // Collect any single user receivers we had already retrieved.
   21081                         scannedFirstReceivers = true;
   21082                         for (int i=0; i<receivers.size(); i++) {
   21083                             ResolveInfo ri = receivers.get(i);
   21084                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   21085                                 ComponentName cn = new ComponentName(
   21086                                         ri.activityInfo.packageName, ri.activityInfo.name);
   21087                                 if (singleUserReceivers == null) {
   21088                                     singleUserReceivers = new HashSet<ComponentName>();
   21089                                 }
   21090                                 singleUserReceivers.add(cn);
   21091                             }
   21092                         }
   21093                     }
   21094                     // Add the new results to the existing results, tracking
   21095                     // and de-dupping single user receivers.
   21096                     for (int i=0; i<newReceivers.size(); i++) {
   21097                         ResolveInfo ri = newReceivers.get(i);
   21098                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   21099                             ComponentName cn = new ComponentName(
   21100                                     ri.activityInfo.packageName, ri.activityInfo.name);
   21101                             if (singleUserReceivers == null) {
   21102                                 singleUserReceivers = new HashSet<ComponentName>();
   21103                             }
   21104                             if (!singleUserReceivers.contains(cn)) {
   21105                                 singleUserReceivers.add(cn);
   21106                                 receivers.add(ri);
   21107                             }
   21108                         } else {
   21109                             receivers.add(ri);
   21110                         }
   21111                     }
   21112                 }
   21113             }
   21114         } catch (RemoteException ex) {
   21115             // pm is in same process, this will never happen.
   21116         }
   21117         return receivers;
   21118     }
   21119 
   21120     private boolean isPermittedShellBroadcast(Intent intent) {
   21121         // remote bugreport should always be allowed to be taken
   21122         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
   21123     }
   21124 
   21125     private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
   21126             String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
   21127         if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
   21128             // Don't yell about broadcasts sent via shell
   21129             return;
   21130         }
   21131 
   21132         final String action = intent.getAction();
   21133         if (isProtectedBroadcast
   21134                 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
   21135                 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
   21136                 || Intent.ACTION_MEDIA_BUTTON.equals(action)
   21137                 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
   21138                 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
   21139                 || Intent.ACTION_MASTER_CLEAR.equals(action)
   21140                 || Intent.ACTION_FACTORY_RESET.equals(action)
   21141                 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
   21142                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
   21143                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
   21144                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
   21145                 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
   21146                 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
   21147                 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
   21148             // Broadcast is either protected, or it's a public action that
   21149             // we've relaxed, so it's fine for system internals to send.
   21150             return;
   21151         }
   21152 
   21153         // This broadcast may be a problem...  but there are often system components that
   21154         // want to send an internal broadcast to themselves, which is annoying to have to
   21155         // explicitly list each action as a protected broadcast, so we will check for that
   21156         // one safe case and allow it: an explicit broadcast, only being received by something
   21157         // that has protected itself.
   21158         if (intent.getPackage() != null || intent.getComponent() != null) {
   21159             if (receivers == null || receivers.size() == 0) {
   21160                 // Intent is explicit and there's no receivers.
   21161                 // This happens, e.g. , when a system component sends a broadcast to
   21162                 // its own runtime receiver, and there's no manifest receivers for it,
   21163                 // because this method is called twice for each broadcast,
   21164                 // for runtime receivers and manifest receivers and the later check would find
   21165                 // no receivers.
   21166                 return;
   21167             }
   21168             boolean allProtected = true;
   21169             for (int i = receivers.size()-1; i >= 0; i--) {
   21170                 Object target = receivers.get(i);
   21171                 if (target instanceof ResolveInfo) {
   21172                     ResolveInfo ri = (ResolveInfo)target;
   21173                     if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
   21174                         allProtected = false;
   21175                         break;
   21176                     }
   21177                 } else {
   21178                     BroadcastFilter bf = (BroadcastFilter)target;
   21179                     if (bf.requiredPermission == null) {
   21180                         allProtected = false;
   21181                         break;
   21182                     }
   21183                 }
   21184             }
   21185             if (allProtected) {
   21186                 // All safe!
   21187                 return;
   21188             }
   21189         }
   21190 
   21191         // The vast majority of broadcasts sent from system internals
   21192         // should be protected to avoid security holes, so yell loudly
   21193         // to ensure we examine these cases.
   21194         if (callerApp != null) {
   21195             Log.wtf(TAG, "Sending non-protected broadcast " + action
   21196                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
   21197                     new Throwable());
   21198         } else {
   21199             Log.wtf(TAG, "Sending non-protected broadcast " + action
   21200                             + " from system uid " + UserHandle.formatUid(callingUid)
   21201                             + " pkg " + callerPackage,
   21202                     new Throwable());
   21203         }
   21204     }
   21205 
   21206     @GuardedBy("this")
   21207     final int broadcastIntentLocked(ProcessRecord callerApp,
   21208             String callerPackage, Intent intent, String resolvedType,
   21209             IIntentReceiver resultTo, int resultCode, String resultData,
   21210             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
   21211             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
   21212         intent = new Intent(intent);
   21213 
   21214         final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
   21215         // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
   21216         if (callerInstantApp) {
   21217             intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
   21218         }
   21219 
   21220         // By default broadcasts do not go to stopped apps.
   21221         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
   21222 
   21223         // If we have not finished booting, don't allow this to launch new processes.
   21224         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
   21225             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   21226         }
   21227 
   21228         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
   21229                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
   21230                 + " ordered=" + ordered + " userid=" + userId);
   21231         if ((resultTo != null) && !ordered) {
   21232             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
   21233         }
   21234 
   21235         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
   21236                 ALLOW_NON_FULL, "broadcast", callerPackage);
   21237 
   21238         // Make sure that the user who is receiving this broadcast or its parent is running.
   21239         // If not, we will just skip it. Make an exception for shutdown broadcasts, upgrade steps.
   21240         if (userId != UserHandle.USER_ALL && !mUserController.isUserOrItsParentRunning(userId)) {
   21241             if ((callingUid != SYSTEM_UID
   21242                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
   21243                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
   21244                 Slog.w(TAG, "Skipping broadcast of " + intent
   21245                         + ": user " + userId + " and its parent (if any) are stopped");
   21246                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
   21247             }
   21248         }
   21249 
   21250         final String action = intent.getAction();
   21251         BroadcastOptions brOptions = null;
   21252         if (bOptions != null) {
   21253             brOptions = new BroadcastOptions(bOptions);
   21254             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
   21255                 // See if the caller is allowed to do this.  Note we are checking against
   21256                 // the actual real caller (not whoever provided the operation as say a
   21257                 // PendingIntent), because that who is actually supplied the arguments.
   21258                 if (checkComponentPermission(
   21259                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
   21260                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
   21261                         != PackageManager.PERMISSION_GRANTED) {
   21262                     String msg = "Permission Denial: " + intent.getAction()
   21263                             + " broadcast from " + callerPackage + " (pid=" + callingPid
   21264                             + ", uid=" + callingUid + ")"
   21265                             + " requires "
   21266                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
   21267                     Slog.w(TAG, msg);
   21268                     throw new SecurityException(msg);
   21269                 }
   21270             }
   21271             if (brOptions.isDontSendToRestrictedApps()
   21272                     && !isUidActiveLocked(callingUid)
   21273                     && isBackgroundRestrictedNoCheck(callingUid, callerPackage)) {
   21274                 Slog.i(TAG, "Not sending broadcast " + action + " - app " + callerPackage
   21275                         + " has background restrictions");
   21276                 return ActivityManager.START_CANCELED;
   21277             }
   21278         }
   21279 
   21280         // Verify that protected broadcasts are only being sent by system code,
   21281         // and that system code is only sending protected broadcasts.
   21282         final boolean isProtectedBroadcast;
   21283         try {
   21284             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
   21285         } catch (RemoteException e) {
   21286             Slog.w(TAG, "Remote exception", e);
   21287             return ActivityManager.BROADCAST_SUCCESS;
   21288         }
   21289 
   21290         final boolean isCallerSystem;
   21291         switch (UserHandle.getAppId(callingUid)) {
   21292             case ROOT_UID:
   21293             case SYSTEM_UID:
   21294             case PHONE_UID:
   21295             case BLUETOOTH_UID:
   21296             case NFC_UID:
   21297             case SE_UID:
   21298                 isCallerSystem = true;
   21299                 break;
   21300             default:
   21301                 isCallerSystem = (callerApp != null) && callerApp.persistent;
   21302                 break;
   21303         }
   21304 
   21305         // First line security check before anything else: stop non-system apps from
   21306         // sending protected broadcasts.
   21307         if (!isCallerSystem) {
   21308             if (isProtectedBroadcast) {
   21309                 String msg = "Permission Denial: not allowed to send broadcast "
   21310                         + action + " from pid="
   21311                         + callingPid + ", uid=" + callingUid;
   21312                 Slog.w(TAG, msg);
   21313                 throw new SecurityException(msg);
   21314 
   21315             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
   21316                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
   21317                 // Special case for compatibility: we don't want apps to send this,
   21318                 // but historically it has not been protected and apps may be using it
   21319                 // to poke their own app widget.  So, instead of making it protected,
   21320                 // just limit it to the caller.
   21321                 if (callerPackage == null) {
   21322                     String msg = "Permission Denial: not allowed to send broadcast "
   21323                             + action + " from unknown caller.";
   21324                     Slog.w(TAG, msg);
   21325                     throw new SecurityException(msg);
   21326                 } else if (intent.getComponent() != null) {
   21327                     // They are good enough to send to an explicit component...  verify
   21328                     // it is being sent to the calling app.
   21329                     if (!intent.getComponent().getPackageName().equals(
   21330                             callerPackage)) {
   21331                         String msg = "Permission Denial: not allowed to send broadcast "
   21332                                 + action + " to "
   21333                                 + intent.getComponent().getPackageName() + " from "
   21334                                 + callerPackage;
   21335                         Slog.w(TAG, msg);
   21336                         throw new SecurityException(msg);
   21337                     }
   21338                 } else {
   21339                     // Limit broadcast to their own package.
   21340                     intent.setPackage(callerPackage);
   21341                 }
   21342             }
   21343         }
   21344 
   21345         if (action != null) {
   21346             if (getBackgroundLaunchBroadcasts().contains(action)) {
   21347                 if (DEBUG_BACKGROUND_CHECK) {
   21348                     Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
   21349                 }
   21350                 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
   21351             }
   21352 
   21353             switch (action) {
   21354                 case Intent.ACTION_UID_REMOVED:
   21355                 case Intent.ACTION_PACKAGE_REMOVED:
   21356                 case Intent.ACTION_PACKAGE_CHANGED:
   21357                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
   21358                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
   21359                 case Intent.ACTION_PACKAGES_SUSPENDED:
   21360                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
   21361                     // Handle special intents: if this broadcast is from the package
   21362                     // manager about a package being removed, we need to remove all of
   21363                     // its activities from the history stack.
   21364                     if (checkComponentPermission(
   21365                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
   21366                             callingPid, callingUid, -1, true)
   21367                             != PackageManager.PERMISSION_GRANTED) {
   21368                         String msg = "Permission Denial: " + intent.getAction()
   21369                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
   21370                                 + ", uid=" + callingUid + ")"
   21371                                 + " requires "
   21372                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
   21373                         Slog.w(TAG, msg);
   21374                         throw new SecurityException(msg);
   21375                     }
   21376                     switch (action) {
   21377                         case Intent.ACTION_UID_REMOVED:
   21378                             final int uid = getUidFromIntent(intent);
   21379                             if (uid >= 0) {
   21380                                 mBatteryStatsService.removeUid(uid);
   21381                                 mAppOpsService.uidRemoved(uid);
   21382                             }
   21383                             break;
   21384                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
   21385                             // If resources are unavailable just force stop all those packages
   21386                             // and flush the attribute cache as well.
   21387                             String list[] =
   21388                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   21389                             if (list != null && list.length > 0) {
   21390                                 for (int i = 0; i < list.length; i++) {
   21391                                     forceStopPackageLocked(list[i], -1, false, true, true,
   21392                                             false, false, userId, "storage unmount");
   21393                                 }
   21394                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
   21395                                 sendPackageBroadcastLocked(
   21396                                         ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
   21397                                         list, userId);
   21398                             }
   21399                             break;
   21400                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
   21401                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
   21402                             break;
   21403                         case Intent.ACTION_PACKAGE_REMOVED:
   21404                         case Intent.ACTION_PACKAGE_CHANGED:
   21405                             Uri data = intent.getData();
   21406                             String ssp;
   21407                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   21408                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
   21409                                 final boolean replacing =
   21410                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
   21411                                 final boolean killProcess =
   21412                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
   21413                                 final boolean fullUninstall = removed && !replacing;
   21414                                 if (removed) {
   21415                                     if (killProcess) {
   21416                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
   21417                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
   21418                                                 false, true, true, false, fullUninstall, userId,
   21419                                                 removed ? "pkg removed" : "pkg changed");
   21420                                     }
   21421                                     final int cmd = killProcess
   21422                                             ? ApplicationThreadConstants.PACKAGE_REMOVED
   21423                                             : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
   21424                                     sendPackageBroadcastLocked(cmd,
   21425                                             new String[] {ssp}, userId);
   21426                                     if (fullUninstall) {
   21427                                         mAppOpsService.packageRemoved(
   21428                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
   21429 
   21430                                         // Remove all permissions granted from/to this package
   21431                                         removeUriPermissionsForPackageLocked(ssp, userId, true,
   21432                                                 false);
   21433 
   21434                                         mRecentTasks.removeTasksByPackageName(ssp, userId);
   21435 
   21436                                         mServices.forceStopPackageLocked(ssp, userId);
   21437                                         mAppWarnings.onPackageUninstalled(ssp);
   21438                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
   21439                                         mBatteryStatsService.notePackageUninstalled(ssp);
   21440                                     }
   21441                                 } else {
   21442                                     if (killProcess) {
   21443                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
   21444                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
   21445                                                 userId, ProcessList.INVALID_ADJ,
   21446                                                 false, true, true, false, "change " + ssp);
   21447                                     }
   21448                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
   21449                                             intent.getStringArrayExtra(
   21450                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
   21451                                 }
   21452                             }
   21453                             break;
   21454                         case Intent.ACTION_PACKAGES_SUSPENDED:
   21455                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
   21456                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
   21457                                     intent.getAction());
   21458                             final String[] packageNames = intent.getStringArrayExtra(
   21459                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
   21460                             final int userHandle = intent.getIntExtra(
   21461                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
   21462 
   21463                             synchronized(ActivityManagerService.this) {
   21464                                 mRecentTasks.onPackagesSuspendedChanged(
   21465                                         packageNames, suspended, userHandle);
   21466                             }
   21467                             break;
   21468                     }
   21469                     break;
   21470                 case Intent.ACTION_PACKAGE_REPLACED:
   21471                 {
   21472                     final Uri data = intent.getData();
   21473                     final String ssp;
   21474                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
   21475                         ApplicationInfo aInfo = null;
   21476                         try {
   21477                             aInfo = AppGlobals.getPackageManager()
   21478                                     .getApplicationInfo(ssp, STOCK_PM_FLAGS, userId);
   21479                         } catch (RemoteException ignore) {}
   21480                         if (aInfo == null) {
   21481                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
   21482                                     + " ssp=" + ssp + " data=" + data);
   21483                             return ActivityManager.BROADCAST_SUCCESS;
   21484                         }
   21485                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
   21486                         mServices.updateServiceApplicationInfoLocked(aInfo);
   21487                         sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
   21488                                 new String[] {ssp}, userId);
   21489                     }
   21490                     break;
   21491                 }
   21492                 case Intent.ACTION_PACKAGE_ADDED:
   21493                 {
   21494                     // Special case for adding a package: by default turn on compatibility mode.
   21495                     Uri data = intent.getData();
   21496                     String ssp;
   21497                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
   21498                         final boolean replacing =
   21499                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
   21500                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
   21501 
   21502                         try {
   21503                             ApplicationInfo ai = AppGlobals.getPackageManager().
   21504                                     getApplicationInfo(ssp, STOCK_PM_FLAGS, 0);
   21505                             mBatteryStatsService.notePackageInstalled(ssp,
   21506                                     ai != null ? ai.versionCode : 0);
   21507                         } catch (RemoteException e) {
   21508                         }
   21509                     }
   21510                     break;
   21511                 }
   21512                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
   21513                 {
   21514                     Uri data = intent.getData();
   21515                     String ssp;
   21516                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
   21517                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
   21518                         mAppWarnings.onPackageDataCleared(ssp);
   21519                     }
   21520                     break;
   21521                 }
   21522                 case Intent.ACTION_TIMEZONE_CHANGED:
   21523                     // If this is the time zone changed action, queue up a message that will reset
   21524                     // the timezone of all currently running processes. This message will get
   21525                     // queued up before the broadcast happens.
   21526                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
   21527                     break;
   21528                 case Intent.ACTION_TIME_CHANGED:
   21529                     // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
   21530                     // the tri-state value it may contain and "unknown".
   21531                     // For convenience we re-use the Intent extra values.
   21532                     final int NO_EXTRA_VALUE_FOUND = -1;
   21533                     final int timeFormatPreferenceMsgValue = intent.getIntExtra(
   21534                             Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
   21535                             NO_EXTRA_VALUE_FOUND /* defaultValue */);
   21536                     // Only send a message if the time preference is available.
   21537                     if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
   21538                         Message updateTimePreferenceMsg =
   21539                                 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
   21540                                         timeFormatPreferenceMsgValue, 0);
   21541                         mHandler.sendMessage(updateTimePreferenceMsg);
   21542                     }
   21543                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   21544                     synchronized (stats) {
   21545                         stats.noteCurrentTimeChangedLocked();
   21546                     }
   21547                     break;
   21548                 case Intent.ACTION_CLEAR_DNS_CACHE:
   21549                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
   21550                     break;
   21551                 case Proxy.PROXY_CHANGE_ACTION:
   21552                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
   21553                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
   21554                     break;
   21555                 case android.hardware.Camera.ACTION_NEW_PICTURE:
   21556                 case android.hardware.Camera.ACTION_NEW_VIDEO:
   21557                     // In N we just turned these off; in O we are turing them back on partly,
   21558                     // only for registered receivers.  This will still address the main problem
   21559                     // (a spam of apps waking up when a picture is taken putting significant
   21560                     // memory pressure on the system at a bad point), while still allowing apps
   21561                     // that are already actively running to know about this happening.
   21562                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   21563                     break;
   21564                 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
   21565                     mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
   21566                     break;
   21567                 case "com.android.launcher.action.INSTALL_SHORTCUT":
   21568                     // As of O, we no longer support this broadcasts, even for pre-O apps.
   21569                     // Apps should now be using ShortcutManager.pinRequestShortcut().
   21570                     Log.w(TAG, "Broadcast " + action
   21571                             + " no longer supported. It will not be delivered.");
   21572                     return ActivityManager.BROADCAST_SUCCESS;
   21573             }
   21574 
   21575             if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
   21576                     Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
   21577                     Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
   21578                 final int uid = getUidFromIntent(intent);
   21579                 if (uid != -1) {
   21580                     final UidRecord uidRec = mActiveUids.get(uid);
   21581                     if (uidRec != null) {
   21582                         uidRec.updateHasInternetPermission();
   21583                     }
   21584                 }
   21585             }
   21586         }
   21587 
   21588         // Add to the sticky list if requested.
   21589         if (sticky) {
   21590             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
   21591                     callingPid, callingUid)
   21592                     != PackageManager.PERMISSION_GRANTED) {
   21593                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
   21594                         + callingPid + ", uid=" + callingUid
   21595                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   21596                 Slog.w(TAG, msg);
   21597                 throw new SecurityException(msg);
   21598             }
   21599             if (requiredPermissions != null && requiredPermissions.length > 0) {
   21600                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
   21601                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
   21602                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
   21603             }
   21604             if (intent.getComponent() != null) {
   21605                 throw new SecurityException(
   21606                         "Sticky broadcasts can't target a specific component");
   21607             }
   21608             // We use userId directly here, since the "all" target is maintained
   21609             // as a separate set of sticky broadcasts.
   21610             if (userId != UserHandle.USER_ALL) {
   21611                 // But first, if this is not a broadcast to all users, then
   21612                 // make sure it doesn't conflict with an existing broadcast to
   21613                 // all users.
   21614                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
   21615                         UserHandle.USER_ALL);
   21616                 if (stickies != null) {
   21617                     ArrayList<Intent> list = stickies.get(intent.getAction());
   21618                     if (list != null) {
   21619                         int N = list.size();
   21620                         int i;
   21621                         for (i=0; i<N; i++) {
   21622                             if (intent.filterEquals(list.get(i))) {
   21623                                 throw new IllegalArgumentException(
   21624                                         "Sticky broadcast " + intent + " for user "
   21625                                         + userId + " conflicts with existing global broadcast");
   21626                             }
   21627                         }
   21628                     }
   21629                 }
   21630             }
   21631             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   21632             if (stickies == null) {
   21633                 stickies = new ArrayMap<>();
   21634                 mStickyBroadcasts.put(userId, stickies);
   21635             }
   21636             ArrayList<Intent> list = stickies.get(intent.getAction());
   21637             if (list == null) {
   21638                 list = new ArrayList<>();
   21639                 stickies.put(intent.getAction(), list);
   21640             }
   21641             final int stickiesCount = list.size();
   21642             int i;
   21643             for (i = 0; i < stickiesCount; i++) {
   21644                 if (intent.filterEquals(list.get(i))) {
   21645                     // This sticky already exists, replace it.
   21646                     list.set(i, new Intent(intent));
   21647                     break;
   21648                 }
   21649             }
   21650             if (i >= stickiesCount) {
   21651                 list.add(new Intent(intent));
   21652             }
   21653         }
   21654 
   21655         int[] users;
   21656         if (userId == UserHandle.USER_ALL) {
   21657             // Caller wants broadcast to go to all started users.
   21658             users = mUserController.getStartedUserArray();
   21659         } else {
   21660             // Caller wants broadcast to go to one specific user.
   21661             users = new int[] {userId};
   21662         }
   21663 
   21664         // Figure out who all will receive this broadcast.
   21665         List receivers = null;
   21666         List<BroadcastFilter> registeredReceivers = null;
   21667         // Need to resolve the intent to interested receivers...
   21668         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
   21669                  == 0) {
   21670             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
   21671         }
   21672         if (intent.getComponent() == null) {
   21673             if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
   21674                 // Query one target user at a time, excluding shell-restricted users
   21675                 for (int i = 0; i < users.length; i++) {
   21676                     if (mUserController.hasUserRestriction(
   21677                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
   21678                         continue;
   21679                     }
   21680                     List<BroadcastFilter> registeredReceiversForUser =
   21681                             mReceiverResolver.queryIntent(intent,
   21682                                     resolvedType, false /*defaultOnly*/, users[i]);
   21683                     if (registeredReceivers == null) {
   21684                         registeredReceivers = registeredReceiversForUser;
   21685                     } else if (registeredReceiversForUser != null) {
   21686                         registeredReceivers.addAll(registeredReceiversForUser);
   21687                     }
   21688                 }
   21689             } else {
   21690                 registeredReceivers = mReceiverResolver.queryIntent(intent,
   21691                         resolvedType, false /*defaultOnly*/, userId);
   21692             }
   21693         }
   21694 
   21695         final boolean replacePending =
   21696                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
   21697 
   21698         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
   21699                 + " replacePending=" + replacePending);
   21700 
   21701         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
   21702         if (!ordered && NR > 0) {
   21703             // If we are not serializing this broadcast, then send the
   21704             // registered receivers separately so they don't wait for the
   21705             // components to be launched.
   21706             if (isCallerSystem) {
   21707                 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
   21708                         isProtectedBroadcast, registeredReceivers);
   21709             }
   21710             final BroadcastQueue queue = broadcastQueueForIntent(intent);
   21711             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   21712                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
   21713                     requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
   21714                     resultCode, resultData, resultExtras, ordered, sticky, false, userId);
   21715             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
   21716             final boolean replaced = replacePending
   21717                     && (queue.replaceParallelBroadcastLocked(r) != null);
   21718             // Note: We assume resultTo is null for non-ordered broadcasts.
   21719             if (!replaced) {
   21720                 queue.enqueueParallelBroadcastLocked(r);
   21721                 queue.scheduleBroadcastsLocked();
   21722             }
   21723             registeredReceivers = null;
   21724             NR = 0;
   21725         }
   21726 
   21727         // Merge into one list.
   21728         int ir = 0;
   21729         if (receivers != null) {
   21730             // A special case for PACKAGE_ADDED: do not allow the package
   21731             // being added to see this broadcast.  This prevents them from
   21732             // using this as a back door to get run as soon as they are
   21733             // installed.  Maybe in the future we want to have a special install
   21734             // broadcast or such for apps, but we'd like to deliberately make
   21735             // this decision.
   21736             String skipPackages[] = null;
   21737             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
   21738                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
   21739                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
   21740                 Uri data = intent.getData();
   21741                 if (data != null) {
   21742                     String pkgName = data.getSchemeSpecificPart();
   21743                     if (pkgName != null) {
   21744                         skipPackages = new String[] { pkgName };
   21745                     }
   21746                 }
   21747             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
   21748                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   21749             }
   21750             if (skipPackages != null && (skipPackages.length > 0)) {
   21751                 for (String skipPackage : skipPackages) {
   21752                     if (skipPackage != null) {
   21753                         int NT = receivers.size();
   21754                         for (int it=0; it<NT; it++) {
   21755                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
   21756                             if (curt.activityInfo.packageName.equals(skipPackage)) {
   21757                                 receivers.remove(it);
   21758                                 it--;
   21759                                 NT--;
   21760                             }
   21761                         }
   21762                     }
   21763                 }
   21764             }
   21765 
   21766             int NT = receivers != null ? receivers.size() : 0;
   21767             int it = 0;
   21768             ResolveInfo curt = null;
   21769             BroadcastFilter curr = null;
   21770             while (it < NT && ir < NR) {
   21771                 if (curt == null) {
   21772                     curt = (ResolveInfo)receivers.get(it);
   21773                 }
   21774                 if (curr == null) {
   21775                     curr = registeredReceivers.get(ir);
   21776                 }
   21777                 if (curr.getPriority() >= curt.priority) {
   21778                     // Insert this broadcast record into the final list.
   21779                     receivers.add(it, curr);
   21780                     ir++;
   21781                     curr = null;
   21782                     it++;
   21783                     NT++;
   21784                 } else {
   21785                     // Skip to the next ResolveInfo in the final list.
   21786                     it++;
   21787                     curt = null;
   21788                 }
   21789             }
   21790         }
   21791         while (ir < NR) {
   21792             if (receivers == null) {
   21793                 receivers = new ArrayList();
   21794             }
   21795             receivers.add(registeredReceivers.get(ir));
   21796             ir++;
   21797         }
   21798 
   21799         if (isCallerSystem) {
   21800             checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
   21801                     isProtectedBroadcast, receivers);
   21802         }
   21803 
   21804         if ((receivers != null && receivers.size() > 0)
   21805                 || resultTo != null) {
   21806             BroadcastQueue queue = broadcastQueueForIntent(intent);
   21807             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   21808                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
   21809                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
   21810                     resultData, resultExtras, ordered, sticky, false, userId);
   21811 
   21812             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
   21813                     + ": prev had " + queue.mOrderedBroadcasts.size());
   21814             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
   21815                     "Enqueueing broadcast " + r.intent.getAction());
   21816 
   21817             final BroadcastRecord oldRecord =
   21818                     replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
   21819             if (oldRecord != null) {
   21820                 // Replaced, fire the result-to receiver.
   21821                 if (oldRecord.resultTo != null) {
   21822                     final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
   21823                     try {
   21824                         oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
   21825                                 oldRecord.intent,
   21826                                 Activity.RESULT_CANCELED, null, null,
   21827                                 false, false, oldRecord.userId);
   21828                     } catch (RemoteException e) {
   21829                         Slog.w(TAG, "Failure ["
   21830                                 + queue.mQueueName + "] sending broadcast result of "
   21831                                 + intent, e);
   21832 
   21833                     }
   21834                 }
   21835             } else {
   21836                 queue.enqueueOrderedBroadcastLocked(r);
   21837                 queue.scheduleBroadcastsLocked();
   21838             }
   21839         } else {
   21840             // There was nobody interested in the broadcast, but we still want to record
   21841             // that it happened.
   21842             if (intent.getComponent() == null && intent.getPackage() == null
   21843                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   21844                 // This was an implicit broadcast... let's record it for posterity.
   21845                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
   21846             }
   21847         }
   21848 
   21849         return ActivityManager.BROADCAST_SUCCESS;
   21850     }
   21851 
   21852     /**
   21853      * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
   21854      */
   21855     private int getUidFromIntent(Intent intent) {
   21856         if (intent == null) {
   21857             return -1;
   21858         }
   21859         final Bundle intentExtras = intent.getExtras();
   21860         return intent.hasExtra(Intent.EXTRA_UID)
   21861                 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
   21862     }
   21863 
   21864     final void rotateBroadcastStatsIfNeededLocked() {
   21865         final long now = SystemClock.elapsedRealtime();
   21866         if (mCurBroadcastStats == null ||
   21867                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
   21868             mLastBroadcastStats = mCurBroadcastStats;
   21869             if (mLastBroadcastStats != null) {
   21870                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
   21871                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
   21872             }
   21873             mCurBroadcastStats = new BroadcastStats();
   21874         }
   21875     }
   21876 
   21877     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
   21878             int skipCount, long dispatchTime) {
   21879         rotateBroadcastStatsIfNeededLocked();
   21880         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
   21881     }
   21882 
   21883     final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
   21884         rotateBroadcastStatsIfNeededLocked();
   21885         mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
   21886     }
   21887 
   21888     final Intent verifyBroadcastLocked(Intent intent) {
   21889         // Refuse possible leaked file descriptors
   21890         if (intent != null && intent.hasFileDescriptors() == true) {
   21891             throw new IllegalArgumentException("File descriptors passed in Intent");
   21892         }
   21893 
   21894         int flags = intent.getFlags();
   21895 
   21896         if (!mProcessesReady) {
   21897             // if the caller really truly claims to know what they're doing, go
   21898             // ahead and allow the broadcast without launching any receivers
   21899             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
   21900                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
   21901             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   21902                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
   21903                         + " before boot completion");
   21904                 throw new IllegalStateException("Cannot broadcast before boot completed");
   21905             }
   21906         }
   21907 
   21908         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   21909             throw new IllegalArgumentException(
   21910                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   21911         }
   21912 
   21913         if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
   21914             switch (Binder.getCallingUid()) {
   21915                 case ROOT_UID:
   21916                 case SHELL_UID:
   21917                     break;
   21918                 default:
   21919                     Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
   21920                             + Binder.getCallingUid());
   21921                     intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
   21922                     break;
   21923             }
   21924         }
   21925 
   21926         return intent;
   21927     }
   21928 
   21929     public final int broadcastIntent(IApplicationThread caller,
   21930             Intent intent, String resolvedType, IIntentReceiver resultTo,
   21931             int resultCode, String resultData, Bundle resultExtras,
   21932             String[] requiredPermissions, int appOp, Bundle bOptions,
   21933             boolean serialized, boolean sticky, int userId) {
   21934         enforceNotIsolatedCaller("broadcastIntent");
   21935         synchronized(this) {
   21936             intent = verifyBroadcastLocked(intent);
   21937 
   21938             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   21939             final int callingPid = Binder.getCallingPid();
   21940             final int callingUid = Binder.getCallingUid();
   21941             final long origId = Binder.clearCallingIdentity();
   21942             int res = broadcastIntentLocked(callerApp,
   21943                     callerApp != null ? callerApp.info.packageName : null,
   21944                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
   21945                     requiredPermissions, appOp, bOptions, serialized, sticky,
   21946                     callingPid, callingUid, userId);
   21947             Binder.restoreCallingIdentity(origId);
   21948             return res;
   21949         }
   21950     }
   21951 
   21952 
   21953     int broadcastIntentInPackage(String packageName, int uid,
   21954             Intent intent, String resolvedType, IIntentReceiver resultTo,
   21955             int resultCode, String resultData, Bundle resultExtras,
   21956             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
   21957             int userId) {
   21958         synchronized(this) {
   21959             intent = verifyBroadcastLocked(intent);
   21960 
   21961             final long origId = Binder.clearCallingIdentity();
   21962             String[] requiredPermissions = requiredPermission == null ? null
   21963                     : new String[] {requiredPermission};
   21964             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
   21965                     resultTo, resultCode, resultData, resultExtras,
   21966                     requiredPermissions, OP_NONE, bOptions, serialized,
   21967                     sticky, -1, uid, userId);
   21968             Binder.restoreCallingIdentity(origId);
   21969             return res;
   21970         }
   21971     }
   21972 
   21973     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
   21974         // Refuse possible leaked file descriptors
   21975         if (intent != null && intent.hasFileDescriptors() == true) {
   21976             throw new IllegalArgumentException("File descriptors passed in Intent");
   21977         }
   21978 
   21979         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   21980                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
   21981 
   21982         synchronized(this) {
   21983             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
   21984                     != PackageManager.PERMISSION_GRANTED) {
   21985                 String msg = "Permission Denial: unbroadcastIntent() from pid="
   21986                         + Binder.getCallingPid()
   21987                         + ", uid=" + Binder.getCallingUid()
   21988                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   21989                 Slog.w(TAG, msg);
   21990                 throw new SecurityException(msg);
   21991             }
   21992             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   21993             if (stickies != null) {
   21994                 ArrayList<Intent> list = stickies.get(intent.getAction());
   21995                 if (list != null) {
   21996                     int N = list.size();
   21997                     int i;
   21998                     for (i=0; i<N; i++) {
   21999                         if (intent.filterEquals(list.get(i))) {
   22000                             list.remove(i);
   22001                             break;
   22002                         }
   22003                     }
   22004                     if (list.size() <= 0) {
   22005                         stickies.remove(intent.getAction());
   22006                     }
   22007                 }
   22008                 if (stickies.size() <= 0) {
   22009                     mStickyBroadcasts.remove(userId);
   22010                 }
   22011             }
   22012         }
   22013     }
   22014 
   22015     void backgroundServicesFinishedLocked(int userId) {
   22016         for (BroadcastQueue queue : mBroadcastQueues) {
   22017             queue.backgroundServicesFinishedLocked(userId);
   22018         }
   22019     }
   22020 
   22021     public void finishReceiver(IBinder who, int resultCode, String resultData,
   22022             Bundle resultExtras, boolean resultAbort, int flags) {
   22023         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
   22024 
   22025         // Refuse possible leaked file descriptors
   22026         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
   22027             throw new IllegalArgumentException("File descriptors passed in Bundle");
   22028         }
   22029 
   22030         final long origId = Binder.clearCallingIdentity();
   22031         try {
   22032             boolean doNext = false;
   22033             BroadcastRecord r;
   22034 
   22035             synchronized(this) {
   22036                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
   22037                         ? mFgBroadcastQueue : mBgBroadcastQueue;
   22038                 r = queue.getMatchingOrderedReceiver(who);
   22039                 if (r != null) {
   22040                     doNext = r.queue.finishReceiverLocked(r, resultCode,
   22041                         resultData, resultExtras, resultAbort, true);
   22042                 }
   22043                 if (doNext) {
   22044                     r.queue.processNextBroadcastLocked(/*fromMsg=*/ false, /*skipOomAdj=*/ true);
   22045                 }
   22046                 // updateOomAdjLocked() will be done here
   22047                 trimApplicationsLocked();
   22048             }
   22049 
   22050         } finally {
   22051             Binder.restoreCallingIdentity(origId);
   22052         }
   22053     }
   22054 
   22055     // =========================================================
   22056     // INSTRUMENTATION
   22057     // =========================================================
   22058 
   22059     public boolean startInstrumentation(ComponentName className,
   22060             String profileFile, int flags, Bundle arguments,
   22061             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
   22062             int userId, String abiOverride) {
   22063         enforceNotIsolatedCaller("startInstrumentation");
   22064         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   22065                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
   22066         // Refuse possible leaked file descriptors
   22067         if (arguments != null && arguments.hasFileDescriptors()) {
   22068             throw new IllegalArgumentException("File descriptors passed in Bundle");
   22069         }
   22070 
   22071         synchronized(this) {
   22072             InstrumentationInfo ii = null;
   22073             ApplicationInfo ai = null;
   22074             try {
   22075                 ii = mContext.getPackageManager().getInstrumentationInfo(
   22076                     className, STOCK_PM_FLAGS);
   22077                 ai = AppGlobals.getPackageManager().getApplicationInfo(
   22078                         ii.targetPackage, STOCK_PM_FLAGS, userId);
   22079             } catch (PackageManager.NameNotFoundException e) {
   22080             } catch (RemoteException e) {
   22081             }
   22082             if (ii == null) {
   22083                 reportStartInstrumentationFailureLocked(watcher, className,
   22084                         "Unable to find instrumentation info for: " + className);
   22085                 return false;
   22086             }
   22087             if (ai == null) {
   22088                 reportStartInstrumentationFailureLocked(watcher, className,
   22089                         "Unable to find instrumentation target package: " + ii.targetPackage);
   22090                 return false;
   22091             }
   22092             if (!ai.hasCode()) {
   22093                 reportStartInstrumentationFailureLocked(watcher, className,
   22094                         "Instrumentation target has no code: " + ii.targetPackage);
   22095                 return false;
   22096             }
   22097 
   22098             int match = mContext.getPackageManager().checkSignatures(
   22099                     ii.targetPackage, ii.packageName);
   22100             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
   22101                 String msg = "Permission Denial: starting instrumentation "
   22102                         + className + " from pid="
   22103                         + Binder.getCallingPid()
   22104                         + ", uid=" + Binder.getCallingPid()
   22105                         + " not allowed because package " + ii.packageName
   22106                         + " does not have a signature matching the target "
   22107                         + ii.targetPackage;
   22108                 reportStartInstrumentationFailureLocked(watcher, className, msg);
   22109                 throw new SecurityException(msg);
   22110             }
   22111 
   22112             ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
   22113             activeInstr.mClass = className;
   22114             String defProcess = ai.processName;;
   22115             if (ii.targetProcesses == null) {
   22116                 activeInstr.mTargetProcesses = new String[]{ai.processName};
   22117             } else if (ii.targetProcesses.equals("*")) {
   22118                 activeInstr.mTargetProcesses = new String[0];
   22119             } else {
   22120                 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
   22121                 defProcess = activeInstr.mTargetProcesses[0];
   22122             }
   22123             activeInstr.mTargetInfo = ai;
   22124             activeInstr.mProfileFile = profileFile;
   22125             activeInstr.mArguments = arguments;
   22126             activeInstr.mWatcher = watcher;
   22127             activeInstr.mUiAutomationConnection = uiAutomationConnection;
   22128             activeInstr.mResultClass = className;
   22129 
   22130             boolean disableHiddenApiChecks =
   22131                     (flags & INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS) != 0;
   22132             if (disableHiddenApiChecks) {
   22133                 enforceCallingPermission(android.Manifest.permission.DISABLE_HIDDEN_API_CHECKS,
   22134                         "disable hidden API checks");
   22135             }
   22136 
   22137             final long origId = Binder.clearCallingIdentity();
   22138             // Instrumentation can kill and relaunch even persistent processes
   22139             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
   22140                     "start instr");
   22141             // Inform usage stats to make the target package active
   22142             if (mUsageStatsService != null) {
   22143                 mUsageStatsService.reportEvent(ii.targetPackage, userId,
   22144                         UsageEvents.Event.SYSTEM_INTERACTION);
   22145             }
   22146 
   22147             ProcessRecord app = addAppLocked(ai, defProcess, false, disableHiddenApiChecks,
   22148                     abiOverride);
   22149             app.instr = activeInstr;
   22150             activeInstr.mFinished = false;
   22151             activeInstr.mRunningProcesses.add(app);
   22152             if (!mActiveInstrumentation.contains(activeInstr)) {
   22153                 mActiveInstrumentation.add(activeInstr);
   22154             }
   22155             Binder.restoreCallingIdentity(origId);
   22156         }
   22157 
   22158         return true;
   22159     }
   22160 
   22161     /**
   22162      * Report errors that occur while attempting to start Instrumentation.  Always writes the
   22163      * error to the logs, but if somebody is watching, send the report there too.  This enables
   22164      * the "am" command to report errors with more information.
   22165      *
   22166      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
   22167      * @param cn The component name of the instrumentation.
   22168      * @param report The error report.
   22169      */
   22170     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
   22171             ComponentName cn, String report) {
   22172         Slog.w(TAG, report);
   22173         if (watcher != null) {
   22174             Bundle results = new Bundle();
   22175             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
   22176             results.putString("Error", report);
   22177             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
   22178         }
   22179     }
   22180 
   22181     void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
   22182         if (app.instr == null) {
   22183             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
   22184             return;
   22185         }
   22186 
   22187         if (!app.instr.mFinished && results != null) {
   22188             if (app.instr.mCurResults == null) {
   22189                 app.instr.mCurResults = new Bundle(results);
   22190             } else {
   22191                 app.instr.mCurResults.putAll(results);
   22192             }
   22193         }
   22194     }
   22195 
   22196     public void addInstrumentationResults(IApplicationThread target, Bundle results) {
   22197         int userId = UserHandle.getCallingUserId();
   22198         // Refuse possible leaked file descriptors
   22199         if (results != null && results.hasFileDescriptors()) {
   22200             throw new IllegalArgumentException("File descriptors passed in Intent");
   22201         }
   22202 
   22203         synchronized(this) {
   22204             ProcessRecord app = getRecordForAppLocked(target);
   22205             if (app == null) {
   22206                 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
   22207                 return;
   22208             }
   22209             final long origId = Binder.clearCallingIdentity();
   22210             addInstrumentationResultsLocked(app, results);
   22211             Binder.restoreCallingIdentity(origId);
   22212         }
   22213     }
   22214 
   22215     @GuardedBy("this")
   22216     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
   22217         if (app.instr == null) {
   22218             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
   22219             return;
   22220         }
   22221 
   22222         if (!app.instr.mFinished) {
   22223             if (app.instr.mWatcher != null) {
   22224                 Bundle finalResults = app.instr.mCurResults;
   22225                 if (finalResults != null) {
   22226                     if (app.instr.mCurResults != null && results != null) {
   22227                         finalResults.putAll(results);
   22228                     }
   22229                 } else {
   22230                     finalResults = results;
   22231                 }
   22232                 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
   22233                         app.instr.mClass, resultCode, finalResults);
   22234             }
   22235 
   22236             // Can't call out of the system process with a lock held, so post a message.
   22237             if (app.instr.mUiAutomationConnection != null) {
   22238                 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
   22239                         app.instr.mUiAutomationConnection).sendToTarget();
   22240             }
   22241             app.instr.mFinished = true;
   22242         }
   22243 
   22244         app.instr.removeProcess(app);
   22245         app.instr = null;
   22246 
   22247         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
   22248                 "finished inst");
   22249     }
   22250 
   22251     public void finishInstrumentation(IApplicationThread target,
   22252             int resultCode, Bundle results) {
   22253         int userId = UserHandle.getCallingUserId();
   22254         // Refuse possible leaked file descriptors
   22255         if (results != null && results.hasFileDescriptors()) {
   22256             throw new IllegalArgumentException("File descriptors passed in Intent");
   22257         }
   22258 
   22259         synchronized(this) {
   22260             ProcessRecord app = getRecordForAppLocked(target);
   22261             if (app == null) {
   22262                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
   22263                 return;
   22264             }
   22265             final long origId = Binder.clearCallingIdentity();
   22266             finishInstrumentationLocked(app, resultCode, results);
   22267             Binder.restoreCallingIdentity(origId);
   22268         }
   22269     }
   22270 
   22271     // =========================================================
   22272     // CONFIGURATION
   22273     // =========================================================
   22274 
   22275     public ConfigurationInfo getDeviceConfigurationInfo() {
   22276         ConfigurationInfo config = new ConfigurationInfo();
   22277         synchronized (this) {
   22278             final Configuration globalConfig = getGlobalConfiguration();
   22279             config.reqTouchScreen = globalConfig.touchscreen;
   22280             config.reqKeyboardType = globalConfig.keyboard;
   22281             config.reqNavigation = globalConfig.navigation;
   22282             if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
   22283                     || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
   22284                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
   22285             }
   22286             if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
   22287                     && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
   22288                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
   22289             }
   22290             config.reqGlEsVersion = GL_ES_VERSION;
   22291         }
   22292         return config;
   22293     }
   22294 
   22295     ActivityStack getFocusedStack() {
   22296         return mStackSupervisor.getFocusedStack();
   22297     }
   22298 
   22299     @Override
   22300     public StackInfo getFocusedStackInfo() throws RemoteException {
   22301         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
   22302         long ident = Binder.clearCallingIdentity();
   22303         try {
   22304             synchronized (this) {
   22305                 ActivityStack focusedStack = getFocusedStack();
   22306                 if (focusedStack != null) {
   22307                     return mStackSupervisor.getStackInfo(focusedStack.mStackId);
   22308                 }
   22309                 return null;
   22310             }
   22311         } finally {
   22312             Binder.restoreCallingIdentity(ident);
   22313         }
   22314     }
   22315 
   22316     public Configuration getConfiguration() {
   22317         Configuration ci;
   22318         synchronized(this) {
   22319             ci = new Configuration(getGlobalConfiguration());
   22320             ci.userSetLocale = false;
   22321         }
   22322         return ci;
   22323     }
   22324 
   22325     @Override
   22326     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
   22327         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
   22328         synchronized (this) {
   22329             mSuppressResizeConfigChanges = suppress;
   22330         }
   22331     }
   22332 
   22333     /**
   22334      * NOTE: For the pinned stack, this method is usually called after the bounds animation has
   22335      *       animated the stack to the fullscreen, but can also be called if we are relaunching an
   22336      *       activity and clearing the task at the same time.
   22337      */
   22338     @Override
   22339     // TODO: API should just be about changing windowing modes...
   22340     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
   22341         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
   22342                 "moveTasksToFullscreenStack()");
   22343         synchronized (this) {
   22344             final long origId = Binder.clearCallingIdentity();
   22345             try {
   22346                 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
   22347                 if (stack != null){
   22348                     if (!stack.isActivityTypeStandardOrUndefined()) {
   22349                         throw new IllegalArgumentException(
   22350                                 "You can't move tasks from non-standard stacks.");
   22351                     }
   22352                     mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
   22353                 }
   22354             } finally {
   22355                 Binder.restoreCallingIdentity(origId);
   22356             }
   22357         }
   22358     }
   22359 
   22360     @Override
   22361     public void updatePersistentConfiguration(Configuration values) {
   22362         enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
   22363         enforceWriteSettingsPermission("updatePersistentConfiguration()");
   22364         if (values == null) {
   22365             throw new NullPointerException("Configuration must not be null");
   22366         }
   22367 
   22368         int userId = UserHandle.getCallingUserId();
   22369 
   22370         synchronized(this) {
   22371             updatePersistentConfigurationLocked(values, userId);
   22372         }
   22373     }
   22374 
   22375     private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
   22376         final long origId = Binder.clearCallingIdentity();
   22377         try {
   22378             updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
   22379         } finally {
   22380             Binder.restoreCallingIdentity(origId);
   22381         }
   22382     }
   22383 
   22384     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
   22385         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
   22386                 FONT_SCALE, 1.0f, userId);
   22387 
   22388         synchronized (this) {
   22389             if (getGlobalConfiguration().fontScale == scaleFactor) {
   22390                 return;
   22391             }
   22392 
   22393             final Configuration configuration
   22394                     = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
   22395             configuration.fontScale = scaleFactor;
   22396             updatePersistentConfigurationLocked(configuration, userId);
   22397         }
   22398     }
   22399 
   22400     private void enforceWriteSettingsPermission(String func) {
   22401         int uid = Binder.getCallingUid();
   22402         if (uid == ROOT_UID) {
   22403             return;
   22404         }
   22405 
   22406         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
   22407                 Settings.getPackageNameForUid(mContext, uid), false)) {
   22408             return;
   22409         }
   22410 
   22411         String msg = "Permission Denial: " + func + " from pid="
   22412                 + Binder.getCallingPid()
   22413                 + ", uid=" + uid
   22414                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
   22415         Slog.w(TAG, msg);
   22416         throw new SecurityException(msg);
   22417     }
   22418 
   22419     @Override
   22420     public boolean updateConfiguration(Configuration values) {
   22421         enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
   22422 
   22423         synchronized(this) {
   22424             if (values == null && mWindowManager != null) {
   22425                 // sentinel: fetch the current configuration from the window manager
   22426                 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
   22427             }
   22428 
   22429             if (mWindowManager != null) {
   22430                 // Update OOM levels based on display size.
   22431                 mProcessList.applyDisplaySize(mWindowManager);
   22432             }
   22433 
   22434             final long origId = Binder.clearCallingIdentity();
   22435             try {
   22436                 if (values != null) {
   22437                     Settings.System.clearConfiguration(values);
   22438                 }
   22439                 updateConfigurationLocked(values, null, false, false /* persistent */,
   22440                         UserHandle.USER_NULL, false /* deferResume */,
   22441                         mTmpUpdateConfigurationResult);
   22442                 return mTmpUpdateConfigurationResult.changes != 0;
   22443             } finally {
   22444                 Binder.restoreCallingIdentity(origId);
   22445             }
   22446         }
   22447     }
   22448 
   22449     void updateUserConfigurationLocked() {
   22450         final Configuration configuration = new Configuration(getGlobalConfiguration());
   22451         final int currentUserId = mUserController.getCurrentUserId();
   22452         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
   22453                 currentUserId, Settings.System.canWrite(mContext));
   22454         updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
   22455                 false /* persistent */, currentUserId, false /* deferResume */);
   22456     }
   22457 
   22458     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
   22459             boolean initLocale) {
   22460         return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
   22461     }
   22462 
   22463     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
   22464             boolean initLocale, boolean deferResume) {
   22465         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
   22466         return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
   22467                 UserHandle.USER_NULL, deferResume);
   22468     }
   22469 
   22470     // To cache the list of supported system locales
   22471     private String[] mSupportedSystemLocales = null;
   22472 
   22473     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
   22474             boolean initLocale, boolean persistent, int userId, boolean deferResume) {
   22475         return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
   22476                 deferResume, null /* result */);
   22477     }
   22478 
   22479     /**
   22480      * Do either or both things: (1) change the current configuration, and (2)
   22481      * make sure the given activity is running with the (now) current
   22482      * configuration.  Returns true if the activity has been left running, or
   22483      * false if <var>starting</var> is being destroyed to match the new
   22484      * configuration.
   22485      *
   22486      * @param userId is only used when persistent parameter is set to true to persist configuration
   22487      *               for that particular user
   22488      */
   22489     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
   22490             boolean initLocale, boolean persistent, int userId, boolean deferResume,
   22491             UpdateConfigurationResult result) {
   22492         int changes = 0;
   22493         boolean kept = true;
   22494 
   22495         if (mWindowManager != null) {
   22496             mWindowManager.deferSurfaceLayout();
   22497         }
   22498         try {
   22499             if (values != null) {
   22500                 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
   22501                         deferResume);
   22502             }
   22503 
   22504             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
   22505         } finally {
   22506             if (mWindowManager != null) {
   22507                 mWindowManager.continueSurfaceLayout();
   22508             }
   22509         }
   22510 
   22511         if (result != null) {
   22512             result.changes = changes;
   22513             result.activityRelaunched = !kept;
   22514         }
   22515         return kept;
   22516     }
   22517 
   22518     /**
   22519      * Returns true if this configuration change is interesting enough to send an
   22520      * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
   22521      */
   22522     private static boolean isSplitConfigurationChange(int configDiff) {
   22523         return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
   22524     }
   22525 
   22526     /** Update default (global) configuration and notify listeners about changes. */
   22527     private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
   22528             boolean persistent, int userId, boolean deferResume) {
   22529         mTempConfig.setTo(getGlobalConfiguration());
   22530         final int changes = mTempConfig.updateFrom(values);
   22531         if (changes == 0) {
   22532             // Since calling to Activity.setRequestedOrientation leads to freezing the window with
   22533             // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
   22534             // performDisplayOverrideConfigUpdate in order to send the new display configuration
   22535             // (even if there are no actual changes) to unfreeze the window.
   22536             performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
   22537             return 0;
   22538         }
   22539 
   22540         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
   22541                 "Updating global configuration to: " + values);
   22542 
   22543         EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
   22544         StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
   22545                 values.colorMode,
   22546                 values.densityDpi,
   22547                 values.fontScale,
   22548                 values.hardKeyboardHidden,
   22549                 values.keyboard,
   22550                 values.keyboardHidden,
   22551                 values.mcc,
   22552                 values.mnc,
   22553                 values.navigation,
   22554                 values.navigationHidden,
   22555                 values.orientation,
   22556                 values.screenHeightDp,
   22557                 values.screenLayout,
   22558                 values.screenWidthDp,
   22559                 values.smallestScreenWidthDp,
   22560                 values.touchscreen,
   22561                 values.uiMode);
   22562 
   22563 
   22564         if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
   22565             final LocaleList locales = values.getLocales();
   22566             int bestLocaleIndex = 0;
   22567             if (locales.size() > 1) {
   22568                 if (mSupportedSystemLocales == null) {
   22569                     mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
   22570                 }
   22571                 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
   22572             }
   22573             SystemProperties.set("persist.sys.locale",
   22574                     locales.get(bestLocaleIndex).toLanguageTag());
   22575             LocaleList.setDefault(locales, bestLocaleIndex);
   22576             mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
   22577                     locales.get(bestLocaleIndex)));
   22578         }
   22579 
   22580         mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
   22581         mTempConfig.seq = mConfigurationSeq;
   22582 
   22583         // Update stored global config and notify everyone about the change.
   22584         mStackSupervisor.onConfigurationChanged(mTempConfig);
   22585 
   22586         Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
   22587         // TODO(multi-display): Update UsageEvents#Event to include displayId.
   22588         mUsageStatsService.reportConfigurationChange(mTempConfig,
   22589                 mUserController.getCurrentUserId());
   22590 
   22591         // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
   22592         updateShouldShowDialogsLocked(mTempConfig);
   22593 
   22594         AttributeCache ac = AttributeCache.instance();
   22595         if (ac != null) {
   22596             ac.updateConfiguration(mTempConfig);
   22597         }
   22598 
   22599         // Make sure all resources in our process are updated right now, so that anyone who is going
   22600         // to retrieve resource values after we return will be sure to get the new ones. This is
   22601         // especially important during boot, where the first config change needs to guarantee all
   22602         // resources have that config before following boot code is executed.
   22603         mSystemThread.applyConfigurationToResources(mTempConfig);
   22604 
   22605         // We need another copy of global config because we're scheduling some calls instead of
   22606         // running them in place. We need to be sure that object we send will be handled unchanged.
   22607         final Configuration configCopy = new Configuration(mTempConfig);
   22608         if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
   22609             Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
   22610             msg.obj = configCopy;
   22611             msg.arg1 = userId;
   22612             mHandler.sendMessage(msg);
   22613         }
   22614 
   22615         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   22616             ProcessRecord app = mLruProcesses.get(i);
   22617             try {
   22618                 if (app.thread != null) {
   22619                     if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
   22620                             + app.processName + " new config " + configCopy);
   22621                     mLifecycleManager.scheduleTransaction(app.thread,
   22622                             ConfigurationChangeItem.obtain(configCopy));
   22623                 }
   22624             } catch (Exception e) {
   22625                 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
   22626             }
   22627         }
   22628 
   22629         Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
   22630         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
   22631                 | Intent.FLAG_RECEIVER_FOREGROUND
   22632                 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
   22633         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
   22634                 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
   22635                 UserHandle.USER_ALL);
   22636         if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
   22637             intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
   22638             intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
   22639                     | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
   22640                     | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
   22641             if (initLocale || !mProcessesReady) {
   22642                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   22643             }
   22644             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
   22645                     OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
   22646                     UserHandle.USER_ALL);
   22647         }
   22648 
   22649         // Send a broadcast to PackageInstallers if the configuration change is interesting
   22650         // for the purposes of installing additional splits.
   22651         if (!initLocale && isSplitConfigurationChange(changes)) {
   22652             intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
   22653             intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
   22654                     | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
   22655 
   22656             // Typically only app stores will have this permission.
   22657             String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
   22658             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
   22659                     OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
   22660         }
   22661 
   22662         // Override configuration of the default display duplicates global config, so we need to
   22663         // update it also. This will also notify WindowManager about changes.
   22664         performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
   22665                 DEFAULT_DISPLAY);
   22666 
   22667         return changes;
   22668     }
   22669 
   22670     @Override
   22671     public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
   22672         enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
   22673 
   22674         synchronized (this) {
   22675             // Check if display is initialized in AM.
   22676             if (!mStackSupervisor.isDisplayAdded(displayId)) {
   22677                 // Call might come when display is not yet added or has already been removed.
   22678                 if (DEBUG_CONFIGURATION) {
   22679                     Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
   22680                             + displayId);
   22681                 }
   22682                 return false;
   22683             }
   22684 
   22685             if (values == null && mWindowManager != null) {
   22686                 // sentinel: fetch the current configuration from the window manager
   22687                 values = mWindowManager.computeNewConfiguration(displayId);
   22688             }
   22689 
   22690             if (mWindowManager != null) {
   22691                 // Update OOM levels based on display size.
   22692                 mProcessList.applyDisplaySize(mWindowManager);
   22693             }
   22694 
   22695             final long origId = Binder.clearCallingIdentity();
   22696             try {
   22697                 if (values != null) {
   22698                     Settings.System.clearConfiguration(values);
   22699                 }
   22700                 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
   22701                         false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
   22702                 return mTmpUpdateConfigurationResult.changes != 0;
   22703             } finally {
   22704                 Binder.restoreCallingIdentity(origId);
   22705             }
   22706         }
   22707     }
   22708 
   22709     boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
   22710             boolean deferResume, int displayId) {
   22711         return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
   22712                 displayId, null /* result */);
   22713     }
   22714 
   22715     /**
   22716      * Updates override configuration specific for the selected display. If no config is provided,
   22717      * new one will be computed in WM based on current display info.
   22718      */
   22719     private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
   22720             ActivityRecord starting, boolean deferResume, int displayId,
   22721             UpdateConfigurationResult result) {
   22722         int changes = 0;
   22723         boolean kept = true;
   22724 
   22725         if (mWindowManager != null) {
   22726             mWindowManager.deferSurfaceLayout();
   22727         }
   22728         try {
   22729             if (values != null) {
   22730                 if (displayId == DEFAULT_DISPLAY) {
   22731                     // Override configuration of the default display duplicates global config, so
   22732                     // we're calling global config update instead for default display. It will also
   22733                     // apply the correct override config.
   22734                     changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
   22735                             false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
   22736                 } else {
   22737                     changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
   22738                 }
   22739             }
   22740 
   22741             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
   22742         } finally {
   22743             if (mWindowManager != null) {
   22744                 mWindowManager.continueSurfaceLayout();
   22745             }
   22746         }
   22747 
   22748         if (result != null) {
   22749             result.changes = changes;
   22750             result.activityRelaunched = !kept;
   22751         }
   22752         return kept;
   22753     }
   22754 
   22755     private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
   22756             int displayId) {
   22757         mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
   22758         final int changes = mTempConfig.updateFrom(values);
   22759         if (changes != 0) {
   22760             Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
   22761                     + mTempConfig + " for displayId=" + displayId);
   22762             mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
   22763 
   22764             final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
   22765             if (isDensityChange && displayId == DEFAULT_DISPLAY) {
   22766                 mAppWarnings.onDensityChanged();
   22767 
   22768                 killAllBackgroundProcessesExcept(N,
   22769                         ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
   22770             }
   22771         }
   22772 
   22773         // Update the configuration with WM first and check if any of the stacks need to be resized
   22774         // due to the configuration change. If so, resize the stacks now and do any relaunches if
   22775         // necessary. This way we don't need to relaunch again afterwards in
   22776         // ensureActivityConfiguration().
   22777         if (mWindowManager != null) {
   22778             final int[] resizedStacks =
   22779                     mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
   22780             if (resizedStacks != null) {
   22781                 for (int stackId : resizedStacks) {
   22782                     resizeStackWithBoundsFromWindowManager(stackId, deferResume);
   22783                 }
   22784             }
   22785         }
   22786 
   22787         return changes;
   22788     }
   22789 
   22790     /** Applies latest configuration and/or visibility updates if needed. */
   22791     private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
   22792         boolean kept = true;
   22793         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
   22794         // mainStack is null during startup.
   22795         if (mainStack != null) {
   22796             if (changes != 0 && starting == null) {
   22797                 // If the configuration changed, and the caller is not already
   22798                 // in the process of starting an activity, then find the top
   22799                 // activity to check if its configuration needs to change.
   22800                 starting = mainStack.topRunningActivityLocked();
   22801             }
   22802 
   22803             if (starting != null) {
   22804                 kept = starting.ensureActivityConfiguration(changes,
   22805                         false /* preserveWindow */);
   22806                 // And we need to make sure at this point that all other activities
   22807                 // are made visible with the correct configuration.
   22808                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
   22809                         !PRESERVE_WINDOWS);
   22810             }
   22811         }
   22812 
   22813         return kept;
   22814     }
   22815 
   22816     /** Helper method that requests bounds from WM and applies them to stack. */
   22817     private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
   22818         final Rect newStackBounds = new Rect();
   22819         final ActivityStack stack = mStackSupervisor.getStack(stackId);
   22820 
   22821         // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
   22822         if (stack == null) {
   22823             final StringWriter writer = new StringWriter();
   22824             final PrintWriter printWriter = new PrintWriter(writer);
   22825             mStackSupervisor.dumpDisplays(printWriter);
   22826             printWriter.flush();
   22827 
   22828             Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
   22829         }
   22830 
   22831         stack.getBoundsForNewConfiguration(newStackBounds);
   22832         mStackSupervisor.resizeStackLocked(
   22833                 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
   22834                 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
   22835                 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
   22836     }
   22837 
   22838     /**
   22839      * Decide based on the configuration whether we should show the ANR,
   22840      * crash, etc dialogs.  The idea is that if there is no affordance to
   22841      * press the on-screen buttons, or the user experience would be more
   22842      * greatly impacted than the crash itself, we shouldn't show the dialog.
   22843      *
   22844      * A thought: SystemUI might also want to get told about this, the Power
   22845      * dialog / global actions also might want different behaviors.
   22846      */
   22847     private void updateShouldShowDialogsLocked(Configuration config) {
   22848         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
   22849                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
   22850                                    && config.navigation == Configuration.NAVIGATION_NONAV);
   22851         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
   22852         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
   22853                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
   22854                 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
   22855                 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
   22856         final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
   22857                 HIDE_ERROR_DIALOGS, 0) != 0;
   22858         mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
   22859     }
   22860 
   22861     @Override
   22862     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
   22863         synchronized (this) {
   22864             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
   22865             if (srec != null) {
   22866                 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
   22867             }
   22868         }
   22869         return false;
   22870     }
   22871 
   22872     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
   22873             Intent resultData) {
   22874 
   22875         synchronized (this) {
   22876             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   22877             if (r != null) {
   22878                 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
   22879             }
   22880             return false;
   22881         }
   22882     }
   22883 
   22884     public int getLaunchedFromUid(IBinder activityToken) {
   22885         ActivityRecord srec;
   22886         synchronized (this) {
   22887             srec = ActivityRecord.forTokenLocked(activityToken);
   22888         }
   22889         if (srec == null) {
   22890             return -1;
   22891         }
   22892         return srec.launchedFromUid;
   22893     }
   22894 
   22895     public String getLaunchedFromPackage(IBinder activityToken) {
   22896         ActivityRecord srec;
   22897         synchronized (this) {
   22898             srec = ActivityRecord.forTokenLocked(activityToken);
   22899         }
   22900         if (srec == null) {
   22901             return null;
   22902         }
   22903         return srec.launchedFromPackage;
   22904     }
   22905 
   22906     // =========================================================
   22907     // LIFETIME MANAGEMENT
   22908     // =========================================================
   22909 
   22910     // Returns whether the app is receiving broadcast.
   22911     // If receiving, fetch all broadcast queues which the app is
   22912     // the current [or imminent] receiver on.
   22913     private boolean isReceivingBroadcastLocked(ProcessRecord app,
   22914             ArraySet<BroadcastQueue> receivingQueues) {
   22915         final int N = app.curReceivers.size();
   22916         if (N > 0) {
   22917             for (int i = 0; i < N; i++) {
   22918                 receivingQueues.add(app.curReceivers.valueAt(i).queue);
   22919             }
   22920             return true;
   22921         }
   22922 
   22923         // It's not the current receiver, but it might be starting up to become one
   22924         for (BroadcastQueue queue : mBroadcastQueues) {
   22925             final BroadcastRecord r = queue.mPendingBroadcast;
   22926             if (r != null && r.curApp == app) {
   22927                 // found it; report which queue it's in
   22928                 receivingQueues.add(queue);
   22929             }
   22930         }
   22931 
   22932         return !receivingQueues.isEmpty();
   22933     }
   22934 
   22935     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
   22936             int targetUid, ComponentName targetComponent, String targetProcess) {
   22937         if (!mTrackingAssociations) {
   22938             return null;
   22939         }
   22940         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
   22941                 = mAssociations.get(targetUid);
   22942         if (components == null) {
   22943             components = new ArrayMap<>();
   22944             mAssociations.put(targetUid, components);
   22945         }
   22946         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
   22947         if (sourceUids == null) {
   22948             sourceUids = new SparseArray<>();
   22949             components.put(targetComponent, sourceUids);
   22950         }
   22951         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
   22952         if (sourceProcesses == null) {
   22953             sourceProcesses = new ArrayMap<>();
   22954             sourceUids.put(sourceUid, sourceProcesses);
   22955         }
   22956         Association ass = sourceProcesses.get(sourceProcess);
   22957         if (ass == null) {
   22958             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
   22959                     targetProcess);
   22960             sourceProcesses.put(sourceProcess, ass);
   22961         }
   22962         ass.mCount++;
   22963         ass.mNesting++;
   22964         if (ass.mNesting == 1) {
   22965             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
   22966             ass.mLastState = sourceState;
   22967         }
   22968         return ass;
   22969     }
   22970 
   22971     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
   22972             ComponentName targetComponent) {
   22973         if (!mTrackingAssociations) {
   22974             return;
   22975         }
   22976         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
   22977                 = mAssociations.get(targetUid);
   22978         if (components == null) {
   22979             return;
   22980         }
   22981         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
   22982         if (sourceUids == null) {
   22983             return;
   22984         }
   22985         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
   22986         if (sourceProcesses == null) {
   22987             return;
   22988         }
   22989         Association ass = sourceProcesses.get(sourceProcess);
   22990         if (ass == null || ass.mNesting <= 0) {
   22991             return;
   22992         }
   22993         ass.mNesting--;
   22994         if (ass.mNesting == 0) {
   22995             long uptime = SystemClock.uptimeMillis();
   22996             ass.mTime += uptime - ass.mStartTime;
   22997             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
   22998                     += uptime - ass.mLastStateUptime;
   22999             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
   23000         }
   23001     }
   23002 
   23003     private void noteUidProcessState(final int uid, final int state) {
   23004         mBatteryStatsService.noteUidProcessState(uid, state);
   23005         mAppOpsService.updateUidProcState(uid, state);
   23006         if (mTrackingAssociations) {
   23007             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
   23008                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
   23009                         = mAssociations.valueAt(i1);
   23010                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
   23011                     SparseArray<ArrayMap<String, Association>> sourceUids
   23012                             = targetComponents.valueAt(i2);
   23013                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
   23014                     if (sourceProcesses != null) {
   23015                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
   23016                             Association ass = sourceProcesses.valueAt(i4);
   23017                             if (ass.mNesting >= 1) {
   23018                                 // currently associated
   23019                                 long uptime = SystemClock.uptimeMillis();
   23020                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
   23021                                         += uptime - ass.mLastStateUptime;
   23022                                 ass.mLastState = state;
   23023                                 ass.mLastStateUptime = uptime;
   23024                             }
   23025                         }
   23026                     }
   23027                 }
   23028             }
   23029         }
   23030     }
   23031 
   23032     private final boolean computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
   23033             boolean doingAll, long now) {
   23034         if (mAdjSeq == app.adjSeq) {
   23035             if (app.adjSeq == app.completedAdjSeq) {
   23036                 // This adjustment has already been computed successfully.
   23037                 return false;
   23038             } else {
   23039                 // The process is being computed, so there is a cycle. We cannot
   23040                 // rely on this process's state.
   23041                 app.containsCycle = true;
   23042                 return false;
   23043             }
   23044         }
   23045 
   23046         if (app.thread == null) {
   23047             app.adjSeq = mAdjSeq;
   23048             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   23049             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   23050             app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ;
   23051             app.completedAdjSeq = app.adjSeq;
   23052             return false;
   23053         }
   23054 
   23055         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
   23056         app.adjSource = null;
   23057         app.adjTarget = null;
   23058         app.empty = false;
   23059         app.cached = false;
   23060 
   23061         final int activitiesSize = app.activities.size();
   23062         final int appUid = app.info.uid;
   23063         final int logUid = mCurOomAdjUid;
   23064 
   23065         int prevAppAdj = app.curAdj;
   23066 
   23067         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   23068             // The max adjustment doesn't allow this app to be anything
   23069             // below foreground, so it is not worth doing work for it.
   23070             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23071                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making fixed: " + app);
   23072             }
   23073             app.adjType = "fixed";
   23074             app.adjSeq = mAdjSeq;
   23075             app.curRawAdj = app.maxAdj;
   23076             app.foregroundActivities = false;
   23077             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   23078             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
   23079             // System processes can do UI, and when they do we want to have
   23080             // them trim their memory after the user leaves the UI.  To
   23081             // facilitate this, here we need to determine whether or not it
   23082             // is currently showing UI.
   23083             app.systemNoUi = true;
   23084             if (app == TOP_APP) {
   23085                 app.systemNoUi = false;
   23086                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
   23087                 app.adjType = "pers-top-activity";
   23088             } else if (app.hasTopUi) {
   23089                 // sched group/proc state adjustment is below
   23090                 app.systemNoUi = false;
   23091                 app.adjType = "pers-top-ui";
   23092             } else if (activitiesSize > 0) {
   23093                 for (int j = 0; j < activitiesSize; j++) {
   23094                     final ActivityRecord r = app.activities.get(j);
   23095                     if (r.visible) {
   23096                         app.systemNoUi = false;
   23097                     }
   23098                 }
   23099             }
   23100             if (!app.systemNoUi) {
   23101               if (mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE) {
   23102                   // screen on, promote UI
   23103                   app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
   23104                   app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
   23105               } else {
   23106                   // screen off, restrict UI scheduling
   23107                   app.curProcState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
   23108                   app.curSchedGroup = ProcessList.SCHED_GROUP_RESTRICTED;
   23109               }
   23110             }
   23111             app.curAdj = app.maxAdj;
   23112             app.completedAdjSeq = app.adjSeq;
   23113             // if curAdj is less than prevAppAdj, then this process was promoted
   23114             return app.curAdj < prevAppAdj;
   23115         }
   23116 
   23117         app.systemNoUi = false;
   23118 
   23119         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
   23120 
   23121         // Determine the importance of the process, starting with most
   23122         // important to least, and assign an appropriate OOM adjustment.
   23123         int adj;
   23124         int schedGroup;
   23125         int procState;
   23126         int cachedAdjSeq;
   23127 
   23128         boolean foregroundActivities = false;
   23129         mTmpBroadcastQueue.clear();
   23130         if (PROCESS_STATE_CUR_TOP == ActivityManager.PROCESS_STATE_TOP && app == TOP_APP) {
   23131             // The last app on the list is the foreground app.
   23132             adj = ProcessList.FOREGROUND_APP_ADJ;
   23133             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
   23134             app.adjType = "top-activity";
   23135             foregroundActivities = true;
   23136             procState = PROCESS_STATE_CUR_TOP;
   23137             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23138                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top: " + app);
   23139             }
   23140         } else if (app.runningRemoteAnimation) {
   23141             adj = ProcessList.VISIBLE_APP_ADJ;
   23142             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
   23143             app.adjType = "running-remote-anim";
   23144             procState = PROCESS_STATE_CUR_TOP;
   23145             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23146                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making running remote anim: " + app);
   23147             }
   23148         } else if (app.instr != null) {
   23149             // Don't want to kill running instrumentation.
   23150             adj = ProcessList.FOREGROUND_APP_ADJ;
   23151             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   23152             app.adjType = "instrumentation";
   23153             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
   23154             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23155                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making instrumentation: " + app);
   23156             }
   23157         } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
   23158             // An app that is currently receiving a broadcast also
   23159             // counts as being in the foreground for OOM killer purposes.
   23160             // It's placed in a sched group based on the nature of the
   23161             // broadcast as reflected by which queue it's active in.
   23162             adj = ProcessList.FOREGROUND_APP_ADJ;
   23163             schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
   23164                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
   23165             app.adjType = "broadcast";
   23166             procState = ActivityManager.PROCESS_STATE_RECEIVER;
   23167             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23168                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making broadcast: " + app);
   23169             }
   23170         } else if (app.executingServices.size() > 0) {
   23171             // An app that is currently executing a service callback also
   23172             // counts as being in the foreground.
   23173             adj = ProcessList.FOREGROUND_APP_ADJ;
   23174             schedGroup = app.execServicesFg ?
   23175                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
   23176             app.adjType = "exec-service";
   23177             procState = ActivityManager.PROCESS_STATE_SERVICE;
   23178             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23179                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making exec-service: " + app);
   23180             }
   23181             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
   23182         } else if (app == TOP_APP) {
   23183             adj = ProcessList.FOREGROUND_APP_ADJ;
   23184             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   23185             app.adjType = "top-sleeping";
   23186             foregroundActivities = true;
   23187             procState = PROCESS_STATE_CUR_TOP;
   23188             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23189                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top (sleeping): " + app);
   23190             }
   23191         } else {
   23192             // As far as we know the process is empty.  We may change our mind later.
   23193             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   23194             // At this point we don't actually know the adjustment.  Use the cached adj
   23195             // value that the caller wants us to.
   23196             adj = cachedAdj;
   23197             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   23198             app.cached = true;
   23199             app.empty = true;
   23200             app.adjType = "cch-empty";
   23201             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23202                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making empty: " + app);
   23203             }
   23204         }
   23205 
   23206         // Examine all activities if not already foreground.
   23207         if (!foregroundActivities && activitiesSize > 0) {
   23208             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
   23209             for (int j = 0; j < activitiesSize; j++) {
   23210                 final ActivityRecord r = app.activities.get(j);
   23211                 if (r.app != app) {
   23212                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
   23213                             + " instead of expected " + app);
   23214                     if (r.app == null || (r.app.uid == app.uid)) {
   23215                         // Only fix things up when they look sane
   23216                         r.setProcess(app);
   23217                     } else {
   23218                         continue;
   23219                     }
   23220                 }
   23221                 if (r.visible) {
   23222                     // App has a visible activity; only upgrade adjustment.
   23223                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   23224                         adj = ProcessList.VISIBLE_APP_ADJ;
   23225                         app.adjType = "vis-activity";
   23226                         if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23227                             reportOomAdjMessageLocked(TAG_OOM_ADJ,
   23228                                     "Raise adj to vis-activity: " + app);
   23229                         }
   23230                     }
   23231                     if (procState > PROCESS_STATE_CUR_TOP) {
   23232                         procState = PROCESS_STATE_CUR_TOP;
   23233                         app.adjType = "vis-activity";
   23234                         if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23235                             reportOomAdjMessageLocked(TAG_OOM_ADJ,
   23236                                     "Raise procstate to vis-activity (top): " + app);
   23237                         }
   23238                     }
   23239                     if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) {
   23240                         schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   23241                     }
   23242                     app.cached = false;
   23243                     app.empty = false;
   23244                     foregroundActivities = true;
   23245                     final TaskRecord task = r.getTask();
   23246                     if (task != null && minLayer > 0) {
   23247                         final int layer = task.mLayerRank;
   23248                         if (layer >= 0 && minLayer > layer) {
   23249                             minLayer = layer;
   23250                         }
   23251                     }
   23252                     break;
   23253                 } else if (r.isState(ActivityState.PAUSING, ActivityState.PAUSED)) {
   23254                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   23255                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   23256                         app.adjType = "pause-activity";
   23257                         if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23258                             reportOomAdjMessageLocked(TAG_OOM_ADJ,
   23259                                     "Raise adj to pause-activity: "  + app);
   23260                         }
   23261                     }
   23262                     if (procState > PROCESS_STATE_CUR_TOP) {
   23263                         procState = PROCESS_STATE_CUR_TOP;
   23264                         app.adjType = "pause-activity";
   23265                         if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23266                             reportOomAdjMessageLocked(TAG_OOM_ADJ,
   23267                                     "Raise procstate to pause-activity (top): "  + app);
   23268                         }
   23269                     }
   23270                     if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) {
   23271                         schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   23272                     }
   23273                     app.cached = false;
   23274                     app.empty = false;
   23275                     foregroundActivities = true;
   23276                 } else if (r.isState(ActivityState.STOPPING)) {
   23277                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   23278                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   23279                         app.adjType = "stop-activity";
   23280                         if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23281                             reportOomAdjMessageLocked(TAG_OOM_ADJ,
   23282                                     "Raise adj to stop-activity: "  + app);
   23283                         }
   23284                     }
   23285                     // For the process state, we will at this point consider the
   23286                     // process to be cached.  It will be cached either as an activity
   23287                     // or empty depending on whether the activity is finishing.  We do
   23288                     // this so that we can treat the process as cached for purposes of
   23289                     // memory trimming (determing current memory level, trim command to
   23290                     // send to process) since there can be an arbitrary number of stopping
   23291                     // processes and they should soon all go into the cached state.
   23292                     if (!r.finishing) {
   23293                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   23294                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   23295                             app.adjType = "stop-activity";
   23296                             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23297                                 reportOomAdjMessageLocked(TAG_OOM_ADJ,
   23298                                         "Raise procstate to stop-activity: " + app);
   23299                             }
   23300                         }
   23301                     }
   23302                     app.cached = false;
   23303                     app.empty = false;
   23304                     foregroundActivities = true;
   23305                 } else {
   23306                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   23307                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   23308                         app.adjType = "cch-act";
   23309                         if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23310                             reportOomAdjMessageLocked(TAG_OOM_ADJ,
   23311                                     "Raise procstate to cached activity: " + app);
   23312                         }
   23313                     }
   23314                 }
   23315             }
   23316             if (adj == ProcessList.VISIBLE_APP_ADJ) {
   23317                 adj += minLayer;
   23318             }
   23319         }
   23320         if (procState > ActivityManager.PROCESS_STATE_CACHED_RECENT && app.recentTasks.size() > 0) {
   23321             procState = ActivityManager.PROCESS_STATE_CACHED_RECENT;
   23322             app.adjType = "cch-rec";
   23323             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23324                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to cached recent: " + app);
   23325             }
   23326         }
   23327 
   23328         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
   23329                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
   23330             if (app.foregroundServices) {
   23331                 // The user is aware of this app, so make it visible.
   23332                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   23333                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
   23334                 app.cached = false;
   23335                 app.adjType = "fg-service";
   23336                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   23337                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23338                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to fg service: " + app);
   23339                 }
   23340             } else if (app.hasOverlayUi) {
   23341                 // The process is display an overlay UI.
   23342                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   23343                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   23344                 app.cached = false;
   23345                 app.adjType = "has-overlay-ui";
   23346                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   23347                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23348                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to overlay ui: " + app);
   23349                 }
   23350             }
   23351         }
   23352 
   23353         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
   23354                 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
   23355             if (app.forcingToImportant != null) {
   23356                 // This is currently used for toasts...  they are not interactive, and
   23357                 // we don't want them to cause the app to become fully foreground (and
   23358                 // thus out of background check), so we yes the best background level we can.
   23359                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   23360                 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
   23361                 app.cached = false;
   23362                 app.adjType = "force-imp";
   23363                 app.adjSource = app.forcingToImportant;
   23364                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   23365                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23366                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to force imp: " + app);
   23367                 }
   23368             }
   23369         }
   23370 
   23371         if (app == mHeavyWeightProcess) {
   23372             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   23373                 // We don't want to kill the current heavy-weight process.
   23374                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
   23375                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   23376                 app.cached = false;
   23377                 app.adjType = "heavy";
   23378                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23379                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to heavy: " + app);
   23380                 }
   23381             }
   23382             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
   23383                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
   23384                 app.adjType = "heavy";
   23385                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23386                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to heavy: " + app);
   23387                 }
   23388             }
   23389         }
   23390 
   23391         if (app == mHomeProcess) {
   23392             if (adj > ProcessList.HOME_APP_ADJ) {
   23393                 // This process is hosting what we currently consider to be the
   23394                 // home app, so we don't want to let it go into the background.
   23395                 adj = ProcessList.HOME_APP_ADJ;
   23396                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   23397                 app.cached = false;
   23398                 app.adjType = "home";
   23399                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23400                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to home: " + app);
   23401                 }
   23402             }
   23403             if (procState > ActivityManager.PROCESS_STATE_HOME) {
   23404                 procState = ActivityManager.PROCESS_STATE_HOME;
   23405                 app.adjType = "home";
   23406                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23407                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to home: " + app);
   23408                 }
   23409             }
   23410         }
   23411 
   23412         if (app == mPreviousProcess && app.activities.size() > 0) {
   23413             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
   23414                 // This was the previous process that showed UI to the user.
   23415                 // We want to try to keep it around more aggressively, to give
   23416                 // a good experience around switching between two apps.
   23417                 adj = ProcessList.PREVIOUS_APP_ADJ;
   23418                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   23419                 app.cached = false;
   23420                 app.adjType = "previous";
   23421                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23422                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to prev: " + app);
   23423                 }
   23424             }
   23425             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   23426                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   23427                 app.adjType = "previous";
   23428                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23429                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to prev: " + app);
   23430                 }
   23431             }
   23432         }
   23433 
   23434         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
   23435                 + " reason=" + app.adjType);
   23436 
   23437         // By default, we use the computed adjustment.  It may be changed if
   23438         // there are applications dependent on our services or providers, but
   23439         // this gives us a baseline and makes sure we don't get into an
   23440         // infinite recursion.
   23441         app.curRawAdj = adj;
   23442         app.hasStartedServices = false;
   23443         app.adjSeq = mAdjSeq;
   23444 
   23445         if (mBackupTarget != null && app == mBackupTarget.app) {
   23446             // If possible we want to avoid killing apps while they're being backed up
   23447             if (adj > ProcessList.BACKUP_APP_ADJ) {
   23448                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
   23449                 adj = ProcessList.BACKUP_APP_ADJ;
   23450                 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
   23451                     procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
   23452                 }
   23453                 app.adjType = "backup";
   23454                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23455                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to backup: " + app);
   23456                 }
   23457                 app.cached = false;
   23458             }
   23459             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
   23460                 procState = ActivityManager.PROCESS_STATE_BACKUP;
   23461                 app.adjType = "backup";
   23462                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23463                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to backup: " + app);
   23464                 }
   23465             }
   23466         }
   23467 
   23468         boolean mayBeTop = false;
   23469         String mayBeTopType = null;
   23470         Object mayBeTopSource = null;
   23471         Object mayBeTopTarget = null;
   23472 
   23473         for (int is = app.services.size()-1;
   23474                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   23475                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   23476                         || procState > ActivityManager.PROCESS_STATE_TOP);
   23477                 is--) {
   23478             ServiceRecord s = app.services.valueAt(is);
   23479             if (s.startRequested) {
   23480                 app.hasStartedServices = true;
   23481                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
   23482                     procState = ActivityManager.PROCESS_STATE_SERVICE;
   23483                     app.adjType = "started-services";
   23484                     if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23485                         reportOomAdjMessageLocked(TAG_OOM_ADJ,
   23486                                 "Raise procstate to started service: " + app);
   23487                     }
   23488                 }
   23489                 if (app.hasShownUi && app != mHomeProcess) {
   23490                     // If this process has shown some UI, let it immediately
   23491                     // go to the LRU list because it may be pretty heavy with
   23492                     // UI stuff.  We'll tag it with a label just to help
   23493                     // debug and understand what is going on.
   23494                     if (adj > ProcessList.SERVICE_ADJ) {
   23495                         app.adjType = "cch-started-ui-services";
   23496                     }
   23497                 } else {
   23498                     if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
   23499                         // This service has seen some activity within
   23500                         // recent memory, so we will keep its process ahead
   23501                         // of the background processes.
   23502                         if (adj > ProcessList.SERVICE_ADJ) {
   23503                             adj = ProcessList.SERVICE_ADJ;
   23504                             app.adjType = "started-services";
   23505                             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23506                                 reportOomAdjMessageLocked(TAG_OOM_ADJ,
   23507                                         "Raise adj to started service: " + app);
   23508                             }
   23509                             app.cached = false;
   23510                         }
   23511                     }
   23512                     // If we have let the service slide into the background
   23513                     // state, still have some text describing what it is doing
   23514                     // even though the service no longer has an impact.
   23515                     if (adj > ProcessList.SERVICE_ADJ) {
   23516                         app.adjType = "cch-started-services";
   23517                     }
   23518                 }
   23519             }
   23520 
   23521             for (int conni = s.connections.size()-1;
   23522                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   23523                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   23524                             || procState > ActivityManager.PROCESS_STATE_TOP);
   23525                     conni--) {
   23526                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
   23527                 for (int i = 0;
   23528                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
   23529                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   23530                                 || procState > ActivityManager.PROCESS_STATE_TOP);
   23531                         i++) {
   23532                     // XXX should compute this based on the max of
   23533                     // all connected clients.
   23534                     ConnectionRecord cr = clist.get(i);
   23535                     if (cr.binding.client == app) {
   23536                         // Binding to ourself is not interesting.
   23537                         continue;
   23538                     }
   23539 
   23540                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
   23541                         ProcessRecord client = cr.binding.client;
   23542                         computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
   23543                         if (client.containsCycle) {
   23544                             // We've detected a cycle. We should ignore this connection and allow
   23545                             // this process to retry computeOomAdjLocked later in case a later-checked
   23546                             // connection from a client  would raise its priority legitimately.
   23547                             app.containsCycle = true;
   23548                             continue;
   23549                         }
   23550                         int clientAdj = client.curRawAdj;
   23551                         int clientProcState = client.curProcState;
   23552                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   23553                             // If the other app is cached for any reason, for purposes here
   23554                             // we are going to consider it empty.  The specific cached state
   23555                             // doesn't propagate except under certain conditions.
   23556                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   23557                         }
   23558                         String adjType = null;
   23559                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
   23560                             // Not doing bind OOM management, so treat
   23561                             // this guy more like a started service.
   23562                             if (app.hasShownUi && app != mHomeProcess) {
   23563                                 // If this process has shown some UI, let it immediately
   23564                                 // go to the LRU list because it may be pretty heavy with
   23565                                 // UI stuff.  We'll tag it with a label just to help
   23566                                 // debug and understand what is going on.
   23567                                 if (adj > clientAdj) {
   23568                                     adjType = "cch-bound-ui-services";
   23569                                 }
   23570                                 app.cached = false;
   23571                                 clientAdj = adj;
   23572                                 clientProcState = procState;
   23573                             } else {
   23574                                 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
   23575                                     // This service has not seen activity within
   23576                                     // recent memory, so allow it to drop to the
   23577                                     // LRU list if there is no other reason to keep
   23578                                     // it around.  We'll also tag it with a label just
   23579                                     // to help debug and undertand what is going on.
   23580                                     if (adj > clientAdj) {
   23581                                         adjType = "cch-bound-services";
   23582                                     }
   23583                                     clientAdj = adj;
   23584                                 }
   23585                             }
   23586                         }
   23587                         if (adj > clientAdj) {
   23588                             // If this process has recently shown UI, and
   23589                             // the process that is binding to it is less
   23590                             // important than being visible, then we don't
   23591                             // care about the binding as much as we care
   23592                             // about letting this process get into the LRU
   23593                             // list to be killed and restarted if needed for
   23594                             // memory.
   23595                             if (app.hasShownUi && app != mHomeProcess
   23596                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   23597                                 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
   23598                                     adjType = "cch-bound-ui-services";
   23599                                 }
   23600                             } else {
   23601                                 int newAdj;
   23602                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
   23603                                         |Context.BIND_IMPORTANT)) != 0) {
   23604                                     if (clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
   23605                                         newAdj = clientAdj;
   23606                                     } else {
   23607                                         // make this service persistent
   23608                                         newAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
   23609                                         schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   23610                                         procState = ActivityManager.PROCESS_STATE_PERSISTENT;
   23611                                     }
   23612                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
   23613                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
   23614                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   23615                                     newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
   23616                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   23617                                     newAdj = clientAdj;
   23618                                 } else {
   23619                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   23620                                         newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
   23621                                     } else {
   23622                                         newAdj = adj;
   23623                                     }
   23624                                 }
   23625                                 if (!client.cached) {
   23626                                     app.cached = false;
   23627                                 }
   23628                                 if (adj >  newAdj) {
   23629                                     adj = newAdj;
   23630                                     adjType = "service";
   23631                                 }
   23632                             }
   23633                         }
   23634                         if ((cr.flags & (Context.BIND_NOT_FOREGROUND
   23635                                 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
   23636                             // This will treat important bound services identically to
   23637                             // the top app, which may behave differently than generic
   23638                             // foreground work.
   23639                             if (client.curSchedGroup > schedGroup) {
   23640                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
   23641                                     schedGroup = client.curSchedGroup;
   23642                                 } else {
   23643                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   23644                                 }
   23645                             }
   23646                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   23647                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   23648                                     // Special handling of clients who are in the top state.
   23649                                     // We *may* want to consider this process to be in the
   23650                                     // top state as well, but only if there is not another
   23651                                     // reason for it to be running.  Being on the top is a
   23652                                     // special state, meaning you are specifically running
   23653                                     // for the current top app.  If the process is already
   23654                                     // running in the background for some other reason, it
   23655                                     // is more important to continue considering it to be
   23656                                     // in the background state.
   23657                                     mayBeTop = true;
   23658                                     mayBeTopType = "service";
   23659                                     mayBeTopSource = cr.binding.client;
   23660                                     mayBeTopTarget = s.name;
   23661                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   23662                                 } else {
   23663                                     // Special handling for above-top states (persistent
   23664                                     // processes).  These should not bring the current process
   23665                                     // into the top state, since they are not on top.  Instead
   23666                                     // give them the best state after that.
   23667                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
   23668                                         clientProcState =
   23669                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
   23670                                     } else if (mWakefulness
   23671                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
   23672                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
   23673                                                     != 0) {
   23674                                         clientProcState =
   23675                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
   23676                                     } else {
   23677                                         clientProcState =
   23678                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   23679                                     }
   23680                                 }
   23681                             }
   23682                         } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
   23683                             if (clientProcState <
   23684                                     ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
   23685                                 clientProcState =
   23686                                         ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
   23687                             }
   23688                         } else {
   23689                             if (clientProcState <
   23690                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   23691                                 clientProcState =
   23692                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
   23693                             }
   23694                         }
   23695                         if (procState > clientProcState) {
   23696                             procState = clientProcState;
   23697                             if (adjType == null) {
   23698                                 adjType = "service";
   23699                             }
   23700                         }
   23701                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   23702                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
   23703                             app.pendingUiClean = true;
   23704                         }
   23705                         if (adjType != null) {
   23706                             app.adjType = adjType;
   23707                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   23708                                     .REASON_SERVICE_IN_USE;
   23709                             app.adjSource = cr.binding.client;
   23710                             app.adjSourceProcState = clientProcState;
   23711                             app.adjTarget = s.name;
   23712                             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23713                                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType
   23714                                         + ": " + app + ", due to " + cr.binding.client
   23715                                         + " adj=" + adj + " procState="
   23716                                         + ProcessList.makeProcStateString(procState));
   23717                             }
   23718                         }
   23719                     }
   23720                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
   23721                         app.treatLikeActivity = true;
   23722                     }
   23723                     final ActivityRecord a = cr.activity;
   23724                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
   23725                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && (a.visible
   23726                                 || a.isState(ActivityState.RESUMED, ActivityState.PAUSING))) {
   23727                             adj = ProcessList.FOREGROUND_APP_ADJ;
   23728                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   23729                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
   23730                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
   23731                                 } else {
   23732                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   23733                                 }
   23734                             }
   23735                             app.cached = false;
   23736                             app.adjType = "service";
   23737                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   23738                                     .REASON_SERVICE_IN_USE;
   23739                             app.adjSource = a;
   23740                             app.adjSourceProcState = procState;
   23741                             app.adjTarget = s.name;
   23742                             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23743                                 reportOomAdjMessageLocked(TAG_OOM_ADJ,
   23744                                         "Raise to service w/activity: " + app);
   23745                             }
   23746                         }
   23747                     }
   23748                 }
   23749             }
   23750         }
   23751 
   23752         for (int provi = app.pubProviders.size()-1;
   23753                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   23754                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   23755                         || procState > ActivityManager.PROCESS_STATE_TOP);
   23756                 provi--) {
   23757             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
   23758             for (int i = cpr.connections.size()-1;
   23759                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   23760                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
   23761                             || procState > ActivityManager.PROCESS_STATE_TOP);
   23762                     i--) {
   23763                 ContentProviderConnection conn = cpr.connections.get(i);
   23764                 ProcessRecord client = conn.client;
   23765                 if (client == app) {
   23766                     // Being our own client is not interesting.
   23767                     continue;
   23768                 }
   23769                 computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
   23770                 if (client.containsCycle) {
   23771                     // We've detected a cycle. We should ignore this connection and allow
   23772                     // this process to retry computeOomAdjLocked later in case a later-checked
   23773                     // connection from a client  would raise its priority legitimately.
   23774                     app.containsCycle = true;
   23775                     continue;
   23776                 }
   23777                 int clientAdj = client.curRawAdj;
   23778                 int clientProcState = client.curProcState;
   23779                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   23780                     // If the other app is cached for any reason, for purposes here
   23781                     // we are going to consider it empty.
   23782                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   23783                 }
   23784                 String adjType = null;
   23785                 if (adj > clientAdj) {
   23786                     if (app.hasShownUi && app != mHomeProcess
   23787                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   23788                         adjType = "cch-ui-provider";
   23789                     } else {
   23790                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
   23791                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
   23792                         adjType = "provider";
   23793                     }
   23794                     app.cached &= client.cached;
   23795                 }
   23796                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   23797                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   23798                         // Special handling of clients who are in the top state.
   23799                         // We *may* want to consider this process to be in the
   23800                         // top state as well, but only if there is not another
   23801                         // reason for it to be running.  Being on the top is a
   23802                         // special state, meaning you are specifically running
   23803                         // for the current top app.  If the process is already
   23804                         // running in the background for some other reason, it
   23805                         // is more important to continue considering it to be
   23806                         // in the background state.
   23807                         mayBeTop = true;
   23808                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   23809                         mayBeTopType = adjType = "provider-top";
   23810                         mayBeTopSource = client;
   23811                         mayBeTopTarget = cpr.name;
   23812                     } else {
   23813                         // Special handling for above-top states (persistent
   23814                         // processes).  These should not bring the current process
   23815                         // into the top state, since they are not on top.  Instead
   23816                         // give them the best state after that.
   23817                         clientProcState =
   23818                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
   23819                         if (adjType == null) {
   23820                             adjType = "provider";
   23821                         }
   23822                     }
   23823                 }
   23824                 if (procState > clientProcState) {
   23825                     procState = clientProcState;
   23826                 }
   23827                 if (client.curSchedGroup > schedGroup) {
   23828                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   23829                 }
   23830                 if (adjType != null) {
   23831                     app.adjType = adjType;
   23832                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   23833                             .REASON_PROVIDER_IN_USE;
   23834                     app.adjSource = client;
   23835                     app.adjSourceProcState = clientProcState;
   23836                     app.adjTarget = cpr.name;
   23837                     if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23838                         reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType
   23839                                 + ": " + app + ", due to " + client
   23840                                 + " adj=" + adj + " procState="
   23841                                 + ProcessList.makeProcStateString(procState));
   23842                     }
   23843                 }
   23844             }
   23845             // If the provider has external (non-framework) process
   23846             // dependencies, ensure that its adjustment is at least
   23847             // FOREGROUND_APP_ADJ.
   23848             if (cpr.hasExternalProcessHandles()) {
   23849                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
   23850                     adj = ProcessList.FOREGROUND_APP_ADJ;
   23851                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   23852                     app.cached = false;
   23853                     app.adjType = "ext-provider";
   23854                     app.adjTarget = cpr.name;
   23855                     if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23856                         reportOomAdjMessageLocked(TAG_OOM_ADJ,
   23857                                 "Raise adj to external provider: " + app);
   23858                     }
   23859                 }
   23860                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
   23861                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   23862                     reportOomAdjMessageLocked(TAG_OOM_ADJ,
   23863                             "Raise procstate to external provider: " + app);
   23864                 }
   23865             }
   23866         }
   23867 
   23868         if (app.lastProviderTime > 0 &&
   23869                 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
   23870             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
   23871                 adj = ProcessList.PREVIOUS_APP_ADJ;
   23872                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
   23873                 app.cached = false;
   23874                 app.adjType = "recent-provider";
   23875                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23876                     reportOomAdjMessageLocked(TAG_OOM_ADJ,
   23877                             "Raise adj to recent provider: " + app);
   23878                 }
   23879             }
   23880             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   23881                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   23882                 app.adjType = "recent-provider";
   23883                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23884                     reportOomAdjMessageLocked(TAG_OOM_ADJ,
   23885                             "Raise procstate to recent provider: " + app);
   23886                 }
   23887             }
   23888         }
   23889 
   23890         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
   23891             // A client of one of our services or providers is in the top state.  We
   23892             // *may* want to be in the top state, but not if we are already running in
   23893             // the background for some other reason.  For the decision here, we are going
   23894             // to pick out a few specific states that we want to remain in when a client
   23895             // is top (states that tend to be longer-term) and otherwise allow it to go
   23896             // to the top state.
   23897             switch (procState) {
   23898                 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
   23899                 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
   23900                     // Something else is keeping it at this level, just leave it.
   23901                     break;
   23902                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
   23903                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
   23904                 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
   23905                 case ActivityManager.PROCESS_STATE_SERVICE:
   23906                     // These all are longer-term states, so pull them up to the top
   23907                     // of the background states, but not all the way to the top state.
   23908                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
   23909                     app.adjType = mayBeTopType;
   23910                     app.adjSource = mayBeTopSource;
   23911                     app.adjTarget = mayBeTopTarget;
   23912                     if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23913                         reportOomAdjMessageLocked(TAG_OOM_ADJ, "May be top raise to " + mayBeTopType
   23914                                 + ": " + app + ", due to " + mayBeTopSource
   23915                                 + " adj=" + adj + " procState="
   23916                                 + ProcessList.makeProcStateString(procState));
   23917                     }
   23918                     break;
   23919                 default:
   23920                     // Otherwise, top is a better choice, so take it.
   23921                     procState = ActivityManager.PROCESS_STATE_TOP;
   23922                     app.adjType = mayBeTopType;
   23923                     app.adjSource = mayBeTopSource;
   23924                     app.adjTarget = mayBeTopTarget;
   23925                     if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
   23926                         reportOomAdjMessageLocked(TAG_OOM_ADJ, "May be top raise to " + mayBeTopType
   23927                                 + ": " + app + ", due to " + mayBeTopSource
   23928                                 + " adj=" + adj + " procState="
   23929                                 + ProcessList.makeProcStateString(procState));
   23930                     }
   23931                     break;
   23932             }
   23933         }
   23934 
   23935         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
   23936             if (app.hasClientActivities) {
   23937                 // This is a cached process, but with client activities.  Mark it so.
   23938                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
   23939                 app.adjType = "cch-client-act";
   23940             } else if (app.treatLikeActivity) {
   23941                 // This is a cached process, but somebody wants us to treat it like it has
   23942                 // an activity, okay!
   23943                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   23944                 app.adjType = "cch-as-act";
   23945             }
   23946         }
   23947 
   23948         if (adj == ProcessList.SERVICE_ADJ) {
   23949             if (doingAll) {
   23950                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
   23951                 mNewNumServiceProcs++;
   23952                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
   23953                 if (!app.serviceb) {
   23954                     // This service isn't far enough down on the LRU list to
   23955                     // normally be a B service, but if we are low on RAM and it
   23956                     // is large we want to force it down since we would prefer to
   23957                     // keep launcher over it.
   23958                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
   23959                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
   23960                         app.serviceHighRam = true;
   23961                         app.serviceb = true;
   23962                         //Slog.i(TAG, "ADJ " + app + " high ram!");
   23963                     } else {
   23964                         mNewNumAServiceProcs++;
   23965                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
   23966                     }
   23967                 } else {
   23968                     app.serviceHighRam = false;
   23969                 }
   23970             }
   23971             if (app.serviceb) {
   23972                 adj = ProcessList.SERVICE_B_ADJ;
   23973             }
   23974         }
   23975 
   23976         app.curRawAdj = adj;
   23977 
   23978         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
   23979         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
   23980         if (adj > app.maxAdj) {
   23981             adj = app.maxAdj;
   23982             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   23983                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
   23984             }
   23985         }
   23986 
   23987         // Put bound foreground services in a special sched group for additional
   23988         // restrictions on screen off
   23989         if (procState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE &&
   23990             mWakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE) {
   23991             if (schedGroup > ProcessList.SCHED_GROUP_RESTRICTED) {
   23992                 schedGroup = ProcessList.SCHED_GROUP_RESTRICTED;
   23993             }
   23994         }
   23995 
   23996         // Do final modification to adj.  Everything we do between here and applying
   23997         // the final setAdj must be done in this function, because we will also use
   23998         // it when computing the final cached adj later.  Note that we don't need to
   23999         // worry about this for max adj above, since max adj will always be used to
   24000         // keep it out of the cached vaues.
   24001         app.curAdj = app.modifyRawOomAdj(adj);
   24002         app.curSchedGroup = schedGroup;
   24003         app.curProcState = procState;
   24004         app.foregroundActivities = foregroundActivities;
   24005         app.completedAdjSeq = mAdjSeq;
   24006 
   24007         // if curAdj is less than prevAppAdj, then this process was promoted
   24008         return app.curAdj < prevAppAdj;
   24009     }
   24010 
   24011     /**
   24012      * Record new PSS sample for a process.
   24013      */
   24014     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
   24015             long rss, int statType, long pssDuration, long now) {
   24016         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
   24017                 swapPss * 1024, rss * 1024, statType, procState, pssDuration);
   24018         proc.lastPssTime = now;
   24019         proc.baseProcessTracker.addPss(pss, uss, rss, true, statType, pssDuration, proc.pkgList);
   24020         if (DEBUG_PSS) Slog.d(TAG_PSS,
   24021                 "pss of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
   24022                 + " state=" + ProcessList.makeProcStateString(procState));
   24023         if (proc.initialIdlePss == 0) {
   24024             proc.initialIdlePss = pss;
   24025         }
   24026         proc.lastPss = pss;
   24027         proc.lastSwapPss = swapPss;
   24028         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
   24029             proc.lastCachedPss = pss;
   24030             proc.lastCachedSwapPss = swapPss;
   24031         }
   24032 
   24033         final SparseArray<Pair<Long, String>> watchUids
   24034                 = mMemWatchProcesses.getMap().get(proc.processName);
   24035         Long check = null;
   24036         if (watchUids != null) {
   24037             Pair<Long, String> val = watchUids.get(proc.uid);
   24038             if (val == null) {
   24039                 val = watchUids.get(0);
   24040             }
   24041             if (val != null) {
   24042                 check = val.first;
   24043             }
   24044         }
   24045         if (check != null) {
   24046             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
   24047                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   24048                 if (!isDebuggable) {
   24049                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   24050                         isDebuggable = true;
   24051                     }
   24052                 }
   24053                 if (isDebuggable) {
   24054                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
   24055                     final ProcessRecord myProc = proc;
   24056                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
   24057                     mMemWatchDumpProcName = proc.processName;
   24058                     mMemWatchDumpFile = heapdumpFile.toString();
   24059                     mMemWatchDumpPid = proc.pid;
   24060                     mMemWatchDumpUid = proc.uid;
   24061                     BackgroundThread.getHandler().post(new Runnable() {
   24062                         @Override
   24063                         public void run() {
   24064                             revokeUriPermission(ActivityThread.currentActivityThread()
   24065                                             .getApplicationThread(),
   24066                                     null, DumpHeapActivity.JAVA_URI,
   24067                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
   24068                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
   24069                                     UserHandle.myUserId());
   24070                             ParcelFileDescriptor fd = null;
   24071                             try {
   24072                                 heapdumpFile.delete();
   24073                                 fd = ParcelFileDescriptor.open(heapdumpFile,
   24074                                         ParcelFileDescriptor.MODE_CREATE |
   24075                                                 ParcelFileDescriptor.MODE_TRUNCATE |
   24076                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
   24077                                                 ParcelFileDescriptor.MODE_APPEND);
   24078                                 IApplicationThread thread = myProc.thread;
   24079                                 if (thread != null) {
   24080                                     try {
   24081                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
   24082                                                 "Requesting dump heap from "
   24083                                                 + myProc + " to " + heapdumpFile);
   24084                                         thread.dumpHeap(/* managed= */ true,
   24085                                                 /* mallocInfo= */ false, /* runGc= */ false,
   24086                                                 heapdumpFile.toString(), fd);
   24087                                     } catch (RemoteException e) {
   24088                                     }
   24089                                 }
   24090                             } catch (FileNotFoundException e) {
   24091                                 e.printStackTrace();
   24092                             } finally {
   24093                                 if (fd != null) {
   24094                                     try {
   24095                                         fd.close();
   24096                                     } catch (IOException e) {
   24097                                     }
   24098                                 }
   24099                             }
   24100                         }
   24101                     });
   24102                 } else {
   24103                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
   24104                             + ", but debugging not enabled");
   24105                 }
   24106             }
   24107         }
   24108     }
   24109 
   24110     /**
   24111      * Schedule PSS collection of a process.
   24112      */
   24113     boolean requestPssLocked(ProcessRecord proc, int procState) {
   24114         if (mPendingPssProcesses.contains(proc)) {
   24115             return false;
   24116         }
   24117         if (mPendingPssProcesses.size() == 0) {
   24118             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   24119         }
   24120         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of: " + proc);
   24121         proc.pssProcState = procState;
   24122         proc.pssStatType = ProcessStats.ADD_PSS_INTERNAL_SINGLE;
   24123         mPendingPssProcesses.add(proc);
   24124         return true;
   24125     }
   24126 
   24127     /**
   24128      * Schedule PSS collection of all processes.
   24129      */
   24130     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
   24131         if (!always) {
   24132             if (now < (mLastFullPssTime +
   24133                     (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
   24134                             : mConstants.FULL_PSS_MIN_INTERVAL))) {
   24135                 return;
   24136             }
   24137         }
   24138         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of all procs!  memLowered=" + memLowered);
   24139         mLastFullPssTime = now;
   24140         mFullPssPending = true;
   24141         for (int i = mPendingPssProcesses.size() - 1; i >= 0; i--) {
   24142             ProcessList.abortNextPssTime(mPendingPssProcesses.get(i).procStateMemTracker);;
   24143         }
   24144         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
   24145         mPendingPssProcesses.clear();
   24146         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   24147             ProcessRecord app = mLruProcesses.get(i);
   24148             if (app.thread == null
   24149                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
   24150                 continue;
   24151             }
   24152             if (memLowered || (always && now >
   24153                             app.lastStateTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
   24154                     || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
   24155                 app.pssProcState = app.setProcState;
   24156                 app.pssStatType = always ? ProcessStats.ADD_PSS_INTERNAL_ALL_POLL
   24157                         : ProcessStats.ADD_PSS_INTERNAL_ALL_MEM;
   24158                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
   24159                         app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
   24160                 mPendingPssProcesses.add(app);
   24161             }
   24162         }
   24163         if (!mBgHandler.hasMessages(COLLECT_PSS_BG_MSG)) {
   24164             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   24165         }
   24166     }
   24167 
   24168     public void setTestPssMode(boolean enabled) {
   24169         synchronized (this) {
   24170             mTestPssMode = enabled;
   24171             if (enabled) {
   24172                 // Whenever we enable the mode, we want to take a snapshot all of current
   24173                 // process mem use.
   24174                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
   24175             }
   24176         }
   24177     }
   24178 
   24179     /**
   24180      * Ask a given process to GC right now.
   24181      */
   24182     final void performAppGcLocked(ProcessRecord app) {
   24183         try {
   24184             app.lastRequestedGc = SystemClock.uptimeMillis();
   24185             if (app.thread != null) {
   24186                 if (app.reportLowMemory) {
   24187                     app.reportLowMemory = false;
   24188                     app.thread.scheduleLowMemory();
   24189                 } else {
   24190                     app.thread.processInBackground();
   24191                 }
   24192             }
   24193         } catch (Exception e) {
   24194             // whatever.
   24195         }
   24196     }
   24197 
   24198     /**
   24199      * Returns true if things are idle enough to perform GCs.
   24200      */
   24201     private final boolean canGcNowLocked() {
   24202         boolean processingBroadcasts = false;
   24203         for (BroadcastQueue q : mBroadcastQueues) {
   24204             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
   24205                 processingBroadcasts = true;
   24206             }
   24207         }
   24208         return !processingBroadcasts
   24209                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
   24210     }
   24211 
   24212     /**
   24213      * Perform GCs on all processes that are waiting for it, but only
   24214      * if things are idle.
   24215      */
   24216     final void performAppGcsLocked() {
   24217         final int N = mProcessesToGc.size();
   24218         if (N <= 0) {
   24219             return;
   24220         }
   24221         if (canGcNowLocked()) {
   24222             while (mProcessesToGc.size() > 0) {
   24223                 ProcessRecord proc = mProcessesToGc.remove(0);
   24224                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
   24225                     if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
   24226                             <= SystemClock.uptimeMillis()) {
   24227                         // To avoid spamming the system, we will GC processes one
   24228                         // at a time, waiting a few seconds between each.
   24229                         performAppGcLocked(proc);
   24230                         scheduleAppGcsLocked();
   24231                         return;
   24232                     } else {
   24233                         // It hasn't been long enough since we last GCed this
   24234                         // process...  put it in the list to wait for its time.
   24235                         addProcessToGcListLocked(proc);
   24236                         break;
   24237                     }
   24238                 }
   24239             }
   24240 
   24241             scheduleAppGcsLocked();
   24242         }
   24243     }
   24244 
   24245     /**
   24246      * If all looks good, perform GCs on all processes waiting for them.
   24247      */
   24248     final void performAppGcsIfAppropriateLocked() {
   24249         if (canGcNowLocked()) {
   24250             performAppGcsLocked();
   24251             return;
   24252         }
   24253         // Still not idle, wait some more.
   24254         scheduleAppGcsLocked();
   24255     }
   24256 
   24257     /**
   24258      * Schedule the execution of all pending app GCs.
   24259      */
   24260     final void scheduleAppGcsLocked() {
   24261         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
   24262 
   24263         if (mProcessesToGc.size() > 0) {
   24264             // Schedule a GC for the time to the next process.
   24265             ProcessRecord proc = mProcessesToGc.get(0);
   24266             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
   24267 
   24268             long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
   24269             long now = SystemClock.uptimeMillis();
   24270             if (when < (now+mConstants.GC_TIMEOUT)) {
   24271                 when = now + mConstants.GC_TIMEOUT;
   24272             }
   24273             mHandler.sendMessageAtTime(msg, when);
   24274         }
   24275     }
   24276 
   24277     /**
   24278      * Add a process to the array of processes waiting to be GCed.  Keeps the
   24279      * list in sorted order by the last GC time.  The process can't already be
   24280      * on the list.
   24281      */
   24282     final void addProcessToGcListLocked(ProcessRecord proc) {
   24283         boolean added = false;
   24284         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
   24285             if (mProcessesToGc.get(i).lastRequestedGc <
   24286                     proc.lastRequestedGc) {
   24287                 added = true;
   24288                 mProcessesToGc.add(i+1, proc);
   24289                 break;
   24290             }
   24291         }
   24292         if (!added) {
   24293             mProcessesToGc.add(0, proc);
   24294         }
   24295     }
   24296 
   24297     /**
   24298      * Set up to ask a process to GC itself.  This will either do it
   24299      * immediately, or put it on the list of processes to gc the next
   24300      * time things are idle.
   24301      */
   24302     final void scheduleAppGcLocked(ProcessRecord app) {
   24303         long now = SystemClock.uptimeMillis();
   24304         if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
   24305             return;
   24306         }
   24307         if (!mProcessesToGc.contains(app)) {
   24308             addProcessToGcListLocked(app);
   24309             scheduleAppGcsLocked();
   24310         }
   24311     }
   24312 
   24313     final void checkExcessivePowerUsageLocked() {
   24314         updateCpuStatsNow();
   24315 
   24316         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   24317         boolean doCpuKills = true;
   24318         if (mLastPowerCheckUptime == 0) {
   24319             doCpuKills = false;
   24320         }
   24321         final long curUptime = SystemClock.uptimeMillis();
   24322         final long uptimeSince = curUptime - mLastPowerCheckUptime;
   24323         mLastPowerCheckUptime = curUptime;
   24324         int i = mLruProcesses.size();
   24325         while (i > 0) {
   24326             i--;
   24327             ProcessRecord app = mLruProcesses.get(i);
   24328             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
   24329                 if (app.lastCpuTime <= 0) {
   24330                     continue;
   24331                 }
   24332                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
   24333                 if (DEBUG_POWER) {
   24334                     StringBuilder sb = new StringBuilder(128);
   24335                     sb.append("CPU for ");
   24336                     app.toShortString(sb);
   24337                     sb.append(": over ");
   24338                     TimeUtils.formatDuration(uptimeSince, sb);
   24339                     sb.append(" used ");
   24340                     TimeUtils.formatDuration(cputimeUsed, sb);
   24341                     sb.append(" (");
   24342                     sb.append((cputimeUsed*100)/uptimeSince);
   24343                     sb.append("%)");
   24344                     Slog.i(TAG_POWER, sb.toString());
   24345                 }
   24346                 // If the process has used too much CPU over the last duration, the
   24347                 // user probably doesn't want this, so kill!
   24348                 if (doCpuKills && uptimeSince > 0) {
   24349                     // What is the limit for this process?
   24350                     int cpuLimit;
   24351                     long checkDur = curUptime - app.whenUnimportant;
   24352                     if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
   24353                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
   24354                     } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
   24355                             || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
   24356                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
   24357                     } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
   24358                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
   24359                     } else {
   24360                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
   24361                     }
   24362                     if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
   24363                         synchronized (stats) {
   24364                             stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
   24365                                     uptimeSince, cputimeUsed);
   24366                         }
   24367                         app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
   24368                                 + " dur=" + checkDur + " limit=" + cpuLimit, true);
   24369                         app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
   24370                     }
   24371                 }
   24372                 app.lastCpuTime = app.curCpuTime;
   24373             }
   24374         }
   24375     }
   24376 
   24377     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
   24378             long nowElapsed) {
   24379         boolean success = true;
   24380 
   24381         if (app.curRawAdj != app.setRawAdj) {
   24382             app.setRawAdj = app.curRawAdj;
   24383         }
   24384 
   24385         int changes = 0;
   24386 
   24387         if (app.curAdj != app.setAdj) {
   24388             ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
   24389             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
   24390                 String msg = "Set " + app.pid + " " + app.processName + " adj "
   24391                         + app.curAdj + ": " + app.adjType;
   24392                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
   24393             }
   24394             app.setAdj = app.curAdj;
   24395             app.verifiedAdj = ProcessList.INVALID_ADJ;
   24396         }
   24397 
   24398         if (app.setSchedGroup != app.curSchedGroup) {
   24399             int oldSchedGroup = app.setSchedGroup;
   24400             app.setSchedGroup = app.curSchedGroup;
   24401             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
   24402                 String msg = "Setting sched group of " + app.processName
   24403                         + " to " + app.curSchedGroup + ": " + app.adjType;
   24404                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
   24405             }
   24406             if (app.waitingToKill != null && app.curReceivers.isEmpty()
   24407                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
   24408                 app.kill(app.waitingToKill, true);
   24409                 success = false;
   24410             } else {
   24411                 int processGroup;
   24412                 switch (app.curSchedGroup) {
   24413                     case ProcessList.SCHED_GROUP_BACKGROUND:
   24414                         processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
   24415                         break;
   24416                     case ProcessList.SCHED_GROUP_TOP_APP:
   24417                     case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
   24418                         processGroup = THREAD_GROUP_TOP_APP;
   24419                         break;
   24420                     case ProcessList.SCHED_GROUP_RESTRICTED:
   24421                         processGroup = THREAD_GROUP_RESTRICTED;
   24422                         break;
   24423                     default:
   24424                         processGroup = THREAD_GROUP_DEFAULT;
   24425                         break;
   24426                 }
   24427                 long oldId = Binder.clearCallingIdentity();
   24428                 try {
   24429                     setProcessGroup(app.pid, processGroup);
   24430                     if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
   24431                         // do nothing if we already switched to RT
   24432                         if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
   24433                             mVrController.onTopProcChangedLocked(app);
   24434                             if (mUseFifoUiScheduling) {
   24435                                 // Switch UI pipeline for app to SCHED_FIFO
   24436                                 app.savedPriority = Process.getThreadPriority(app.pid);
   24437                                 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
   24438                                 if (app.renderThreadTid != 0) {
   24439                                     scheduleAsFifoPriority(app.renderThreadTid,
   24440                                         /* suppressLogs */true);
   24441                                     if (DEBUG_OOM_ADJ) {
   24442                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
   24443                                             app.renderThreadTid + ") to FIFO");
   24444                                     }
   24445                                 } else {
   24446                                     if (DEBUG_OOM_ADJ) {
   24447                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
   24448                                     }
   24449                                 }
   24450                             } else {
   24451                                 // Boost priority for top app UI and render threads
   24452                                 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
   24453                                 if (app.renderThreadTid != 0) {
   24454                                     try {
   24455                                         setThreadPriority(app.renderThreadTid,
   24456                                                 TOP_APP_PRIORITY_BOOST);
   24457                                     } catch (IllegalArgumentException e) {
   24458                                         // thread died, ignore
   24459                                     }
   24460                                 }
   24461                             }
   24462                         }
   24463                     } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
   24464                                app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
   24465                         mVrController.onTopProcChangedLocked(app);
   24466                         if (mUseFifoUiScheduling) {
   24467                             try {
   24468                                 // Reset UI pipeline to SCHED_OTHER
   24469                                 setThreadScheduler(app.pid, SCHED_OTHER, 0);
   24470                                 setThreadPriority(app.pid, app.savedPriority);
   24471                                 if (app.renderThreadTid != 0) {
   24472                                     setThreadScheduler(app.renderThreadTid,
   24473                                         SCHED_OTHER, 0);
   24474                                     setThreadPriority(app.renderThreadTid, -4);
   24475                                 }
   24476                             } catch (IllegalArgumentException e) {
   24477                                 Slog.w(TAG,
   24478                                         "Failed to set scheduling policy, thread does not exist:\n"
   24479                                                 + e);
   24480                             } catch (SecurityException e) {
   24481                                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
   24482                             }
   24483                         } else {
   24484                             // Reset priority for top app UI and render threads
   24485                             setThreadPriority(app.pid, 0);
   24486                             if (app.renderThreadTid != 0) {
   24487                                 setThreadPriority(app.renderThreadTid, 0);
   24488                             }
   24489                         }
   24490                     }
   24491                 } catch (Exception e) {
   24492                     if (false) {
   24493                         Slog.w(TAG, "Failed setting process group of " + app.pid
   24494                                 + " to " + app.curSchedGroup);
   24495                         Slog.w(TAG, "at location", e);
   24496                     }
   24497                 } finally {
   24498                     Binder.restoreCallingIdentity(oldId);
   24499                 }
   24500             }
   24501         }
   24502         if (app.repForegroundActivities != app.foregroundActivities) {
   24503             app.repForegroundActivities = app.foregroundActivities;
   24504             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
   24505         }
   24506         if (app.repProcState != app.curProcState) {
   24507             app.repProcState = app.curProcState;
   24508             if (app.thread != null) {
   24509                 try {
   24510                     if (false) {
   24511                         //RuntimeException h = new RuntimeException("here");
   24512                         Slog.i(TAG, "Sending new process state " + app.repProcState
   24513                                 + " to " + app /*, h*/);
   24514                     }
   24515                     app.thread.setProcessState(app.repProcState);
   24516                 } catch (RemoteException e) {
   24517                 }
   24518             }
   24519         }
   24520         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
   24521                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
   24522             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
   24523                 // Experimental code to more aggressively collect pss while
   24524                 // running test...  the problem is that this tends to collect
   24525                 // the data right when a process is transitioning between process
   24526                 // states, which will tend to give noisy data.
   24527                 long start = SystemClock.uptimeMillis();
   24528                 long startTime = SystemClock.currentThreadTimeMillis();
   24529                 long pss = Debug.getPss(app.pid, mTmpLong, null);
   24530                 long endTime = SystemClock.currentThreadTimeMillis();
   24531                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1],
   24532                         mTmpLong[2], ProcessStats.ADD_PSS_INTERNAL_SINGLE, endTime-startTime, now);
   24533                 mPendingPssProcesses.remove(app);
   24534                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
   24535                         + " to " + app.curProcState + ": "
   24536                         + (SystemClock.uptimeMillis()-start) + "ms");
   24537             }
   24538             app.lastStateTime = now;
   24539             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
   24540                     app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
   24541             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
   24542                     + ProcessList.makeProcStateString(app.setProcState) + " to "
   24543                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
   24544                     + (app.nextPssTime-now) + ": " + app);
   24545         } else {
   24546             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
   24547                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
   24548                     mTestPssMode)))) {
   24549                 if (requestPssLocked(app, app.setProcState)) {
   24550                     app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
   24551                             app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
   24552                 }
   24553             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
   24554                     "Not requesting pss of " + app + ": next=" + (app.nextPssTime-now));
   24555         }
   24556         if (app.setProcState != app.curProcState) {
   24557             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
   24558                 String msg = "Proc state change of " + app.processName
   24559                         + " to " + ProcessList.makeProcStateString(app.curProcState)
   24560                         + " (" + app.curProcState + ")" + ": " + app.adjType;
   24561                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
   24562             }
   24563             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
   24564             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
   24565             if (setImportant && !curImportant) {
   24566                 // This app is no longer something we consider important enough to allow to
   24567                 // use arbitrary amounts of battery power.  Note
   24568                 // its current CPU time to later know to kill it if
   24569                 // it is not behaving well.
   24570                 app.whenUnimportant = now;
   24571                 app.lastCpuTime = 0;
   24572             }
   24573             // Inform UsageStats of important process state change
   24574             // Must be called before updating setProcState
   24575             maybeUpdateUsageStatsLocked(app, nowElapsed);
   24576 
   24577             app.setProcState = app.curProcState;
   24578             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
   24579                 app.notCachedSinceIdle = false;
   24580             }
   24581             if (!doingAll) {
   24582                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
   24583             } else {
   24584                 app.procStateChanged = true;
   24585             }
   24586         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
   24587                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
   24588             // For apps that sit around for a long time in the interactive state, we need
   24589             // to report this at least once a day so they don't go idle.
   24590             maybeUpdateUsageStatsLocked(app, nowElapsed);
   24591         }
   24592 
   24593         if (changes != 0) {
   24594             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   24595                     "Changes in " + app + ": " + changes);
   24596             int i = mPendingProcessChanges.size()-1;
   24597             ProcessChangeItem item = null;
   24598             while (i >= 0) {
   24599                 item = mPendingProcessChanges.get(i);
   24600                 if (item.pid == app.pid) {
   24601                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   24602                             "Re-using existing item: " + item);
   24603                     break;
   24604                 }
   24605                 i--;
   24606             }
   24607             if (i < 0) {
   24608                 // No existing item in pending changes; need a new one.
   24609                 final int NA = mAvailProcessChanges.size();
   24610                 if (NA > 0) {
   24611                     item = mAvailProcessChanges.remove(NA-1);
   24612                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   24613                             "Retrieving available item: " + item);
   24614                 } else {
   24615                     item = new ProcessChangeItem();
   24616                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   24617                             "Allocating new item: " + item);
   24618                 }
   24619                 item.changes = 0;
   24620                 item.pid = app.pid;
   24621                 item.uid = app.info.uid;
   24622                 if (mPendingProcessChanges.size() == 0) {
   24623                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   24624                             "*** Enqueueing dispatch processes changed!");
   24625                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
   24626                 }
   24627                 mPendingProcessChanges.add(item);
   24628             }
   24629             item.changes |= changes;
   24630             item.foregroundActivities = app.repForegroundActivities;
   24631             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
   24632                     "Item " + Integer.toHexString(System.identityHashCode(item))
   24633                     + " " + app.toShortString() + ": changes=" + item.changes
   24634                     + " foreground=" + item.foregroundActivities
   24635                     + " type=" + app.adjType + " source=" + app.adjSource
   24636                     + " target=" + app.adjTarget);
   24637         }
   24638 
   24639         return success;
   24640     }
   24641 
   24642     private boolean isEphemeralLocked(int uid) {
   24643         String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
   24644         if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
   24645             return false;
   24646         }
   24647         return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
   24648                 packages[0]);
   24649     }
   24650 
   24651     @VisibleForTesting
   24652     final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
   24653         final UidRecord.ChangeItem pendingChange;
   24654         if (uidRec == null || uidRec.pendingChange == null) {
   24655             if (mPendingUidChanges.size() == 0) {
   24656                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   24657                         "*** Enqueueing dispatch uid changed!");
   24658                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
   24659             }
   24660             final int NA = mAvailUidChanges.size();
   24661             if (NA > 0) {
   24662                 pendingChange = mAvailUidChanges.remove(NA-1);
   24663                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   24664                         "Retrieving available item: " + pendingChange);
   24665             } else {
   24666                 pendingChange = new UidRecord.ChangeItem();
   24667                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   24668                         "Allocating new item: " + pendingChange);
   24669             }
   24670             if (uidRec != null) {
   24671                 uidRec.pendingChange = pendingChange;
   24672                 if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
   24673                     // If this uid is going away, and we haven't yet reported it is gone,
   24674                     // then do so now.
   24675                     change |= UidRecord.CHANGE_IDLE;
   24676                 }
   24677             } else if (uid < 0) {
   24678                 throw new IllegalArgumentException("No UidRecord or uid");
   24679             }
   24680             pendingChange.uidRecord = uidRec;
   24681             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
   24682             mPendingUidChanges.add(pendingChange);
   24683         } else {
   24684             pendingChange = uidRec.pendingChange;
   24685             // If there is no change in idle or active state, then keep whatever was pending.
   24686             if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
   24687                 change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
   24688                         | UidRecord.CHANGE_ACTIVE));
   24689             }
   24690             // If there is no change in cached or uncached state, then keep whatever was pending.
   24691             if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
   24692                 change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
   24693                         | UidRecord.CHANGE_UNCACHED));
   24694             }
   24695             // If this is a report of the UID being gone, then we shouldn't keep any previous
   24696             // report of it being active or cached.  (That is, a gone uid is never active,
   24697             // and never cached.)
   24698             if ((change & UidRecord.CHANGE_GONE) != 0) {
   24699                 change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
   24700                 if (!uidRec.idle) {
   24701                     // If this uid is going away, and we haven't yet reported it is gone,
   24702                     // then do so now.
   24703                     change |= UidRecord.CHANGE_IDLE;
   24704                 }
   24705             }
   24706         }
   24707         pendingChange.change = change;
   24708         pendingChange.processState = uidRec != null
   24709                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
   24710         pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
   24711         pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
   24712         if (uidRec != null) {
   24713             uidRec.lastReportedChange = change;
   24714             uidRec.updateLastDispatchedProcStateSeq(change);
   24715         }
   24716 
   24717         // Directly update the power manager, since we sit on top of it and it is critical
   24718         // it be kept in sync (so wake locks will be held as soon as appropriate).
   24719         if (mLocalPowerManager != null) {
   24720             // TO DO: dispatch cached/uncached changes here, so we don't need to report
   24721             // all proc state changes.
   24722             if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
   24723                 mLocalPowerManager.uidActive(pendingChange.uid);
   24724             }
   24725             if ((change & UidRecord.CHANGE_IDLE) != 0) {
   24726                 mLocalPowerManager.uidIdle(pendingChange.uid);
   24727             }
   24728             if ((change & UidRecord.CHANGE_GONE) != 0) {
   24729                 mLocalPowerManager.uidGone(pendingChange.uid);
   24730             } else {
   24731                 mLocalPowerManager.updateUidProcState(pendingChange.uid,
   24732                         pendingChange.processState);
   24733             }
   24734         }
   24735     }
   24736 
   24737     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
   24738             String authority) {
   24739         if (app == null) return;
   24740         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
   24741             UserState userState = mUserController.getStartedUserState(app.userId);
   24742             if (userState == null) return;
   24743             final long now = SystemClock.elapsedRealtime();
   24744             Long lastReported = userState.mProviderLastReportedFg.get(authority);
   24745             if (lastReported == null || lastReported < now - 60 * 1000L) {
   24746                 if (mSystemReady) {
   24747                     // Cannot touch the user stats if not system ready
   24748                     mUsageStatsService.reportContentProviderUsage(
   24749                             authority, providerPkgName, app.userId);
   24750                 }
   24751                 userState.mProviderLastReportedFg.put(authority, now);
   24752             }
   24753         }
   24754     }
   24755 
   24756     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
   24757         if (DEBUG_USAGE_STATS) {
   24758             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
   24759                     + "] state changes: old = " + app.setProcState + ", new = "
   24760                     + app.curProcState);
   24761         }
   24762         if (mUsageStatsService == null) {
   24763             return;
   24764         }
   24765         boolean isInteraction;
   24766         // To avoid some abuse patterns, we are going to be careful about what we consider
   24767         // to be an app interaction.  Being the top activity doesn't count while the display
   24768         // is sleeping, nor do short foreground services.
   24769         if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP) {
   24770             isInteraction = true;
   24771             app.fgInteractionTime = 0;
   24772         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
   24773             if (app.fgInteractionTime == 0) {
   24774                 app.fgInteractionTime = nowElapsed;
   24775                 isInteraction = false;
   24776             } else {
   24777                 isInteraction = nowElapsed > app.fgInteractionTime
   24778                         + mConstants.SERVICE_USAGE_INTERACTION_TIME;
   24779             }
   24780         } else {
   24781             isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   24782             app.fgInteractionTime = 0;
   24783         }
   24784         if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
   24785                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
   24786             app.interactionEventTime = nowElapsed;
   24787             String[] packages = app.getPackageList();
   24788             if (packages != null) {
   24789                 for (int i = 0; i < packages.length; i++) {
   24790                     mUsageStatsService.reportEvent(packages[i], app.userId,
   24791                             UsageEvents.Event.SYSTEM_INTERACTION);
   24792                 }
   24793             }
   24794         }
   24795         app.reportedInteraction = isInteraction;
   24796         if (!isInteraction) {
   24797             app.interactionEventTime = 0;
   24798         }
   24799     }
   24800 
   24801     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
   24802         if (proc.thread != null) {
   24803             if (proc.baseProcessTracker != null) {
   24804                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
   24805             }
   24806         }
   24807     }
   24808 
   24809     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
   24810             ProcessRecord TOP_APP, boolean doingAll, long now) {
   24811         if (app.thread == null) {
   24812             return false;
   24813         }
   24814 
   24815         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
   24816 
   24817         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
   24818     }
   24819 
   24820     @GuardedBy("this")
   24821     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
   24822             boolean oomAdj) {
   24823         if (isForeground != proc.foregroundServices) {
   24824             proc.foregroundServices = isForeground;
   24825             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
   24826                     proc.info.uid);
   24827             if (isForeground) {
   24828                 if (curProcs == null) {
   24829                     curProcs = new ArrayList<ProcessRecord>();
   24830                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
   24831                 }
   24832                 if (!curProcs.contains(proc)) {
   24833                     curProcs.add(proc);
   24834                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
   24835                             proc.info.packageName, proc.info.uid);
   24836                 }
   24837             } else {
   24838                 if (curProcs != null) {
   24839                     if (curProcs.remove(proc)) {
   24840                         mBatteryStatsService.noteEvent(
   24841                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
   24842                                 proc.info.packageName, proc.info.uid);
   24843                         if (curProcs.size() <= 0) {
   24844                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
   24845                         }
   24846                     }
   24847                 }
   24848             }
   24849             if (oomAdj) {
   24850                 updateOomAdjLocked();
   24851             }
   24852         }
   24853     }
   24854 
   24855     private final ActivityRecord resumedAppLocked() {
   24856         ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
   24857         String pkg;
   24858         int uid;
   24859         if (act != null) {
   24860             pkg = act.packageName;
   24861             uid = act.info.applicationInfo.uid;
   24862         } else {
   24863             pkg = null;
   24864             uid = -1;
   24865         }
   24866         // Has the UID or resumed package name changed?
   24867         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
   24868                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
   24869             if (mCurResumedPackage != null) {
   24870                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
   24871                         mCurResumedPackage, mCurResumedUid);
   24872             }
   24873             mCurResumedPackage = pkg;
   24874             mCurResumedUid = uid;
   24875             if (mCurResumedPackage != null) {
   24876                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
   24877                         mCurResumedPackage, mCurResumedUid);
   24878             }
   24879         }
   24880         return act;
   24881     }
   24882 
   24883     /**
   24884      * Update OomAdj for a specific process.
   24885      * @param app The process to update
   24886      * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
   24887      *                  if necessary, or skip.
   24888      * @return whether updateOomAdjLocked(app) was successful.
   24889      */
   24890     @GuardedBy("this")
   24891     final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
   24892         final ActivityRecord TOP_ACT = resumedAppLocked();
   24893         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   24894         final boolean wasCached = app.cached;
   24895 
   24896         mAdjSeq++;
   24897 
   24898         // This is the desired cached adjusment we want to tell it to use.
   24899         // If our app is currently cached, we know it, and that is it.  Otherwise,
   24900         // we don't know it yet, and it needs to now be cached we will then
   24901         // need to do a complete oom adj.
   24902         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
   24903                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
   24904         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
   24905                 SystemClock.uptimeMillis());
   24906         if (oomAdjAll
   24907                 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
   24908             // Changed to/from cached state, so apps after it in the LRU
   24909             // list may also be changed.
   24910             updateOomAdjLocked();
   24911         }
   24912         return success;
   24913     }
   24914 
   24915     @GuardedBy("this")
   24916     final void updateOomAdjLocked() {
   24917         final ActivityRecord TOP_ACT = resumedAppLocked();
   24918         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   24919         final long now = SystemClock.uptimeMillis();
   24920         final long nowElapsed = SystemClock.elapsedRealtime();
   24921         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
   24922         final int N = mLruProcesses.size();
   24923 
   24924         if (false) {
   24925             RuntimeException e = new RuntimeException();
   24926             e.fillInStackTrace();
   24927             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
   24928         }
   24929 
   24930         // Reset state in all uid records.
   24931         for (int i=mActiveUids.size()-1; i>=0; i--) {
   24932             final UidRecord uidRec = mActiveUids.valueAt(i);
   24933             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   24934                     "Starting update of " + uidRec);
   24935             uidRec.reset();
   24936         }
   24937 
   24938         mStackSupervisor.rankTaskLayersIfNeeded();
   24939 
   24940         mAdjSeq++;
   24941         mNewNumServiceProcs = 0;
   24942         mNewNumAServiceProcs = 0;
   24943 
   24944         final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
   24945         final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
   24946 
   24947         // Let's determine how many processes we have running vs.
   24948         // how many slots we have for background processes; we may want
   24949         // to put multiple processes in a slot of there are enough of
   24950         // them.
   24951         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
   24952                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
   24953         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
   24954         if (numEmptyProcs > cachedProcessLimit) {
   24955             // If there are more empty processes than our limit on cached
   24956             // processes, then use the cached process limit for the factor.
   24957             // This ensures that the really old empty processes get pushed
   24958             // down to the bottom, so if we are running low on memory we will
   24959             // have a better chance at keeping around more cached processes
   24960             // instead of a gazillion empty processes.
   24961             numEmptyProcs = cachedProcessLimit;
   24962         }
   24963         int emptyFactor = numEmptyProcs/numSlots;
   24964         if (emptyFactor < 1) emptyFactor = 1;
   24965         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
   24966         if (cachedFactor < 1) cachedFactor = 1;
   24967         int stepCached = 0;
   24968         int stepEmpty = 0;
   24969         int numCached = 0;
   24970         int numEmpty = 0;
   24971         int numTrimming = 0;
   24972 
   24973         mNumNonCachedProcs = 0;
   24974         mNumCachedHiddenProcs = 0;
   24975 
   24976         // First update the OOM adjustment for each of the
   24977         // application processes based on their current state.
   24978         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
   24979         int nextCachedAdj = curCachedAdj+1;
   24980         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
   24981         int nextEmptyAdj = curEmptyAdj+2;
   24982 
   24983         boolean retryCycles = false;
   24984 
   24985         // need to reset cycle state before calling computeOomAdjLocked because of service connections
   24986         for (int i=N-1; i>=0; i--) {
   24987             ProcessRecord app = mLruProcesses.get(i);
   24988             app.containsCycle = false;
   24989         }
   24990         for (int i=N-1; i>=0; i--) {
   24991             ProcessRecord app = mLruProcesses.get(i);
   24992             if (!app.killedByAm && app.thread != null) {
   24993                 app.procStateChanged = false;
   24994                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
   24995 
   24996                 // if any app encountered a cycle, we need to perform an additional loop later
   24997                 retryCycles |= app.containsCycle;
   24998 
   24999                 // If we haven't yet assigned the final cached adj
   25000                 // to the process, do that now.
   25001                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
   25002                     switch (app.curProcState) {
   25003                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   25004                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   25005                         case ActivityManager.PROCESS_STATE_CACHED_RECENT:
   25006                             // This process is a cached process holding activities...
   25007                             // assign it the next cached value for that type, and then
   25008                             // step that cached level.
   25009                             app.curRawAdj = curCachedAdj;
   25010                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
   25011                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
   25012                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
   25013                                     + ")");
   25014                             if (curCachedAdj != nextCachedAdj) {
   25015                                 stepCached++;
   25016                                 if (stepCached >= cachedFactor) {
   25017                                     stepCached = 0;
   25018                                     curCachedAdj = nextCachedAdj;
   25019                                     nextCachedAdj += 2;
   25020                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   25021                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
   25022                                     }
   25023                                 }
   25024                             }
   25025                             break;
   25026                         default:
   25027                             // For everything else, assign next empty cached process
   25028                             // level and bump that up.  Note that this means that
   25029                             // long-running services that have dropped down to the
   25030                             // cached level will be treated as empty (since their process
   25031                             // state is still as a service), which is what we want.
   25032                             app.curRawAdj = curEmptyAdj;
   25033                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
   25034                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
   25035                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
   25036                                     + ")");
   25037                             if (curEmptyAdj != nextEmptyAdj) {
   25038                                 stepEmpty++;
   25039                                 if (stepEmpty >= emptyFactor) {
   25040                                     stepEmpty = 0;
   25041                                     curEmptyAdj = nextEmptyAdj;
   25042                                     nextEmptyAdj += 2;
   25043                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   25044                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
   25045                                     }
   25046                                 }
   25047                             }
   25048                             break;
   25049                     }
   25050                 }
   25051 
   25052 
   25053             }
   25054         }
   25055 
   25056         // Cycle strategy:
   25057         // - Retry computing any process that has encountered a cycle.
   25058         // - Continue retrying until no process was promoted.
   25059         // - Iterate from least important to most important.
   25060         int cycleCount = 0;
   25061         while (retryCycles) {
   25062             cycleCount++;
   25063             retryCycles = false;
   25064 
   25065             for (int i=0; i<N; i++) {
   25066                 ProcessRecord app = mLruProcesses.get(i);
   25067                 if (!app.killedByAm && app.thread != null && app.containsCycle == true) {
   25068                     app.adjSeq--;
   25069                     app.completedAdjSeq--;
   25070                 }
   25071             }
   25072 
   25073             for (int i=0; i<N; i++) {
   25074                 ProcessRecord app = mLruProcesses.get(i);
   25075                 if (!app.killedByAm && app.thread != null && app.containsCycle == true) {
   25076                     if (computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now)) {
   25077                         retryCycles = true;
   25078                     }
   25079                 }
   25080             }
   25081         }
   25082         for (int i=N-1; i>=0; i--) {
   25083             ProcessRecord app = mLruProcesses.get(i);
   25084             if (!app.killedByAm && app.thread != null) {
   25085                 applyOomAdjLocked(app, true, now, nowElapsed);
   25086 
   25087                 // Count the number of process types.
   25088                 switch (app.curProcState) {
   25089                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   25090                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   25091                         mNumCachedHiddenProcs++;
   25092                         numCached++;
   25093                         if (numCached > cachedProcessLimit) {
   25094                             app.kill("cached #" + numCached, true);
   25095                         }
   25096                         break;
   25097                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
   25098                         if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
   25099                                 && app.lastActivityTime < oldTime) {
   25100                             app.kill("empty for "
   25101                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
   25102                                     / 1000) + "s", true);
   25103                         } else {
   25104                             numEmpty++;
   25105                             if (numEmpty > emptyProcessLimit) {
   25106                                 app.kill("empty #" + numEmpty, true);
   25107                             }
   25108                         }
   25109                         break;
   25110                     default:
   25111                         mNumNonCachedProcs++;
   25112                         break;
   25113                 }
   25114 
   25115                 if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) {
   25116                     // If this is an isolated process, there are no services
   25117                     // running in it, and it's not a special process with a
   25118                     // custom entry point, then the process is no longer
   25119                     // needed.  We agressively kill these because we can by
   25120                     // definition not re-use the same process again, and it is
   25121                     // good to avoid having whatever code was running in them
   25122                     // left sitting around after no longer needed.
   25123                     app.kill("isolated not needed", true);
   25124                 } else {
   25125                     // Keeping this process, update its uid.
   25126                     final UidRecord uidRec = app.uidRecord;
   25127                     if (uidRec != null) {
   25128                         uidRec.ephemeral = app.info.isInstantApp();
   25129                         if (uidRec.curProcState > app.curProcState) {
   25130                             uidRec.curProcState = app.curProcState;
   25131                         }
   25132                         if (app.foregroundServices) {
   25133                             uidRec.foregroundServices = true;
   25134                         }
   25135                     }
   25136                 }
   25137 
   25138                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   25139                         && !app.killedByAm) {
   25140                     numTrimming++;
   25141                 }
   25142             }
   25143         }
   25144 
   25145         incrementProcStateSeqAndNotifyAppsLocked();
   25146 
   25147         mNumServiceProcs = mNewNumServiceProcs;
   25148 
   25149         // Now determine the memory trimming level of background processes.
   25150         // Unfortunately we need to start at the back of the list to do this
   25151         // properly.  We only do this if the number of background apps we
   25152         // are managing to keep around is less than half the maximum we desire;
   25153         // if we are keeping a good number around, we'll let them use whatever
   25154         // memory they want.
   25155         final int numCachedAndEmpty = numCached + numEmpty;
   25156         int memFactor;
   25157         if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
   25158                 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
   25159             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
   25160                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
   25161             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
   25162                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
   25163             } else {
   25164                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
   25165             }
   25166         } else {
   25167             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
   25168         }
   25169         // We always allow the memory level to go up (better).  We only allow it to go
   25170         // down if we are in a state where that is allowed, *and* the total number of processes
   25171         // has gone down since last time.
   25172         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
   25173                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
   25174                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
   25175         if (memFactor > mLastMemoryLevel) {
   25176             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
   25177                 memFactor = mLastMemoryLevel;
   25178                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
   25179             }
   25180         }
   25181         if (memFactor != mLastMemoryLevel) {
   25182             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
   25183         }
   25184         mLastMemoryLevel = memFactor;
   25185         mLastNumProcesses = mLruProcesses.size();
   25186         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
   25187         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
   25188         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
   25189             if (mLowRamStartTime == 0) {
   25190                 mLowRamStartTime = now;
   25191             }
   25192             int step = 0;
   25193             int fgTrimLevel;
   25194             switch (memFactor) {
   25195                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
   25196                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
   25197                     break;
   25198                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
   25199                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
   25200                     break;
   25201                 default:
   25202                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
   25203                     break;
   25204             }
   25205             int factor = numTrimming/3;
   25206             int minFactor = 2;
   25207             if (mHomeProcess != null) minFactor++;
   25208             if (mPreviousProcess != null) minFactor++;
   25209             if (factor < minFactor) factor = minFactor;
   25210             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
   25211             for (int i=N-1; i>=0; i--) {
   25212                 ProcessRecord app = mLruProcesses.get(i);
   25213                 if (allChanged || app.procStateChanged) {
   25214                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
   25215                     app.procStateChanged = false;
   25216                 }
   25217                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   25218                         && !app.killedByAm) {
   25219                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
   25220                         try {
   25221                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   25222                                     "Trimming memory of " + app.processName + " to " + curLevel);
   25223                             app.thread.scheduleTrimMemory(curLevel);
   25224                         } catch (RemoteException e) {
   25225                         }
   25226                         if (false) {
   25227                             // For now we won't do this; our memory trimming seems
   25228                             // to be good enough at this point that destroying
   25229                             // activities causes more harm than good.
   25230                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
   25231                                     && app != mHomeProcess && app != mPreviousProcess) {
   25232                                 // Need to do this on its own message because the stack may not
   25233                                 // be in a consistent state at this point.
   25234                                 // For these apps we will also finish their activities
   25235                                 // to help them free memory.
   25236                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
   25237                             }
   25238                         }
   25239                     }
   25240                     app.trimMemoryLevel = curLevel;
   25241                     step++;
   25242                     if (step >= factor) {
   25243                         step = 0;
   25244                         switch (curLevel) {
   25245                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
   25246                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
   25247                                 break;
   25248                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
   25249                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   25250                                 break;
   25251                         }
   25252                     }
   25253                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
   25254                         && !app.killedByAm) {
   25255                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
   25256                             && app.thread != null) {
   25257                         try {
   25258                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   25259                                     "Trimming memory of heavy-weight " + app.processName
   25260                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   25261                             app.thread.scheduleTrimMemory(
   25262                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   25263                         } catch (RemoteException e) {
   25264                         }
   25265                     }
   25266                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   25267                 } else {
   25268                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   25269                             || app.systemNoUi) && app.pendingUiClean) {
   25270                         // If this application is now in the background and it
   25271                         // had done UI, then give it the special trim level to
   25272                         // have it free UI resources.
   25273                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
   25274                         if (app.trimMemoryLevel < level && app.thread != null) {
   25275                             try {
   25276                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   25277                                         "Trimming memory of bg-ui " + app.processName
   25278                                         + " to " + level);
   25279                                 app.thread.scheduleTrimMemory(level);
   25280                             } catch (RemoteException e) {
   25281                             }
   25282                         }
   25283                         app.pendingUiClean = false;
   25284                     }
   25285                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
   25286                         try {
   25287                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   25288                                     "Trimming memory of fg " + app.processName
   25289                                     + " to " + fgTrimLevel);
   25290                             app.thread.scheduleTrimMemory(fgTrimLevel);
   25291                         } catch (RemoteException e) {
   25292                         }
   25293                     }
   25294                     app.trimMemoryLevel = fgTrimLevel;
   25295                 }
   25296             }
   25297         } else {
   25298             if (mLowRamStartTime != 0) {
   25299                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
   25300                 mLowRamStartTime = 0;
   25301             }
   25302             for (int i=N-1; i>=0; i--) {
   25303                 ProcessRecord app = mLruProcesses.get(i);
   25304                 if (allChanged || app.procStateChanged) {
   25305                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
   25306                     app.procStateChanged = false;
   25307                 }
   25308                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   25309                         || app.systemNoUi) && app.pendingUiClean) {
   25310                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
   25311                             && app.thread != null) {
   25312                         try {
   25313                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
   25314                                     "Trimming memory of ui hidden " + app.processName
   25315                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   25316                             app.thread.scheduleTrimMemory(
   25317                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   25318                         } catch (RemoteException e) {
   25319                         }
   25320                     }
   25321                     app.pendingUiClean = false;
   25322                 }
   25323                 app.trimMemoryLevel = 0;
   25324             }
   25325         }
   25326 
   25327         if (mAlwaysFinishActivities) {
   25328             // Need to do this on its own message because the stack may not
   25329             // be in a consistent state at this point.
   25330             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
   25331         }
   25332 
   25333         if (allChanged) {
   25334             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
   25335         }
   25336 
   25337         ArrayList<UidRecord> becameIdle = null;
   25338 
   25339         // Update from any uid changes.
   25340         if (mLocalPowerManager != null) {
   25341             mLocalPowerManager.startUidChanges();
   25342         }
   25343         for (int i=mActiveUids.size()-1; i>=0; i--) {
   25344             final UidRecord uidRec = mActiveUids.valueAt(i);
   25345             int uidChange = UidRecord.CHANGE_PROCSTATE;
   25346             if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
   25347                     && (uidRec.setProcState != uidRec.curProcState
   25348                            || uidRec.setWhitelist != uidRec.curWhitelist)) {
   25349                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
   25350                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
   25351                         + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
   25352                         + " to " + uidRec.curWhitelist);
   25353                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
   25354                         && !uidRec.curWhitelist) {
   25355                     // UID is now in the background (and not on the temp whitelist).  Was it
   25356                     // previously in the foreground (or on the temp whitelist)?
   25357                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
   25358                             || uidRec.setWhitelist) {
   25359                         uidRec.lastBackgroundTime = nowElapsed;
   25360                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
   25361                             // Note: the background settle time is in elapsed realtime, while
   25362                             // the handler time base is uptime.  All this means is that we may
   25363                             // stop background uids later than we had intended, but that only
   25364                             // happens because the device was sleeping so we are okay anyway.
   25365                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
   25366                                     mConstants.BACKGROUND_SETTLE_TIME);
   25367                         }
   25368                     }
   25369                     if (uidRec.idle && !uidRec.setIdle) {
   25370                         uidChange = UidRecord.CHANGE_IDLE;
   25371                         if (becameIdle == null) {
   25372                             becameIdle = new ArrayList<>();
   25373                         }
   25374                         becameIdle.add(uidRec);
   25375                     }
   25376                 } else {
   25377                     if (uidRec.idle) {
   25378                         uidChange = UidRecord.CHANGE_ACTIVE;
   25379                         EventLogTags.writeAmUidActive(uidRec.uid);
   25380                         uidRec.idle = false;
   25381                     }
   25382                     uidRec.lastBackgroundTime = 0;
   25383                 }
   25384                 final boolean wasCached = uidRec.setProcState
   25385                         > ActivityManager.PROCESS_STATE_RECEIVER;
   25386                 final boolean isCached = uidRec.curProcState
   25387                         > ActivityManager.PROCESS_STATE_RECEIVER;
   25388                 if (wasCached != isCached ||
   25389                         uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
   25390                     uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
   25391                 }
   25392                 uidRec.setProcState = uidRec.curProcState;
   25393                 uidRec.setWhitelist = uidRec.curWhitelist;
   25394                 uidRec.setIdle = uidRec.idle;
   25395                 enqueueUidChangeLocked(uidRec, -1, uidChange);
   25396                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
   25397                 if (uidRec.foregroundServices) {
   25398                     mServices.foregroundServiceProcStateChangedLocked(uidRec);
   25399                 }
   25400             }
   25401         }
   25402         if (mLocalPowerManager != null) {
   25403             mLocalPowerManager.finishUidChanges();
   25404         }
   25405 
   25406         if (becameIdle != null) {
   25407             // If we have any new uids that became idle this time, we need to make sure
   25408             // they aren't left with running services.
   25409             for (int i = becameIdle.size() - 1; i >= 0; i--) {
   25410                 mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
   25411             }
   25412         }
   25413 
   25414         if (mProcessStats.shouldWriteNowLocked(now)) {
   25415             mHandler.post(new Runnable() {
   25416                 @Override public void run() {
   25417                     synchronized (ActivityManagerService.this) {
   25418                         mProcessStats.writeStateAsyncLocked();
   25419                     }
   25420                 }
   25421             });
   25422         }
   25423 
   25424         if (DEBUG_OOM_ADJ) {
   25425             final long duration = SystemClock.uptimeMillis() - now;
   25426             if (false) {
   25427                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
   25428                         new RuntimeException("here").fillInStackTrace());
   25429             } else {
   25430                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
   25431             }
   25432         }
   25433     }
   25434 
   25435     @Override
   25436     public void makePackageIdle(String packageName, int userId) {
   25437         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   25438                 != PackageManager.PERMISSION_GRANTED) {
   25439             String msg = "Permission Denial: makePackageIdle() from pid="
   25440                     + Binder.getCallingPid()
   25441                     + ", uid=" + Binder.getCallingUid()
   25442                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   25443             Slog.w(TAG, msg);
   25444             throw new SecurityException(msg);
   25445         }
   25446         final int callingPid = Binder.getCallingPid();
   25447         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
   25448                 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
   25449         long callingId = Binder.clearCallingIdentity();
   25450         synchronized(this) {
   25451             try {
   25452                 IPackageManager pm = AppGlobals.getPackageManager();
   25453                 int pkgUid = -1;
   25454                 try {
   25455                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
   25456                             | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
   25457                 } catch (RemoteException e) {
   25458                 }
   25459                 if (pkgUid == -1) {
   25460                     throw new IllegalArgumentException("Unknown package name " + packageName);
   25461                 }
   25462 
   25463                 if (mLocalPowerManager != null) {
   25464                     mLocalPowerManager.startUidChanges();
   25465                 }
   25466                 final int appId = UserHandle.getAppId(pkgUid);
   25467                 final int N = mActiveUids.size();
   25468                 for (int i=N-1; i>=0; i--) {
   25469                     final UidRecord uidRec = mActiveUids.valueAt(i);
   25470                     final long bgTime = uidRec.lastBackgroundTime;
   25471                     if (bgTime > 0 && !uidRec.idle) {
   25472                         if (UserHandle.getAppId(uidRec.uid) == appId) {
   25473                             if (userId == UserHandle.USER_ALL ||
   25474                                     userId == UserHandle.getUserId(uidRec.uid)) {
   25475                                 EventLogTags.writeAmUidIdle(uidRec.uid);
   25476                                 uidRec.idle = true;
   25477                                 uidRec.setIdle = true;
   25478                                 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
   25479                                         + " from package " + packageName + " user " + userId);
   25480                                 doStopUidLocked(uidRec.uid, uidRec);
   25481                             }
   25482                         }
   25483                     }
   25484                 }
   25485             } finally {
   25486                 if (mLocalPowerManager != null) {
   25487                     mLocalPowerManager.finishUidChanges();
   25488                 }
   25489                 Binder.restoreCallingIdentity(callingId);
   25490             }
   25491         }
   25492     }
   25493 
   25494     final void idleUids() {
   25495         synchronized (this) {
   25496             final int N = mActiveUids.size();
   25497             if (N <= 0) {
   25498                 return;
   25499             }
   25500             final long nowElapsed = SystemClock.elapsedRealtime();
   25501             final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
   25502             long nextTime = 0;
   25503             if (mLocalPowerManager != null) {
   25504                 mLocalPowerManager.startUidChanges();
   25505             }
   25506             for (int i=N-1; i>=0; i--) {
   25507                 final UidRecord uidRec = mActiveUids.valueAt(i);
   25508                 final long bgTime = uidRec.lastBackgroundTime;
   25509                 if (bgTime > 0 && !uidRec.idle) {
   25510                     if (bgTime <= maxBgTime) {
   25511                         EventLogTags.writeAmUidIdle(uidRec.uid);
   25512                         uidRec.idle = true;
   25513                         uidRec.setIdle = true;
   25514                         doStopUidLocked(uidRec.uid, uidRec);
   25515                     } else {
   25516                         if (nextTime == 0 || nextTime > bgTime) {
   25517                             nextTime = bgTime;
   25518                         }
   25519                     }
   25520                 }
   25521             }
   25522             if (mLocalPowerManager != null) {
   25523                 mLocalPowerManager.finishUidChanges();
   25524             }
   25525             if (nextTime > 0) {
   25526                 mHandler.removeMessages(IDLE_UIDS_MSG);
   25527                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
   25528                         nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
   25529             }
   25530         }
   25531     }
   25532 
   25533     /**
   25534      * Checks if any uid is coming from background to foreground or vice versa and if so, increments
   25535      * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
   25536      * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
   25537      */
   25538     @VisibleForTesting
   25539     @GuardedBy("this")
   25540     void incrementProcStateSeqAndNotifyAppsLocked() {
   25541         if (mWaitForNetworkTimeoutMs <= 0) {
   25542             return;
   25543         }
   25544         // Used for identifying which uids need to block for network.
   25545         ArrayList<Integer> blockingUids = null;
   25546         for (int i = mActiveUids.size() - 1; i >= 0; --i) {
   25547             final UidRecord uidRec = mActiveUids.valueAt(i);
   25548             // If the network is not restricted for uid, then nothing to do here.
   25549             if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
   25550                 continue;
   25551             }
   25552             if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
   25553                 continue;
   25554             }
   25555             // If process state is not changed, then there's nothing to do.
   25556             if (uidRec.setProcState == uidRec.curProcState) {
   25557                 continue;
   25558             }
   25559             final int blockState = getBlockStateForUid(uidRec);
   25560             // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
   25561             // there's nothing the app needs to do in this scenario.
   25562             if (blockState == NETWORK_STATE_NO_CHANGE) {
   25563                 continue;
   25564             }
   25565             synchronized (uidRec.networkStateLock) {
   25566                 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
   25567                 if (blockState == NETWORK_STATE_BLOCK) {
   25568                     if (blockingUids == null) {
   25569                         blockingUids = new ArrayList<>();
   25570                     }
   25571                     blockingUids.add(uidRec.uid);
   25572                 } else {
   25573                     if (DEBUG_NETWORK) {
   25574                         Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
   25575                                 + " threads for uid: " + uidRec);
   25576                     }
   25577                     if (uidRec.waitingForNetwork) {
   25578                         uidRec.networkStateLock.notifyAll();
   25579                     }
   25580                 }
   25581             }
   25582         }
   25583 
   25584         // There are no uids that need to block, so nothing more to do.
   25585         if (blockingUids == null) {
   25586             return;
   25587         }
   25588 
   25589         for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
   25590             final ProcessRecord app = mLruProcesses.get(i);
   25591             if (!blockingUids.contains(app.uid)) {
   25592                 continue;
   25593             }
   25594             if (!app.killedByAm && app.thread != null) {
   25595                 final UidRecord uidRec = mActiveUids.get(app.uid);
   25596                 try {
   25597                     if (DEBUG_NETWORK) {
   25598                         Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
   25599                                 + uidRec);
   25600                     }
   25601                     app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
   25602                 } catch (RemoteException ignored) {
   25603                 }
   25604             }
   25605         }
   25606     }
   25607 
   25608     /**
   25609      * Checks if the uid is coming from background to foreground or vice versa and returns
   25610      * appropriate block state based on this.
   25611      *
   25612      * @return blockState based on whether the uid is coming from background to foreground or
   25613      *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
   25614      *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
   25615      *         {@link #NETWORK_STATE_NO_CHANGE}.
   25616      */
   25617     @VisibleForTesting
   25618     int getBlockStateForUid(UidRecord uidRec) {
   25619         // Denotes whether uid's process state is currently allowed network access.
   25620         final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
   25621                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
   25622         // Denotes whether uid's process state was previously allowed network access.
   25623         final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
   25624                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
   25625 
   25626         // When the uid is coming to foreground, AMS should inform the app thread that it should
   25627         // block for the network rules to get updated before launching an activity.
   25628         if (!wasAllowed && isAllowed) {
   25629             return NETWORK_STATE_BLOCK;
   25630         }
   25631         // When the uid is going to background, AMS should inform the app thread that if an
   25632         // activity launch is blocked for the network rules to get updated, it should be unblocked.
   25633         if (wasAllowed && !isAllowed) {
   25634             return NETWORK_STATE_UNBLOCK;
   25635         }
   25636         return NETWORK_STATE_NO_CHANGE;
   25637     }
   25638 
   25639     final void runInBackgroundDisabled(int uid) {
   25640         synchronized (this) {
   25641             UidRecord uidRec = mActiveUids.get(uid);
   25642             if (uidRec != null) {
   25643                 // This uid is actually running...  should it be considered background now?
   25644                 if (uidRec.idle) {
   25645                     doStopUidLocked(uidRec.uid, uidRec);
   25646                 }
   25647             } else {
   25648                 // This uid isn't actually running...  still send a report about it being "stopped".
   25649                 doStopUidLocked(uid, null);
   25650             }
   25651         }
   25652     }
   25653 
   25654     /**
   25655      * Call {@link #doStopUidLocked} (which will also stop background services) for all idle UIDs.
   25656      */
   25657     void doStopUidForIdleUidsLocked() {
   25658         final int size = mActiveUids.size();
   25659         for (int i = 0; i < size; i++) {
   25660             final int uid = mActiveUids.keyAt(i);
   25661             if (UserHandle.isCore(uid)) {
   25662                 continue;
   25663             }
   25664             final UidRecord uidRec = mActiveUids.valueAt(i);
   25665             if (!uidRec.idle) {
   25666                 continue;
   25667             }
   25668             doStopUidLocked(uidRec.uid, uidRec);
   25669         }
   25670     }
   25671 
   25672     final void doStopUidLocked(int uid, final UidRecord uidRec) {
   25673         mServices.stopInBackgroundLocked(uid);
   25674         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
   25675     }
   25676 
   25677     /**
   25678      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
   25679      */
   25680     @GuardedBy("this")
   25681     void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
   25682             long duration, String tag) {
   25683         if (DEBUG_WHITELISTS) {
   25684             Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
   25685                     + targetUid + ", " + duration + ")");
   25686         }
   25687 
   25688         synchronized (mPidsSelfLocked) {
   25689             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
   25690             if (pr == null) {
   25691                 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
   25692                         + callerPid);
   25693                 return;
   25694             }
   25695             if (!pr.whitelistManager) {
   25696                 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
   25697                         != PackageManager.PERMISSION_GRANTED) {
   25698                     if (DEBUG_WHITELISTS) {
   25699                         Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
   25700                                 + ": pid " + callerPid + " is not allowed");
   25701                     }
   25702                     return;
   25703                 }
   25704             }
   25705         }
   25706 
   25707         tempWhitelistUidLocked(targetUid, duration, tag);
   25708     }
   25709 
   25710     /**
   25711      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
   25712      */
   25713     @GuardedBy("this")
   25714     void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
   25715         mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
   25716         setUidTempWhitelistStateLocked(targetUid, true);
   25717         mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
   25718     }
   25719 
   25720     void pushTempWhitelist() {
   25721         final int N;
   25722         final PendingTempWhitelist[] list;
   25723 
   25724         // First copy out the pending changes...  we need to leave them in the map for now,
   25725         // in case someone needs to check what is coming up while we don't have the lock held.
   25726         synchronized(this) {
   25727             N = mPendingTempWhitelist.size();
   25728             list = new PendingTempWhitelist[N];
   25729             for (int i = 0; i < N; i++) {
   25730                 list[i] = mPendingTempWhitelist.valueAt(i);
   25731             }
   25732         }
   25733 
   25734         // Now safely dispatch changes to device idle controller.
   25735         for (int i = 0; i < N; i++) {
   25736             PendingTempWhitelist ptw = list[i];
   25737             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
   25738                     ptw.duration, true, ptw.tag);
   25739         }
   25740 
   25741         // And now we can safely remove them from the map.
   25742         synchronized(this) {
   25743             for (int i = 0; i < N; i++) {
   25744                 PendingTempWhitelist ptw = list[i];
   25745                 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
   25746                 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
   25747                     mPendingTempWhitelist.removeAt(index);
   25748                 }
   25749             }
   25750         }
   25751     }
   25752 
   25753     @GuardedBy("this")
   25754     final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
   25755         boolean changed = false;
   25756         for (int i=mActiveUids.size()-1; i>=0; i--) {
   25757             final UidRecord uidRec = mActiveUids.valueAt(i);
   25758             if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
   25759                 uidRec.curWhitelist = onWhitelist;
   25760                 changed = true;
   25761             }
   25762         }
   25763         if (changed) {
   25764             updateOomAdjLocked();
   25765         }
   25766     }
   25767 
   25768     @GuardedBy("this")
   25769     final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
   25770         boolean changed = false;
   25771         final UidRecord uidRec = mActiveUids.get(uid);
   25772         if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
   25773             uidRec.curWhitelist = onWhitelist;
   25774             updateOomAdjLocked();
   25775         }
   25776     }
   25777 
   25778     final void trimApplications() {
   25779         synchronized (this) {
   25780             trimApplicationsLocked();
   25781         }
   25782     }
   25783 
   25784     final void trimApplicationsLocked() {
   25785         // First remove any unused application processes whose package
   25786         // has been removed.
   25787         for (int i=mRemovedProcesses.size()-1; i>=0; i--) {
   25788             final ProcessRecord app = mRemovedProcesses.get(i);
   25789             if (app.activities.size() == 0 && app.recentTasks.size() == 0
   25790                     && app.curReceivers.isEmpty() && app.services.size() == 0) {
   25791                 Slog.i(
   25792                     TAG, "Exiting empty application process "
   25793                     + app.toShortString() + " ("
   25794                     + (app.thread != null ? app.thread.asBinder() : null)
   25795                     + ")\n");
   25796                 if (app.pid > 0 && app.pid != MY_PID) {
   25797                     app.kill("empty", false);
   25798                 } else if (app.thread != null) {
   25799                     try {
   25800                         app.thread.scheduleExit();
   25801                     } catch (Exception e) {
   25802                         // Ignore exceptions.
   25803                     }
   25804                 }
   25805                 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
   25806                 mRemovedProcesses.remove(i);
   25807 
   25808                 if (app.persistent) {
   25809                     addAppLocked(app.info, null, false, null /* ABI override */);
   25810                 }
   25811             }
   25812         }
   25813 
   25814         // Now update the oom adj for all processes. Don't skip this, since other callers
   25815         // might be depending on it.
   25816         updateOomAdjLocked();
   25817     }
   25818 
   25819     /** This method sends the specified signal to each of the persistent apps */
   25820     public void signalPersistentProcesses(int sig) throws RemoteException {
   25821         if (sig != SIGNAL_USR1) {
   25822             throw new SecurityException("Only SIGNAL_USR1 is allowed");
   25823         }
   25824 
   25825         synchronized (this) {
   25826             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
   25827                     != PackageManager.PERMISSION_GRANTED) {
   25828                 throw new SecurityException("Requires permission "
   25829                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
   25830             }
   25831 
   25832             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   25833                 ProcessRecord r = mLruProcesses.get(i);
   25834                 if (r.thread != null && r.persistent) {
   25835                     sendSignal(r.pid, sig);
   25836                 }
   25837             }
   25838         }
   25839     }
   25840 
   25841     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
   25842         if (proc == null || proc == mProfileProc) {
   25843             proc = mProfileProc;
   25844             profileType = mProfileType;
   25845             clearProfilerLocked();
   25846         }
   25847         if (proc == null) {
   25848             return;
   25849         }
   25850         try {
   25851             proc.thread.profilerControl(false, null, profileType);
   25852         } catch (RemoteException e) {
   25853             throw new IllegalStateException("Process disappeared");
   25854         }
   25855     }
   25856 
   25857     private void clearProfilerLocked() {
   25858         if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
   25859             try {
   25860                 mProfilerInfo.profileFd.close();
   25861             } catch (IOException e) {
   25862             }
   25863         }
   25864         mProfileApp = null;
   25865         mProfileProc = null;
   25866         mProfilerInfo = null;
   25867     }
   25868 
   25869     public boolean profileControl(String process, int userId, boolean start,
   25870             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
   25871 
   25872         try {
   25873             synchronized (this) {
   25874                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   25875                 // its own permission.
   25876                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   25877                         != PackageManager.PERMISSION_GRANTED) {
   25878                     throw new SecurityException("Requires permission "
   25879                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   25880                 }
   25881 
   25882                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
   25883                     throw new IllegalArgumentException("null profile info or fd");
   25884                 }
   25885 
   25886                 ProcessRecord proc = null;
   25887                 if (process != null) {
   25888                     proc = findProcessLocked(process, userId, "profileControl");
   25889                 }
   25890 
   25891                 if (start && (proc == null || proc.thread == null)) {
   25892                     throw new IllegalArgumentException("Unknown process: " + process);
   25893                 }
   25894 
   25895                 if (start) {
   25896                     stopProfilerLocked(null, 0);
   25897                     setProfileApp(proc.info, proc.processName, profilerInfo);
   25898                     mProfileProc = proc;
   25899                     mProfileType = profileType;
   25900                     ParcelFileDescriptor fd = profilerInfo.profileFd;
   25901                     try {
   25902                         fd = fd.dup();
   25903                     } catch (IOException e) {
   25904                         fd = null;
   25905                     }
   25906                     profilerInfo.profileFd = fd;
   25907                     proc.thread.profilerControl(start, profilerInfo, profileType);
   25908                     fd = null;
   25909                     try {
   25910                         mProfilerInfo.profileFd.close();
   25911                     } catch (IOException e) {
   25912                     }
   25913                     mProfilerInfo.profileFd = null;
   25914 
   25915                     if (proc.pid == MY_PID) {
   25916                         // When profiling the system server itself, avoid closing the file
   25917                         // descriptor, as profilerControl will not create a copy.
   25918                         // Note: it is also not correct to just set profileFd to null, as the
   25919                         //       whole ProfilerInfo instance is passed down!
   25920                         profilerInfo = null;
   25921                     }
   25922                 } else {
   25923                     stopProfilerLocked(proc, profileType);
   25924                     if (profilerInfo != null && profilerInfo.profileFd != null) {
   25925                         try {
   25926                             profilerInfo.profileFd.close();
   25927                         } catch (IOException e) {
   25928                         }
   25929                     }
   25930                 }
   25931 
   25932                 return true;
   25933             }
   25934         } catch (RemoteException e) {
   25935             throw new IllegalStateException("Process disappeared");
   25936         } finally {
   25937             if (profilerInfo != null && profilerInfo.profileFd != null) {
   25938                 try {
   25939                     profilerInfo.profileFd.close();
   25940                 } catch (IOException e) {
   25941                 }
   25942             }
   25943         }
   25944     }
   25945 
   25946     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
   25947         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   25948                 userId, true, ALLOW_FULL_ONLY, callName, null);
   25949         ProcessRecord proc = null;
   25950         try {
   25951             int pid = Integer.parseInt(process);
   25952             synchronized (mPidsSelfLocked) {
   25953                 proc = mPidsSelfLocked.get(pid);
   25954             }
   25955         } catch (NumberFormatException e) {
   25956         }
   25957 
   25958         if (proc == null) {
   25959             ArrayMap<String, SparseArray<ProcessRecord>> all
   25960                     = mProcessNames.getMap();
   25961             SparseArray<ProcessRecord> procs = all.get(process);
   25962             if (procs != null && procs.size() > 0) {
   25963                 proc = procs.valueAt(0);
   25964                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
   25965                     for (int i=1; i<procs.size(); i++) {
   25966                         ProcessRecord thisProc = procs.valueAt(i);
   25967                         if (thisProc.userId == userId) {
   25968                             proc = thisProc;
   25969                             break;
   25970                         }
   25971                     }
   25972                 }
   25973             }
   25974         }
   25975 
   25976         return proc;
   25977     }
   25978 
   25979     public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
   25980             boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
   25981 
   25982         try {
   25983             synchronized (this) {
   25984                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   25985                 // its own permission (same as profileControl).
   25986                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   25987                         != PackageManager.PERMISSION_GRANTED) {
   25988                     throw new SecurityException("Requires permission "
   25989                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   25990                 }
   25991 
   25992                 if (fd == null) {
   25993                     throw new IllegalArgumentException("null fd");
   25994                 }
   25995 
   25996                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
   25997                 if (proc == null || proc.thread == null) {
   25998                     throw new IllegalArgumentException("Unknown process: " + process);
   25999                 }
   26000 
   26001                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   26002                 if (!isDebuggable) {
   26003                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   26004                         throw new SecurityException("Process not debuggable: " + proc);
   26005                     }
   26006                 }
   26007 
   26008                 proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
   26009                 fd = null;
   26010                 return true;
   26011             }
   26012         } catch (RemoteException e) {
   26013             throw new IllegalStateException("Process disappeared");
   26014         } finally {
   26015             if (fd != null) {
   26016                 try {
   26017                     fd.close();
   26018                 } catch (IOException e) {
   26019                 }
   26020             }
   26021         }
   26022     }
   26023 
   26024     @Override
   26025     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
   26026             String reportPackage) {
   26027         if (processName != null) {
   26028             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   26029                     "setDumpHeapDebugLimit()");
   26030         } else {
   26031             synchronized (mPidsSelfLocked) {
   26032                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
   26033                 if (proc == null) {
   26034                     throw new SecurityException("No process found for calling pid "
   26035                             + Binder.getCallingPid());
   26036                 }
   26037                 if (!Build.IS_DEBUGGABLE
   26038                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   26039                     throw new SecurityException("Not running a debuggable build");
   26040                 }
   26041                 processName = proc.processName;
   26042                 uid = proc.uid;
   26043                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
   26044                     throw new SecurityException("Package " + reportPackage + " is not running in "
   26045                             + proc);
   26046                 }
   26047             }
   26048         }
   26049         synchronized (this) {
   26050             if (maxMemSize > 0) {
   26051                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
   26052             } else {
   26053                 if (uid != 0) {
   26054                     mMemWatchProcesses.remove(processName, uid);
   26055                 } else {
   26056                     mMemWatchProcesses.getMap().remove(processName);
   26057                 }
   26058             }
   26059         }
   26060     }
   26061 
   26062     @Override
   26063     public void dumpHeapFinished(String path) {
   26064         synchronized (this) {
   26065             if (Binder.getCallingPid() != mMemWatchDumpPid) {
   26066                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
   26067                         + " does not match last pid " + mMemWatchDumpPid);
   26068                 return;
   26069             }
   26070             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
   26071                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
   26072                         + " does not match last path " + mMemWatchDumpFile);
   26073                 return;
   26074             }
   26075             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
   26076             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
   26077 
   26078             // Forced gc to clean up the remnant hprof fd.
   26079             Runtime.getRuntime().gc();
   26080         }
   26081     }
   26082 
   26083     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
   26084     public void monitor() {
   26085         synchronized (this) { }
   26086     }
   26087 
   26088     void onCoreSettingsChange(Bundle settings) {
   26089         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   26090             ProcessRecord processRecord = mLruProcesses.get(i);
   26091             try {
   26092                 if (processRecord.thread != null) {
   26093                     processRecord.thread.setCoreSettings(settings);
   26094                 }
   26095             } catch (RemoteException re) {
   26096                 /* ignore */
   26097             }
   26098         }
   26099     }
   26100 
   26101     // Multi-user methods
   26102 
   26103     /**
   26104      * Start user, if its not already running, but don't bring it to foreground.
   26105      */
   26106     @Override
   26107     public boolean startUserInBackground(final int userId) {
   26108         return startUserInBackgroundWithListener(userId, null);
   26109     }
   26110 
   26111     @Override
   26112     public boolean startUserInBackgroundWithListener(final int userId,
   26113                 @Nullable IProgressListener unlockListener) {
   26114         return mUserController.startUser(userId, /* foreground */ false, unlockListener);
   26115     }
   26116 
   26117     @Override
   26118     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
   26119         return mUserController.unlockUser(userId, token, secret, listener);
   26120     }
   26121 
   26122     @Override
   26123     public boolean switchUser(final int targetUserId) {
   26124         return mUserController.switchUser(targetUserId);
   26125     }
   26126 
   26127     @Override
   26128     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
   26129         return mUserController.stopUser(userId, force, callback);
   26130     }
   26131 
   26132     @Override
   26133     public UserInfo getCurrentUser() {
   26134         return mUserController.getCurrentUser();
   26135     }
   26136 
   26137     String getStartedUserState(int userId) {
   26138         final UserState userState = mUserController.getStartedUserState(userId);
   26139         return UserState.stateToString(userState.state);
   26140     }
   26141 
   26142     @Override
   26143     public boolean isUserRunning(int userId, int flags) {
   26144         if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
   26145                 && checkCallingPermission(INTERACT_ACROSS_USERS)
   26146                     != PackageManager.PERMISSION_GRANTED) {
   26147             String msg = "Permission Denial: isUserRunning() from pid="
   26148                     + Binder.getCallingPid()
   26149                     + ", uid=" + Binder.getCallingUid()
   26150                     + " requires " + INTERACT_ACROSS_USERS;
   26151             Slog.w(TAG, msg);
   26152             throw new SecurityException(msg);
   26153         }
   26154         return mUserController.isUserRunning(userId, flags);
   26155     }
   26156 
   26157     @Override
   26158     public int[] getRunningUserIds() {
   26159         if (checkCallingPermission(INTERACT_ACROSS_USERS)
   26160                 != PackageManager.PERMISSION_GRANTED) {
   26161             String msg = "Permission Denial: isUserRunning() from pid="
   26162                     + Binder.getCallingPid()
   26163                     + ", uid=" + Binder.getCallingUid()
   26164                     + " requires " + INTERACT_ACROSS_USERS;
   26165             Slog.w(TAG, msg);
   26166             throw new SecurityException(msg);
   26167         }
   26168         return mUserController.getStartedUserArray();
   26169     }
   26170 
   26171     @Override
   26172     public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
   26173         mUserController.registerUserSwitchObserver(observer, name);
   26174     }
   26175 
   26176     @Override
   26177     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
   26178         mUserController.unregisterUserSwitchObserver(observer);
   26179     }
   26180 
   26181     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
   26182         if (info == null) return null;
   26183         ApplicationInfo newInfo = new ApplicationInfo(info);
   26184         newInfo.initForUser(userId);
   26185         return newInfo;
   26186     }
   26187 
   26188     public boolean isUserStopped(int userId) {
   26189         return mUserController.getStartedUserState(userId) == null;
   26190     }
   26191 
   26192     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
   26193         if (aInfo == null
   26194                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
   26195             return aInfo;
   26196         }
   26197 
   26198         ActivityInfo info = new ActivityInfo(aInfo);
   26199         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
   26200         return info;
   26201     }
   26202 
   26203     private boolean processSanityChecksLocked(ProcessRecord process) {
   26204         if (process == null || process.thread == null) {
   26205             return false;
   26206         }
   26207 
   26208         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   26209         if (!isDebuggable) {
   26210             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   26211                 return false;
   26212             }
   26213         }
   26214 
   26215         return true;
   26216     }
   26217 
   26218     public boolean startBinderTracking() throws RemoteException {
   26219         synchronized (this) {
   26220             mBinderTransactionTrackingEnabled = true;
   26221             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
   26222             // permission (same as profileControl).
   26223             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   26224                     != PackageManager.PERMISSION_GRANTED) {
   26225                 throw new SecurityException("Requires permission "
   26226                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   26227             }
   26228 
   26229             for (int i = 0; i < mLruProcesses.size(); i++) {
   26230                 ProcessRecord process = mLruProcesses.get(i);
   26231                 if (!processSanityChecksLocked(process)) {
   26232                     continue;
   26233                 }
   26234                 try {
   26235                     process.thread.startBinderTracking();
   26236                 } catch (RemoteException e) {
   26237                     Log.v(TAG, "Process disappared");
   26238                 }
   26239             }
   26240             return true;
   26241         }
   26242     }
   26243 
   26244     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
   26245         try {
   26246             synchronized (this) {
   26247                 mBinderTransactionTrackingEnabled = false;
   26248                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
   26249                 // permission (same as profileControl).
   26250                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   26251                         != PackageManager.PERMISSION_GRANTED) {
   26252                     throw new SecurityException("Requires permission "
   26253                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   26254                 }
   26255 
   26256                 if (fd == null) {
   26257                     throw new IllegalArgumentException("null fd");
   26258                 }
   26259 
   26260                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
   26261                 pw.println("Binder transaction traces for all processes.\n");
   26262                 for (ProcessRecord process : mLruProcesses) {
   26263                     if (!processSanityChecksLocked(process)) {
   26264                         continue;
   26265                     }
   26266 
   26267                     pw.println("Traces for process: " + process.processName);
   26268                     pw.flush();
   26269                     try {
   26270                         TransferPipe tp = new TransferPipe();
   26271                         try {
   26272                             process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
   26273                             tp.go(fd.getFileDescriptor());
   26274                         } finally {
   26275                             tp.kill();
   26276                         }
   26277                     } catch (IOException e) {
   26278                         pw.println("Failure while dumping IPC traces from " + process +
   26279                                 ".  Exception: " + e);
   26280                         pw.flush();
   26281                     } catch (RemoteException e) {
   26282                         pw.println("Got a RemoteException while dumping IPC traces from " +
   26283                                 process + ".  Exception: " + e);
   26284                         pw.flush();
   26285                     }
   26286                 }
   26287                 fd = null;
   26288                 return true;
   26289             }
   26290         } finally {
   26291             if (fd != null) {
   26292                 try {
   26293                     fd.close();
   26294                 } catch (IOException e) {
   26295                 }
   26296             }
   26297         }
   26298     }
   26299 
   26300     @VisibleForTesting
   26301     final class LocalService extends ActivityManagerInternal {
   26302         @Override
   26303         public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
   26304                 int targetUserId) {
   26305             synchronized (ActivityManagerService.this) {
   26306                 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
   26307                         targetPkg, intent, null, targetUserId);
   26308             }
   26309         }
   26310 
   26311         @Override
   26312         public String checkContentProviderAccess(String authority, int userId) {
   26313             return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
   26314         }
   26315 
   26316         @Override
   26317         public void onWakefulnessChanged(int wakefulness) {
   26318             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
   26319         }
   26320 
   26321         @Override
   26322         public boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
   26323                 String processName, String abiOverride, int uid, Runnable crashHandler) {
   26324             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
   26325                     processName, abiOverride, uid, crashHandler);
   26326         }
   26327 
   26328         @Override
   26329         public SleepToken acquireSleepToken(String tag, int displayId) {
   26330             Preconditions.checkNotNull(tag);
   26331             return ActivityManagerService.this.acquireSleepToken(tag, displayId);
   26332         }
   26333 
   26334         @Override
   26335         public ComponentName getHomeActivityForUser(int userId) {
   26336             synchronized (ActivityManagerService.this) {
   26337                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
   26338                 return homeActivity == null ? null : homeActivity.realActivity;
   26339             }
   26340         }
   26341 
   26342         @Override
   26343         public void onUserRemoved(int userId) {
   26344             synchronized (ActivityManagerService.this) {
   26345                 ActivityManagerService.this.onUserStoppedLocked(userId);
   26346             }
   26347             mBatteryStatsService.onUserRemoved(userId);
   26348             mUserController.onUserRemoved(userId);
   26349         }
   26350 
   26351         @Override
   26352         public void onLocalVoiceInteractionStarted(IBinder activity,
   26353                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
   26354             synchronized (ActivityManagerService.this) {
   26355                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
   26356                         voiceSession, voiceInteractor);
   26357             }
   26358         }
   26359 
   26360         @Override
   26361         public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
   26362             synchronized (ActivityManagerService.this) {
   26363                 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
   26364                         reasons, timestamp);
   26365             }
   26366         }
   26367 
   26368         @Override
   26369         public void notifyAppTransitionFinished() {
   26370             synchronized (ActivityManagerService.this) {
   26371                 mStackSupervisor.notifyAppTransitionDone();
   26372             }
   26373         }
   26374 
   26375         @Override
   26376         public void notifyAppTransitionCancelled() {
   26377             synchronized (ActivityManagerService.this) {
   26378                 mStackSupervisor.notifyAppTransitionDone();
   26379             }
   26380         }
   26381 
   26382         @Override
   26383         public List<IBinder> getTopVisibleActivities() {
   26384             synchronized (ActivityManagerService.this) {
   26385                 return mStackSupervisor.getTopVisibleActivities();
   26386             }
   26387         }
   26388 
   26389         @Override
   26390         public void notifyDockedStackMinimizedChanged(boolean minimized) {
   26391             synchronized (ActivityManagerService.this) {
   26392                 mStackSupervisor.setDockedStackMinimized(minimized);
   26393             }
   26394         }
   26395 
   26396         @Override
   26397         public void killForegroundAppsForUser(int userHandle) {
   26398             synchronized (ActivityManagerService.this) {
   26399                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
   26400                 final int NP = mProcessNames.getMap().size();
   26401                 for (int ip = 0; ip < NP; ip++) {
   26402                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   26403                     final int NA = apps.size();
   26404                     for (int ia = 0; ia < NA; ia++) {
   26405                         final ProcessRecord app = apps.valueAt(ia);
   26406                         if (app.persistent) {
   26407                             // We don't kill persistent processes.
   26408                             continue;
   26409                         }
   26410                         if (app.removed) {
   26411                             procs.add(app);
   26412                         } else if (app.userId == userHandle && app.foregroundActivities) {
   26413                             app.removed = true;
   26414                             procs.add(app);
   26415                         }
   26416                     }
   26417                 }
   26418 
   26419                 final int N = procs.size();
   26420                 for (int i = 0; i < N; i++) {
   26421                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
   26422                 }
   26423             }
   26424         }
   26425 
   26426         @Override
   26427         public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
   26428                 long duration) {
   26429             if (!(target instanceof PendingIntentRecord)) {
   26430                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
   26431                 return;
   26432             }
   26433             synchronized (ActivityManagerService.this) {
   26434                 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
   26435             }
   26436         }
   26437 
   26438         @Override
   26439         public void setDeviceIdleWhitelist(int[] allAppids, int[] exceptIdleAppids) {
   26440             synchronized (ActivityManagerService.this) {
   26441                 mDeviceIdleWhitelist = allAppids;
   26442                 mDeviceIdleExceptIdleWhitelist = exceptIdleAppids;
   26443             }
   26444         }
   26445 
   26446         @Override
   26447         public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
   26448             synchronized (ActivityManagerService.this) {
   26449                 mDeviceIdleTempWhitelist = appids;
   26450                 setAppIdTempWhitelistStateLocked(changingAppId, adding);
   26451             }
   26452         }
   26453 
   26454         @Override
   26455         public void updatePersistentConfigurationForUser(@NonNull Configuration values,
   26456                 int userId) {
   26457             Preconditions.checkNotNull(values, "Configuration must not be null");
   26458             Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
   26459             synchronized (ActivityManagerService.this) {
   26460                 updateConfigurationLocked(values, null, false, true, userId,
   26461                         false /* deferResume */);
   26462             }
   26463         }
   26464 
   26465         @Override
   26466         public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
   26467                 Bundle bOptions) {
   26468             Preconditions.checkNotNull(intents, "intents");
   26469             final String[] resolvedTypes = new String[intents.length];
   26470 
   26471             // UID of the package on user userId.
   26472             // "= 0" is needed because otherwise catch(RemoteException) would make it look like
   26473             // packageUid may not be initialized.
   26474             int packageUid = 0;
   26475             final long ident = Binder.clearCallingIdentity();
   26476 
   26477             try {
   26478                 for (int i = 0; i < intents.length; i++) {
   26479                     resolvedTypes[i] =
   26480                             intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
   26481                 }
   26482 
   26483                 packageUid = AppGlobals.getPackageManager().getPackageUid(
   26484                         packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
   26485             } catch (RemoteException e) {
   26486                 // Shouldn't happen.
   26487             } finally {
   26488                 Binder.restoreCallingIdentity(ident);
   26489             }
   26490 
   26491             synchronized (ActivityManagerService.this) {
   26492                 return mActivityStartController.startActivitiesInPackage(
   26493                         packageUid, packageName,
   26494                         intents, resolvedTypes, null /* resultTo */,
   26495                         SafeActivityOptions.fromBundle(bOptions), userId,
   26496                         false /* validateIncomingUser */);
   26497             }
   26498         }
   26499 
   26500         @Override
   26501         public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
   26502                 Intent intent, Bundle options, int userId) {
   26503             return ActivityManagerService.this.startActivityAsUser(
   26504                     caller, callerPacakge, intent,
   26505                     intent.resolveTypeIfNeeded(mContext.getContentResolver()),
   26506                     null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
   26507                     false /*validateIncomingUser*/);
   26508         }
   26509 
   26510         @Override
   26511         public int getUidProcessState(int uid) {
   26512             return getUidState(uid);
   26513         }
   26514 
   26515         @Override
   26516         public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
   26517             synchronized (ActivityManagerService.this) {
   26518 
   26519                 // We might change the visibilities here, so prepare an empty app transition which
   26520                 // might be overridden later if we actually change visibilities.
   26521                 final boolean wasTransitionSet =
   26522                         mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
   26523                 if (!wasTransitionSet) {
   26524                     mWindowManager.prepareAppTransition(TRANSIT_NONE,
   26525                             false /* alwaysKeepCurrent */);
   26526                 }
   26527                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   26528 
   26529                 // If there was a transition set already we don't want to interfere with it as we
   26530                 // might be starting it too early.
   26531                 if (!wasTransitionSet) {
   26532                     mWindowManager.executeAppTransition();
   26533                 }
   26534             }
   26535             if (callback != null) {
   26536                 callback.run();
   26537             }
   26538         }
   26539 
   26540         @Override
   26541         public boolean isSystemReady() {
   26542             // no need to synchronize(this) just to read & return the value
   26543             return mSystemReady;
   26544         }
   26545 
   26546         @Override
   26547         public void notifyKeyguardTrustedChanged() {
   26548             synchronized (ActivityManagerService.this) {
   26549                 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
   26550                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   26551                 }
   26552             }
   26553         }
   26554 
   26555         /**
   26556          * Sets if the given pid has an overlay UI or not.
   26557          *
   26558          * @param pid The pid we are setting overlay UI for.
   26559          * @param hasOverlayUi True if the process has overlay UI.
   26560          * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
   26561          */
   26562         @Override
   26563         public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
   26564             synchronized (ActivityManagerService.this) {
   26565                 final ProcessRecord pr;
   26566                 synchronized (mPidsSelfLocked) {
   26567                     pr = mPidsSelfLocked.get(pid);
   26568                     if (pr == null) {
   26569                         Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
   26570                         return;
   26571                     }
   26572                 }
   26573                 if (pr.hasOverlayUi == hasOverlayUi) {
   26574                     return;
   26575                 }
   26576                 pr.hasOverlayUi = hasOverlayUi;
   26577                 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
   26578                 updateOomAdjLocked(pr, true);
   26579             }
   26580         }
   26581 
   26582         @Override
   26583         public void setRunningRemoteAnimation(int pid, boolean runningRemoteAnimation) {
   26584             ActivityManagerService.this.setRunningRemoteAnimation(pid, runningRemoteAnimation);
   26585         }
   26586 
   26587         /**
   26588          * Called after the network policy rules are updated by
   26589          * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
   26590          * and {@param procStateSeq}.
   26591          */
   26592         @Override
   26593         public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
   26594             if (DEBUG_NETWORK) {
   26595                 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
   26596                         + uid + " seq: " + procStateSeq);
   26597             }
   26598             UidRecord record;
   26599             synchronized (ActivityManagerService.this) {
   26600                 record = mActiveUids.get(uid);
   26601                 if (record == null) {
   26602                     if (DEBUG_NETWORK) {
   26603                         Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
   26604                                 + " procStateSeq: " + procStateSeq);
   26605                     }
   26606                     return;
   26607                 }
   26608             }
   26609             synchronized (record.networkStateLock) {
   26610                 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
   26611                     if (DEBUG_NETWORK) {
   26612                         Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
   26613                                 + " been handled for uid: " + uid);
   26614                     }
   26615                     return;
   26616                 }
   26617                 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
   26618                 if (record.curProcStateSeq > procStateSeq) {
   26619                     if (DEBUG_NETWORK) {
   26620                         Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
   26621                                 + ", curProcstateSeq: " + record.curProcStateSeq
   26622                                 + ", procStateSeq: " + procStateSeq);
   26623                     }
   26624                     return;
   26625                 }
   26626                 if (record.waitingForNetwork) {
   26627                     if (DEBUG_NETWORK) {
   26628                         Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
   26629                                 + ", procStateSeq: " + procStateSeq);
   26630                     }
   26631                     record.networkStateLock.notifyAll();
   26632                 }
   26633             }
   26634         }
   26635 
   26636         @Override
   26637         public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
   26638             synchronized (ActivityManagerService.this) {
   26639                 mActiveVoiceInteractionServiceComponent = component;
   26640             }
   26641         }
   26642 
   26643         /**
   26644          * Called after virtual display Id is updated by
   26645          * {@link com.android.server.vr.Vr2dDisplay} with a specific
   26646          * {@param vrVr2dDisplayId}.
   26647          */
   26648         @Override
   26649         public void setVr2dDisplayId(int vr2dDisplayId) {
   26650             if (DEBUG_STACK) {
   26651                 Slog.d(TAG, "setVr2dDisplayId called for: " +
   26652                         vr2dDisplayId);
   26653             }
   26654             synchronized (ActivityManagerService.this) {
   26655                 mVr2dDisplayId = vr2dDisplayId;
   26656             }
   26657         }
   26658 
   26659         @Override
   26660         public void saveANRState(String reason) {
   26661             synchronized (ActivityManagerService.this) {
   26662                 final StringWriter sw = new StringWriter();
   26663                 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
   26664                 pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
   26665                 if (reason != null) {
   26666                     pw.println("  Reason: " + reason);
   26667                 }
   26668                 pw.println();
   26669                 mActivityStartController.dump(pw, "  ", null);
   26670                 pw.println();
   26671                 pw.println("-------------------------------------------------------------------------------");
   26672                 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
   26673                         true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
   26674                         "" /* header */);
   26675                 pw.println();
   26676                 pw.close();
   26677 
   26678                 mLastANRState = sw.toString();
   26679             }
   26680         }
   26681 
   26682         @Override
   26683         public void clearSavedANRState() {
   26684             synchronized (ActivityManagerService.this) {
   26685                 mLastANRState = null;
   26686             }
   26687         }
   26688 
   26689         @Override
   26690         public void setFocusedActivity(IBinder token) {
   26691             synchronized (ActivityManagerService.this) {
   26692                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
   26693                 if (r == null) {
   26694                     throw new IllegalArgumentException(
   26695                             "setFocusedActivity: No activity record matching token=" + token);
   26696                 }
   26697                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
   26698                         r, "setFocusedActivity")) {
   26699                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
   26700                 }
   26701             }
   26702         }
   26703 
   26704         @Override
   26705         public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
   26706             synchronized (ActivityManagerService.this) {
   26707                 if (mUserController.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
   26708                     ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
   26709                     if (types == null) {
   26710                         if (uid < 0) {
   26711                             return;
   26712                         }
   26713                         types = new ArrayMap<>();
   26714                         mAllowAppSwitchUids.put(userId, types);
   26715                     }
   26716                     if (uid < 0) {
   26717                         types.remove(type);
   26718                     } else {
   26719                         types.put(type, uid);
   26720                     }
   26721                 }
   26722             }
   26723         }
   26724 
   26725         @Override
   26726         public boolean isRuntimeRestarted() {
   26727             return mSystemServiceManager.isRuntimeRestarted();
   26728         }
   26729 
   26730         @Override
   26731         public boolean hasRunningActivity(int uid, @Nullable String packageName) {
   26732             if (packageName == null) return false;
   26733 
   26734             synchronized (ActivityManagerService.this) {
   26735                 for (int i = 0; i < mLruProcesses.size(); i++) {
   26736                     final ProcessRecord processRecord = mLruProcesses.get(i);
   26737                     if (processRecord.uid == uid) {
   26738                         for (int j = 0; j < processRecord.activities.size(); j++) {
   26739                             final ActivityRecord activityRecord = processRecord.activities.get(j);
   26740                             if (packageName.equals(activityRecord.packageName)) {
   26741                                 return true;
   26742                             }
   26743                         }
   26744                     }
   26745                 }
   26746             }
   26747             return false;
   26748         }
   26749 
   26750         @Override
   26751         public void registerScreenObserver(ScreenObserver observer) {
   26752             mScreenObservers.add(observer);
   26753         }
   26754 
   26755         @Override
   26756         public boolean canStartMoreUsers() {
   26757             return mUserController.canStartMoreUsers();
   26758         }
   26759 
   26760         @Override
   26761         public void setSwitchingFromSystemUserMessage(String switchingFromSystemUserMessage) {
   26762             mUserController.setSwitchingFromSystemUserMessage(switchingFromSystemUserMessage);
   26763         }
   26764 
   26765         @Override
   26766         public void setSwitchingToSystemUserMessage(String switchingToSystemUserMessage) {
   26767             mUserController.setSwitchingToSystemUserMessage(switchingToSystemUserMessage);
   26768         }
   26769 
   26770         @Override
   26771         public int getMaxRunningUsers() {
   26772             return mUserController.mMaxRunningUsers;
   26773         }
   26774 
   26775         @Override
   26776         public boolean isCallerRecents(int callingUid) {
   26777             return getRecentTasks().isCallerRecents(callingUid);
   26778         }
   26779 
   26780         @Override
   26781         public boolean isRecentsComponentHomeActivity(int userId) {
   26782             return getRecentTasks().isRecentsComponentHomeActivity(userId);
   26783         }
   26784 
   26785         @Override
   26786         public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
   26787             ActivityManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
   26788         }
   26789 
   26790         @Override
   26791         public boolean isUidActive(int uid) {
   26792             synchronized (ActivityManagerService.this) {
   26793                 return isUidActiveLocked(uid);
   26794             }
   26795         }
   26796 
   26797         @Override
   26798         public List<ProcessMemoryState> getMemoryStateForProcesses() {
   26799             List<ProcessMemoryState> processMemoryStates = new ArrayList<>();
   26800             synchronized (mPidsSelfLocked) {
   26801                 for (int i = 0, size = mPidsSelfLocked.size(); i < size; i++) {
   26802                     final ProcessRecord r = mPidsSelfLocked.valueAt(i);
   26803                     final int pid = r.pid;
   26804                     final int uid = r.uid;
   26805                     final MemoryStat memoryStat = readMemoryStatFromFilesystem(uid, pid);
   26806                     if (memoryStat == null) {
   26807                         continue;
   26808                     }
   26809                     ProcessMemoryState processMemoryState =
   26810                             new ProcessMemoryState(uid,
   26811                                     r.processName,
   26812                                     r.maxAdj,
   26813                                     memoryStat.pgfault,
   26814                                     memoryStat.pgmajfault,
   26815                                     memoryStat.rssInBytes,
   26816                                     memoryStat.cacheInBytes,
   26817                                     memoryStat.swapInBytes);
   26818                     processMemoryStates.add(processMemoryState);
   26819                 }
   26820             }
   26821             return processMemoryStates;
   26822         }
   26823 
   26824         @Override
   26825         public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
   26826             ActivityManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
   26827         }
   26828     }
   26829 
   26830     /**
   26831      * Called by app main thread to wait for the network policy rules to get updated.
   26832      *
   26833      * @param procStateSeq The sequence number indicating the process state change that the main
   26834      *                     thread is interested in.
   26835      */
   26836     @Override
   26837     public void waitForNetworkStateUpdate(long procStateSeq) {
   26838         final int callingUid = Binder.getCallingUid();
   26839         if (DEBUG_NETWORK) {
   26840             Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
   26841         }
   26842         UidRecord record;
   26843         synchronized (this) {
   26844             record = mActiveUids.get(callingUid);
   26845             if (record == null) {
   26846                 return;
   26847             }
   26848         }
   26849         synchronized (record.networkStateLock) {
   26850             if (record.lastDispatchedProcStateSeq < procStateSeq) {
   26851                 if (DEBUG_NETWORK) {
   26852                     Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
   26853                             + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
   26854                             + " lastProcStateSeqDispatchedToObservers: "
   26855                             + record.lastDispatchedProcStateSeq);
   26856                 }
   26857                 return;
   26858             }
   26859             if (record.curProcStateSeq > procStateSeq) {
   26860                 if (DEBUG_NETWORK) {
   26861                     Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
   26862                             + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
   26863                             + ", procStateSeq: " + procStateSeq);
   26864                 }
   26865                 return;
   26866             }
   26867             if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
   26868                 if (DEBUG_NETWORK) {
   26869                     Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
   26870                             + procStateSeq + ", so no need to wait. Uid: "
   26871                             + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
   26872                             + record.lastNetworkUpdatedProcStateSeq);
   26873                 }
   26874                 return;
   26875             }
   26876             try {
   26877                 if (DEBUG_NETWORK) {
   26878                     Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
   26879                         + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
   26880                 }
   26881                 final long startTime = SystemClock.uptimeMillis();
   26882                 record.waitingForNetwork = true;
   26883                 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
   26884                 record.waitingForNetwork = false;
   26885                 final long totalTime = SystemClock.uptimeMillis() - startTime;
   26886                 if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
   26887                     Slog.w(TAG_NETWORK, "Total time waited for network rules to get updated: "
   26888                             + totalTime + ". Uid: " + callingUid + " procStateSeq: "
   26889                             + procStateSeq + " UidRec: " + record
   26890                             + " validateUidRec: " + mValidateUids.get(callingUid));
   26891                 }
   26892             } catch (InterruptedException e) {
   26893                 Thread.currentThread().interrupt();
   26894             }
   26895         }
   26896     }
   26897 
   26898     public void waitForBroadcastIdle(PrintWriter pw) {
   26899         enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
   26900         while (true) {
   26901             boolean idle = true;
   26902             synchronized (this) {
   26903                 for (BroadcastQueue queue : mBroadcastQueues) {
   26904                     if (!queue.isIdle()) {
   26905                         final String msg = "Waiting for queue " + queue + " to become idle...";
   26906                         pw.println(msg);
   26907                         pw.flush();
   26908                         Slog.v(TAG, msg);
   26909                         idle = false;
   26910                     }
   26911                 }
   26912             }
   26913 
   26914             if (idle) {
   26915                 final String msg = "All broadcast queues are idle!";
   26916                 pw.println(msg);
   26917                 pw.flush();
   26918                 Slog.v(TAG, msg);
   26919                 return;
   26920             } else {
   26921                 SystemClock.sleep(1000);
   26922             }
   26923         }
   26924     }
   26925 
   26926     /**
   26927      * Return the user id of the last resumed activity.
   26928      */
   26929     @Override
   26930     public @UserIdInt int getLastResumedActivityUserId() {
   26931         enforceCallingPermission(
   26932                 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
   26933         synchronized (this) {
   26934             if (mLastResumedActivity == null) {
   26935                 return mUserController.getCurrentUserId();
   26936             }
   26937             return mLastResumedActivity.userId;
   26938         }
   26939     }
   26940 
   26941     /**
   26942      * Kill processes for the user with id userId and that depend on the package named packageName
   26943      */
   26944     @Override
   26945     public void killPackageDependents(String packageName, int userId) {
   26946         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
   26947         if (packageName == null) {
   26948             throw new NullPointerException(
   26949                     "Cannot kill the dependents of a package without its name.");
   26950         }
   26951 
   26952         long callingId = Binder.clearCallingIdentity();
   26953         IPackageManager pm = AppGlobals.getPackageManager();
   26954         int pkgUid = -1;
   26955         try {
   26956             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
   26957         } catch (RemoteException e) {
   26958         }
   26959         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
   26960             throw new IllegalArgumentException(
   26961                     "Cannot kill dependents of non-existing package " + packageName);
   26962         }
   26963         try {
   26964             synchronized(this) {
   26965                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
   26966                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
   26967                         "dep: " + packageName);
   26968             }
   26969         } finally {
   26970             Binder.restoreCallingIdentity(callingId);
   26971         }
   26972     }
   26973 
   26974     @Override
   26975     public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
   26976             CharSequence message) throws RemoteException {
   26977         if (message != null) {
   26978             enforceCallingPermission(permission.SHOW_KEYGUARD_MESSAGE,
   26979                     "dismissKeyguard()");
   26980         }
   26981         final long callingId = Binder.clearCallingIdentity();
   26982         try {
   26983             mKeyguardController.dismissKeyguard(token, callback, message);
   26984         } finally {
   26985             Binder.restoreCallingIdentity(callingId);
   26986         }
   26987     }
   26988 
   26989     @Override
   26990     public int restartUserInBackground(final int userId) {
   26991         return mUserController.restartUser(userId, /* foreground */ false);
   26992     }
   26993 
   26994     @Override
   26995     public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
   26996         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   26997                 "scheduleApplicationInfoChanged()");
   26998 
   26999         synchronized (this) {
   27000             final long origId = Binder.clearCallingIdentity();
   27001             try {
   27002                 updateApplicationInfoLocked(packageNames, userId);
   27003             } finally {
   27004                 Binder.restoreCallingIdentity(origId);
   27005             }
   27006         }
   27007     }
   27008 
   27009     void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
   27010         final boolean updateFrameworkRes = packagesToUpdate.contains("android");
   27011         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   27012             final ProcessRecord app = mLruProcesses.get(i);
   27013             if (app.thread == null) {
   27014                 continue;
   27015             }
   27016 
   27017             if (userId != UserHandle.USER_ALL && app.userId != userId) {
   27018                 continue;
   27019             }
   27020 
   27021             final int packageCount = app.pkgList.size();
   27022             for (int j = 0; j < packageCount; j++) {
   27023                 final String packageName = app.pkgList.keyAt(j);
   27024                 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
   27025                     try {
   27026                         final ApplicationInfo ai = AppGlobals.getPackageManager()
   27027                                 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
   27028                         if (ai != null) {
   27029                             app.thread.scheduleApplicationInfoChanged(ai);
   27030                         }
   27031                     } catch (RemoteException e) {
   27032                         Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
   27033                                     packageName, app));
   27034                     }
   27035                 }
   27036             }
   27037         }
   27038         if (updateFrameworkRes) {
   27039             // Update system server components that need to know about changed overlays. Because the
   27040             // overlay is applied in ActivityThread, we need to serialize through its thread too.
   27041             final Executor executor = ActivityThread.currentActivityThread().getExecutor();
   27042             final DisplayManagerInternal display =
   27043                     LocalServices.getService(DisplayManagerInternal.class);
   27044             if (display != null) {
   27045                 executor.execute(display::onOverlayChanged);
   27046             }
   27047             if (mWindowManager != null) {
   27048                 executor.execute(mWindowManager::onOverlayChanged);
   27049             }
   27050         }
   27051     }
   27052 
   27053     /**
   27054      * Attach an agent to the specified process (proces name or PID)
   27055      */
   27056     public void attachAgent(String process, String path) {
   27057         try {
   27058             synchronized (this) {
   27059                 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
   27060                 if (proc == null || proc.thread == null) {
   27061                     throw new IllegalArgumentException("Unknown process: " + process);
   27062                 }
   27063 
   27064                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   27065                 if (!isDebuggable) {
   27066                     if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   27067                         throw new SecurityException("Process not debuggable: " + proc);
   27068                     }
   27069                 }
   27070 
   27071                 proc.thread.attachAgent(path);
   27072             }
   27073         } catch (RemoteException e) {
   27074             throw new IllegalStateException("Process disappeared");
   27075         }
   27076     }
   27077 
   27078     @VisibleForTesting
   27079     public static class Injector {
   27080         private NetworkManagementInternal mNmi;
   27081 
   27082         public Context getContext() {
   27083             return null;
   27084         }
   27085 
   27086         public AppOpsService getAppOpsService(File file, Handler handler) {
   27087             return new AppOpsService(file, handler);
   27088         }
   27089 
   27090         public Handler getUiHandler(ActivityManagerService service) {
   27091             return service.new UiHandler();
   27092         }
   27093 
   27094         public boolean isNetworkRestrictedForUid(int uid) {
   27095             if (ensureHasNetworkManagementInternal()) {
   27096                 return mNmi.isNetworkRestrictedForUid(uid);
   27097             }
   27098             return false;
   27099         }
   27100 
   27101         private boolean ensureHasNetworkManagementInternal() {
   27102             if (mNmi == null) {
   27103                 mNmi = LocalServices.getService(NetworkManagementInternal.class);
   27104             }
   27105             return mNmi != null;
   27106         }
   27107     }
   27108 
   27109     @Override
   27110     public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
   27111             throws RemoteException {
   27112         synchronized (this) {
   27113             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   27114             if (r == null) {
   27115                 return;
   27116             }
   27117             final long origId = Binder.clearCallingIdentity();
   27118             try {
   27119                 r.setShowWhenLocked(showWhenLocked);
   27120             } finally {
   27121                 Binder.restoreCallingIdentity(origId);
   27122             }
   27123         }
   27124     }
   27125 
   27126     @Override
   27127     public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
   27128         synchronized (this) {
   27129             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   27130             if (r == null) {
   27131                 return;
   27132             }
   27133             final long origId = Binder.clearCallingIdentity();
   27134             try {
   27135                 r.setTurnScreenOn(turnScreenOn);
   27136             } finally {
   27137                 Binder.restoreCallingIdentity(origId);
   27138             }
   27139         }
   27140     }
   27141 
   27142     @Override
   27143     public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition)
   27144             throws RemoteException {
   27145         enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
   27146                 "registerRemoteAnimations");
   27147         definition.setCallingPid(Binder.getCallingPid());
   27148         synchronized (this) {
   27149             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   27150             if (r == null) {
   27151                 return;
   27152             }
   27153             final long origId = Binder.clearCallingIdentity();
   27154             try {
   27155                 r.registerRemoteAnimations(definition);
   27156             } finally {
   27157                 Binder.restoreCallingIdentity(origId);
   27158             }
   27159         }
   27160     }
   27161 
   27162     @Override
   27163     public void registerRemoteAnimationForNextActivityStart(String packageName,
   27164             RemoteAnimationAdapter adapter) throws RemoteException {
   27165         enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
   27166                 "registerRemoteAnimationForNextActivityStart");
   27167         adapter.setCallingPid(Binder.getCallingPid());
   27168         synchronized (this) {
   27169             final long origId = Binder.clearCallingIdentity();
   27170             try {
   27171                 mActivityStartController.registerRemoteAnimationForNextActivityStart(packageName,
   27172                         adapter);
   27173             } finally {
   27174                 Binder.restoreCallingIdentity(origId);
   27175             }
   27176         }
   27177     }
   27178 
   27179     /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
   27180     @Override
   27181     public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
   27182         synchronized (this) {
   27183             final long origId = Binder.clearCallingIdentity();
   27184             try {
   27185                 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
   27186             } finally {
   27187                 Binder.restoreCallingIdentity(origId);
   27188             }
   27189         }
   27190     }
   27191 }
   27192