• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.content.pm.PackageManager.PERMISSION_GRANTED;
20 
21 import android.app.AppOpsManager;
22 import android.appwidget.AppWidgetManager;
23 import com.android.internal.R;
24 import com.android.internal.os.BatteryStatsImpl;
25 import com.android.internal.os.ProcessStats;
26 import com.android.server.AppOpsService;
27 import com.android.server.AttributeCache;
28 import com.android.server.IntentResolver;
29 import com.android.server.ProcessMap;
30 import com.android.server.SystemServer;
31 import com.android.server.Watchdog;
32 import com.android.server.am.ActivityStack.ActivityState;
33 import com.android.server.firewall.IntentFirewall;
34 import com.android.server.pm.UserManagerService;
35 import com.android.server.wm.AppTransition;
36 import com.android.server.wm.WindowManagerService;
37 
38 import dalvik.system.Zygote;
39 
40 import android.app.Activity;
41 import android.app.ActivityManager;
42 import android.app.ActivityManagerNative;
43 import android.app.ActivityOptions;
44 import android.app.ActivityThread;
45 import android.app.AlertDialog;
46 import android.app.AppGlobals;
47 import android.app.ApplicationErrorReport;
48 import android.app.Dialog;
49 import android.app.IActivityController;
50 import android.app.IApplicationThread;
51 import android.app.IInstrumentationWatcher;
52 import android.app.INotificationManager;
53 import android.app.IProcessObserver;
54 import android.app.IServiceConnection;
55 import android.app.IStopUserCallback;
56 import android.app.IThumbnailReceiver;
57 import android.app.IUiAutomationConnection;
58 import android.app.IUserSwitchObserver;
59 import android.app.Instrumentation;
60 import android.app.Notification;
61 import android.app.NotificationManager;
62 import android.app.PendingIntent;
63 import android.app.backup.IBackupManager;
64 import android.content.ActivityNotFoundException;
65 import android.content.BroadcastReceiver;
66 import android.content.ClipData;
67 import android.content.ComponentCallbacks2;
68 import android.content.ComponentName;
69 import android.content.ContentProvider;
70 import android.content.ContentResolver;
71 import android.content.Context;
72 import android.content.DialogInterface;
73 import android.content.IContentProvider;
74 import android.content.IIntentReceiver;
75 import android.content.IIntentSender;
76 import android.content.Intent;
77 import android.content.IntentFilter;
78 import android.content.IntentSender;
79 import android.content.pm.ActivityInfo;
80 import android.content.pm.ApplicationInfo;
81 import android.content.pm.ConfigurationInfo;
82 import android.content.pm.IPackageDataObserver;
83 import android.content.pm.IPackageManager;
84 import android.content.pm.InstrumentationInfo;
85 import android.content.pm.PackageInfo;
86 import android.content.pm.PackageManager;
87 import android.content.pm.UserInfo;
88 import android.content.pm.PackageManager.NameNotFoundException;
89 import android.content.pm.PathPermission;
90 import android.content.pm.ProviderInfo;
91 import android.content.pm.ResolveInfo;
92 import android.content.pm.ServiceInfo;
93 import android.content.res.CompatibilityInfo;
94 import android.content.res.Configuration;
95 import android.graphics.Bitmap;
96 import android.net.Proxy;
97 import android.net.ProxyProperties;
98 import android.net.Uri;
99 import android.os.Binder;
100 import android.os.Build;
101 import android.os.Bundle;
102 import android.os.Debug;
103 import android.os.DropBoxManager;
104 import android.os.Environment;
105 import android.os.FileObserver;
106 import android.os.FileUtils;
107 import android.os.Handler;
108 import android.os.IBinder;
109 import android.os.IPermissionController;
110 import android.os.IRemoteCallback;
111 import android.os.IUserManager;
112 import android.os.Looper;
113 import android.os.Message;
114 import android.os.Parcel;
115 import android.os.ParcelFileDescriptor;
116 import android.os.Process;
117 import android.os.RemoteCallbackList;
118 import android.os.RemoteException;
119 import android.os.SELinux;
120 import android.os.ServiceManager;
121 import android.os.StrictMode;
122 import android.os.SystemClock;
123 import android.os.SystemProperties;
124 import android.os.UpdateLock;
125 import android.os.UserHandle;
126 import android.provider.Settings;
127 import android.text.format.Time;
128 import android.util.EventLog;
129 import android.util.Log;
130 import android.util.Pair;
131 import android.util.PrintWriterPrinter;
132 import android.util.Slog;
133 import android.util.SparseArray;
134 import android.util.TimeUtils;
135 import android.view.Gravity;
136 import android.view.LayoutInflater;
137 import android.view.View;
138 import android.view.WindowManager;
139 
140 import java.io.BufferedInputStream;
141 import java.io.BufferedOutputStream;
142 import java.io.BufferedReader;
143 import java.io.DataInputStream;
144 import java.io.DataOutputStream;
145 import java.io.File;
146 import java.io.FileDescriptor;
147 import java.io.FileInputStream;
148 import java.io.FileNotFoundException;
149 import java.io.FileOutputStream;
150 import java.io.IOException;
151 import java.io.InputStreamReader;
152 import java.io.PrintWriter;
153 import java.io.StringWriter;
154 import java.lang.ref.WeakReference;
155 import java.util.ArrayList;
156 import java.util.Arrays;
157 import java.util.Collections;
158 import java.util.Comparator;
159 import java.util.HashMap;
160 import java.util.HashSet;
161 import java.util.Iterator;
162 import java.util.List;
163 import java.util.Locale;
164 import java.util.Map;
165 import java.util.Set;
166 import java.util.concurrent.atomic.AtomicBoolean;
167 import java.util.concurrent.atomic.AtomicLong;
168 
169 public final class ActivityManagerService  extends ActivityManagerNative
170         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
171     private static final String USER_DATA_DIR = "/data/user/";
172     static final String TAG = "ActivityManager";
173     static final String TAG_MU = "ActivityManagerServiceMU";
174     static final boolean DEBUG = false;
175     static final boolean localLOGV = DEBUG;
176     static final boolean DEBUG_SWITCH = localLOGV || false;
177     static final boolean DEBUG_TASKS = localLOGV || false;
178     static final boolean DEBUG_THUMBNAILS = localLOGV || false;
179     static final boolean DEBUG_PAUSE = localLOGV || false;
180     static final boolean DEBUG_OOM_ADJ = localLOGV || false;
181     static final boolean DEBUG_TRANSITION = localLOGV || false;
182     static final boolean DEBUG_BROADCAST = localLOGV || false;
183     static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
184     static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
185     static final boolean DEBUG_SERVICE = localLOGV || false;
186     static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
187     static final boolean DEBUG_VISBILITY = localLOGV || false;
188     static final boolean DEBUG_PROCESSES = localLOGV || false;
189     static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
190     static final boolean DEBUG_CLEANUP = localLOGV || false;
191     static final boolean DEBUG_PROVIDER = localLOGV || false;
192     static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
193     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
194     static final boolean DEBUG_RESULTS = localLOGV || false;
195     static final boolean DEBUG_BACKUP = localLOGV || false;
196     static final boolean DEBUG_CONFIGURATION = localLOGV || false;
197     static final boolean DEBUG_POWER = localLOGV || false;
198     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
199     static final boolean DEBUG_MU = localLOGV || false;
200     static final boolean DEBUG_IMMERSIVE = localLOGV || false;
201     static final boolean VALIDATE_TOKENS = false;
202     static final boolean SHOW_ACTIVITY_START_TIME = true;
203 
204     // Control over CPU and battery monitoring.
205     static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
206     static final boolean MONITOR_CPU_USAGE = true;
207     static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
208     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
209     static final boolean MONITOR_THREAD_CPU_USAGE = false;
210 
211     // The flags that are set for all calls we make to the package manager.
212     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
213 
214     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
215 
216     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
217 
218     // Maximum number of recent tasks that we can remember.
219     static final int MAX_RECENT_TASKS = 20;
220 
221     // Amount of time after a call to stopAppSwitches() during which we will
222     // prevent further untrusted switches from happening.
223     static final long APP_SWITCH_DELAY_TIME = 5*1000;
224 
225     // How long we wait for a launched process to attach to the activity manager
226     // before we decide it's never going to come up for real.
227     static final int PROC_START_TIMEOUT = 10*1000;
228 
229     // How long we wait for a launched process to attach to the activity manager
230     // before we decide it's never going to come up for real, when the process was
231     // started with a wrapper for instrumentation (such as Valgrind) because it
232     // could take much longer than usual.
233     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
234 
235     // How long to wait after going idle before forcing apps to GC.
236     static final int GC_TIMEOUT = 5*1000;
237 
238     // The minimum amount of time between successive GC requests for a process.
239     static final int GC_MIN_INTERVAL = 60*1000;
240 
241     // The rate at which we check for apps using excessive power -- 15 mins.
242     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
243 
244     // The minimum sample duration we will allow before deciding we have
245     // enough data on wake locks to start killing things.
246     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
247 
248     // The minimum sample duration we will allow before deciding we have
249     // enough data on CPU usage to start killing things.
250     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
251 
252     // How long we allow a receiver to run before giving up on it.
253     static final int BROADCAST_FG_TIMEOUT = 10*1000;
254     static final int BROADCAST_BG_TIMEOUT = 60*1000;
255 
256     // How long we wait until we timeout on key dispatching.
257     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
258 
259     // How long we wait until we timeout on key dispatching during instrumentation.
260     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
261 
262     // Amount of time we wait for observers to handle a user switch before
263     // giving up on them and unfreezing the screen.
264     static final int USER_SWITCH_TIMEOUT = 2*1000;
265 
266     // Maximum number of users we allow to be running at a time.
267     static final int MAX_RUNNING_USERS = 3;
268 
269     // How long to wait in getTopActivityExtras for the activity to respond with the result.
270     static final int PENDING_ACTIVITY_RESULT_TIMEOUT = 2*2000;
271 
272     static final int MY_PID = Process.myPid();
273 
274     static final String[] EMPTY_STRING_ARRAY = new String[0];
275 
276     public ActivityStack mMainStack;
277 
278     public IntentFirewall mIntentFirewall;
279 
280     private final boolean mHeadless;
281 
282     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
283     // default actuion automatically.  Important for devices without direct input
284     // devices.
285     private boolean mShowDialogs = true;
286 
287     /**
288      * Description of a request to start a new activity, which has been held
289      * due to app switches being disabled.
290      */
291     static class PendingActivityLaunch {
292         ActivityRecord r;
293         ActivityRecord sourceRecord;
294         int startFlags;
295     }
296 
297     final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
298             = new ArrayList<PendingActivityLaunch>();
299 
300 
301     BroadcastQueue mFgBroadcastQueue;
302     BroadcastQueue mBgBroadcastQueue;
303     // Convenient for easy iteration over the queues. Foreground is first
304     // so that dispatch of foreground broadcasts gets precedence.
305     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
306 
broadcastQueueForIntent(Intent intent)307     BroadcastQueue broadcastQueueForIntent(Intent intent) {
308         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
309         if (DEBUG_BACKGROUND_BROADCAST) {
310             Slog.i(TAG, "Broadcast intent " + intent + " on "
311                     + (isFg ? "foreground" : "background")
312                     + " queue");
313         }
314         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
315     }
316 
broadcastRecordForReceiverLocked(IBinder receiver)317     BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
318         for (BroadcastQueue queue : mBroadcastQueues) {
319             BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
320             if (r != null) {
321                 return r;
322             }
323         }
324         return null;
325     }
326 
327     /**
328      * Activity we have told the window manager to have key focus.
329      */
330     ActivityRecord mFocusedActivity = null;
331 
332     /**
333      * List of intents that were used to start the most recent tasks.
334      */
335     final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
336 
337     public class PendingActivityExtras extends Binder implements Runnable {
338         public final ActivityRecord activity;
339         public boolean haveResult = false;
340         public Bundle result = null;
PendingActivityExtras(ActivityRecord _activity)341         public PendingActivityExtras(ActivityRecord _activity) {
342             activity = _activity;
343         }
344         @Override
run()345         public void run() {
346             Slog.w(TAG, "getTopActivityExtras failed: timeout retrieving from " + activity);
347             synchronized (this) {
348                 haveResult = true;
349                 notifyAll();
350             }
351         }
352     }
353 
354     final ArrayList<PendingActivityExtras> mPendingActivityExtras
355             = new ArrayList<PendingActivityExtras>();
356 
357     /**
358      * Process management.
359      */
360     final ProcessList mProcessList = new ProcessList();
361 
362     /**
363      * All of the applications we currently have running organized by name.
364      * The keys are strings of the application package name (as
365      * returned by the package manager), and the keys are ApplicationRecord
366      * objects.
367      */
368     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
369 
370     /**
371      * The currently running isolated processes.
372      */
373     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
374 
375     /**
376      * Counter for assigning isolated process uids, to avoid frequently reusing the
377      * same ones.
378      */
379     int mNextIsolatedProcessUid = 0;
380 
381     /**
382      * The currently running heavy-weight process, if any.
383      */
384     ProcessRecord mHeavyWeightProcess = null;
385 
386     /**
387      * The last time that various processes have crashed.
388      */
389     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
390 
391     /**
392      * Set of applications that we consider to be bad, and will reject
393      * incoming broadcasts from (which the user has no control over).
394      * Processes are added to this set when they have crashed twice within
395      * a minimum amount of time; they are removed from it when they are
396      * later restarted (hopefully due to some user action).  The value is the
397      * time it was added to the list.
398      */
399     final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
400 
401     /**
402      * All of the processes we currently have running organized by pid.
403      * The keys are the pid running the application.
404      *
405      * <p>NOTE: This object is protected by its own lock, NOT the global
406      * activity manager lock!
407      */
408     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
409 
410     /**
411      * All of the processes that have been forced to be foreground.  The key
412      * is the pid of the caller who requested it (we hold a death
413      * link on it).
414      */
415     abstract class ForegroundToken implements IBinder.DeathRecipient {
416         int pid;
417         IBinder token;
418     }
419     final SparseArray<ForegroundToken> mForegroundProcesses
420             = new SparseArray<ForegroundToken>();
421 
422     /**
423      * List of records for processes that someone had tried to start before the
424      * system was ready.  We don't start them at that point, but ensure they
425      * are started by the time booting is complete.
426      */
427     final ArrayList<ProcessRecord> mProcessesOnHold
428             = new ArrayList<ProcessRecord>();
429 
430     /**
431      * List of persistent applications that are in the process
432      * of being started.
433      */
434     final ArrayList<ProcessRecord> mPersistentStartingProcesses
435             = new ArrayList<ProcessRecord>();
436 
437     /**
438      * Processes that are being forcibly torn down.
439      */
440     final ArrayList<ProcessRecord> mRemovedProcesses
441             = new ArrayList<ProcessRecord>();
442 
443     /**
444      * List of running applications, sorted by recent usage.
445      * The first entry in the list is the least recently used.
446      * It contains ApplicationRecord objects.  This list does NOT include
447      * any persistent application records (since we never want to exit them).
448      */
449     final ArrayList<ProcessRecord> mLruProcesses
450             = new ArrayList<ProcessRecord>();
451 
452     /**
453      * List of processes that should gc as soon as things are idle.
454      */
455     final ArrayList<ProcessRecord> mProcessesToGc
456             = new ArrayList<ProcessRecord>();
457 
458     /**
459      * This is the process holding what we currently consider to be
460      * the "home" activity.
461      */
462     ProcessRecord mHomeProcess;
463 
464     /**
465      * This is the process holding the activity the user last visited that
466      * is in a different process from the one they are currently in.
467      */
468     ProcessRecord mPreviousProcess;
469 
470     /**
471      * The time at which the previous process was last visible.
472      */
473     long mPreviousProcessVisibleTime;
474 
475     /**
476      * Which uses have been started, so are allowed to run code.
477      */
478     final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
479 
480     /**
481      * LRU list of history of current users.  Most recently current is at the end.
482      */
483     final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
484 
485     /**
486      * Constant array of the users that are currently started.
487      */
488     int[] mStartedUserArray = new int[] { 0 };
489 
490     /**
491      * Registered observers of the user switching mechanics.
492      */
493     final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
494             = new RemoteCallbackList<IUserSwitchObserver>();
495 
496     /**
497      * Currently active user switch.
498      */
499     Object mCurUserSwitchCallback;
500 
501     /**
502      * Packages that the user has asked to have run in screen size
503      * compatibility mode instead of filling the screen.
504      */
505     final CompatModePackages mCompatModePackages;
506 
507     /**
508      * Set of PendingResultRecord objects that are currently active.
509      */
510     final HashSet mPendingResultRecords = new HashSet();
511 
512     /**
513      * Set of IntentSenderRecord objects that are currently active.
514      */
515     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
516             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
517 
518     /**
519      * Fingerprints (hashCode()) of stack traces that we've
520      * already logged DropBox entries for.  Guarded by itself.  If
521      * something (rogue user app) forces this over
522      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
523      */
524     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
525     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
526 
527     /**
528      * Strict Mode background batched logging state.
529      *
530      * The string buffer is guarded by itself, and its lock is also
531      * used to determine if another batched write is already
532      * in-flight.
533      */
534     private final StringBuilder mStrictModeBuffer = new StringBuilder();
535 
536     /**
537      * Keeps track of all IIntentReceivers that have been registered for
538      * broadcasts.  Hash keys are the receiver IBinder, hash value is
539      * a ReceiverList.
540      */
541     final HashMap mRegisteredReceivers = new HashMap();
542 
543     /**
544      * Resolver for broadcast intents to registered receivers.
545      * Holds BroadcastFilter (subclass of IntentFilter).
546      */
547     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
548             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
549         @Override
550         protected boolean allowFilterResult(
551                 BroadcastFilter filter, List<BroadcastFilter> dest) {
552             IBinder target = filter.receiverList.receiver.asBinder();
553             for (int i=dest.size()-1; i>=0; i--) {
554                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
555                     return false;
556                 }
557             }
558             return true;
559         }
560 
561         @Override
562         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
563             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
564                     || userId == filter.owningUserId) {
565                 return super.newResult(filter, match, userId);
566             }
567             return null;
568         }
569 
570         @Override
571         protected BroadcastFilter[] newArray(int size) {
572             return new BroadcastFilter[size];
573         }
574 
575         @Override
576         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
577             return packageName.equals(filter.packageName);
578         }
579     };
580 
581     /**
582      * State of all active sticky broadcasts per user.  Keys are the action of the
583      * sticky Intent, values are an ArrayList of all broadcasted intents with
584      * that action (which should usually be one).  The SparseArray is keyed
585      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
586      * for stickies that are sent to all users.
587      */
588     final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
589             new SparseArray<HashMap<String, ArrayList<Intent>>>();
590 
591     final ActiveServices mServices;
592 
593     /**
594      * Backup/restore process management
595      */
596     String mBackupAppName = null;
597     BackupRecord mBackupTarget = null;
598 
599     /**
600      * List of PendingThumbnailsRecord objects of clients who are still
601      * waiting to receive all of the thumbnails for a task.
602      */
603     final ArrayList mPendingThumbnails = new ArrayList();
604 
605     /**
606      * List of HistoryRecord objects that have been finished and must
607      * still report back to a pending thumbnail receiver.
608      */
609     final ArrayList mCancelledThumbnails = new ArrayList();
610 
611     final ProviderMap mProviderMap;
612 
613     /**
614      * List of content providers who have clients waiting for them.  The
615      * application is currently being launched and the provider will be
616      * removed from this list once it is published.
617      */
618     final ArrayList<ContentProviderRecord> mLaunchingProviders
619             = new ArrayList<ContentProviderRecord>();
620 
621     /**
622      * Global set of specific Uri permissions that have been granted.
623      */
624     final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
625             = new SparseArray<HashMap<Uri, UriPermission>>();
626 
627     CoreSettingsObserver mCoreSettingsObserver;
628 
629     /**
630      * Thread-local storage used to carry caller permissions over through
631      * indirect content-provider access.
632      */
633     private class Identity {
634         public int pid;
635         public int uid;
636 
Identity(int _pid, int _uid)637         Identity(int _pid, int _uid) {
638             pid = _pid;
639             uid = _uid;
640         }
641     }
642 
643     private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
644 
645     /**
646      * All information we have collected about the runtime performance of
647      * any user id that can impact battery performance.
648      */
649     final BatteryStatsService mBatteryStatsService;
650 
651     /**
652      * Information about component usage
653      */
654     final UsageStatsService mUsageStatsService;
655 
656     /**
657      * Information about and control over application operations
658      */
659     final AppOpsService mAppOpsService;
660 
661     /**
662      * Current configuration information.  HistoryRecord objects are given
663      * a reference to this object to indicate which configuration they are
664      * currently running in, so this object must be kept immutable.
665      */
666     Configuration mConfiguration = new Configuration();
667 
668     /**
669      * Current sequencing integer of the configuration, for skipping old
670      * configurations.
671      */
672     int mConfigurationSeq = 0;
673 
674     /**
675      * Hardware-reported OpenGLES version.
676      */
677     final int GL_ES_VERSION;
678 
679     /**
680      * List of initialization arguments to pass to all processes when binding applications to them.
681      * For example, references to the commonly used services.
682      */
683     HashMap<String, IBinder> mAppBindArgs;
684 
685     /**
686      * Temporary to avoid allocations.  Protected by main lock.
687      */
688     final StringBuilder mStringBuilder = new StringBuilder(256);
689 
690     /**
691      * Used to control how we initialize the service.
692      */
693     boolean mStartRunning = false;
694     ComponentName mTopComponent;
695     String mTopAction;
696     String mTopData;
697     boolean mProcessesReady = false;
698     boolean mSystemReady = false;
699     boolean mBooting = false;
700     boolean mWaitingUpdate = false;
701     boolean mDidUpdate = false;
702     boolean mOnBattery = false;
703     boolean mLaunchWarningShown = false;
704 
705     Context mContext;
706 
707     int mFactoryTest;
708 
709     boolean mCheckedForSetup;
710 
711     /**
712      * The time at which we will allow normal application switches again,
713      * after a call to {@link #stopAppSwitches()}.
714      */
715     long mAppSwitchesAllowedTime;
716 
717     /**
718      * This is set to true after the first switch after mAppSwitchesAllowedTime
719      * is set; any switches after that will clear the time.
720      */
721     boolean mDidAppSwitch;
722 
723     /**
724      * Last time (in realtime) at which we checked for power usage.
725      */
726     long mLastPowerCheckRealtime;
727 
728     /**
729      * Last time (in uptime) at which we checked for power usage.
730      */
731     long mLastPowerCheckUptime;
732 
733     /**
734      * Set while we are wanting to sleep, to prevent any
735      * activities from being started/resumed.
736      */
737     boolean mSleeping = false;
738 
739     /**
740      * State of external calls telling us if the device is asleep.
741      */
742     boolean mWentToSleep = false;
743 
744     /**
745      * State of external call telling us if the lock screen is shown.
746      */
747     boolean mLockScreenShown = false;
748 
749     /**
750      * Set if we are shutting down the system, similar to sleeping.
751      */
752     boolean mShuttingDown = false;
753 
754     /**
755      * Task identifier that activities are currently being started
756      * in.  Incremented each time a new task is created.
757      * todo: Replace this with a TokenSpace class that generates non-repeating
758      * integers that won't wrap.
759      */
760     int mCurTask = 1;
761 
762     /**
763      * Current sequence id for oom_adj computation traversal.
764      */
765     int mAdjSeq = 0;
766 
767     /**
768      * Current sequence id for process LRU updating.
769      */
770     int mLruSeq = 0;
771 
772     /**
773      * Keep track of the non-hidden/empty process we last found, to help
774      * determine how to distribute hidden/empty processes next time.
775      */
776     int mNumNonHiddenProcs = 0;
777 
778     /**
779      * Keep track of the number of hidden procs, to balance oom adj
780      * distribution between those and empty procs.
781      */
782     int mNumHiddenProcs = 0;
783 
784     /**
785      * Keep track of the number of service processes we last found, to
786      * determine on the next iteration which should be B services.
787      */
788     int mNumServiceProcs = 0;
789     int mNewNumServiceProcs = 0;
790 
791     /**
792      * System monitoring: number of processes that died since the last
793      * N procs were started.
794      */
795     int[] mProcDeaths = new int[20];
796 
797     /**
798      * This is set if we had to do a delayed dexopt of an app before launching
799      * it, to increasing the ANR timeouts in that case.
800      */
801     boolean mDidDexOpt;
802 
803     String mDebugApp = null;
804     boolean mWaitForDebugger = false;
805     boolean mDebugTransient = false;
806     String mOrigDebugApp = null;
807     boolean mOrigWaitForDebugger = false;
808     boolean mAlwaysFinishActivities = false;
809     IActivityController mController = null;
810     String mProfileApp = null;
811     ProcessRecord mProfileProc = null;
812     String mProfileFile;
813     ParcelFileDescriptor mProfileFd;
814     int mProfileType = 0;
815     boolean mAutoStopProfiler = false;
816     String mOpenGlTraceApp = null;
817 
818     static class ProcessChangeItem {
819         static final int CHANGE_ACTIVITIES = 1<<0;
820         static final int CHANGE_IMPORTANCE= 1<<1;
821         int changes;
822         int uid;
823         int pid;
824         int importance;
825         boolean foregroundActivities;
826     }
827 
828     final RemoteCallbackList<IProcessObserver> mProcessObservers
829             = new RemoteCallbackList<IProcessObserver>();
830     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
831 
832     final ArrayList<ProcessChangeItem> mPendingProcessChanges
833             = new ArrayList<ProcessChangeItem>();
834     final ArrayList<ProcessChangeItem> mAvailProcessChanges
835             = new ArrayList<ProcessChangeItem>();
836 
837     /**
838      * Runtime statistics collection thread.  This object's lock is used to
839      * protect all related state.
840      */
841     final Thread mProcessStatsThread;
842 
843     /**
844      * Used to collect process stats when showing not responding dialog.
845      * Protected by mProcessStatsThread.
846      */
847     final ProcessStats mProcessStats = new ProcessStats(
848             MONITOR_THREAD_CPU_USAGE);
849     final AtomicLong mLastCpuTime = new AtomicLong(0);
850     final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
851 
852     long mLastWriteTime = 0;
853 
854     /**
855      * Used to retain an update lock when the foreground activity is in
856      * immersive mode.
857      */
858     final UpdateLock mUpdateLock = new UpdateLock("immersive");
859 
860     /**
861      * Set to true after the system has finished booting.
862      */
863     boolean mBooted = false;
864 
865     int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
866     int mProcessLimitOverride = -1;
867 
868     WindowManagerService mWindowManager;
869 
870     static ActivityManagerService mSelf;
871     static ActivityThread mSystemThread;
872 
873     private int mCurrentUserId = 0;
874     private int[] mCurrentUserArray = new int[] { 0 };
875     private UserManagerService mUserManager;
876 
877     private final class AppDeathRecipient implements IBinder.DeathRecipient {
878         final ProcessRecord mApp;
879         final int mPid;
880         final IApplicationThread mAppThread;
881 
AppDeathRecipient(ProcessRecord app, int pid, IApplicationThread thread)882         AppDeathRecipient(ProcessRecord app, int pid,
883                 IApplicationThread thread) {
884             if (localLOGV) Slog.v(
885                 TAG, "New death recipient " + this
886                 + " for thread " + thread.asBinder());
887             mApp = app;
888             mPid = pid;
889             mAppThread = thread;
890         }
891 
binderDied()892         public void binderDied() {
893             if (localLOGV) Slog.v(
894                 TAG, "Death received in " + this
895                 + " for thread " + mAppThread.asBinder());
896             synchronized(ActivityManagerService.this) {
897                 appDiedLocked(mApp, mPid, mAppThread);
898             }
899         }
900     }
901 
902     static final int SHOW_ERROR_MSG = 1;
903     static final int SHOW_NOT_RESPONDING_MSG = 2;
904     static final int SHOW_FACTORY_ERROR_MSG = 3;
905     static final int UPDATE_CONFIGURATION_MSG = 4;
906     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
907     static final int WAIT_FOR_DEBUGGER_MSG = 6;
908     static final int SERVICE_TIMEOUT_MSG = 12;
909     static final int UPDATE_TIME_ZONE = 13;
910     static final int SHOW_UID_ERROR_MSG = 14;
911     static final int IM_FEELING_LUCKY_MSG = 15;
912     static final int PROC_START_TIMEOUT_MSG = 20;
913     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
914     static final int KILL_APPLICATION_MSG = 22;
915     static final int FINALIZE_PENDING_INTENT_MSG = 23;
916     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
917     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
918     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
919     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
920     static final int CLEAR_DNS_CACHE = 28;
921     static final int UPDATE_HTTP_PROXY = 29;
922     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
923     static final int DISPATCH_PROCESSES_CHANGED = 31;
924     static final int DISPATCH_PROCESS_DIED = 32;
925     static final int REPORT_MEM_USAGE = 33;
926     static final int REPORT_USER_SWITCH_MSG = 34;
927     static final int CONTINUE_USER_SWITCH_MSG = 35;
928     static final int USER_SWITCH_TIMEOUT_MSG = 36;
929     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
930 
931     static final int FIRST_ACTIVITY_STACK_MSG = 100;
932     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
933     static final int FIRST_COMPAT_MODE_MSG = 300;
934 
935     AlertDialog mUidAlert;
936     CompatModeDialog mCompatModeDialog;
937     long mLastMemUsageReportTime = 0;
938 
939     /**
940      * Flag whether the current user is a "monkey", i.e. whether
941      * the UI is driven by a UI automation tool.
942      */
943     private boolean mUserIsMonkey;
944 
945     final Handler mHandler = new Handler() {
946         //public Handler() {
947         //    if (localLOGV) Slog.v(TAG, "Handler started!");
948         //}
949 
950         public void handleMessage(Message msg) {
951             switch (msg.what) {
952             case SHOW_ERROR_MSG: {
953                 HashMap data = (HashMap) msg.obj;
954                 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
955                         Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
956                 synchronized (ActivityManagerService.this) {
957                     ProcessRecord proc = (ProcessRecord)data.get("app");
958                     AppErrorResult res = (AppErrorResult) data.get("result");
959                     if (proc != null && proc.crashDialog != null) {
960                         Slog.e(TAG, "App already has crash dialog: " + proc);
961                         if (res != null) {
962                             res.set(0);
963                         }
964                         return;
965                     }
966                     if (!showBackground && UserHandle.getAppId(proc.uid)
967                             >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
968                             && proc.pid != MY_PID) {
969                         Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
970                         if (res != null) {
971                             res.set(0);
972                         }
973                         return;
974                     }
975                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
976                         Dialog d = new AppErrorDialog(mContext,
977                                 ActivityManagerService.this, res, proc);
978                         d.show();
979                         proc.crashDialog = d;
980                     } else {
981                         // The device is asleep, so just pretend that the user
982                         // saw a crash dialog and hit "force quit".
983                         if (res != null) {
984                             res.set(0);
985                         }
986                     }
987                 }
988 
989                 ensureBootCompleted();
990             } break;
991             case SHOW_NOT_RESPONDING_MSG: {
992                 synchronized (ActivityManagerService.this) {
993                     HashMap data = (HashMap) msg.obj;
994                     ProcessRecord proc = (ProcessRecord)data.get("app");
995                     if (proc != null && proc.anrDialog != null) {
996                         Slog.e(TAG, "App already has anr dialog: " + proc);
997                         return;
998                     }
999 
1000                     Intent intent = new Intent("android.intent.action.ANR");
1001                     if (!mProcessesReady) {
1002                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1003                                 | Intent.FLAG_RECEIVER_FOREGROUND);
1004                     }
1005                     broadcastIntentLocked(null, null, intent,
1006                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1007                             false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1008 
1009                     if (mShowDialogs) {
1010                         Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1011                                 mContext, proc, (ActivityRecord)data.get("activity"),
1012                                 msg.arg1 != 0);
1013                         d.show();
1014                         proc.anrDialog = d;
1015                     } else {
1016                         // Just kill the app if there is no dialog to be shown.
1017                         killAppAtUsersRequest(proc, null);
1018                     }
1019                 }
1020 
1021                 ensureBootCompleted();
1022             } break;
1023             case SHOW_STRICT_MODE_VIOLATION_MSG: {
1024                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1025                 synchronized (ActivityManagerService.this) {
1026                     ProcessRecord proc = (ProcessRecord) data.get("app");
1027                     if (proc == null) {
1028                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1029                         break;
1030                     }
1031                     if (proc.crashDialog != null) {
1032                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1033                         return;
1034                     }
1035                     AppErrorResult res = (AppErrorResult) data.get("result");
1036                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1037                         Dialog d = new StrictModeViolationDialog(mContext,
1038                                 ActivityManagerService.this, res, proc);
1039                         d.show();
1040                         proc.crashDialog = d;
1041                     } else {
1042                         // The device is asleep, so just pretend that the user
1043                         // saw a crash dialog and hit "force quit".
1044                         res.set(0);
1045                     }
1046                 }
1047                 ensureBootCompleted();
1048             } break;
1049             case SHOW_FACTORY_ERROR_MSG: {
1050                 Dialog d = new FactoryErrorDialog(
1051                     mContext, msg.getData().getCharSequence("msg"));
1052                 d.show();
1053                 ensureBootCompleted();
1054             } break;
1055             case UPDATE_CONFIGURATION_MSG: {
1056                 final ContentResolver resolver = mContext.getContentResolver();
1057                 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1058             } break;
1059             case GC_BACKGROUND_PROCESSES_MSG: {
1060                 synchronized (ActivityManagerService.this) {
1061                     performAppGcsIfAppropriateLocked();
1062                 }
1063             } break;
1064             case WAIT_FOR_DEBUGGER_MSG: {
1065                 synchronized (ActivityManagerService.this) {
1066                     ProcessRecord app = (ProcessRecord)msg.obj;
1067                     if (msg.arg1 != 0) {
1068                         if (!app.waitedForDebugger) {
1069                             Dialog d = new AppWaitingForDebuggerDialog(
1070                                     ActivityManagerService.this,
1071                                     mContext, app);
1072                             app.waitDialog = d;
1073                             app.waitedForDebugger = true;
1074                             d.show();
1075                         }
1076                     } else {
1077                         if (app.waitDialog != null) {
1078                             app.waitDialog.dismiss();
1079                             app.waitDialog = null;
1080                         }
1081                     }
1082                 }
1083             } break;
1084             case SERVICE_TIMEOUT_MSG: {
1085                 if (mDidDexOpt) {
1086                     mDidDexOpt = false;
1087                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1088                     nmsg.obj = msg.obj;
1089                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1090                     return;
1091                 }
1092                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1093             } break;
1094             case UPDATE_TIME_ZONE: {
1095                 synchronized (ActivityManagerService.this) {
1096                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1097                         ProcessRecord r = mLruProcesses.get(i);
1098                         if (r.thread != null) {
1099                             try {
1100                                 r.thread.updateTimeZone();
1101                             } catch (RemoteException ex) {
1102                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1103                             }
1104                         }
1105                     }
1106                 }
1107             } break;
1108             case CLEAR_DNS_CACHE: {
1109                 synchronized (ActivityManagerService.this) {
1110                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1111                         ProcessRecord r = mLruProcesses.get(i);
1112                         if (r.thread != null) {
1113                             try {
1114                                 r.thread.clearDnsCache();
1115                             } catch (RemoteException ex) {
1116                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1117                             }
1118                         }
1119                     }
1120                 }
1121             } break;
1122             case UPDATE_HTTP_PROXY: {
1123                 ProxyProperties proxy = (ProxyProperties)msg.obj;
1124                 String host = "";
1125                 String port = "";
1126                 String exclList = "";
1127                 if (proxy != null) {
1128                     host = proxy.getHost();
1129                     port = Integer.toString(proxy.getPort());
1130                     exclList = proxy.getExclusionList();
1131                 }
1132                 synchronized (ActivityManagerService.this) {
1133                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1134                         ProcessRecord r = mLruProcesses.get(i);
1135                         if (r.thread != null) {
1136                             try {
1137                                 r.thread.setHttpProxy(host, port, exclList);
1138                             } catch (RemoteException ex) {
1139                                 Slog.w(TAG, "Failed to update http proxy for: " +
1140                                         r.info.processName);
1141                             }
1142                         }
1143                     }
1144                 }
1145             } break;
1146             case SHOW_UID_ERROR_MSG: {
1147                 String title = "System UIDs Inconsistent";
1148                 String text = "UIDs on the system are inconsistent, you need to wipe your"
1149                         + " data partition or your device will be unstable.";
1150                 Log.e(TAG, title + ": " + text);
1151                 if (mShowDialogs) {
1152                     // XXX This is a temporary dialog, no need to localize.
1153                     AlertDialog d = new BaseErrorDialog(mContext);
1154                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1155                     d.setCancelable(false);
1156                     d.setTitle(title);
1157                     d.setMessage(text);
1158                     d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1159                             mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1160                     mUidAlert = d;
1161                     d.show();
1162                 }
1163             } break;
1164             case IM_FEELING_LUCKY_MSG: {
1165                 if (mUidAlert != null) {
1166                     mUidAlert.dismiss();
1167                     mUidAlert = null;
1168                 }
1169             } break;
1170             case PROC_START_TIMEOUT_MSG: {
1171                 if (mDidDexOpt) {
1172                     mDidDexOpt = false;
1173                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1174                     nmsg.obj = msg.obj;
1175                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1176                     return;
1177                 }
1178                 ProcessRecord app = (ProcessRecord)msg.obj;
1179                 synchronized (ActivityManagerService.this) {
1180                     processStartTimedOutLocked(app);
1181                 }
1182             } break;
1183             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1184                 synchronized (ActivityManagerService.this) {
1185                     doPendingActivityLaunchesLocked(true);
1186                 }
1187             } break;
1188             case KILL_APPLICATION_MSG: {
1189                 synchronized (ActivityManagerService.this) {
1190                     int appid = msg.arg1;
1191                     boolean restart = (msg.arg2 == 1);
1192                     String pkg = (String) msg.obj;
1193                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
1194                             UserHandle.USER_ALL);
1195                 }
1196             } break;
1197             case FINALIZE_PENDING_INTENT_MSG: {
1198                 ((PendingIntentRecord)msg.obj).completeFinalize();
1199             } break;
1200             case POST_HEAVY_NOTIFICATION_MSG: {
1201                 INotificationManager inm = NotificationManager.getService();
1202                 if (inm == null) {
1203                     return;
1204                 }
1205 
1206                 ActivityRecord root = (ActivityRecord)msg.obj;
1207                 ProcessRecord process = root.app;
1208                 if (process == null) {
1209                     return;
1210                 }
1211 
1212                 try {
1213                     Context context = mContext.createPackageContext(process.info.packageName, 0);
1214                     String text = mContext.getString(R.string.heavy_weight_notification,
1215                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
1216                     Notification notification = new Notification();
1217                     notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1218                     notification.when = 0;
1219                     notification.flags = Notification.FLAG_ONGOING_EVENT;
1220                     notification.tickerText = text;
1221                     notification.defaults = 0; // please be quiet
1222                     notification.sound = null;
1223                     notification.vibrate = null;
1224                     notification.setLatestEventInfo(context, text,
1225                             mContext.getText(R.string.heavy_weight_notification_detail),
1226                             PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1227                                     PendingIntent.FLAG_CANCEL_CURRENT, null,
1228                                     new UserHandle(root.userId)));
1229 
1230                     try {
1231                         int[] outId = new int[1];
1232                         inm.enqueueNotificationWithTag("android", "android", null,
1233                                 R.string.heavy_weight_notification,
1234                                 notification, outId, root.userId);
1235                     } catch (RuntimeException e) {
1236                         Slog.w(ActivityManagerService.TAG,
1237                                 "Error showing notification for heavy-weight app", e);
1238                     } catch (RemoteException e) {
1239                     }
1240                 } catch (NameNotFoundException e) {
1241                     Slog.w(TAG, "Unable to create context for heavy notification", e);
1242                 }
1243             } break;
1244             case CANCEL_HEAVY_NOTIFICATION_MSG: {
1245                 INotificationManager inm = NotificationManager.getService();
1246                 if (inm == null) {
1247                     return;
1248                 }
1249                 try {
1250                     inm.cancelNotificationWithTag("android", null,
1251                             R.string.heavy_weight_notification,  msg.arg1);
1252                 } catch (RuntimeException e) {
1253                     Slog.w(ActivityManagerService.TAG,
1254                             "Error canceling notification for service", e);
1255                 } catch (RemoteException e) {
1256                 }
1257             } break;
1258             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1259                 synchronized (ActivityManagerService.this) {
1260                     checkExcessivePowerUsageLocked(true);
1261                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1262                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1263                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1264                 }
1265             } break;
1266             case SHOW_COMPAT_MODE_DIALOG_MSG: {
1267                 synchronized (ActivityManagerService.this) {
1268                     ActivityRecord ar = (ActivityRecord)msg.obj;
1269                     if (mCompatModeDialog != null) {
1270                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1271                                 ar.info.applicationInfo.packageName)) {
1272                             return;
1273                         }
1274                         mCompatModeDialog.dismiss();
1275                         mCompatModeDialog = null;
1276                     }
1277                     if (ar != null && false) {
1278                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1279                                 ar.packageName)) {
1280                             int mode = mCompatModePackages.computeCompatModeLocked(
1281                                     ar.info.applicationInfo);
1282                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1283                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1284                                 mCompatModeDialog = new CompatModeDialog(
1285                                         ActivityManagerService.this, mContext,
1286                                         ar.info.applicationInfo);
1287                                 mCompatModeDialog.show();
1288                             }
1289                         }
1290                     }
1291                 }
1292                 break;
1293             }
1294             case DISPATCH_PROCESSES_CHANGED: {
1295                 dispatchProcessesChanged();
1296                 break;
1297             }
1298             case DISPATCH_PROCESS_DIED: {
1299                 final int pid = msg.arg1;
1300                 final int uid = msg.arg2;
1301                 dispatchProcessDied(pid, uid);
1302                 break;
1303             }
1304             case REPORT_MEM_USAGE: {
1305                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1306                 if (!isDebuggable) {
1307                     return;
1308                 }
1309                 synchronized (ActivityManagerService.this) {
1310                     long now = SystemClock.uptimeMillis();
1311                     if (now < (mLastMemUsageReportTime+5*60*1000)) {
1312                         // Don't report more than every 5 minutes to somewhat
1313                         // avoid spamming.
1314                         return;
1315                     }
1316                     mLastMemUsageReportTime = now;
1317                 }
1318                 Thread thread = new Thread() {
1319                     @Override public void run() {
1320                         StringBuilder dropBuilder = new StringBuilder(1024);
1321                         StringBuilder logBuilder = new StringBuilder(1024);
1322                         StringWriter oomSw = new StringWriter();
1323                         PrintWriter oomPw = new PrintWriter(oomSw);
1324                         StringWriter catSw = new StringWriter();
1325                         PrintWriter catPw = new PrintWriter(catSw);
1326                         String[] emptyArgs = new String[] { };
1327                         StringBuilder tag = new StringBuilder(128);
1328                         StringBuilder stack = new StringBuilder(128);
1329                         tag.append("Low on memory -- ");
1330                         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1331                                 tag, stack);
1332                         dropBuilder.append(stack);
1333                         dropBuilder.append('\n');
1334                         dropBuilder.append('\n');
1335                         String oomString = oomSw.toString();
1336                         dropBuilder.append(oomString);
1337                         dropBuilder.append('\n');
1338                         logBuilder.append(oomString);
1339                         try {
1340                             java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1341                                     "procrank", });
1342                             final InputStreamReader converter = new InputStreamReader(
1343                                     proc.getInputStream());
1344                             BufferedReader in = new BufferedReader(converter);
1345                             String line;
1346                             while (true) {
1347                                 line = in.readLine();
1348                                 if (line == null) {
1349                                     break;
1350                                 }
1351                                 if (line.length() > 0) {
1352                                     logBuilder.append(line);
1353                                     logBuilder.append('\n');
1354                                 }
1355                                 dropBuilder.append(line);
1356                                 dropBuilder.append('\n');
1357                             }
1358                             converter.close();
1359                         } catch (IOException e) {
1360                         }
1361                         synchronized (ActivityManagerService.this) {
1362                             catPw.println();
1363                             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1364                             catPw.println();
1365                             mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1366                                     false, false, null);
1367                             catPw.println();
1368                             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1369                         }
1370                         dropBuilder.append(catSw.toString());
1371                         addErrorToDropBox("lowmem", null, "system_server", null,
1372                                 null, tag.toString(), dropBuilder.toString(), null, null);
1373                         Slog.i(TAG, logBuilder.toString());
1374                         synchronized (ActivityManagerService.this) {
1375                             long now = SystemClock.uptimeMillis();
1376                             if (mLastMemUsageReportTime < now) {
1377                                 mLastMemUsageReportTime = now;
1378                             }
1379                         }
1380                     }
1381                 };
1382                 thread.start();
1383                 break;
1384             }
1385             case REPORT_USER_SWITCH_MSG: {
1386                 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1387                 break;
1388             }
1389             case CONTINUE_USER_SWITCH_MSG: {
1390                 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1391                 break;
1392             }
1393             case USER_SWITCH_TIMEOUT_MSG: {
1394                 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1395                 break;
1396             }
1397             case IMMERSIVE_MODE_LOCK_MSG: {
1398                 final boolean nextState = (msg.arg1 != 0);
1399                 if (mUpdateLock.isHeld() != nextState) {
1400                     if (DEBUG_IMMERSIVE) {
1401                         final ActivityRecord r = (ActivityRecord) msg.obj;
1402                         Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1403                     }
1404                     if (nextState) {
1405                         mUpdateLock.acquire();
1406                     } else {
1407                         mUpdateLock.release();
1408                     }
1409                 }
1410                 break;
1411             }
1412             }
1413         }
1414     };
1415 
setSystemProcess()1416     public static void setSystemProcess() {
1417         try {
1418             ActivityManagerService m = mSelf;
1419 
1420             ServiceManager.addService("activity", m, true);
1421             ServiceManager.addService("meminfo", new MemBinder(m));
1422             ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1423             ServiceManager.addService("dbinfo", new DbBinder(m));
1424             if (MONITOR_CPU_USAGE) {
1425                 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1426             }
1427             ServiceManager.addService("permission", new PermissionController(m));
1428 
1429             ApplicationInfo info =
1430                 mSelf.mContext.getPackageManager().getApplicationInfo(
1431                             "android", STOCK_PM_FLAGS);
1432             mSystemThread.installSystemApplicationInfo(info);
1433 
1434             synchronized (mSelf) {
1435                 ProcessRecord app = mSelf.newProcessRecordLocked(
1436                         mSystemThread.getApplicationThread(), info,
1437                         info.processName, false);
1438                 app.persistent = true;
1439                 app.pid = MY_PID;
1440                 app.maxAdj = ProcessList.SYSTEM_ADJ;
1441                 mSelf.mProcessNames.put(app.processName, app.uid, app);
1442                 synchronized (mSelf.mPidsSelfLocked) {
1443                     mSelf.mPidsSelfLocked.put(app.pid, app);
1444                 }
1445                 mSelf.updateLruProcessLocked(app, true);
1446             }
1447         } catch (PackageManager.NameNotFoundException e) {
1448             throw new RuntimeException(
1449                     "Unable to find android system package", e);
1450         }
1451     }
1452 
setWindowManager(WindowManagerService wm)1453     public void setWindowManager(WindowManagerService wm) {
1454         mWindowManager = wm;
1455     }
1456 
startObservingNativeCrashes()1457     public void startObservingNativeCrashes() {
1458         final NativeCrashListener ncl = new NativeCrashListener();
1459         ncl.start();
1460     }
1461 
main(int factoryTest)1462     public static final Context main(int factoryTest) {
1463         AThread thr = new AThread();
1464         thr.start();
1465 
1466         synchronized (thr) {
1467             while (thr.mService == null) {
1468                 try {
1469                     thr.wait();
1470                 } catch (InterruptedException e) {
1471                 }
1472             }
1473         }
1474 
1475         ActivityManagerService m = thr.mService;
1476         mSelf = m;
1477         ActivityThread at = ActivityThread.systemMain();
1478         mSystemThread = at;
1479         Context context = at.getSystemContext();
1480         context.setTheme(android.R.style.Theme_Holo);
1481         m.mContext = context;
1482         m.mFactoryTest = factoryTest;
1483         m.mMainStack = new ActivityStack(m, context, true, thr.mLooper);
1484         m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface());
1485 
1486         m.mBatteryStatsService.publish(context);
1487         m.mUsageStatsService.publish(context);
1488         m.mAppOpsService.publish(context);
1489 
1490         synchronized (thr) {
1491             thr.mReady = true;
1492             thr.notifyAll();
1493         }
1494 
1495         m.startRunning(null, null, null, null);
1496 
1497         return context;
1498     }
1499 
self()1500     public static ActivityManagerService self() {
1501         return mSelf;
1502     }
1503 
1504     static class AThread extends Thread {
1505         ActivityManagerService mService;
1506         Looper mLooper;
1507         boolean mReady = false;
1508 
AThread()1509         public AThread() {
1510             super("ActivityManager");
1511         }
1512 
run()1513         public void run() {
1514             Looper.prepare();
1515 
1516             android.os.Process.setThreadPriority(
1517                     android.os.Process.THREAD_PRIORITY_FOREGROUND);
1518             android.os.Process.setCanSelfBackground(false);
1519 
1520             ActivityManagerService m = new ActivityManagerService();
1521 
1522             synchronized (this) {
1523                 mService = m;
1524                 mLooper = Looper.myLooper();
1525                 notifyAll();
1526             }
1527 
1528             synchronized (this) {
1529                 while (!mReady) {
1530                     try {
1531                         wait();
1532                     } catch (InterruptedException e) {
1533                     }
1534                 }
1535             }
1536 
1537             // For debug builds, log event loop stalls to dropbox for analysis.
1538             if (StrictMode.conditionallyEnableDebugLogging()) {
1539                 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1540             }
1541 
1542             Looper.loop();
1543         }
1544     }
1545 
1546     static class MemBinder extends Binder {
1547         ActivityManagerService mActivityManagerService;
MemBinder(ActivityManagerService activityManagerService)1548         MemBinder(ActivityManagerService activityManagerService) {
1549             mActivityManagerService = activityManagerService;
1550         }
1551 
1552         @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)1553         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1554             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1555                     != PackageManager.PERMISSION_GRANTED) {
1556                 pw.println("Permission Denial: can't dump meminfo from from pid="
1557                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1558                         + " without permission " + android.Manifest.permission.DUMP);
1559                 return;
1560             }
1561 
1562             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1563                     false, null, null, null);
1564         }
1565     }
1566 
1567     static class GraphicsBinder extends Binder {
1568         ActivityManagerService mActivityManagerService;
GraphicsBinder(ActivityManagerService activityManagerService)1569         GraphicsBinder(ActivityManagerService activityManagerService) {
1570             mActivityManagerService = activityManagerService;
1571         }
1572 
1573         @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)1574         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1575             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1576                     != PackageManager.PERMISSION_GRANTED) {
1577                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1578                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1579                         + " without permission " + android.Manifest.permission.DUMP);
1580                 return;
1581             }
1582 
1583             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1584         }
1585     }
1586 
1587     static class DbBinder extends Binder {
1588         ActivityManagerService mActivityManagerService;
DbBinder(ActivityManagerService activityManagerService)1589         DbBinder(ActivityManagerService activityManagerService) {
1590             mActivityManagerService = activityManagerService;
1591         }
1592 
1593         @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)1594         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1595             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1596                     != PackageManager.PERMISSION_GRANTED) {
1597                 pw.println("Permission Denial: can't dump dbinfo from from pid="
1598                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1599                         + " without permission " + android.Manifest.permission.DUMP);
1600                 return;
1601             }
1602 
1603             mActivityManagerService.dumpDbInfo(fd, pw, args);
1604         }
1605     }
1606 
1607     static class CpuBinder extends Binder {
1608         ActivityManagerService mActivityManagerService;
CpuBinder(ActivityManagerService activityManagerService)1609         CpuBinder(ActivityManagerService activityManagerService) {
1610             mActivityManagerService = activityManagerService;
1611         }
1612 
1613         @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)1614         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1615             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1616                     != PackageManager.PERMISSION_GRANTED) {
1617                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
1618                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1619                         + " without permission " + android.Manifest.permission.DUMP);
1620                 return;
1621             }
1622 
1623             synchronized (mActivityManagerService.mProcessStatsThread) {
1624                 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1625                 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1626                         SystemClock.uptimeMillis()));
1627             }
1628         }
1629     }
1630 
ActivityManagerService()1631     private ActivityManagerService() {
1632         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1633 
1634         mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1635         mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1636         mBroadcastQueues[0] = mFgBroadcastQueue;
1637         mBroadcastQueues[1] = mBgBroadcastQueue;
1638 
1639         mServices = new ActiveServices(this);
1640         mProviderMap = new ProviderMap(this);
1641 
1642         File dataDir = Environment.getDataDirectory();
1643         File systemDir = new File(dataDir, "system");
1644         systemDir.mkdirs();
1645         mBatteryStatsService = new BatteryStatsService(new File(
1646                 systemDir, "batterystats.bin").toString());
1647         mBatteryStatsService.getActiveStatistics().readLocked();
1648         mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1649         mOnBattery = DEBUG_POWER ? true
1650                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1651         mBatteryStatsService.getActiveStatistics().setCallback(this);
1652 
1653         mUsageStatsService = new UsageStatsService(new File(
1654                 systemDir, "usagestats").toString());
1655         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"));
1656         mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1657 
1658         // User 0 is the first and only user that runs at boot.
1659         mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1660         mUserLru.add(Integer.valueOf(0));
1661         updateStartedUserArrayLocked();
1662 
1663         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1664             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1665 
1666         mConfiguration.setToDefaults();
1667         mConfiguration.setLocale(Locale.getDefault());
1668 
1669         mConfigurationSeq = mConfiguration.seq = 1;
1670         mProcessStats.init();
1671 
1672         mCompatModePackages = new CompatModePackages(this, systemDir);
1673 
1674         // Add ourself to the Watchdog monitors.
1675         Watchdog.getInstance().addMonitor(this);
1676 
1677         mProcessStatsThread = new Thread("ProcessStats") {
1678             public void run() {
1679                 while (true) {
1680                     try {
1681                         try {
1682                             synchronized(this) {
1683                                 final long now = SystemClock.uptimeMillis();
1684                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1685                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1686                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1687                                 //        + ", write delay=" + nextWriteDelay);
1688                                 if (nextWriteDelay < nextCpuDelay) {
1689                                     nextCpuDelay = nextWriteDelay;
1690                                 }
1691                                 if (nextCpuDelay > 0) {
1692                                     mProcessStatsMutexFree.set(true);
1693                                     this.wait(nextCpuDelay);
1694                                 }
1695                             }
1696                         } catch (InterruptedException e) {
1697                         }
1698                         updateCpuStatsNow();
1699                     } catch (Exception e) {
1700                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
1701                     }
1702                 }
1703             }
1704         };
1705         mProcessStatsThread.start();
1706     }
1707 
1708     @Override
onTransact(int code, Parcel data, Parcel reply, int flags)1709     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1710             throws RemoteException {
1711         if (code == SYSPROPS_TRANSACTION) {
1712             // We need to tell all apps about the system property change.
1713             ArrayList<IBinder> procs = new ArrayList<IBinder>();
1714             synchronized(this) {
1715                 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1716                     final int NA = apps.size();
1717                     for (int ia=0; ia<NA; ia++) {
1718                         ProcessRecord app = apps.valueAt(ia);
1719                         if (app.thread != null) {
1720                             procs.add(app.thread.asBinder());
1721                         }
1722                     }
1723                 }
1724             }
1725 
1726             int N = procs.size();
1727             for (int i=0; i<N; i++) {
1728                 Parcel data2 = Parcel.obtain();
1729                 try {
1730                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1731                 } catch (RemoteException e) {
1732                 }
1733                 data2.recycle();
1734             }
1735         }
1736         try {
1737             return super.onTransact(code, data, reply, flags);
1738         } catch (RuntimeException e) {
1739             // The activity manager only throws security exceptions, so let's
1740             // log all others.
1741             if (!(e instanceof SecurityException)) {
1742                 Slog.e(TAG, "Activity Manager Crash", e);
1743             }
1744             throw e;
1745         }
1746     }
1747 
updateCpuStats()1748     void updateCpuStats() {
1749         final long now = SystemClock.uptimeMillis();
1750         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1751             return;
1752         }
1753         if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1754             synchronized (mProcessStatsThread) {
1755                 mProcessStatsThread.notify();
1756             }
1757         }
1758     }
1759 
updateCpuStatsNow()1760     void updateCpuStatsNow() {
1761         synchronized (mProcessStatsThread) {
1762             mProcessStatsMutexFree.set(false);
1763             final long now = SystemClock.uptimeMillis();
1764             boolean haveNewCpuStats = false;
1765 
1766             if (MONITOR_CPU_USAGE &&
1767                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1768                 mLastCpuTime.set(now);
1769                 haveNewCpuStats = true;
1770                 mProcessStats.update();
1771                 //Slog.i(TAG, mProcessStats.printCurrentState());
1772                 //Slog.i(TAG, "Total CPU usage: "
1773                 //        + mProcessStats.getTotalCpuPercent() + "%");
1774 
1775                 // Slog the cpu usage if the property is set.
1776                 if ("true".equals(SystemProperties.get("events.cpu"))) {
1777                     int user = mProcessStats.getLastUserTime();
1778                     int system = mProcessStats.getLastSystemTime();
1779                     int iowait = mProcessStats.getLastIoWaitTime();
1780                     int irq = mProcessStats.getLastIrqTime();
1781                     int softIrq = mProcessStats.getLastSoftIrqTime();
1782                     int idle = mProcessStats.getLastIdleTime();
1783 
1784                     int total = user + system + iowait + irq + softIrq + idle;
1785                     if (total == 0) total = 1;
1786 
1787                     EventLog.writeEvent(EventLogTags.CPU,
1788                             ((user+system+iowait+irq+softIrq) * 100) / total,
1789                             (user * 100) / total,
1790                             (system * 100) / total,
1791                             (iowait * 100) / total,
1792                             (irq * 100) / total,
1793                             (softIrq * 100) / total);
1794                 }
1795             }
1796 
1797             long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1798             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1799             synchronized(bstats) {
1800                 synchronized(mPidsSelfLocked) {
1801                     if (haveNewCpuStats) {
1802                         if (mOnBattery) {
1803                             int perc = bstats.startAddingCpuLocked();
1804                             int totalUTime = 0;
1805                             int totalSTime = 0;
1806                             final int N = mProcessStats.countStats();
1807                             for (int i=0; i<N; i++) {
1808                                 ProcessStats.Stats st = mProcessStats.getStats(i);
1809                                 if (!st.working) {
1810                                     continue;
1811                                 }
1812                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1813                                 int otherUTime = (st.rel_utime*perc)/100;
1814                                 int otherSTime = (st.rel_stime*perc)/100;
1815                                 totalUTime += otherUTime;
1816                                 totalSTime += otherSTime;
1817                                 if (pr != null) {
1818                                     BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1819                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1820                                             st.rel_stime-otherSTime);
1821                                     ps.addSpeedStepTimes(cpuSpeedTimes);
1822                                     pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1823                                 } else {
1824                                     BatteryStatsImpl.Uid.Proc ps =
1825                                             bstats.getProcessStatsLocked(st.name, st.pid);
1826                                     if (ps != null) {
1827                                         ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1828                                                 st.rel_stime-otherSTime);
1829                                         ps.addSpeedStepTimes(cpuSpeedTimes);
1830                                     }
1831                                 }
1832                             }
1833                             bstats.finishAddingCpuLocked(perc, totalUTime,
1834                                     totalSTime, cpuSpeedTimes);
1835                         }
1836                     }
1837                 }
1838 
1839                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1840                     mLastWriteTime = now;
1841                     mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1842                 }
1843             }
1844         }
1845     }
1846 
1847     @Override
batteryNeedsCpuUpdate()1848     public void batteryNeedsCpuUpdate() {
1849         updateCpuStatsNow();
1850     }
1851 
1852     @Override
batteryPowerChanged(boolean onBattery)1853     public void batteryPowerChanged(boolean onBattery) {
1854         // When plugging in, update the CPU stats first before changing
1855         // the plug state.
1856         updateCpuStatsNow();
1857         synchronized (this) {
1858             synchronized(mPidsSelfLocked) {
1859                 mOnBattery = DEBUG_POWER ? true : onBattery;
1860             }
1861         }
1862     }
1863 
1864     /**
1865      * Initialize the application bind args. These are passed to each
1866      * process when the bindApplication() IPC is sent to the process. They're
1867      * lazily setup to make sure the services are running when they're asked for.
1868      */
getCommonServicesLocked()1869     private HashMap<String, IBinder> getCommonServicesLocked() {
1870         if (mAppBindArgs == null) {
1871             mAppBindArgs = new HashMap<String, IBinder>();
1872 
1873             // Setup the application init args
1874             mAppBindArgs.put("package", ServiceManager.getService("package"));
1875             mAppBindArgs.put("window", ServiceManager.getService("window"));
1876             mAppBindArgs.put(Context.ALARM_SERVICE,
1877                     ServiceManager.getService(Context.ALARM_SERVICE));
1878         }
1879         return mAppBindArgs;
1880     }
1881 
setFocusedActivityLocked(ActivityRecord r)1882     final void setFocusedActivityLocked(ActivityRecord r) {
1883         if (mFocusedActivity != r) {
1884             mFocusedActivity = r;
1885             if (r != null) {
1886                 mWindowManager.setFocusedApp(r.appToken, true);
1887             }
1888             applyUpdateLockStateLocked(r);
1889         }
1890     }
1891 
applyUpdateLockStateLocked(ActivityRecord r)1892     final void applyUpdateLockStateLocked(ActivityRecord r) {
1893         // Modifications to the UpdateLock state are done on our handler, outside
1894         // the activity manager's locks.  The new state is determined based on the
1895         // state *now* of the relevant activity record.  The object is passed to
1896         // the handler solely for logging detail, not to be consulted/modified.
1897         final boolean nextState = r != null && r.immersive;
1898         mHandler.sendMessage(
1899                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
1900     }
1901 
updateLruProcessInternalLocked(ProcessRecord app, int bestPos)1902     private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) {
1903         // put it on the LRU to keep track of when it should be exited.
1904         int lrui = mLruProcesses.indexOf(app);
1905         if (lrui >= 0) mLruProcesses.remove(lrui);
1906 
1907         int i = mLruProcesses.size()-1;
1908         int skipTop = 0;
1909 
1910         app.lruSeq = mLruSeq;
1911 
1912         // compute the new weight for this process.
1913         app.lastActivityTime = SystemClock.uptimeMillis();
1914         if (app.activities.size() > 0) {
1915             // If this process has activities, we more strongly want to keep
1916             // it around.
1917             app.lruWeight = app.lastActivityTime;
1918         } else if (app.pubProviders.size() > 0) {
1919             // If this process contains content providers, we want to keep
1920             // it a little more strongly.
1921             app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1922             // Also don't let it kick out the first few "real" hidden processes.
1923             skipTop = ProcessList.MIN_HIDDEN_APPS;
1924         } else {
1925             // If this process doesn't have activities, we less strongly
1926             // want to keep it around, and generally want to avoid getting
1927             // in front of any very recently used activities.
1928             app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1929             // Also don't let it kick out the first few "real" hidden processes.
1930             skipTop = ProcessList.MIN_HIDDEN_APPS;
1931         }
1932 
1933         while (i >= 0) {
1934             ProcessRecord p = mLruProcesses.get(i);
1935             // If this app shouldn't be in front of the first N background
1936             // apps, then skip over that many that are currently hidden.
1937             if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1938                 skipTop--;
1939             }
1940             if (p.lruWeight <= app.lruWeight || i < bestPos) {
1941                 mLruProcesses.add(i+1, app);
1942                 break;
1943             }
1944             i--;
1945         }
1946         if (i < 0) {
1947             mLruProcesses.add(0, app);
1948         }
1949 
1950         // If the app is currently using a content provider or service,
1951         // bump those processes as well.
1952         if (app.connections.size() > 0) {
1953             for (ConnectionRecord cr : app.connections) {
1954                 if (cr.binding != null && cr.binding.service != null
1955                         && cr.binding.service.app != null
1956                         && cr.binding.service.app.lruSeq != mLruSeq) {
1957                     updateLruProcessInternalLocked(cr.binding.service.app, i+1);
1958                 }
1959             }
1960         }
1961         for (int j=app.conProviders.size()-1; j>=0; j--) {
1962             ContentProviderRecord cpr = app.conProviders.get(j).provider;
1963             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1964                 updateLruProcessInternalLocked(cpr.proc, i+1);
1965             }
1966         }
1967     }
1968 
updateLruProcessLocked(ProcessRecord app, boolean oomAdj)1969     final void updateLruProcessLocked(ProcessRecord app,
1970             boolean oomAdj) {
1971         mLruSeq++;
1972         updateLruProcessInternalLocked(app, 0);
1973 
1974         //Slog.i(TAG, "Putting proc to front: " + app.processName);
1975         if (oomAdj) {
1976             updateOomAdjLocked();
1977         }
1978     }
1979 
getProcessRecordLocked( String processName, int uid)1980     final ProcessRecord getProcessRecordLocked(
1981             String processName, int uid) {
1982         if (uid == Process.SYSTEM_UID) {
1983             // The system gets to run in any process.  If there are multiple
1984             // processes with the same uid, just pick the first (this
1985             // should never happen).
1986             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1987                     processName);
1988             if (procs == null) return null;
1989             final int N = procs.size();
1990             for (int i = 0; i < N; i++) {
1991                 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1992             }
1993         }
1994         ProcessRecord proc = mProcessNames.get(processName, uid);
1995         return proc;
1996     }
1997 
ensurePackageDexOpt(String packageName)1998     void ensurePackageDexOpt(String packageName) {
1999         IPackageManager pm = AppGlobals.getPackageManager();
2000         try {
2001             if (pm.performDexOpt(packageName)) {
2002                 mDidDexOpt = true;
2003             }
2004         } catch (RemoteException e) {
2005         }
2006     }
2007 
isNextTransitionForward()2008     boolean isNextTransitionForward() {
2009         int transit = mWindowManager.getPendingAppTransition();
2010         return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2011                 || transit == AppTransition.TRANSIT_TASK_OPEN
2012                 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2013     }
2014 
startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, boolean allowWhileBooting, boolean isolated)2015     final ProcessRecord startProcessLocked(String processName,
2016             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2017             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2018             boolean isolated) {
2019         ProcessRecord app;
2020         if (!isolated) {
2021             app = getProcessRecordLocked(processName, info.uid);
2022         } else {
2023             // If this is an isolated process, it can't re-use an existing process.
2024             app = null;
2025         }
2026         // We don't have to do anything more if:
2027         // (1) There is an existing application record; and
2028         // (2) The caller doesn't think it is dead, OR there is no thread
2029         //     object attached to it so we know it couldn't have crashed; and
2030         // (3) There is a pid assigned to it, so it is either starting or
2031         //     already running.
2032         if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2033                 + " app=" + app + " knownToBeDead=" + knownToBeDead
2034                 + " thread=" + (app != null ? app.thread : null)
2035                 + " pid=" + (app != null ? app.pid : -1));
2036         if (app != null && app.pid > 0) {
2037             if (!knownToBeDead || app.thread == null) {
2038                 // We already have the app running, or are waiting for it to
2039                 // come up (we have a pid but not yet its thread), so keep it.
2040                 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2041                 // If this is a new package in the process, add the package to the list
2042                 app.addPackage(info.packageName);
2043                 return app;
2044             } else {
2045                 // An application record is attached to a previous process,
2046                 // clean it up now.
2047                 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2048                 handleAppDiedLocked(app, true, true);
2049             }
2050         }
2051 
2052         String hostingNameStr = hostingName != null
2053                 ? hostingName.flattenToShortString() : null;
2054 
2055         if (!isolated) {
2056             if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2057                 // If we are in the background, then check to see if this process
2058                 // is bad.  If so, we will just silently fail.
2059                 if (mBadProcesses.get(info.processName, info.uid) != null) {
2060                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2061                             + "/" + info.processName);
2062                     return null;
2063                 }
2064             } else {
2065                 // When the user is explicitly starting a process, then clear its
2066                 // crash count so that we won't make it bad until they see at
2067                 // least one crash dialog again, and make the process good again
2068                 // if it had been bad.
2069                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2070                         + "/" + info.processName);
2071                 mProcessCrashTimes.remove(info.processName, info.uid);
2072                 if (mBadProcesses.get(info.processName, info.uid) != null) {
2073                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2074                             UserHandle.getUserId(info.uid), info.uid,
2075                             info.processName);
2076                     mBadProcesses.remove(info.processName, info.uid);
2077                     if (app != null) {
2078                         app.bad = false;
2079                     }
2080                 }
2081             }
2082         }
2083 
2084         if (app == null) {
2085             app = newProcessRecordLocked(null, info, processName, isolated);
2086             if (app == null) {
2087                 Slog.w(TAG, "Failed making new process record for "
2088                         + processName + "/" + info.uid + " isolated=" + isolated);
2089                 return null;
2090             }
2091             mProcessNames.put(processName, app.uid, app);
2092             if (isolated) {
2093                 mIsolatedProcesses.put(app.uid, app);
2094             }
2095         } else {
2096             // If this is a new package in the process, add the package to the list
2097             app.addPackage(info.packageName);
2098         }
2099 
2100         // If the system is not ready yet, then hold off on starting this
2101         // process until it is.
2102         if (!mProcessesReady
2103                 && !isAllowedWhileBooting(info)
2104                 && !allowWhileBooting) {
2105             if (!mProcessesOnHold.contains(app)) {
2106                 mProcessesOnHold.add(app);
2107             }
2108             if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2109             return app;
2110         }
2111 
2112         startProcessLocked(app, hostingType, hostingNameStr);
2113         return (app.pid != 0) ? app : null;
2114     }
2115 
isAllowedWhileBooting(ApplicationInfo ai)2116     boolean isAllowedWhileBooting(ApplicationInfo ai) {
2117         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2118     }
2119 
startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr)2120     private final void startProcessLocked(ProcessRecord app,
2121             String hostingType, String hostingNameStr) {
2122         if (app.pid > 0 && app.pid != MY_PID) {
2123             synchronized (mPidsSelfLocked) {
2124                 mPidsSelfLocked.remove(app.pid);
2125                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2126             }
2127             app.setPid(0);
2128         }
2129 
2130         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2131                 "startProcessLocked removing on hold: " + app);
2132         mProcessesOnHold.remove(app);
2133 
2134         updateCpuStats();
2135 
2136         System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2137         mProcDeaths[0] = 0;
2138 
2139         try {
2140             int uid = app.uid;
2141 
2142             int[] gids = null;
2143             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2144             if (!app.isolated) {
2145                 int[] permGids = null;
2146                 try {
2147                     final PackageManager pm = mContext.getPackageManager();
2148                     permGids = pm.getPackageGids(app.info.packageName);
2149 
2150                     if (Environment.isExternalStorageEmulated()) {
2151                         if (pm.checkPermission(
2152                                 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2153                                 app.info.packageName) == PERMISSION_GRANTED) {
2154                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2155                         } else {
2156                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2157                         }
2158                     }
2159                 } catch (PackageManager.NameNotFoundException e) {
2160                     Slog.w(TAG, "Unable to retrieve gids", e);
2161                 }
2162 
2163                 /*
2164                  * Add shared application GID so applications can share some
2165                  * resources like shared libraries
2166                  */
2167                 if (permGids == null) {
2168                     gids = new int[1];
2169                 } else {
2170                     gids = new int[permGids.length + 1];
2171                     System.arraycopy(permGids, 0, gids, 1, permGids.length);
2172                 }
2173                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2174             }
2175             if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2176                 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2177                         && mTopComponent != null
2178                         && app.processName.equals(mTopComponent.getPackageName())) {
2179                     uid = 0;
2180                 }
2181                 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2182                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2183                     uid = 0;
2184                 }
2185             }
2186             int debugFlags = 0;
2187             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2188                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2189                 // Also turn on CheckJNI for debuggable apps. It's quite
2190                 // awkward to turn on otherwise.
2191                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2192             }
2193             // Run the app in safe mode if its manifest requests so or the
2194             // system is booted in safe mode.
2195             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2196                 Zygote.systemInSafeMode == true) {
2197                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2198             }
2199             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2200                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2201             }
2202             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2203                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2204             }
2205             if ("1".equals(SystemProperties.get("debug.assert"))) {
2206                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2207             }
2208 
2209             // Start the process.  It will either succeed and return a result containing
2210             // the PID of the new process, or else throw a RuntimeException.
2211             Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2212                     app.processName, uid, uid, gids, debugFlags, mountExternal,
2213                     app.info.targetSdkVersion, app.info.seinfo, null);
2214 
2215             BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2216             synchronized (bs) {
2217                 if (bs.isOnBattery()) {
2218                     app.batteryStats.incStartsLocked();
2219                 }
2220             }
2221 
2222             EventLog.writeEvent(EventLogTags.AM_PROC_START,
2223                     UserHandle.getUserId(uid), startResult.pid, uid,
2224                     app.processName, hostingType,
2225                     hostingNameStr != null ? hostingNameStr : "");
2226 
2227             if (app.persistent) {
2228                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2229             }
2230 
2231             StringBuilder buf = mStringBuilder;
2232             buf.setLength(0);
2233             buf.append("Start proc ");
2234             buf.append(app.processName);
2235             buf.append(" for ");
2236             buf.append(hostingType);
2237             if (hostingNameStr != null) {
2238                 buf.append(" ");
2239                 buf.append(hostingNameStr);
2240             }
2241             buf.append(": pid=");
2242             buf.append(startResult.pid);
2243             buf.append(" uid=");
2244             buf.append(uid);
2245             buf.append(" gids={");
2246             if (gids != null) {
2247                 for (int gi=0; gi<gids.length; gi++) {
2248                     if (gi != 0) buf.append(", ");
2249                     buf.append(gids[gi]);
2250 
2251                 }
2252             }
2253             buf.append("}");
2254             Slog.i(TAG, buf.toString());
2255             app.setPid(startResult.pid);
2256             app.usingWrapper = startResult.usingWrapper;
2257             app.removed = false;
2258             synchronized (mPidsSelfLocked) {
2259                 this.mPidsSelfLocked.put(startResult.pid, app);
2260                 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2261                 msg.obj = app;
2262                 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2263                         ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2264             }
2265         } catch (RuntimeException e) {
2266             // XXX do better error recovery.
2267             app.setPid(0);
2268             Slog.e(TAG, "Failure starting process " + app.processName, e);
2269         }
2270     }
2271 
updateUsageStats(ActivityRecord resumedComponent, boolean resumed)2272     void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2273         if (resumed) {
2274             mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2275         } else {
2276             mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2277         }
2278     }
2279 
startHomeActivityLocked(int userId)2280     boolean startHomeActivityLocked(int userId) {
2281         if (mHeadless) {
2282             // Added because none of the other calls to ensureBootCompleted seem to fire
2283             // when running headless.
2284             ensureBootCompleted();
2285             return false;
2286         }
2287 
2288         if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2289                 && mTopAction == null) {
2290             // We are running in factory test mode, but unable to find
2291             // the factory test app, so just sit around displaying the
2292             // error message and don't try to start anything.
2293             return false;
2294         }
2295         Intent intent = new Intent(
2296             mTopAction,
2297             mTopData != null ? Uri.parse(mTopData) : null);
2298         intent.setComponent(mTopComponent);
2299         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2300             intent.addCategory(Intent.CATEGORY_HOME);
2301         }
2302         ActivityInfo aInfo =
2303             resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2304         if (aInfo != null) {
2305             intent.setComponent(new ComponentName(
2306                     aInfo.applicationInfo.packageName, aInfo.name));
2307             // Don't do this if the home app is currently being
2308             // instrumented.
2309             aInfo = new ActivityInfo(aInfo);
2310             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2311             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2312                     aInfo.applicationInfo.uid);
2313             if (app == null || app.instrumentationClass == null) {
2314                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2315                 mMainStack.startActivityLocked(null, intent, null, aInfo,
2316                         null, null, 0, 0, 0, null, 0, null, false, null);
2317             }
2318         }
2319 
2320         return true;
2321     }
2322 
resolveActivityInfo(Intent intent, int flags, int userId)2323     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2324         ActivityInfo ai = null;
2325         ComponentName comp = intent.getComponent();
2326         try {
2327             if (comp != null) {
2328                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2329             } else {
2330                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2331                         intent,
2332                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2333                             flags, userId);
2334 
2335                 if (info != null) {
2336                     ai = info.activityInfo;
2337                 }
2338             }
2339         } catch (RemoteException e) {
2340             // ignore
2341         }
2342 
2343         return ai;
2344     }
2345 
2346     /**
2347      * Starts the "new version setup screen" if appropriate.
2348      */
startSetupActivityLocked()2349     void startSetupActivityLocked() {
2350         // Only do this once per boot.
2351         if (mCheckedForSetup) {
2352             return;
2353         }
2354 
2355         // We will show this screen if the current one is a different
2356         // version than the last one shown, and we are not running in
2357         // low-level factory test mode.
2358         final ContentResolver resolver = mContext.getContentResolver();
2359         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2360                 Settings.Global.getInt(resolver,
2361                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2362             mCheckedForSetup = true;
2363 
2364             // See if we should be showing the platform update setup UI.
2365             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2366             List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2367                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2368 
2369             // We don't allow third party apps to replace this.
2370             ResolveInfo ri = null;
2371             for (int i=0; ris != null && i<ris.size(); i++) {
2372                 if ((ris.get(i).activityInfo.applicationInfo.flags
2373                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
2374                     ri = ris.get(i);
2375                     break;
2376                 }
2377             }
2378 
2379             if (ri != null) {
2380                 String vers = ri.activityInfo.metaData != null
2381                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2382                         : null;
2383                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2384                     vers = ri.activityInfo.applicationInfo.metaData.getString(
2385                             Intent.METADATA_SETUP_VERSION);
2386                 }
2387                 String lastVers = Settings.Secure.getString(
2388                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
2389                 if (vers != null && !vers.equals(lastVers)) {
2390                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2391                     intent.setComponent(new ComponentName(
2392                             ri.activityInfo.packageName, ri.activityInfo.name));
2393                     mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2394                             null, null, 0, 0, 0, null, 0, null, false, null);
2395                 }
2396             }
2397         }
2398     }
2399 
compatibilityInfoForPackageLocked(ApplicationInfo ai)2400     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2401         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2402     }
2403 
enforceNotIsolatedCaller(String caller)2404     void enforceNotIsolatedCaller(String caller) {
2405         if (UserHandle.isIsolated(Binder.getCallingUid())) {
2406             throw new SecurityException("Isolated process not allowed to call " + caller);
2407         }
2408     }
2409 
getFrontActivityScreenCompatMode()2410     public int getFrontActivityScreenCompatMode() {
2411         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2412         synchronized (this) {
2413             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2414         }
2415     }
2416 
setFrontActivityScreenCompatMode(int mode)2417     public void setFrontActivityScreenCompatMode(int mode) {
2418         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2419                 "setFrontActivityScreenCompatMode");
2420         synchronized (this) {
2421             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2422         }
2423     }
2424 
getPackageScreenCompatMode(String packageName)2425     public int getPackageScreenCompatMode(String packageName) {
2426         enforceNotIsolatedCaller("getPackageScreenCompatMode");
2427         synchronized (this) {
2428             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2429         }
2430     }
2431 
setPackageScreenCompatMode(String packageName, int mode)2432     public void setPackageScreenCompatMode(String packageName, int mode) {
2433         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2434                 "setPackageScreenCompatMode");
2435         synchronized (this) {
2436             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2437         }
2438     }
2439 
getPackageAskScreenCompat(String packageName)2440     public boolean getPackageAskScreenCompat(String packageName) {
2441         enforceNotIsolatedCaller("getPackageAskScreenCompat");
2442         synchronized (this) {
2443             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2444         }
2445     }
2446 
setPackageAskScreenCompat(String packageName, boolean ask)2447     public void setPackageAskScreenCompat(String packageName, boolean ask) {
2448         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2449                 "setPackageAskScreenCompat");
2450         synchronized (this) {
2451             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2452         }
2453     }
2454 
reportResumedActivityLocked(ActivityRecord r)2455     void reportResumedActivityLocked(ActivityRecord r) {
2456         //Slog.i(TAG, "**** REPORT RESUME: " + r);
2457         updateUsageStats(r, true);
2458     }
2459 
dispatchProcessesChanged()2460     private void dispatchProcessesChanged() {
2461         int N;
2462         synchronized (this) {
2463             N = mPendingProcessChanges.size();
2464             if (mActiveProcessChanges.length < N) {
2465                 mActiveProcessChanges = new ProcessChangeItem[N];
2466             }
2467             mPendingProcessChanges.toArray(mActiveProcessChanges);
2468             mAvailProcessChanges.addAll(mPendingProcessChanges);
2469             mPendingProcessChanges.clear();
2470             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2471         }
2472         int i = mProcessObservers.beginBroadcast();
2473         while (i > 0) {
2474             i--;
2475             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2476             if (observer != null) {
2477                 try {
2478                     for (int j=0; j<N; j++) {
2479                         ProcessChangeItem item = mActiveProcessChanges[j];
2480                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2481                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2482                                     + item.pid + " uid=" + item.uid + ": "
2483                                     + item.foregroundActivities);
2484                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
2485                                     item.foregroundActivities);
2486                         }
2487                         if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2488                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2489                                     + item.pid + " uid=" + item.uid + ": " + item.importance);
2490                             observer.onImportanceChanged(item.pid, item.uid,
2491                                     item.importance);
2492                         }
2493                     }
2494                 } catch (RemoteException e) {
2495                 }
2496             }
2497         }
2498         mProcessObservers.finishBroadcast();
2499     }
2500 
dispatchProcessDied(int pid, int uid)2501     private void dispatchProcessDied(int pid, int uid) {
2502         int i = mProcessObservers.beginBroadcast();
2503         while (i > 0) {
2504             i--;
2505             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2506             if (observer != null) {
2507                 try {
2508                     observer.onProcessDied(pid, uid);
2509                 } catch (RemoteException e) {
2510                 }
2511             }
2512         }
2513         mProcessObservers.finishBroadcast();
2514     }
2515 
doPendingActivityLaunchesLocked(boolean doResume)2516     final void doPendingActivityLaunchesLocked(boolean doResume) {
2517         final int N = mPendingActivityLaunches.size();
2518         if (N <= 0) {
2519             return;
2520         }
2521         for (int i=0; i<N; i++) {
2522             PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2523             mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2524                     pal.startFlags, doResume && i == (N-1), null);
2525         }
2526         mPendingActivityLaunches.clear();
2527     }
2528 
startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, String profileFile, ParcelFileDescriptor profileFd, Bundle options)2529     public final int startActivity(IApplicationThread caller, String callingPackage,
2530             Intent intent, String resolvedType, IBinder resultTo,
2531             String resultWho, int requestCode, int startFlags,
2532             String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2533         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
2534                 resultWho, requestCode,
2535                 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2536     }
2537 
startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId)2538     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
2539             Intent intent, String resolvedType, IBinder resultTo,
2540             String resultWho, int requestCode, int startFlags,
2541             String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2542         enforceNotIsolatedCaller("startActivity");
2543         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2544                 false, true, "startActivity", null);
2545         return mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
2546                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2547                 null, null, options, userId);
2548     }
2549 
startActivityAndWait(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId)2550     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
2551             Intent intent, String resolvedType, IBinder resultTo,
2552             String resultWho, int requestCode, int startFlags, String profileFile,
2553             ParcelFileDescriptor profileFd, Bundle options, int userId) {
2554         enforceNotIsolatedCaller("startActivityAndWait");
2555         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2556                 false, true, "startActivityAndWait", null);
2557         WaitResult res = new WaitResult();
2558         mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
2559                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2560                 res, null, options, UserHandle.getCallingUserId());
2561         return res;
2562     }
2563 
startActivityWithConfig(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, Configuration config, Bundle options, int userId)2564     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
2565             Intent intent, String resolvedType, IBinder resultTo,
2566             String resultWho, int requestCode, int startFlags, Configuration config,
2567             Bundle options, int userId) {
2568         enforceNotIsolatedCaller("startActivityWithConfig");
2569         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2570                 false, true, "startActivityWithConfig", null);
2571         int ret = mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
2572                 resultTo, resultWho, requestCode, startFlags,
2573                 null, null, null, config, options, userId);
2574         return ret;
2575     }
2576 
startActivityIntentSender(IApplicationThread caller, IntentSender intent, Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle options)2577     public int startActivityIntentSender(IApplicationThread caller,
2578             IntentSender intent, Intent fillInIntent, String resolvedType,
2579             IBinder resultTo, String resultWho, int requestCode,
2580             int flagsMask, int flagsValues, Bundle options) {
2581         enforceNotIsolatedCaller("startActivityIntentSender");
2582         // Refuse possible leaked file descriptors
2583         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2584             throw new IllegalArgumentException("File descriptors passed in Intent");
2585         }
2586 
2587         IIntentSender sender = intent.getTarget();
2588         if (!(sender instanceof PendingIntentRecord)) {
2589             throw new IllegalArgumentException("Bad PendingIntent object");
2590         }
2591 
2592         PendingIntentRecord pir = (PendingIntentRecord)sender;
2593 
2594         synchronized (this) {
2595             // If this is coming from the currently resumed activity, it is
2596             // effectively saying that app switches are allowed at this point.
2597             if (mMainStack.mResumedActivity != null
2598                     && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2599                             Binder.getCallingUid()) {
2600                 mAppSwitchesAllowedTime = 0;
2601             }
2602         }
2603         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2604                 resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2605         return ret;
2606     }
2607 
startNextMatchingActivity(IBinder callingActivity, Intent intent, Bundle options)2608     public boolean startNextMatchingActivity(IBinder callingActivity,
2609             Intent intent, Bundle options) {
2610         // Refuse possible leaked file descriptors
2611         if (intent != null && intent.hasFileDescriptors() == true) {
2612             throw new IllegalArgumentException("File descriptors passed in Intent");
2613         }
2614 
2615         synchronized (this) {
2616             ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2617             if (r == null) {
2618                 ActivityOptions.abort(options);
2619                 return false;
2620             }
2621             if (r.app == null || r.app.thread == null) {
2622                 // The caller is not running...  d'oh!
2623                 ActivityOptions.abort(options);
2624                 return false;
2625             }
2626             intent = new Intent(intent);
2627             // The caller is not allowed to change the data.
2628             intent.setDataAndType(r.intent.getData(), r.intent.getType());
2629             // And we are resetting to find the next component...
2630             intent.setComponent(null);
2631 
2632             ActivityInfo aInfo = null;
2633             try {
2634                 List<ResolveInfo> resolves =
2635                     AppGlobals.getPackageManager().queryIntentActivities(
2636                             intent, r.resolvedType,
2637                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2638                             UserHandle.getCallingUserId());
2639 
2640                 // Look for the original activity in the list...
2641                 final int N = resolves != null ? resolves.size() : 0;
2642                 for (int i=0; i<N; i++) {
2643                     ResolveInfo rInfo = resolves.get(i);
2644                     if (rInfo.activityInfo.packageName.equals(r.packageName)
2645                             && rInfo.activityInfo.name.equals(r.info.name)) {
2646                         // We found the current one...  the next matching is
2647                         // after it.
2648                         i++;
2649                         if (i<N) {
2650                             aInfo = resolves.get(i).activityInfo;
2651                         }
2652                         break;
2653                     }
2654                 }
2655             } catch (RemoteException e) {
2656             }
2657 
2658             if (aInfo == null) {
2659                 // Nobody who is next!
2660                 ActivityOptions.abort(options);
2661                 return false;
2662             }
2663 
2664             intent.setComponent(new ComponentName(
2665                     aInfo.applicationInfo.packageName, aInfo.name));
2666             intent.setFlags(intent.getFlags()&~(
2667                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2668                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
2669                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2670                     Intent.FLAG_ACTIVITY_NEW_TASK));
2671 
2672             // Okay now we need to start the new activity, replacing the
2673             // currently running activity.  This is a little tricky because
2674             // we want to start the new one as if the current one is finished,
2675             // but not finish the current one first so that there is no flicker.
2676             // And thus...
2677             final boolean wasFinishing = r.finishing;
2678             r.finishing = true;
2679 
2680             // Propagate reply information over to the new activity.
2681             final ActivityRecord resultTo = r.resultTo;
2682             final String resultWho = r.resultWho;
2683             final int requestCode = r.requestCode;
2684             r.resultTo = null;
2685             if (resultTo != null) {
2686                 resultTo.removeResultsLocked(r, resultWho, requestCode);
2687             }
2688 
2689             final long origId = Binder.clearCallingIdentity();
2690             int res = mMainStack.startActivityLocked(r.app.thread, intent,
2691                     r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2692                     resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
2693                     options, false, null);
2694             Binder.restoreCallingIdentity(origId);
2695 
2696             r.finishing = wasFinishing;
2697             if (res != ActivityManager.START_SUCCESS) {
2698                 return false;
2699             }
2700             return true;
2701         }
2702     }
2703 
startActivityInPackage(int uid, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, Bundle options, int userId)2704     final int startActivityInPackage(int uid, String callingPackage,
2705             Intent intent, String resolvedType, IBinder resultTo,
2706             String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
2707 
2708         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2709                 false, true, "startActivityInPackage", null);
2710 
2711         int ret = mMainStack.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
2712                 resultTo, resultWho, requestCode, startFlags,
2713                 null, null, null, null, options, userId);
2714         return ret;
2715     }
2716 
startActivities(IApplicationThread caller, String callingPackage, Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, int userId)2717     public final int startActivities(IApplicationThread caller, String callingPackage,
2718             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
2719             int userId) {
2720         enforceNotIsolatedCaller("startActivities");
2721         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2722                 false, true, "startActivity", null);
2723         int ret = mMainStack.startActivities(caller, -1, callingPackage, intents,
2724                 resolvedTypes, resultTo, options, userId);
2725         return ret;
2726     }
2727 
startActivitiesInPackage(int uid, String callingPackage, Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, int userId)2728     final int startActivitiesInPackage(int uid, String callingPackage,
2729             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2730             Bundle options, int userId) {
2731 
2732         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2733                 false, true, "startActivityInPackage", null);
2734         int ret = mMainStack.startActivities(null, uid, callingPackage, intents, resolvedTypes,
2735                 resultTo, options, userId);
2736         return ret;
2737     }
2738 
addRecentTaskLocked(TaskRecord task)2739     final void addRecentTaskLocked(TaskRecord task) {
2740         int N = mRecentTasks.size();
2741         // Quick case: check if the top-most recent task is the same.
2742         if (N > 0 && mRecentTasks.get(0) == task) {
2743             return;
2744         }
2745         // Remove any existing entries that are the same kind of task.
2746         for (int i=0; i<N; i++) {
2747             TaskRecord tr = mRecentTasks.get(i);
2748             if (task.userId == tr.userId
2749                     && ((task.affinity != null && task.affinity.equals(tr.affinity))
2750                     || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2751                 mRecentTasks.remove(i);
2752                 i--;
2753                 N--;
2754                 if (task.intent == null) {
2755                     // If the new recent task we are adding is not fully
2756                     // specified, then replace it with the existing recent task.
2757                     task = tr;
2758                 }
2759             }
2760         }
2761         if (N >= MAX_RECENT_TASKS) {
2762             mRecentTasks.remove(N-1);
2763         }
2764         mRecentTasks.add(0, task);
2765     }
2766 
setRequestedOrientation(IBinder token, int requestedOrientation)2767     public void setRequestedOrientation(IBinder token,
2768             int requestedOrientation) {
2769         synchronized (this) {
2770             ActivityRecord r = mMainStack.isInStackLocked(token);
2771             if (r == null) {
2772                 return;
2773             }
2774             final long origId = Binder.clearCallingIdentity();
2775             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2776             Configuration config = mWindowManager.updateOrientationFromAppTokens(
2777                     mConfiguration,
2778                     r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2779             if (config != null) {
2780                 r.frozenBeforeDestroy = true;
2781                 if (!updateConfigurationLocked(config, r, false, false)) {
2782                     mMainStack.resumeTopActivityLocked(null);
2783                 }
2784             }
2785             Binder.restoreCallingIdentity(origId);
2786         }
2787     }
2788 
getRequestedOrientation(IBinder token)2789     public int getRequestedOrientation(IBinder token) {
2790         synchronized (this) {
2791             ActivityRecord r = mMainStack.isInStackLocked(token);
2792             if (r == null) {
2793                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2794             }
2795             return mWindowManager.getAppOrientation(r.appToken);
2796         }
2797     }
2798 
2799     /**
2800      * This is the internal entry point for handling Activity.finish().
2801      *
2802      * @param token The Binder token referencing the Activity we want to finish.
2803      * @param resultCode Result code, if any, from this Activity.
2804      * @param resultData Result data (Intent), if any, from this Activity.
2805      *
2806      * @return Returns true if the activity successfully finished, or false if it is still running.
2807      */
finishActivity(IBinder token, int resultCode, Intent resultData)2808     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2809         // Refuse possible leaked file descriptors
2810         if (resultData != null && resultData.hasFileDescriptors() == true) {
2811             throw new IllegalArgumentException("File descriptors passed in Intent");
2812         }
2813 
2814         synchronized(this) {
2815             if (mController != null) {
2816                 // Find the first activity that is not finishing.
2817                 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2818                 if (next != null) {
2819                     // ask watcher if this is allowed
2820                     boolean resumeOK = true;
2821                     try {
2822                         resumeOK = mController.activityResuming(next.packageName);
2823                     } catch (RemoteException e) {
2824                         mController = null;
2825                         Watchdog.getInstance().setActivityController(null);
2826                     }
2827 
2828                     if (!resumeOK) {
2829                         return false;
2830                     }
2831                 }
2832             }
2833             final long origId = Binder.clearCallingIdentity();
2834             boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2835                     resultData, "app-request", true);
2836             Binder.restoreCallingIdentity(origId);
2837             return res;
2838         }
2839     }
2840 
finishHeavyWeightApp()2841     public final void finishHeavyWeightApp() {
2842         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2843                 != PackageManager.PERMISSION_GRANTED) {
2844             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2845                     + Binder.getCallingPid()
2846                     + ", uid=" + Binder.getCallingUid()
2847                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2848             Slog.w(TAG, msg);
2849             throw new SecurityException(msg);
2850         }
2851 
2852         synchronized(this) {
2853             if (mHeavyWeightProcess == null) {
2854                 return;
2855             }
2856 
2857             ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2858                     mHeavyWeightProcess.activities);
2859             for (int i=0; i<activities.size(); i++) {
2860                 ActivityRecord r = activities.get(i);
2861                 if (!r.finishing) {
2862                     int index = mMainStack.indexOfTokenLocked(r.appToken);
2863                     if (index >= 0) {
2864                         mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2865                                 null, "finish-heavy", true);
2866                     }
2867                 }
2868             }
2869 
2870             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
2871                     mHeavyWeightProcess.userId, 0));
2872             mHeavyWeightProcess = null;
2873         }
2874     }
2875 
crashApplication(int uid, int initialPid, String packageName, String message)2876     public void crashApplication(int uid, int initialPid, String packageName,
2877             String message) {
2878         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2879                 != PackageManager.PERMISSION_GRANTED) {
2880             String msg = "Permission Denial: crashApplication() from pid="
2881                     + Binder.getCallingPid()
2882                     + ", uid=" + Binder.getCallingUid()
2883                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2884             Slog.w(TAG, msg);
2885             throw new SecurityException(msg);
2886         }
2887 
2888         synchronized(this) {
2889             ProcessRecord proc = null;
2890 
2891             // Figure out which process to kill.  We don't trust that initialPid
2892             // still has any relation to current pids, so must scan through the
2893             // list.
2894             synchronized (mPidsSelfLocked) {
2895                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2896                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
2897                     if (p.uid != uid) {
2898                         continue;
2899                     }
2900                     if (p.pid == initialPid) {
2901                         proc = p;
2902                         break;
2903                     }
2904                     for (String str : p.pkgList) {
2905                         if (str.equals(packageName)) {
2906                             proc = p;
2907                         }
2908                     }
2909                 }
2910             }
2911 
2912             if (proc == null) {
2913                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2914                         + " initialPid=" + initialPid
2915                         + " packageName=" + packageName);
2916                 return;
2917             }
2918 
2919             if (proc.thread != null) {
2920                 if (proc.pid == Process.myPid()) {
2921                     Log.w(TAG, "crashApplication: trying to crash self!");
2922                     return;
2923                 }
2924                 long ident = Binder.clearCallingIdentity();
2925                 try {
2926                     proc.thread.scheduleCrash(message);
2927                 } catch (RemoteException e) {
2928                 }
2929                 Binder.restoreCallingIdentity(ident);
2930             }
2931         }
2932     }
2933 
finishSubActivity(IBinder token, String resultWho, int requestCode)2934     public final void finishSubActivity(IBinder token, String resultWho,
2935             int requestCode) {
2936         synchronized(this) {
2937             final long origId = Binder.clearCallingIdentity();
2938             mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2939             Binder.restoreCallingIdentity(origId);
2940         }
2941     }
2942 
finishActivityAffinity(IBinder token)2943     public boolean finishActivityAffinity(IBinder token) {
2944         synchronized(this) {
2945             final long origId = Binder.clearCallingIdentity();
2946             boolean res = mMainStack.finishActivityAffinityLocked(token);
2947             Binder.restoreCallingIdentity(origId);
2948             return res;
2949         }
2950     }
2951 
willActivityBeVisible(IBinder token)2952     public boolean willActivityBeVisible(IBinder token) {
2953         synchronized(this) {
2954             int i;
2955             for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2956                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2957                 if (r.appToken == token) {
2958                     return true;
2959                 }
2960                 if (r.fullscreen && !r.finishing) {
2961                     return false;
2962                 }
2963             }
2964             return true;
2965         }
2966     }
2967 
overridePendingTransition(IBinder token, String packageName, int enterAnim, int exitAnim)2968     public void overridePendingTransition(IBinder token, String packageName,
2969             int enterAnim, int exitAnim) {
2970         synchronized(this) {
2971             ActivityRecord self = mMainStack.isInStackLocked(token);
2972             if (self == null) {
2973                 return;
2974             }
2975 
2976             final long origId = Binder.clearCallingIdentity();
2977 
2978             if (self.state == ActivityState.RESUMED
2979                     || self.state == ActivityState.PAUSING) {
2980                 mWindowManager.overridePendingAppTransition(packageName,
2981                         enterAnim, exitAnim, null);
2982             }
2983 
2984             Binder.restoreCallingIdentity(origId);
2985         }
2986     }
2987 
2988     /**
2989      * Main function for removing an existing process from the activity manager
2990      * as a result of that process going away.  Clears out all connections
2991      * to the process.
2992      */
handleAppDiedLocked(ProcessRecord app, boolean restarting, boolean allowRestart)2993     private final void handleAppDiedLocked(ProcessRecord app,
2994             boolean restarting, boolean allowRestart) {
2995         cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2996         if (!restarting) {
2997             mLruProcesses.remove(app);
2998         }
2999 
3000         if (mProfileProc == app) {
3001             clearProfilerLocked();
3002         }
3003 
3004         // Just in case...
3005         if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
3006             if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG,
3007                     "App died while pausing: " + mMainStack.mPausingActivity);
3008             mMainStack.mPausingActivity = null;
3009         }
3010         if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
3011             mMainStack.mLastPausedActivity = null;
3012         }
3013 
3014         // Remove this application's activities from active lists.
3015         boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app);
3016 
3017         app.activities.clear();
3018 
3019         if (app.instrumentationClass != null) {
3020             Slog.w(TAG, "Crash of app " + app.processName
3021                   + " running instrumentation " + app.instrumentationClass);
3022             Bundle info = new Bundle();
3023             info.putString("shortMsg", "Process crashed.");
3024             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3025         }
3026 
3027         if (!restarting) {
3028             if (!mMainStack.resumeTopActivityLocked(null)) {
3029                 // If there was nothing to resume, and we are not already
3030                 // restarting this process, but there is a visible activity that
3031                 // is hosted by the process...  then make sure all visible
3032                 // activities are running, taking care of restarting this
3033                 // process.
3034                 if (hasVisibleActivities) {
3035                     mMainStack.ensureActivitiesVisibleLocked(null, 0);
3036                 }
3037             }
3038         }
3039     }
3040 
getLRURecordIndexForAppLocked(IApplicationThread thread)3041     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3042         IBinder threadBinder = thread.asBinder();
3043         // Find the application record.
3044         for (int i=mLruProcesses.size()-1; i>=0; i--) {
3045             ProcessRecord rec = mLruProcesses.get(i);
3046             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3047                 return i;
3048             }
3049         }
3050         return -1;
3051     }
3052 
getRecordForAppLocked( IApplicationThread thread)3053     final ProcessRecord getRecordForAppLocked(
3054             IApplicationThread thread) {
3055         if (thread == null) {
3056             return null;
3057         }
3058 
3059         int appIndex = getLRURecordIndexForAppLocked(thread);
3060         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3061     }
3062 
appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread)3063     final void appDiedLocked(ProcessRecord app, int pid,
3064             IApplicationThread thread) {
3065 
3066         mProcDeaths[0]++;
3067 
3068         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3069         synchronized (stats) {
3070             stats.noteProcessDiedLocked(app.info.uid, pid);
3071         }
3072 
3073         // Clean up already done if the process has been re-started.
3074         if (app.pid == pid && app.thread != null &&
3075                 app.thread.asBinder() == thread.asBinder()) {
3076             if (!app.killedBackground) {
3077                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3078                         + ") has died.");
3079             }
3080             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3081             if (DEBUG_CLEANUP) Slog.v(
3082                 TAG, "Dying app: " + app + ", pid: " + pid
3083                 + ", thread: " + thread.asBinder());
3084             boolean doLowMem = app.instrumentationClass == null;
3085             handleAppDiedLocked(app, false, true);
3086 
3087             if (doLowMem) {
3088                 // If there are no longer any background processes running,
3089                 // and the app that died was not running instrumentation,
3090                 // then tell everyone we are now low on memory.
3091                 boolean haveBg = false;
3092                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3093                     ProcessRecord rec = mLruProcesses.get(i);
3094                     if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3095                         haveBg = true;
3096                         break;
3097                     }
3098                 }
3099 
3100                 if (!haveBg) {
3101                     EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3102                     long now = SystemClock.uptimeMillis();
3103                     for (int i=mLruProcesses.size()-1; i>=0; i--) {
3104                         ProcessRecord rec = mLruProcesses.get(i);
3105                         if (rec != app && rec.thread != null &&
3106                                 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3107                             // The low memory report is overriding any current
3108                             // state for a GC request.  Make sure to do
3109                             // heavy/important/visible/foreground processes first.
3110                             if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3111                                 rec.lastRequestedGc = 0;
3112                             } else {
3113                                 rec.lastRequestedGc = rec.lastLowMemory;
3114                             }
3115                             rec.reportLowMemory = true;
3116                             rec.lastLowMemory = now;
3117                             mProcessesToGc.remove(rec);
3118                             addProcessToGcListLocked(rec);
3119                         }
3120                     }
3121                     mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3122                     scheduleAppGcsLocked();
3123                 }
3124             }
3125         } else if (app.pid != pid) {
3126             // A new process has already been started.
3127             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3128                     + ") has died and restarted (pid " + app.pid + ").");
3129             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3130         } else if (DEBUG_PROCESSES) {
3131             Slog.d(TAG, "Received spurious death notification for thread "
3132                     + thread.asBinder());
3133         }
3134     }
3135 
3136     /**
3137      * If a stack trace dump file is configured, dump process stack traces.
3138      * @param clearTraces causes the dump file to be erased prior to the new
3139      *    traces being written, if true; when false, the new traces will be
3140      *    appended to any existing file content.
3141      * @param firstPids of dalvik VM processes to dump stack traces for first
3142      * @param lastPids of dalvik VM processes to dump stack traces for last
3143      * @param nativeProcs optional list of native process names to dump stack crawls
3144      * @return file containing stack traces, or null if no dump file is configured
3145      */
dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs)3146     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3147             ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3148         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3149         if (tracesPath == null || tracesPath.length() == 0) {
3150             return null;
3151         }
3152 
3153         File tracesFile = new File(tracesPath);
3154         try {
3155             File tracesDir = tracesFile.getParentFile();
3156             if (!tracesDir.exists()) {
3157                 tracesFile.mkdirs();
3158                 if (!SELinux.restorecon(tracesDir)) {
3159                     return null;
3160                 }
3161             }
3162             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3163 
3164             if (clearTraces && tracesFile.exists()) tracesFile.delete();
3165             tracesFile.createNewFile();
3166             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3167         } catch (IOException e) {
3168             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3169             return null;
3170         }
3171 
3172         dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3173         return tracesFile;
3174     }
3175 
dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs)3176     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3177             ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3178         // Use a FileObserver to detect when traces finish writing.
3179         // The order of traces is considered important to maintain for legibility.
3180         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3181             public synchronized void onEvent(int event, String path) { notify(); }
3182         };
3183 
3184         try {
3185             observer.startWatching();
3186 
3187             // First collect all of the stacks of the most important pids.
3188             if (firstPids != null) {
3189                 try {
3190                     int num = firstPids.size();
3191                     for (int i = 0; i < num; i++) {
3192                         synchronized (observer) {
3193                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3194                             observer.wait(200);  // Wait for write-close, give up after 200msec
3195                         }
3196                     }
3197                 } catch (InterruptedException e) {
3198                     Log.wtf(TAG, e);
3199                 }
3200             }
3201 
3202             // Next measure CPU usage.
3203             if (processStats != null) {
3204                 processStats.init();
3205                 System.gc();
3206                 processStats.update();
3207                 try {
3208                     synchronized (processStats) {
3209                         processStats.wait(500); // measure over 1/2 second.
3210                     }
3211                 } catch (InterruptedException e) {
3212                 }
3213                 processStats.update();
3214 
3215                 // We'll take the stack crawls of just the top apps using CPU.
3216                 final int N = processStats.countWorkingStats();
3217                 int numProcs = 0;
3218                 for (int i=0; i<N && numProcs<5; i++) {
3219                     ProcessStats.Stats stats = processStats.getWorkingStats(i);
3220                     if (lastPids.indexOfKey(stats.pid) >= 0) {
3221                         numProcs++;
3222                         try {
3223                             synchronized (observer) {
3224                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3225                                 observer.wait(200);  // Wait for write-close, give up after 200msec
3226                             }
3227                         } catch (InterruptedException e) {
3228                             Log.wtf(TAG, e);
3229                         }
3230 
3231                     }
3232                 }
3233             }
3234 
3235         } finally {
3236             observer.stopWatching();
3237         }
3238 
3239         if (nativeProcs != null) {
3240             int[] pids = Process.getPidsForCommands(nativeProcs);
3241             if (pids != null) {
3242                 for (int pid : pids) {
3243                     Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3244                 }
3245             }
3246         }
3247     }
3248 
logAppTooSlow(ProcessRecord app, long startTime, String msg)3249     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3250         if (true || IS_USER_BUILD) {
3251             return;
3252         }
3253         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3254         if (tracesPath == null || tracesPath.length() == 0) {
3255             return;
3256         }
3257 
3258         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3259         StrictMode.allowThreadDiskWrites();
3260         try {
3261             final File tracesFile = new File(tracesPath);
3262             final File tracesDir = tracesFile.getParentFile();
3263             final File tracesTmp = new File(tracesDir, "__tmp__");
3264             try {
3265                 if (!tracesDir.exists()) {
3266                     tracesFile.mkdirs();
3267                     if (!SELinux.restorecon(tracesDir.getPath())) {
3268                         return;
3269                     }
3270                 }
3271                 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3272 
3273                 if (tracesFile.exists()) {
3274                     tracesTmp.delete();
3275                     tracesFile.renameTo(tracesTmp);
3276                 }
3277                 StringBuilder sb = new StringBuilder();
3278                 Time tobj = new Time();
3279                 tobj.set(System.currentTimeMillis());
3280                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3281                 sb.append(": ");
3282                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3283                 sb.append(" since ");
3284                 sb.append(msg);
3285                 FileOutputStream fos = new FileOutputStream(tracesFile);
3286                 fos.write(sb.toString().getBytes());
3287                 if (app == null) {
3288                     fos.write("\n*** No application process!".getBytes());
3289                 }
3290                 fos.close();
3291                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3292             } catch (IOException e) {
3293                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3294                 return;
3295             }
3296 
3297             if (app != null) {
3298                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
3299                 firstPids.add(app.pid);
3300                 dumpStackTraces(tracesPath, firstPids, null, null, null);
3301             }
3302 
3303             File lastTracesFile = null;
3304             File curTracesFile = null;
3305             for (int i=9; i>=0; i--) {
3306                 String name = String.format("slow%02d.txt", i);
3307                 curTracesFile = new File(tracesDir, name);
3308                 if (curTracesFile.exists()) {
3309                     if (lastTracesFile != null) {
3310                         curTracesFile.renameTo(lastTracesFile);
3311                     } else {
3312                         curTracesFile.delete();
3313                     }
3314                 }
3315                 lastTracesFile = curTracesFile;
3316             }
3317             tracesFile.renameTo(curTracesFile);
3318             if (tracesTmp.exists()) {
3319                 tracesTmp.renameTo(tracesFile);
3320             }
3321         } finally {
3322             StrictMode.setThreadPolicy(oldPolicy);
3323         }
3324     }
3325 
appNotResponding(ProcessRecord app, ActivityRecord activity, ActivityRecord parent, boolean aboveSystem, final String annotation)3326     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3327             ActivityRecord parent, boolean aboveSystem, final String annotation) {
3328         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3329         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3330 
3331         if (mController != null) {
3332             try {
3333                 // 0 == continue, -1 = kill process immediately
3334                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3335                 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3336             } catch (RemoteException e) {
3337                 mController = null;
3338                 Watchdog.getInstance().setActivityController(null);
3339             }
3340         }
3341 
3342         long anrTime = SystemClock.uptimeMillis();
3343         if (MONITOR_CPU_USAGE) {
3344             updateCpuStatsNow();
3345         }
3346 
3347         synchronized (this) {
3348             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3349             if (mShuttingDown) {
3350                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3351                 return;
3352             } else if (app.notResponding) {
3353                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3354                 return;
3355             } else if (app.crashing) {
3356                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3357                 return;
3358             }
3359 
3360             // In case we come through here for the same app before completing
3361             // this one, mark as anring now so we will bail out.
3362             app.notResponding = true;
3363 
3364             // Log the ANR to the event log.
3365             EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3366                     app.processName, app.info.flags, annotation);
3367 
3368             // Dump thread traces as quickly as we can, starting with "interesting" processes.
3369             firstPids.add(app.pid);
3370 
3371             int parentPid = app.pid;
3372             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3373             if (parentPid != app.pid) firstPids.add(parentPid);
3374 
3375             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3376 
3377             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3378                 ProcessRecord r = mLruProcesses.get(i);
3379                 if (r != null && r.thread != null) {
3380                     int pid = r.pid;
3381                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3382                         if (r.persistent) {
3383                             firstPids.add(pid);
3384                         } else {
3385                             lastPids.put(pid, Boolean.TRUE);
3386                         }
3387                     }
3388                 }
3389             }
3390         }
3391 
3392         // Log the ANR to the main log.
3393         StringBuilder info = new StringBuilder();
3394         info.setLength(0);
3395         info.append("ANR in ").append(app.processName);
3396         if (activity != null && activity.shortComponentName != null) {
3397             info.append(" (").append(activity.shortComponentName).append(")");
3398         }
3399         info.append("\n");
3400         if (annotation != null) {
3401             info.append("Reason: ").append(annotation).append("\n");
3402         }
3403         if (parent != null && parent != activity) {
3404             info.append("Parent: ").append(parent.shortComponentName).append("\n");
3405         }
3406 
3407         final ProcessStats processStats = new ProcessStats(true);
3408 
3409         File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3410 
3411         String cpuInfo = null;
3412         if (MONITOR_CPU_USAGE) {
3413             updateCpuStatsNow();
3414             synchronized (mProcessStatsThread) {
3415                 cpuInfo = mProcessStats.printCurrentState(anrTime);
3416             }
3417             info.append(processStats.printCurrentLoad());
3418             info.append(cpuInfo);
3419         }
3420 
3421         info.append(processStats.printCurrentState(anrTime));
3422 
3423         Slog.e(TAG, info.toString());
3424         if (tracesFile == null) {
3425             // There is no trace file, so dump (only) the alleged culprit's threads to the log
3426             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3427         }
3428 
3429         addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3430                 cpuInfo, tracesFile, null);
3431 
3432         if (mController != null) {
3433             try {
3434                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3435                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3436                 if (res != 0) {
3437                     if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3438                     return;
3439                 }
3440             } catch (RemoteException e) {
3441                 mController = null;
3442                 Watchdog.getInstance().setActivityController(null);
3443             }
3444         }
3445 
3446         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3447         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3448                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3449 
3450         synchronized (this) {
3451             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3452                 Slog.w(TAG, "Killing " + app + ": background ANR");
3453                 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
3454                         app.processName, app.setAdj, "background ANR");
3455                 Process.killProcessQuiet(app.pid);
3456                 return;
3457             }
3458 
3459             // Set the app's notResponding state, and look up the errorReportReceiver
3460             makeAppNotRespondingLocked(app,
3461                     activity != null ? activity.shortComponentName : null,
3462                     annotation != null ? "ANR " + annotation : "ANR",
3463                     info.toString());
3464 
3465             // Bring up the infamous App Not Responding dialog
3466             Message msg = Message.obtain();
3467             HashMap map = new HashMap();
3468             msg.what = SHOW_NOT_RESPONDING_MSG;
3469             msg.obj = map;
3470             msg.arg1 = aboveSystem ? 1 : 0;
3471             map.put("app", app);
3472             if (activity != null) {
3473                 map.put("activity", activity);
3474             }
3475 
3476             mHandler.sendMessage(msg);
3477         }
3478     }
3479 
showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next)3480     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3481         if (!mLaunchWarningShown) {
3482             mLaunchWarningShown = true;
3483             mHandler.post(new Runnable() {
3484                 @Override
3485                 public void run() {
3486                     synchronized (ActivityManagerService.this) {
3487                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3488                         d.show();
3489                         mHandler.postDelayed(new Runnable() {
3490                             @Override
3491                             public void run() {
3492                                 synchronized (ActivityManagerService.this) {
3493                                     d.dismiss();
3494                                     mLaunchWarningShown = false;
3495                                 }
3496                             }
3497                         }, 4000);
3498                     }
3499                 }
3500             });
3501         }
3502     }
3503 
clearApplicationUserData(final String packageName, final IPackageDataObserver observer, int userId)3504     public boolean clearApplicationUserData(final String packageName,
3505             final IPackageDataObserver observer, int userId) {
3506         enforceNotIsolatedCaller("clearApplicationUserData");
3507         int uid = Binder.getCallingUid();
3508         int pid = Binder.getCallingPid();
3509         userId = handleIncomingUser(pid, uid,
3510                 userId, false, true, "clearApplicationUserData", null);
3511         long callingId = Binder.clearCallingIdentity();
3512         try {
3513             IPackageManager pm = AppGlobals.getPackageManager();
3514             int pkgUid = -1;
3515             synchronized(this) {
3516                 try {
3517                     pkgUid = pm.getPackageUid(packageName, userId);
3518                 } catch (RemoteException e) {
3519                 }
3520                 if (pkgUid == -1) {
3521                     Slog.w(TAG, "Invalid packageName: " + packageName);
3522                     if (observer != null) {
3523                         try {
3524                             observer.onRemoveCompleted(packageName, false);
3525                         } catch (RemoteException e) {
3526                             Slog.i(TAG, "Observer no longer exists.");
3527                         }
3528                     }
3529                     return false;
3530                 }
3531                 if (uid == pkgUid || checkComponentPermission(
3532                         android.Manifest.permission.CLEAR_APP_USER_DATA,
3533                         pid, uid, -1, true)
3534                         == PackageManager.PERMISSION_GRANTED) {
3535                     forceStopPackageLocked(packageName, pkgUid);
3536                 } else {
3537                     throw new SecurityException(pid+" does not have permission:"+
3538                             android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3539                                     "for process:"+packageName);
3540                 }
3541             }
3542 
3543             try {
3544                 //clear application user data
3545                 pm.clearApplicationUserData(packageName, observer, userId);
3546                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3547                         Uri.fromParts("package", packageName, null));
3548                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
3549                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3550                         null, null, 0, null, null, null, false, false, userId);
3551             } catch (RemoteException e) {
3552             }
3553         } finally {
3554             Binder.restoreCallingIdentity(callingId);
3555         }
3556         return true;
3557     }
3558 
killBackgroundProcesses(final String packageName, int userId)3559     public void killBackgroundProcesses(final String packageName, int userId) {
3560         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3561                 != PackageManager.PERMISSION_GRANTED &&
3562                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3563                         != PackageManager.PERMISSION_GRANTED) {
3564             String msg = "Permission Denial: killBackgroundProcesses() from pid="
3565                     + Binder.getCallingPid()
3566                     + ", uid=" + Binder.getCallingUid()
3567                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3568             Slog.w(TAG, msg);
3569             throw new SecurityException(msg);
3570         }
3571 
3572         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3573                 userId, true, true, "killBackgroundProcesses", null);
3574         long callingId = Binder.clearCallingIdentity();
3575         try {
3576             IPackageManager pm = AppGlobals.getPackageManager();
3577             synchronized(this) {
3578                 int appId = -1;
3579                 try {
3580                     appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
3581                 } catch (RemoteException e) {
3582                 }
3583                 if (appId == -1) {
3584                     Slog.w(TAG, "Invalid packageName: " + packageName);
3585                     return;
3586                 }
3587                 killPackageProcessesLocked(packageName, appId, userId,
3588                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3589             }
3590         } finally {
3591             Binder.restoreCallingIdentity(callingId);
3592         }
3593     }
3594 
killAllBackgroundProcesses()3595     public void killAllBackgroundProcesses() {
3596         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3597                 != PackageManager.PERMISSION_GRANTED) {
3598             String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3599                     + Binder.getCallingPid()
3600                     + ", uid=" + Binder.getCallingUid()
3601                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3602             Slog.w(TAG, msg);
3603             throw new SecurityException(msg);
3604         }
3605 
3606         long callingId = Binder.clearCallingIdentity();
3607         try {
3608             synchronized(this) {
3609                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3610                 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3611                     final int NA = apps.size();
3612                     for (int ia=0; ia<NA; ia++) {
3613                         ProcessRecord app = apps.valueAt(ia);
3614                         if (app.persistent) {
3615                             // we don't kill persistent processes
3616                             continue;
3617                         }
3618                         if (app.removed) {
3619                             procs.add(app);
3620                         } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3621                             app.removed = true;
3622                             procs.add(app);
3623                         }
3624                     }
3625                 }
3626 
3627                 int N = procs.size();
3628                 for (int i=0; i<N; i++) {
3629                     removeProcessLocked(procs.get(i), false, true, "kill all background");
3630                 }
3631             }
3632         } finally {
3633             Binder.restoreCallingIdentity(callingId);
3634         }
3635     }
3636 
forceStopPackage(final String packageName, int userId)3637     public void forceStopPackage(final String packageName, int userId) {
3638         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3639                 != PackageManager.PERMISSION_GRANTED) {
3640             String msg = "Permission Denial: forceStopPackage() from pid="
3641                     + Binder.getCallingPid()
3642                     + ", uid=" + Binder.getCallingUid()
3643                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3644             Slog.w(TAG, msg);
3645             throw new SecurityException(msg);
3646         }
3647         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3648                 userId, true, true, "forceStopPackage", null);
3649         long callingId = Binder.clearCallingIdentity();
3650         try {
3651             IPackageManager pm = AppGlobals.getPackageManager();
3652             synchronized(this) {
3653                 int[] users = userId == UserHandle.USER_ALL
3654                         ? getUsersLocked() : new int[] { userId };
3655                 for (int user : users) {
3656                     int pkgUid = -1;
3657                     try {
3658                         pkgUid = pm.getPackageUid(packageName, user);
3659                     } catch (RemoteException e) {
3660                     }
3661                     if (pkgUid == -1) {
3662                         Slog.w(TAG, "Invalid packageName: " + packageName);
3663                         continue;
3664                     }
3665                     try {
3666                         pm.setPackageStoppedState(packageName, true, user);
3667                     } catch (RemoteException e) {
3668                     } catch (IllegalArgumentException e) {
3669                         Slog.w(TAG, "Failed trying to unstop package "
3670                                 + packageName + ": " + e);
3671                     }
3672                     if (isUserRunningLocked(user, false)) {
3673                         forceStopPackageLocked(packageName, pkgUid);
3674                     }
3675                 }
3676             }
3677         } finally {
3678             Binder.restoreCallingIdentity(callingId);
3679         }
3680     }
3681 
3682     /*
3683      * The pkg name and app id have to be specified.
3684      */
killApplicationWithAppId(String pkg, int appid)3685     public void killApplicationWithAppId(String pkg, int appid) {
3686         if (pkg == null) {
3687             return;
3688         }
3689         // Make sure the uid is valid.
3690         if (appid < 0) {
3691             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
3692             return;
3693         }
3694         int callerUid = Binder.getCallingUid();
3695         // Only the system server can kill an application
3696         if (callerUid == Process.SYSTEM_UID) {
3697             // Post an aysnc message to kill the application
3698             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3699             msg.arg1 = appid;
3700             msg.arg2 = 0;
3701             msg.obj = pkg;
3702             mHandler.sendMessage(msg);
3703         } else {
3704             throw new SecurityException(callerUid + " cannot kill pkg: " +
3705                     pkg);
3706         }
3707     }
3708 
closeSystemDialogs(String reason)3709     public void closeSystemDialogs(String reason) {
3710         enforceNotIsolatedCaller("closeSystemDialogs");
3711 
3712         final int pid = Binder.getCallingPid();
3713         final int uid = Binder.getCallingUid();
3714         final long origId = Binder.clearCallingIdentity();
3715         try {
3716             synchronized (this) {
3717                 // Only allow this from foreground processes, so that background
3718                 // applications can't abuse it to prevent system UI from being shown.
3719                 if (uid >= Process.FIRST_APPLICATION_UID) {
3720                     ProcessRecord proc;
3721                     synchronized (mPidsSelfLocked) {
3722                         proc = mPidsSelfLocked.get(pid);
3723                     }
3724                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
3725                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
3726                                 + " from background process " + proc);
3727                         return;
3728                     }
3729                 }
3730                 closeSystemDialogsLocked(reason);
3731             }
3732         } finally {
3733             Binder.restoreCallingIdentity(origId);
3734         }
3735     }
3736 
closeSystemDialogsLocked(String reason)3737     void closeSystemDialogsLocked(String reason) {
3738         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3739         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3740                 | Intent.FLAG_RECEIVER_FOREGROUND);
3741         if (reason != null) {
3742             intent.putExtra("reason", reason);
3743         }
3744         mWindowManager.closeSystemDialogs(reason);
3745 
3746         for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3747             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3748             if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3749                 r.stack.finishActivityLocked(r, i,
3750                         Activity.RESULT_CANCELED, null, "close-sys", true);
3751             }
3752         }
3753 
3754         broadcastIntentLocked(null, null, intent, null,
3755                 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
3756                 Process.SYSTEM_UID, UserHandle.USER_ALL);
3757     }
3758 
getProcessMemoryInfo(int[] pids)3759     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3760             throws RemoteException {
3761         enforceNotIsolatedCaller("getProcessMemoryInfo");
3762         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3763         for (int i=pids.length-1; i>=0; i--) {
3764             infos[i] = new Debug.MemoryInfo();
3765             Debug.getMemoryInfo(pids[i], infos[i]);
3766         }
3767         return infos;
3768     }
3769 
getProcessPss(int[] pids)3770     public long[] getProcessPss(int[] pids) throws RemoteException {
3771         enforceNotIsolatedCaller("getProcessPss");
3772         long[] pss = new long[pids.length];
3773         for (int i=pids.length-1; i>=0; i--) {
3774             pss[i] = Debug.getPss(pids[i]);
3775         }
3776         return pss;
3777     }
3778 
killApplicationProcess(String processName, int uid)3779     public void killApplicationProcess(String processName, int uid) {
3780         if (processName == null) {
3781             return;
3782         }
3783 
3784         int callerUid = Binder.getCallingUid();
3785         // Only the system server can kill an application
3786         if (callerUid == Process.SYSTEM_UID) {
3787             synchronized (this) {
3788                 ProcessRecord app = getProcessRecordLocked(processName, uid);
3789                 if (app != null && app.thread != null) {
3790                     try {
3791                         app.thread.scheduleSuicide();
3792                     } catch (RemoteException e) {
3793                         // If the other end already died, then our work here is done.
3794                     }
3795                 } else {
3796                     Slog.w(TAG, "Process/uid not found attempting kill of "
3797                             + processName + " / " + uid);
3798                 }
3799             }
3800         } else {
3801             throw new SecurityException(callerUid + " cannot kill app process: " +
3802                     processName);
3803         }
3804     }
3805 
forceStopPackageLocked(final String packageName, int uid)3806     private void forceStopPackageLocked(final String packageName, int uid) {
3807         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
3808                 false, true, false, UserHandle.getUserId(uid));
3809         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3810                 Uri.fromParts("package", packageName, null));
3811         if (!mProcessesReady) {
3812             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3813                     | Intent.FLAG_RECEIVER_FOREGROUND);
3814         }
3815         intent.putExtra(Intent.EXTRA_UID, uid);
3816         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
3817         broadcastIntentLocked(null, null, intent,
3818                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
3819                 false, false,
3820                 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3821     }
3822 
forceStopUserLocked(int userId)3823     private void forceStopUserLocked(int userId) {
3824         forceStopPackageLocked(null, -1, false, false, true, false, userId);
3825         Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3826         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3827                 | Intent.FLAG_RECEIVER_FOREGROUND);
3828         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3829         broadcastIntentLocked(null, null, intent,
3830                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
3831                 false, false,
3832                 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
3833     }
3834 
killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, boolean evenPersistent, String reason)3835     private final boolean killPackageProcessesLocked(String packageName, int appId,
3836             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3837             boolean doit, boolean evenPersistent, String reason) {
3838         ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3839 
3840         // Remove all processes this package may have touched: all with the
3841         // same UID (except for the system or root user), and all whose name
3842         // matches the package name.
3843         final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3844         for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3845             final int NA = apps.size();
3846             for (int ia=0; ia<NA; ia++) {
3847                 ProcessRecord app = apps.valueAt(ia);
3848                 if (app.persistent && !evenPersistent) {
3849                     // we don't kill persistent processes
3850                     continue;
3851                 }
3852                 if (app.removed) {
3853                     if (doit) {
3854                         procs.add(app);
3855                     }
3856                     continue;
3857                 }
3858 
3859                 // Skip process if it doesn't meet our oom adj requirement.
3860                 if (app.setAdj < minOomAdj) {
3861                     continue;
3862                 }
3863 
3864                 // If no package is specified, we call all processes under the
3865                 // give user id.
3866                 if (packageName == null) {
3867                     if (app.userId != userId) {
3868                         continue;
3869                     }
3870                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
3871                         continue;
3872                     }
3873                 // Package has been specified, we want to hit all processes
3874                 // that match it.  We need to qualify this by the processes
3875                 // that are running under the specified app and user ID.
3876                 } else {
3877                     if (UserHandle.getAppId(app.uid) != appId) {
3878                         continue;
3879                     }
3880                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
3881                         continue;
3882                     }
3883                     if (!app.pkgList.contains(packageName)) {
3884                         continue;
3885                     }
3886                 }
3887 
3888                 // Process has passed all conditions, kill it!
3889                 if (!doit) {
3890                     return true;
3891                 }
3892                 app.removed = true;
3893                 procs.add(app);
3894             }
3895         }
3896 
3897         int N = procs.size();
3898         for (int i=0; i<N; i++) {
3899             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3900         }
3901         return N > 0;
3902     }
3903 
forceStopPackageLocked(String name, int appId, boolean callerWillRestart, boolean purgeCache, boolean doit, boolean evenPersistent, int userId)3904     private final boolean forceStopPackageLocked(String name, int appId,
3905             boolean callerWillRestart, boolean purgeCache, boolean doit,
3906             boolean evenPersistent, int userId) {
3907         int i;
3908         int N;
3909 
3910         if (userId == UserHandle.USER_ALL && name == null) {
3911             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
3912         }
3913 
3914         if (appId < 0 && name != null) {
3915             try {
3916                 appId = UserHandle.getAppId(
3917                         AppGlobals.getPackageManager().getPackageUid(name, 0));
3918             } catch (RemoteException e) {
3919             }
3920         }
3921 
3922         if (doit) {
3923             if (name != null) {
3924                 Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
3925                         + " user=" + userId);
3926             } else {
3927                 Slog.i(TAG, "Force stopping user " + userId);
3928             }
3929 
3930             Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3931             while (badApps.hasNext()) {
3932                 SparseArray<Long> ba = badApps.next();
3933                 for (i=ba.size()-1; i>=0; i--) {
3934                     boolean remove = false;
3935                     final int entUid = ba.keyAt(i);
3936                     if (name != null) {
3937                         if (userId == UserHandle.USER_ALL) {
3938                             if (UserHandle.getAppId(entUid) == appId) {
3939                                 remove = true;
3940                             }
3941                         } else {
3942                             if (entUid == UserHandle.getUid(userId, appId)) {
3943                                 remove = true;
3944                             }
3945                         }
3946                     } else if (UserHandle.getUserId(entUid) == userId) {
3947                         remove = true;
3948                     }
3949                     if (remove) {
3950                         ba.removeAt(i);
3951                     }
3952                 }
3953                 if (ba.size() == 0) {
3954                     badApps.remove();
3955                 }
3956             }
3957         }
3958 
3959         boolean didSomething = killPackageProcessesLocked(name, appId, userId,
3960                 -100, callerWillRestart, true, doit, evenPersistent,
3961                 name == null ? ("force stop user " + userId) : ("force stop " + name));
3962 
3963         TaskRecord lastTask = null;
3964         for (i=0; i<mMainStack.mHistory.size(); i++) {
3965             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3966             final boolean samePackage = r.packageName.equals(name)
3967                     || (name == null && r.userId == userId);
3968             if ((userId == UserHandle.USER_ALL || r.userId == userId)
3969                     && (samePackage || r.task == lastTask)
3970                     && (r.app == null || evenPersistent || !r.app.persistent)) {
3971                 if (!doit) {
3972                     if (r.finishing) {
3973                         // If this activity is just finishing, then it is not
3974                         // interesting as far as something to stop.
3975                         continue;
3976                     }
3977                     return true;
3978                 }
3979                 didSomething = true;
3980                 Slog.i(TAG, "  Force finishing activity " + r);
3981                 if (samePackage) {
3982                     if (r.app != null) {
3983                         r.app.removed = true;
3984                     }
3985                     r.app = null;
3986                 }
3987                 lastTask = r.task;
3988                 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3989                         null, "force-stop", true)) {
3990                     i--;
3991                 }
3992             }
3993         }
3994 
3995         if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3996             if (!doit) {
3997                 return true;
3998             }
3999             didSomething = true;
4000         }
4001 
4002         if (name == null) {
4003             // Remove all sticky broadcasts from this user.
4004             mStickyBroadcasts.remove(userId);
4005         }
4006 
4007         ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4008         if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4009                 userId, providers)) {
4010             if (!doit) {
4011                 return true;
4012             }
4013             didSomething = true;
4014         }
4015         N = providers.size();
4016         for (i=0; i<N; i++) {
4017             removeDyingProviderLocked(null, providers.get(i), true);
4018         }
4019 
4020         if (name == null) {
4021             // Remove pending intents.  For now we only do this when force
4022             // stopping users, because we have some problems when doing this
4023             // for packages -- app widgets are not currently cleaned up for
4024             // such packages, so they can be left with bad pending intents.
4025             if (mIntentSenderRecords.size() > 0) {
4026                 Iterator<WeakReference<PendingIntentRecord>> it
4027                         = mIntentSenderRecords.values().iterator();
4028                 while (it.hasNext()) {
4029                     WeakReference<PendingIntentRecord> wpir = it.next();
4030                     if (wpir == null) {
4031                         it.remove();
4032                         continue;
4033                     }
4034                     PendingIntentRecord pir = wpir.get();
4035                     if (pir == null) {
4036                         it.remove();
4037                         continue;
4038                     }
4039                     if (name == null) {
4040                         // Stopping user, remove all objects for the user.
4041                         if (pir.key.userId != userId) {
4042                             // Not the same user, skip it.
4043                             continue;
4044                         }
4045                     } else {
4046                         if (UserHandle.getAppId(pir.uid) != appId) {
4047                             // Different app id, skip it.
4048                             continue;
4049                         }
4050                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4051                             // Different user, skip it.
4052                             continue;
4053                         }
4054                         if (!pir.key.packageName.equals(name)) {
4055                             // Different package, skip it.
4056                             continue;
4057                         }
4058                     }
4059                     if (!doit) {
4060                         return true;
4061                     }
4062                     didSomething = true;
4063                     it.remove();
4064                     pir.canceled = true;
4065                     if (pir.key.activity != null) {
4066                         pir.key.activity.pendingResults.remove(pir.ref);
4067                     }
4068                 }
4069             }
4070         }
4071 
4072         if (doit) {
4073             if (purgeCache && name != null) {
4074                 AttributeCache ac = AttributeCache.instance();
4075                 if (ac != null) {
4076                     ac.removePackage(name);
4077                 }
4078             }
4079             if (mBooted) {
4080                 mMainStack.resumeTopActivityLocked(null);
4081                 mMainStack.scheduleIdleLocked();
4082             }
4083         }
4084 
4085         return didSomething;
4086     }
4087 
removeProcessLocked(ProcessRecord app, boolean callerWillRestart, boolean allowRestart, String reason)4088     private final boolean removeProcessLocked(ProcessRecord app,
4089             boolean callerWillRestart, boolean allowRestart, String reason) {
4090         final String name = app.processName;
4091         final int uid = app.uid;
4092         if (DEBUG_PROCESSES) Slog.d(
4093             TAG, "Force removing proc " + app.toShortString() + " (" + name
4094             + "/" + uid + ")");
4095 
4096         mProcessNames.remove(name, uid);
4097         mIsolatedProcesses.remove(app.uid);
4098         if (mHeavyWeightProcess == app) {
4099             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4100                     mHeavyWeightProcess.userId, 0));
4101             mHeavyWeightProcess = null;
4102         }
4103         boolean needRestart = false;
4104         if (app.pid > 0 && app.pid != MY_PID) {
4105             int pid = app.pid;
4106             synchronized (mPidsSelfLocked) {
4107                 mPidsSelfLocked.remove(pid);
4108                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4109             }
4110             Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
4111             handleAppDiedLocked(app, true, allowRestart);
4112             mLruProcesses.remove(app);
4113             Process.killProcessQuiet(pid);
4114 
4115             if (app.persistent && !app.isolated) {
4116                 if (!callerWillRestart) {
4117                     addAppLocked(app.info, false);
4118                 } else {
4119                     needRestart = true;
4120                 }
4121             }
4122         } else {
4123             mRemovedProcesses.add(app);
4124         }
4125 
4126         return needRestart;
4127     }
4128 
processStartTimedOutLocked(ProcessRecord app)4129     private final void processStartTimedOutLocked(ProcessRecord app) {
4130         final int pid = app.pid;
4131         boolean gone = false;
4132         synchronized (mPidsSelfLocked) {
4133             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4134             if (knownApp != null && knownApp.thread == null) {
4135                 mPidsSelfLocked.remove(pid);
4136                 gone = true;
4137             }
4138         }
4139 
4140         if (gone) {
4141             Slog.w(TAG, "Process " + app + " failed to attach");
4142             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4143                     pid, app.uid, app.processName);
4144             mProcessNames.remove(app.processName, app.uid);
4145             mIsolatedProcesses.remove(app.uid);
4146             if (mHeavyWeightProcess == app) {
4147                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4148                         mHeavyWeightProcess.userId, 0));
4149                 mHeavyWeightProcess = null;
4150             }
4151             // Take care of any launching providers waiting for this process.
4152             checkAppInLaunchingProvidersLocked(app, true);
4153             // Take care of any services that are waiting for the process.
4154             mServices.processStartTimedOutLocked(app);
4155             EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid,
4156                     app.processName, app.setAdj, "start timeout");
4157             Process.killProcessQuiet(pid);
4158             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4159                 Slog.w(TAG, "Unattached app died before backup, skipping");
4160                 try {
4161                     IBackupManager bm = IBackupManager.Stub.asInterface(
4162                             ServiceManager.getService(Context.BACKUP_SERVICE));
4163                     bm.agentDisconnected(app.info.packageName);
4164                 } catch (RemoteException e) {
4165                     // Can't happen; the backup manager is local
4166                 }
4167             }
4168             if (isPendingBroadcastProcessLocked(pid)) {
4169                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4170                 skipPendingBroadcastLocked(pid);
4171             }
4172         } else {
4173             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4174         }
4175     }
4176 
attachApplicationLocked(IApplicationThread thread, int pid)4177     private final boolean attachApplicationLocked(IApplicationThread thread,
4178             int pid) {
4179 
4180         // Find the application record that is being attached...  either via
4181         // the pid if we are running in multiple processes, or just pull the
4182         // next app record if we are emulating process with anonymous threads.
4183         ProcessRecord app;
4184         if (pid != MY_PID && pid >= 0) {
4185             synchronized (mPidsSelfLocked) {
4186                 app = mPidsSelfLocked.get(pid);
4187             }
4188         } else {
4189             app = null;
4190         }
4191 
4192         if (app == null) {
4193             Slog.w(TAG, "No pending application record for pid " + pid
4194                     + " (IApplicationThread " + thread + "); dropping process");
4195             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4196             if (pid > 0 && pid != MY_PID) {
4197                 Process.killProcessQuiet(pid);
4198             } else {
4199                 try {
4200                     thread.scheduleExit();
4201                 } catch (Exception e) {
4202                     // Ignore exceptions.
4203                 }
4204             }
4205             return false;
4206         }
4207 
4208         // If this application record is still attached to a previous
4209         // process, clean it up now.
4210         if (app.thread != null) {
4211             handleAppDiedLocked(app, true, true);
4212         }
4213 
4214         // Tell the process all about itself.
4215 
4216         if (localLOGV) Slog.v(
4217                 TAG, "Binding process pid " + pid + " to record " + app);
4218 
4219         String processName = app.processName;
4220         try {
4221             AppDeathRecipient adr = new AppDeathRecipient(
4222                     app, pid, thread);
4223             thread.asBinder().linkToDeath(adr, 0);
4224             app.deathRecipient = adr;
4225         } catch (RemoteException e) {
4226             app.resetPackageList();
4227             startProcessLocked(app, "link fail", processName);
4228             return false;
4229         }
4230 
4231         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4232 
4233         app.thread = thread;
4234         app.curAdj = app.setAdj = -100;
4235         app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4236         app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4237         app.forcingToForeground = null;
4238         app.foregroundServices = false;
4239         app.hasShownUi = false;
4240         app.debugging = false;
4241 
4242         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4243 
4244         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4245         List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4246 
4247         if (!normalMode) {
4248             Slog.i(TAG, "Launching preboot mode app: " + app);
4249         }
4250 
4251         if (localLOGV) Slog.v(
4252             TAG, "New app record " + app
4253             + " thread=" + thread.asBinder() + " pid=" + pid);
4254         try {
4255             int testMode = IApplicationThread.DEBUG_OFF;
4256             if (mDebugApp != null && mDebugApp.equals(processName)) {
4257                 testMode = mWaitForDebugger
4258                     ? IApplicationThread.DEBUG_WAIT
4259                     : IApplicationThread.DEBUG_ON;
4260                 app.debugging = true;
4261                 if (mDebugTransient) {
4262                     mDebugApp = mOrigDebugApp;
4263                     mWaitForDebugger = mOrigWaitForDebugger;
4264                 }
4265             }
4266             String profileFile = app.instrumentationProfileFile;
4267             ParcelFileDescriptor profileFd = null;
4268             boolean profileAutoStop = false;
4269             if (mProfileApp != null && mProfileApp.equals(processName)) {
4270                 mProfileProc = app;
4271                 profileFile = mProfileFile;
4272                 profileFd = mProfileFd;
4273                 profileAutoStop = mAutoStopProfiler;
4274             }
4275             boolean enableOpenGlTrace = false;
4276             if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4277                 enableOpenGlTrace = true;
4278                 mOpenGlTraceApp = null;
4279             }
4280 
4281             // If the app is being launched for restore or full backup, set it up specially
4282             boolean isRestrictedBackupMode = false;
4283             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4284                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4285                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4286                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4287             }
4288 
4289             ensurePackageDexOpt(app.instrumentationInfo != null
4290                     ? app.instrumentationInfo.packageName
4291                     : app.info.packageName);
4292             if (app.instrumentationClass != null) {
4293                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4294             }
4295             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4296                     + processName + " with config " + mConfiguration);
4297             ApplicationInfo appInfo = app.instrumentationInfo != null
4298                     ? app.instrumentationInfo : app.info;
4299             app.compat = compatibilityInfoForPackageLocked(appInfo);
4300             if (profileFd != null) {
4301                 profileFd = profileFd.dup();
4302             }
4303             thread.bindApplication(processName, appInfo, providers,
4304                     app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4305                     app.instrumentationArguments, app.instrumentationWatcher,
4306                     app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4307                     isRestrictedBackupMode || !normalMode, app.persistent,
4308                     new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4309                     mCoreSettingsObserver.getCoreSettingsLocked());
4310             updateLruProcessLocked(app, false);
4311             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4312         } catch (Exception e) {
4313             // todo: Yikes!  What should we do?  For now we will try to
4314             // start another process, but that could easily get us in
4315             // an infinite loop of restarting processes...
4316             Slog.w(TAG, "Exception thrown during bind!", e);
4317 
4318             app.resetPackageList();
4319             app.unlinkDeathRecipient();
4320             startProcessLocked(app, "bind fail", processName);
4321             return false;
4322         }
4323 
4324         // Remove this record from the list of starting applications.
4325         mPersistentStartingProcesses.remove(app);
4326         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4327                 "Attach application locked removing on hold: " + app);
4328         mProcessesOnHold.remove(app);
4329 
4330         boolean badApp = false;
4331         boolean didSomething = false;
4332 
4333         // See if the top visible activity is waiting to run in this process...
4334         ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4335         if (hr != null && normalMode) {
4336             if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4337                     && processName.equals(hr.processName)) {
4338                 try {
4339                     if (mHeadless) {
4340                         Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4341                     } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4342                         didSomething = true;
4343                     }
4344                 } catch (Exception e) {
4345                     Slog.w(TAG, "Exception in new application when starting activity "
4346                           + hr.intent.getComponent().flattenToShortString(), e);
4347                     badApp = true;
4348                 }
4349             } else {
4350                 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4351             }
4352         }
4353 
4354         // Find any services that should be running in this process...
4355         if (!badApp) {
4356             try {
4357                 didSomething |= mServices.attachApplicationLocked(app, processName);
4358             } catch (Exception e) {
4359                 badApp = true;
4360             }
4361         }
4362 
4363         // Check if a next-broadcast receiver is in this process...
4364         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4365             try {
4366                 didSomething = sendPendingBroadcastsLocked(app);
4367             } catch (Exception e) {
4368                 // If the app died trying to launch the receiver we declare it 'bad'
4369                 badApp = true;
4370             }
4371         }
4372 
4373         // Check whether the next backup agent is in this process...
4374         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4375             if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4376             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4377             try {
4378                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4379                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4380                         mBackupTarget.backupMode);
4381             } catch (Exception e) {
4382                 Slog.w(TAG, "Exception scheduling backup agent creation: ");
4383                 e.printStackTrace();
4384             }
4385         }
4386 
4387         if (badApp) {
4388             // todo: Also need to kill application to deal with all
4389             // kinds of exceptions.
4390             handleAppDiedLocked(app, false, true);
4391             return false;
4392         }
4393 
4394         if (!didSomething) {
4395             updateOomAdjLocked();
4396         }
4397 
4398         return true;
4399     }
4400 
attachApplication(IApplicationThread thread)4401     public final void attachApplication(IApplicationThread thread) {
4402         synchronized (this) {
4403             int callingPid = Binder.getCallingPid();
4404             final long origId = Binder.clearCallingIdentity();
4405             attachApplicationLocked(thread, callingPid);
4406             Binder.restoreCallingIdentity(origId);
4407         }
4408     }
4409 
activityIdle(IBinder token, Configuration config, boolean stopProfiling)4410     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4411         final long origId = Binder.clearCallingIdentity();
4412         ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4413         if (stopProfiling) {
4414             synchronized (this) {
4415                 if (mProfileProc == r.app) {
4416                     if (mProfileFd != null) {
4417                         try {
4418                             mProfileFd.close();
4419                         } catch (IOException e) {
4420                         }
4421                         clearProfilerLocked();
4422                     }
4423                 }
4424             }
4425         }
4426         Binder.restoreCallingIdentity(origId);
4427     }
4428 
enableScreenAfterBoot()4429     void enableScreenAfterBoot() {
4430         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4431                 SystemClock.uptimeMillis());
4432         mWindowManager.enableScreenAfterBoot();
4433 
4434         synchronized (this) {
4435             updateEventDispatchingLocked();
4436         }
4437     }
4438 
showBootMessage(final CharSequence msg, final boolean always)4439     public void showBootMessage(final CharSequence msg, final boolean always) {
4440         enforceNotIsolatedCaller("showBootMessage");
4441         mWindowManager.showBootMessage(msg, always);
4442     }
4443 
dismissKeyguardOnNextActivity()4444     public void dismissKeyguardOnNextActivity() {
4445         enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4446         final long token = Binder.clearCallingIdentity();
4447         try {
4448             synchronized (this) {
4449                 if (mLockScreenShown) {
4450                     mLockScreenShown = false;
4451                     comeOutOfSleepIfNeededLocked();
4452                 }
4453                 mMainStack.dismissKeyguardOnNextActivityLocked();
4454             }
4455         } finally {
4456             Binder.restoreCallingIdentity(token);
4457         }
4458     }
4459 
finishBooting()4460     final void finishBooting() {
4461         IntentFilter pkgFilter = new IntentFilter();
4462         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4463         pkgFilter.addDataScheme("package");
4464         mContext.registerReceiver(new BroadcastReceiver() {
4465             @Override
4466             public void onReceive(Context context, Intent intent) {
4467                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4468                 if (pkgs != null) {
4469                     for (String pkg : pkgs) {
4470                         synchronized (ActivityManagerService.this) {
4471                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4472                                 setResultCode(Activity.RESULT_OK);
4473                                 return;
4474                             }
4475                         }
4476                     }
4477                 }
4478             }
4479         }, pkgFilter);
4480 
4481         synchronized (this) {
4482             // Ensure that any processes we had put on hold are now started
4483             // up.
4484             final int NP = mProcessesOnHold.size();
4485             if (NP > 0) {
4486                 ArrayList<ProcessRecord> procs =
4487                     new ArrayList<ProcessRecord>(mProcessesOnHold);
4488                 for (int ip=0; ip<NP; ip++) {
4489                     if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4490                             + procs.get(ip));
4491                     startProcessLocked(procs.get(ip), "on-hold", null);
4492                 }
4493             }
4494 
4495             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4496                 // Start looking for apps that are abusing wake locks.
4497                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4498                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4499                 // Tell anyone interested that we are done booting!
4500                 SystemProperties.set("sys.boot_completed", "1");
4501                 SystemProperties.set("dev.bootcomplete", "1");
4502                 for (int i=0; i<mStartedUsers.size(); i++) {
4503                     UserStartedState uss = mStartedUsers.valueAt(i);
4504                     if (uss.mState == UserStartedState.STATE_BOOTING) {
4505                         uss.mState = UserStartedState.STATE_RUNNING;
4506                         final int userId = mStartedUsers.keyAt(i);
4507                         Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4508                         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4509                         broadcastIntentLocked(null, null, intent,
4510                                 null, null, 0, null, null,
4511                                 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4512                                 AppOpsManager.OP_NONE, false, false, MY_PID, Process.SYSTEM_UID,
4513                                 userId);
4514                     }
4515                 }
4516             }
4517         }
4518     }
4519 
ensureBootCompleted()4520     final void ensureBootCompleted() {
4521         boolean booting;
4522         boolean enableScreen;
4523         synchronized (this) {
4524             booting = mBooting;
4525             mBooting = false;
4526             enableScreen = !mBooted;
4527             mBooted = true;
4528         }
4529 
4530         if (booting) {
4531             finishBooting();
4532         }
4533 
4534         if (enableScreen) {
4535             enableScreenAfterBoot();
4536         }
4537     }
4538 
activityResumed(IBinder token)4539     public final void activityResumed(IBinder token) {
4540         final long origId = Binder.clearCallingIdentity();
4541         mMainStack.activityResumed(token);
4542         Binder.restoreCallingIdentity(origId);
4543     }
4544 
activityPaused(IBinder token)4545     public final void activityPaused(IBinder token) {
4546         final long origId = Binder.clearCallingIdentity();
4547         mMainStack.activityPaused(token, false);
4548         Binder.restoreCallingIdentity(origId);
4549     }
4550 
activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, CharSequence description)4551     public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4552             CharSequence description) {
4553         if (localLOGV) Slog.v(
4554             TAG, "Activity stopped: token=" + token);
4555 
4556         // Refuse possible leaked file descriptors
4557         if (icicle != null && icicle.hasFileDescriptors()) {
4558             throw new IllegalArgumentException("File descriptors passed in Bundle");
4559         }
4560 
4561         ActivityRecord r = null;
4562 
4563         final long origId = Binder.clearCallingIdentity();
4564 
4565         synchronized (this) {
4566             r = mMainStack.isInStackLocked(token);
4567             if (r != null) {
4568                 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4569             }
4570         }
4571 
4572         if (r != null) {
4573             sendPendingThumbnail(r, null, null, null, false);
4574         }
4575 
4576         trimApplications();
4577 
4578         Binder.restoreCallingIdentity(origId);
4579     }
4580 
activityDestroyed(IBinder token)4581     public final void activityDestroyed(IBinder token) {
4582         if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4583         mMainStack.activityDestroyed(token);
4584     }
4585 
getCallingPackage(IBinder token)4586     public String getCallingPackage(IBinder token) {
4587         synchronized (this) {
4588             ActivityRecord r = getCallingRecordLocked(token);
4589             return r != null ? r.info.packageName : null;
4590         }
4591     }
4592 
getCallingActivity(IBinder token)4593     public ComponentName getCallingActivity(IBinder token) {
4594         synchronized (this) {
4595             ActivityRecord r = getCallingRecordLocked(token);
4596             return r != null ? r.intent.getComponent() : null;
4597         }
4598     }
4599 
getCallingRecordLocked(IBinder token)4600     private ActivityRecord getCallingRecordLocked(IBinder token) {
4601         ActivityRecord r = mMainStack.isInStackLocked(token);
4602         if (r == null) {
4603             return null;
4604         }
4605         return r.resultTo;
4606     }
4607 
getActivityClassForToken(IBinder token)4608     public ComponentName getActivityClassForToken(IBinder token) {
4609         synchronized(this) {
4610             ActivityRecord r = mMainStack.isInStackLocked(token);
4611             if (r == null) {
4612                 return null;
4613             }
4614             return r.intent.getComponent();
4615         }
4616     }
4617 
getPackageForToken(IBinder token)4618     public String getPackageForToken(IBinder token) {
4619         synchronized(this) {
4620             ActivityRecord r = mMainStack.isInStackLocked(token);
4621             if (r == null) {
4622                 return null;
4623             }
4624             return r.packageName;
4625         }
4626     }
4627 
getIntentSender(int type, String packageName, IBinder token, String resultWho, int requestCode, Intent[] intents, String[] resolvedTypes, int flags, Bundle options, int userId)4628     public IIntentSender getIntentSender(int type,
4629             String packageName, IBinder token, String resultWho,
4630             int requestCode, Intent[] intents, String[] resolvedTypes,
4631             int flags, Bundle options, int userId) {
4632         enforceNotIsolatedCaller("getIntentSender");
4633         // Refuse possible leaked file descriptors
4634         if (intents != null) {
4635             if (intents.length < 1) {
4636                 throw new IllegalArgumentException("Intents array length must be >= 1");
4637             }
4638             for (int i=0; i<intents.length; i++) {
4639                 Intent intent = intents[i];
4640                 if (intent != null) {
4641                     if (intent.hasFileDescriptors()) {
4642                         throw new IllegalArgumentException("File descriptors passed in Intent");
4643                     }
4644                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4645                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4646                         throw new IllegalArgumentException(
4647                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4648                     }
4649                     intents[i] = new Intent(intent);
4650                 }
4651             }
4652             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4653                 throw new IllegalArgumentException(
4654                         "Intent array length does not match resolvedTypes length");
4655             }
4656         }
4657         if (options != null) {
4658             if (options.hasFileDescriptors()) {
4659                 throw new IllegalArgumentException("File descriptors passed in options");
4660             }
4661         }
4662 
4663         synchronized(this) {
4664             int callingUid = Binder.getCallingUid();
4665             int origUserId = userId;
4666             userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
4667                     type == ActivityManager.INTENT_SENDER_BROADCAST, false,
4668                     "getIntentSender", null);
4669             if (origUserId == UserHandle.USER_CURRENT) {
4670                 // We don't want to evaluate this until the pending intent is
4671                 // actually executed.  However, we do want to always do the
4672                 // security checking for it above.
4673                 userId = UserHandle.USER_CURRENT;
4674             }
4675             try {
4676                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4677                     int uid = AppGlobals.getPackageManager()
4678                             .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4679                     if (!UserHandle.isSameApp(callingUid, uid)) {
4680                         String msg = "Permission Denial: getIntentSender() from pid="
4681                             + Binder.getCallingPid()
4682                             + ", uid=" + Binder.getCallingUid()
4683                             + ", (need uid=" + uid + ")"
4684                             + " is not allowed to send as package " + packageName;
4685                         Slog.w(TAG, msg);
4686                         throw new SecurityException(msg);
4687                     }
4688                 }
4689 
4690                 return getIntentSenderLocked(type, packageName, callingUid, userId,
4691                         token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4692 
4693             } catch (RemoteException e) {
4694                 throw new SecurityException(e);
4695             }
4696         }
4697     }
4698 
getIntentSenderLocked(int type, String packageName, int callingUid, int userId, IBinder token, String resultWho, int requestCode, Intent[] intents, String[] resolvedTypes, int flags, Bundle options)4699     IIntentSender getIntentSenderLocked(int type, String packageName,
4700             int callingUid, int userId, IBinder token, String resultWho,
4701             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4702             Bundle options) {
4703         if (DEBUG_MU)
4704             Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4705         ActivityRecord activity = null;
4706         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4707             activity = mMainStack.isInStackLocked(token);
4708             if (activity == null) {
4709                 return null;
4710             }
4711             if (activity.finishing) {
4712                 return null;
4713             }
4714         }
4715 
4716         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4717         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4718         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4719         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4720                 |PendingIntent.FLAG_UPDATE_CURRENT);
4721 
4722         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4723                 type, packageName, activity, resultWho,
4724                 requestCode, intents, resolvedTypes, flags, options, userId);
4725         WeakReference<PendingIntentRecord> ref;
4726         ref = mIntentSenderRecords.get(key);
4727         PendingIntentRecord rec = ref != null ? ref.get() : null;
4728         if (rec != null) {
4729             if (!cancelCurrent) {
4730                 if (updateCurrent) {
4731                     if (rec.key.requestIntent != null) {
4732                         rec.key.requestIntent.replaceExtras(intents != null ?
4733                                 intents[intents.length - 1] : null);
4734                     }
4735                     if (intents != null) {
4736                         intents[intents.length-1] = rec.key.requestIntent;
4737                         rec.key.allIntents = intents;
4738                         rec.key.allResolvedTypes = resolvedTypes;
4739                     } else {
4740                         rec.key.allIntents = null;
4741                         rec.key.allResolvedTypes = null;
4742                     }
4743                 }
4744                 return rec;
4745             }
4746             rec.canceled = true;
4747             mIntentSenderRecords.remove(key);
4748         }
4749         if (noCreate) {
4750             return rec;
4751         }
4752         rec = new PendingIntentRecord(this, key, callingUid);
4753         mIntentSenderRecords.put(key, rec.ref);
4754         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4755             if (activity.pendingResults == null) {
4756                 activity.pendingResults
4757                         = new HashSet<WeakReference<PendingIntentRecord>>();
4758             }
4759             activity.pendingResults.add(rec.ref);
4760         }
4761         return rec;
4762     }
4763 
cancelIntentSender(IIntentSender sender)4764     public void cancelIntentSender(IIntentSender sender) {
4765         if (!(sender instanceof PendingIntentRecord)) {
4766             return;
4767         }
4768         synchronized(this) {
4769             PendingIntentRecord rec = (PendingIntentRecord)sender;
4770             try {
4771                 int uid = AppGlobals.getPackageManager()
4772                         .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4773                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4774                     String msg = "Permission Denial: cancelIntentSender() from pid="
4775                         + Binder.getCallingPid()
4776                         + ", uid=" + Binder.getCallingUid()
4777                         + " is not allowed to cancel packges "
4778                         + rec.key.packageName;
4779                     Slog.w(TAG, msg);
4780                     throw new SecurityException(msg);
4781                 }
4782             } catch (RemoteException e) {
4783                 throw new SecurityException(e);
4784             }
4785             cancelIntentSenderLocked(rec, true);
4786         }
4787     }
4788 
cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity)4789     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4790         rec.canceled = true;
4791         mIntentSenderRecords.remove(rec.key);
4792         if (cleanActivity && rec.key.activity != null) {
4793             rec.key.activity.pendingResults.remove(rec.ref);
4794         }
4795     }
4796 
getPackageForIntentSender(IIntentSender pendingResult)4797     public String getPackageForIntentSender(IIntentSender pendingResult) {
4798         if (!(pendingResult instanceof PendingIntentRecord)) {
4799             return null;
4800         }
4801         try {
4802             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4803             return res.key.packageName;
4804         } catch (ClassCastException e) {
4805         }
4806         return null;
4807     }
4808 
getUidForIntentSender(IIntentSender sender)4809     public int getUidForIntentSender(IIntentSender sender) {
4810         if (sender instanceof PendingIntentRecord) {
4811             try {
4812                 PendingIntentRecord res = (PendingIntentRecord)sender;
4813                 return res.uid;
4814             } catch (ClassCastException e) {
4815             }
4816         }
4817         return -1;
4818     }
4819 
isIntentSenderTargetedToPackage(IIntentSender pendingResult)4820     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4821         if (!(pendingResult instanceof PendingIntentRecord)) {
4822             return false;
4823         }
4824         try {
4825             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4826             if (res.key.allIntents == null) {
4827                 return false;
4828             }
4829             for (int i=0; i<res.key.allIntents.length; i++) {
4830                 Intent intent = res.key.allIntents[i];
4831                 if (intent.getPackage() != null && intent.getComponent() != null) {
4832                     return false;
4833                 }
4834             }
4835             return true;
4836         } catch (ClassCastException e) {
4837         }
4838         return false;
4839     }
4840 
isIntentSenderAnActivity(IIntentSender pendingResult)4841     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4842         if (!(pendingResult instanceof PendingIntentRecord)) {
4843             return false;
4844         }
4845         try {
4846             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4847             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4848                 return true;
4849             }
4850             return false;
4851         } catch (ClassCastException e) {
4852         }
4853         return false;
4854     }
4855 
getIntentForIntentSender(IIntentSender pendingResult)4856     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
4857         if (!(pendingResult instanceof PendingIntentRecord)) {
4858             return null;
4859         }
4860         try {
4861             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4862             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
4863         } catch (ClassCastException e) {
4864         }
4865         return null;
4866     }
4867 
setProcessLimit(int max)4868     public void setProcessLimit(int max) {
4869         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4870                 "setProcessLimit()");
4871         synchronized (this) {
4872             mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4873             mProcessLimitOverride = max;
4874         }
4875         trimApplications();
4876     }
4877 
4878     public int getProcessLimit() {
4879         synchronized (this) {
4880             return mProcessLimitOverride;
4881         }
4882     }
4883 
4884     void foregroundTokenDied(ForegroundToken token) {
4885         synchronized (ActivityManagerService.this) {
4886             synchronized (mPidsSelfLocked) {
4887                 ForegroundToken cur
4888                     = mForegroundProcesses.get(token.pid);
4889                 if (cur != token) {
4890                     return;
4891                 }
4892                 mForegroundProcesses.remove(token.pid);
4893                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4894                 if (pr == null) {
4895                     return;
4896                 }
4897                 pr.forcingToForeground = null;
4898                 pr.foregroundServices = false;
4899             }
4900             updateOomAdjLocked();
4901         }
4902     }
4903 
4904     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4905         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4906                 "setProcessForeground()");
4907         synchronized(this) {
4908             boolean changed = false;
4909 
4910             synchronized (mPidsSelfLocked) {
4911                 ProcessRecord pr = mPidsSelfLocked.get(pid);
4912                 if (pr == null && isForeground) {
4913                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4914                     return;
4915                 }
4916                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4917                 if (oldToken != null) {
4918                     oldToken.token.unlinkToDeath(oldToken, 0);
4919                     mForegroundProcesses.remove(pid);
4920                     if (pr != null) {
4921                         pr.forcingToForeground = null;
4922                     }
4923                     changed = true;
4924                 }
4925                 if (isForeground && token != null) {
4926                     ForegroundToken newToken = new ForegroundToken() {
4927                         public void binderDied() {
4928                             foregroundTokenDied(this);
4929                         }
4930                     };
4931                     newToken.pid = pid;
4932                     newToken.token = token;
4933                     try {
4934                         token.linkToDeath(newToken, 0);
4935                         mForegroundProcesses.put(pid, newToken);
4936                         pr.forcingToForeground = token;
4937                         changed = true;
4938                     } catch (RemoteException e) {
4939                         // If the process died while doing this, we will later
4940                         // do the cleanup with the process death link.
4941                     }
4942                 }
4943             }
4944 
4945             if (changed) {
4946                 updateOomAdjLocked();
4947             }
4948         }
4949     }
4950 
4951     // =========================================================
4952     // PERMISSIONS
4953     // =========================================================
4954 
4955     static class PermissionController extends IPermissionController.Stub {
4956         ActivityManagerService mActivityManagerService;
4957         PermissionController(ActivityManagerService activityManagerService) {
4958             mActivityManagerService = activityManagerService;
4959         }
4960 
4961         public boolean checkPermission(String permission, int pid, int uid) {
4962             return mActivityManagerService.checkPermission(permission, pid,
4963                     uid) == PackageManager.PERMISSION_GRANTED;
4964         }
4965     }
4966 
4967     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
4968         public int checkComponentPermission(String permission, int pid, int uid,
4969                 int owningUid, boolean exported) {
4970             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
4971                     owningUid, exported);
4972         }
4973 
4974         public Object getAMSLock() {
4975             return ActivityManagerService.this;
4976         }
4977     }
4978 
4979     /**
4980      * This can be called with or without the global lock held.
4981      */
4982     int checkComponentPermission(String permission, int pid, int uid,
4983             int owningUid, boolean exported) {
4984         // We might be performing an operation on behalf of an indirect binder
4985         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4986         // client identity accordingly before proceeding.
4987         Identity tlsIdentity = sCallerIdentity.get();
4988         if (tlsIdentity != null) {
4989             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4990                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4991             uid = tlsIdentity.uid;
4992             pid = tlsIdentity.pid;
4993         }
4994 
4995         if (pid == MY_PID) {
4996             return PackageManager.PERMISSION_GRANTED;
4997         }
4998 
4999         return ActivityManager.checkComponentPermission(permission, uid,
5000                 owningUid, exported);
5001     }
5002 
5003     /**
5004      * As the only public entry point for permissions checking, this method
5005      * can enforce the semantic that requesting a check on a null global
5006      * permission is automatically denied.  (Internally a null permission
5007      * string is used when calling {@link #checkComponentPermission} in cases
5008      * when only uid-based security is needed.)
5009      *
5010      * This can be called with or without the global lock held.
5011      */
5012     public int checkPermission(String permission, int pid, int uid) {
5013         if (permission == null) {
5014             return PackageManager.PERMISSION_DENIED;
5015         }
5016         return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5017     }
5018 
5019     /**
5020      * Binder IPC calls go through the public entry point.
5021      * This can be called with or without the global lock held.
5022      */
5023     int checkCallingPermission(String permission) {
5024         return checkPermission(permission,
5025                 Binder.getCallingPid(),
5026                 UserHandle.getAppId(Binder.getCallingUid()));
5027     }
5028 
5029     /**
5030      * This can be called with or without the global lock held.
5031      */
5032     void enforceCallingPermission(String permission, String func) {
5033         if (checkCallingPermission(permission)
5034                 == PackageManager.PERMISSION_GRANTED) {
5035             return;
5036         }
5037 
5038         String msg = "Permission Denial: " + func + " from pid="
5039                 + Binder.getCallingPid()
5040                 + ", uid=" + Binder.getCallingUid()
5041                 + " requires " + permission;
5042         Slog.w(TAG, msg);
5043         throw new SecurityException(msg);
5044     }
5045 
5046     /**
5047      * Determine if UID is holding permissions required to access {@link Uri} in
5048      * the given {@link ProviderInfo}. Final permission checking is always done
5049      * in {@link ContentProvider}.
5050      */
5051     private final boolean checkHoldingPermissionsLocked(
5052             IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5053         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5054                 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5055 
5056         if (pi.applicationInfo.uid == uid) {
5057             return true;
5058         } else if (!pi.exported) {
5059             return false;
5060         }
5061 
5062         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5063         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5064         try {
5065             // check if target holds top-level <provider> permissions
5066             if (!readMet && pi.readPermission != null
5067                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5068                 readMet = true;
5069             }
5070             if (!writeMet && pi.writePermission != null
5071                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5072                 writeMet = true;
5073             }
5074 
5075             // track if unprotected read/write is allowed; any denied
5076             // <path-permission> below removes this ability
5077             boolean allowDefaultRead = pi.readPermission == null;
5078             boolean allowDefaultWrite = pi.writePermission == null;
5079 
5080             // check if target holds any <path-permission> that match uri
5081             final PathPermission[] pps = pi.pathPermissions;
5082             if (pps != null) {
5083                 final String path = uri.getPath();
5084                 int i = pps.length;
5085                 while (i > 0 && (!readMet || !writeMet)) {
5086                     i--;
5087                     PathPermission pp = pps[i];
5088                     if (pp.match(path)) {
5089                         if (!readMet) {
5090                             final String pprperm = pp.getReadPermission();
5091                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5092                                     + pprperm + " for " + pp.getPath()
5093                                     + ": match=" + pp.match(path)
5094                                     + " check=" + pm.checkUidPermission(pprperm, uid));
5095                             if (pprperm != null) {
5096                                 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5097                                     readMet = true;
5098                                 } else {
5099                                     allowDefaultRead = false;
5100                                 }
5101                             }
5102                         }
5103                         if (!writeMet) {
5104                             final String ppwperm = pp.getWritePermission();
5105                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5106                                     + ppwperm + " for " + pp.getPath()
5107                                     + ": match=" + pp.match(path)
5108                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
5109                             if (ppwperm != null) {
5110                                 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5111                                     writeMet = true;
5112                                 } else {
5113                                     allowDefaultWrite = false;
5114                                 }
5115                             }
5116                         }
5117                     }
5118                 }
5119             }
5120 
5121             // grant unprotected <provider> read/write, if not blocked by
5122             // <path-permission> above
5123             if (allowDefaultRead) readMet = true;
5124             if (allowDefaultWrite) writeMet = true;
5125 
5126         } catch (RemoteException e) {
5127             return false;
5128         }
5129 
5130         return readMet && writeMet;
5131     }
5132 
checkUriPermissionLocked(Uri uri, int uid, int modeFlags)5133     private final boolean checkUriPermissionLocked(Uri uri, int uid,
5134             int modeFlags) {
5135         // Root gets to do everything.
5136         if (uid == 0) {
5137             return true;
5138         }
5139         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5140         if (perms == null) return false;
5141         UriPermission perm = perms.get(uri);
5142         if (perm == null) return false;
5143         return (modeFlags&perm.modeFlags) == modeFlags;
5144     }
5145 
checkUriPermission(Uri uri, int pid, int uid, int modeFlags)5146     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5147         enforceNotIsolatedCaller("checkUriPermission");
5148 
5149         // Another redirected-binder-call permissions check as in
5150         // {@link checkComponentPermission}.
5151         Identity tlsIdentity = sCallerIdentity.get();
5152         if (tlsIdentity != null) {
5153             uid = tlsIdentity.uid;
5154             pid = tlsIdentity.pid;
5155         }
5156 
5157         // Our own process gets to do everything.
5158         if (pid == MY_PID) {
5159             return PackageManager.PERMISSION_GRANTED;
5160         }
5161         synchronized(this) {
5162             return checkUriPermissionLocked(uri, uid, modeFlags)
5163                     ? PackageManager.PERMISSION_GRANTED
5164                     : PackageManager.PERMISSION_DENIED;
5165         }
5166     }
5167 
5168     /**
5169      * Check if the targetPkg can be granted permission to access uri by
5170      * the callingUid using the given modeFlags.  Throws a security exception
5171      * if callingUid is not allowed to do this.  Returns the uid of the target
5172      * if the URI permission grant should be performed; returns -1 if it is not
5173      * needed (for example targetPkg already has permission to access the URI).
5174      * If you already know the uid of the target, you can supply it in
5175      * lastTargetUid else set that to -1.
5176      */
checkGrantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, int modeFlags, int lastTargetUid)5177     int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5178             Uri uri, int modeFlags, int lastTargetUid) {
5179         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5180                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5181         if (modeFlags == 0) {
5182             return -1;
5183         }
5184 
5185         if (targetPkg != null) {
5186             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5187                     "Checking grant " + targetPkg + " permission to " + uri);
5188         }
5189 
5190         final IPackageManager pm = AppGlobals.getPackageManager();
5191 
5192         // If this is not a content: uri, we can't do anything with it.
5193         if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5194             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5195                     "Can't grant URI permission for non-content URI: " + uri);
5196             return -1;
5197         }
5198 
5199         String name = uri.getAuthority();
5200         ProviderInfo pi = null;
5201         ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5202                 UserHandle.getUserId(callingUid));
5203         if (cpr != null) {
5204             pi = cpr.info;
5205         } else {
5206             try {
5207                 pi = pm.resolveContentProvider(name,
5208                         PackageManager.GET_URI_PERMISSION_PATTERNS,
5209                         UserHandle.getUserId(callingUid));
5210             } catch (RemoteException ex) {
5211             }
5212         }
5213         if (pi == null) {
5214             Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5215             return -1;
5216         }
5217 
5218         int targetUid = lastTargetUid;
5219         if (targetUid < 0 && targetPkg != null) {
5220             try {
5221                 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5222                 if (targetUid < 0) {
5223                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5224                             "Can't grant URI permission no uid for: " + targetPkg);
5225                     return -1;
5226                 }
5227             } catch (RemoteException ex) {
5228                 return -1;
5229             }
5230         }
5231 
5232         if (targetUid >= 0) {
5233             // First...  does the target actually need this permission?
5234             if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5235                 // No need to grant the target this permission.
5236                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5237                         "Target " + targetPkg + " already has full permission to " + uri);
5238                 return -1;
5239             }
5240         } else {
5241             // First...  there is no target package, so can anyone access it?
5242             boolean allowed = pi.exported;
5243             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5244                 if (pi.readPermission != null) {
5245                     allowed = false;
5246                 }
5247             }
5248             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5249                 if (pi.writePermission != null) {
5250                     allowed = false;
5251                 }
5252             }
5253             if (allowed) {
5254                 return -1;
5255             }
5256         }
5257 
5258         // Second...  is the provider allowing granting of URI permissions?
5259         if (!pi.grantUriPermissions) {
5260             throw new SecurityException("Provider " + pi.packageName
5261                     + "/" + pi.name
5262                     + " does not allow granting of Uri permissions (uri "
5263                     + uri + ")");
5264         }
5265         if (pi.uriPermissionPatterns != null) {
5266             final int N = pi.uriPermissionPatterns.length;
5267             boolean allowed = false;
5268             for (int i=0; i<N; i++) {
5269                 if (pi.uriPermissionPatterns[i] != null
5270                         && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5271                     allowed = true;
5272                     break;
5273                 }
5274             }
5275             if (!allowed) {
5276                 throw new SecurityException("Provider " + pi.packageName
5277                         + "/" + pi.name
5278                         + " does not allow granting of permission to path of Uri "
5279                         + uri);
5280             }
5281         }
5282 
5283         // Third...  does the caller itself have permission to access
5284         // this uri?
5285         if (callingUid != Process.myUid()) {
5286             if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5287                 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5288                     throw new SecurityException("Uid " + callingUid
5289                             + " does not have permission to uri " + uri);
5290                 }
5291             }
5292         }
5293 
5294         return targetUid;
5295     }
5296 
checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, int modeFlags)5297     public int checkGrantUriPermission(int callingUid, String targetPkg,
5298             Uri uri, int modeFlags) {
5299         enforceNotIsolatedCaller("checkGrantUriPermission");
5300         synchronized(this) {
5301             return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5302         }
5303     }
5304 
grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner)5305     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5306             Uri uri, int modeFlags, UriPermissionOwner owner) {
5307         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5308                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5309         if (modeFlags == 0) {
5310             return;
5311         }
5312 
5313         // So here we are: the caller has the assumed permission
5314         // to the uri, and the target doesn't.  Let's now give this to
5315         // the target.
5316 
5317         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5318                 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5319 
5320         HashMap<Uri, UriPermission> targetUris
5321                 = mGrantedUriPermissions.get(targetUid);
5322         if (targetUris == null) {
5323             targetUris = new HashMap<Uri, UriPermission>();
5324             mGrantedUriPermissions.put(targetUid, targetUris);
5325         }
5326 
5327         UriPermission perm = targetUris.get(uri);
5328         if (perm == null) {
5329             perm = new UriPermission(targetUid, uri);
5330             targetUris.put(uri, perm);
5331         }
5332 
5333         perm.modeFlags |= modeFlags;
5334         if (owner == null) {
5335             perm.globalModeFlags |= modeFlags;
5336         } else {
5337             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5338                  perm.readOwners.add(owner);
5339                  owner.addReadPermission(perm);
5340             }
5341             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5342                  perm.writeOwners.add(owner);
5343                  owner.addWritePermission(perm);
5344             }
5345         }
5346     }
5347 
grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner)5348     void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5349             int modeFlags, UriPermissionOwner owner) {
5350         if (targetPkg == null) {
5351             throw new NullPointerException("targetPkg");
5352         }
5353 
5354         int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5355         if (targetUid < 0) {
5356             return;
5357         }
5358 
5359         grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5360     }
5361 
5362     static class NeededUriGrants extends ArrayList<Uri> {
5363         final String targetPkg;
5364         final int targetUid;
5365         final int flags;
5366 
NeededUriGrants(String _targetPkg, int _targetUid, int _flags)5367         NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5368             targetPkg = _targetPkg;
5369             targetUid = _targetUid;
5370             flags = _flags;
5371         }
5372     }
5373 
5374     /**
5375      * Like checkGrantUriPermissionLocked, but takes an Intent.
5376      */
checkGrantUriPermissionFromIntentLocked(int callingUid, String targetPkg, Intent intent, int mode, NeededUriGrants needed)5377     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5378             String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5379         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5380                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5381                 + " clip=" + (intent != null ? intent.getClipData() : null)
5382                 + " from " + intent + "; flags=0x"
5383                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5384 
5385         if (targetPkg == null) {
5386             throw new NullPointerException("targetPkg");
5387         }
5388 
5389         if (intent == null) {
5390             return null;
5391         }
5392         Uri data = intent.getData();
5393         ClipData clip = intent.getClipData();
5394         if (data == null && clip == null) {
5395             return null;
5396         }
5397         if (data != null) {
5398             int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5399                 mode, needed != null ? needed.targetUid : -1);
5400             if (target > 0) {
5401                 if (needed == null) {
5402                     needed = new NeededUriGrants(targetPkg, target, mode);
5403                 }
5404                 needed.add(data);
5405             }
5406         }
5407         if (clip != null) {
5408             for (int i=0; i<clip.getItemCount(); i++) {
5409                 Uri uri = clip.getItemAt(i).getUri();
5410                 if (uri != null) {
5411                     int target = -1;
5412                     target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5413                             mode, needed != null ? needed.targetUid : -1);
5414                     if (target > 0) {
5415                         if (needed == null) {
5416                             needed = new NeededUriGrants(targetPkg, target, mode);
5417                         }
5418                         needed.add(uri);
5419                     }
5420                 } else {
5421                     Intent clipIntent = clip.getItemAt(i).getIntent();
5422                     if (clipIntent != null) {
5423                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5424                                 callingUid, targetPkg, clipIntent, mode, needed);
5425                         if (newNeeded != null) {
5426                             needed = newNeeded;
5427                         }
5428                     }
5429                 }
5430             }
5431         }
5432 
5433         return needed;
5434     }
5435 
5436     /**
5437      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5438      */
grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, UriPermissionOwner owner)5439     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5440             UriPermissionOwner owner) {
5441         if (needed != null) {
5442             for (int i=0; i<needed.size(); i++) {
5443                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5444                         needed.get(i), needed.flags, owner);
5445             }
5446         }
5447     }
5448 
grantUriPermissionFromIntentLocked(int callingUid, String targetPkg, Intent intent, UriPermissionOwner owner)5449     void grantUriPermissionFromIntentLocked(int callingUid,
5450             String targetPkg, Intent intent, UriPermissionOwner owner) {
5451         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5452                 intent, intent != null ? intent.getFlags() : 0, null);
5453         if (needed == null) {
5454             return;
5455         }
5456 
5457         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5458     }
5459 
grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, int modeFlags)5460     public void grantUriPermission(IApplicationThread caller, String targetPkg,
5461             Uri uri, int modeFlags) {
5462         enforceNotIsolatedCaller("grantUriPermission");
5463         synchronized(this) {
5464             final ProcessRecord r = getRecordForAppLocked(caller);
5465             if (r == null) {
5466                 throw new SecurityException("Unable to find app for caller "
5467                         + caller
5468                         + " when granting permission to uri " + uri);
5469             }
5470             if (targetPkg == null) {
5471                 throw new IllegalArgumentException("null target");
5472             }
5473             if (uri == null) {
5474                 throw new IllegalArgumentException("null uri");
5475             }
5476 
5477             grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5478                     null);
5479         }
5480     }
5481 
removeUriPermissionIfNeededLocked(UriPermission perm)5482     void removeUriPermissionIfNeededLocked(UriPermission perm) {
5483         if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5484                 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5485             HashMap<Uri, UriPermission> perms
5486                     = mGrantedUriPermissions.get(perm.uid);
5487             if (perms != null) {
5488                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5489                         "Removing " + perm.uid + " permission to " + perm.uri);
5490                 perms.remove(perm.uri);
5491                 if (perms.size() == 0) {
5492                     mGrantedUriPermissions.remove(perm.uid);
5493                 }
5494             }
5495         }
5496     }
5497 
revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags)5498     private void revokeUriPermissionLocked(int callingUid, Uri uri,
5499             int modeFlags) {
5500         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5501                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5502         if (modeFlags == 0) {
5503             return;
5504         }
5505 
5506         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5507                 "Revoking all granted permissions to " + uri);
5508 
5509         final IPackageManager pm = AppGlobals.getPackageManager();
5510 
5511         final String authority = uri.getAuthority();
5512         ProviderInfo pi = null;
5513         int userId = UserHandle.getUserId(callingUid);
5514         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5515         if (cpr != null) {
5516             pi = cpr.info;
5517         } else {
5518             try {
5519                 pi = pm.resolveContentProvider(authority,
5520                         PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5521             } catch (RemoteException ex) {
5522             }
5523         }
5524         if (pi == null) {
5525             Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5526             return;
5527         }
5528 
5529         // Does the caller have this permission on the URI?
5530         if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5531             // Right now, if you are not the original owner of the permission,
5532             // you are not allowed to revoke it.
5533             //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5534                 throw new SecurityException("Uid " + callingUid
5535                         + " does not have permission to uri " + uri);
5536             //}
5537         }
5538 
5539         // Go through all of the permissions and remove any that match.
5540         final List<String> SEGMENTS = uri.getPathSegments();
5541         if (SEGMENTS != null) {
5542             final int NS = SEGMENTS.size();
5543             int N = mGrantedUriPermissions.size();
5544             for (int i=0; i<N; i++) {
5545                 HashMap<Uri, UriPermission> perms
5546                         = mGrantedUriPermissions.valueAt(i);
5547                 Iterator<UriPermission> it = perms.values().iterator();
5548             toploop:
5549                 while (it.hasNext()) {
5550                     UriPermission perm = it.next();
5551                     Uri targetUri = perm.uri;
5552                     if (!authority.equals(targetUri.getAuthority())) {
5553                         continue;
5554                     }
5555                     List<String> targetSegments = targetUri.getPathSegments();
5556                     if (targetSegments == null) {
5557                         continue;
5558                     }
5559                     if (targetSegments.size() < NS) {
5560                         continue;
5561                     }
5562                     for (int j=0; j<NS; j++) {
5563                         if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5564                             continue toploop;
5565                         }
5566                     }
5567                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5568                             "Revoking " + perm.uid + " permission to " + perm.uri);
5569                     perm.clearModes(modeFlags);
5570                     if (perm.modeFlags == 0) {
5571                         it.remove();
5572                     }
5573                 }
5574                 if (perms.size() == 0) {
5575                     mGrantedUriPermissions.remove(
5576                             mGrantedUriPermissions.keyAt(i));
5577                     N--;
5578                     i--;
5579                 }
5580             }
5581         }
5582     }
5583 
revokeUriPermission(IApplicationThread caller, Uri uri, int modeFlags)5584     public void revokeUriPermission(IApplicationThread caller, Uri uri,
5585             int modeFlags) {
5586         enforceNotIsolatedCaller("revokeUriPermission");
5587         synchronized(this) {
5588             final ProcessRecord r = getRecordForAppLocked(caller);
5589             if (r == null) {
5590                 throw new SecurityException("Unable to find app for caller "
5591                         + caller
5592                         + " when revoking permission to uri " + uri);
5593             }
5594             if (uri == null) {
5595                 Slog.w(TAG, "revokeUriPermission: null uri");
5596                 return;
5597             }
5598 
5599             modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5600                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5601             if (modeFlags == 0) {
5602                 return;
5603             }
5604 
5605             final IPackageManager pm = AppGlobals.getPackageManager();
5606 
5607             final String authority = uri.getAuthority();
5608             ProviderInfo pi = null;
5609             ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5610             if (cpr != null) {
5611                 pi = cpr.info;
5612             } else {
5613                 try {
5614                     pi = pm.resolveContentProvider(authority,
5615                             PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5616                 } catch (RemoteException ex) {
5617                 }
5618             }
5619             if (pi == null) {
5620                 Slog.w(TAG, "No content provider found for permission revoke: "
5621                         + uri.toSafeString());
5622                 return;
5623             }
5624 
5625             revokeUriPermissionLocked(r.uid, uri, modeFlags);
5626         }
5627     }
5628 
5629     @Override
newUriPermissionOwner(String name)5630     public IBinder newUriPermissionOwner(String name) {
5631         enforceNotIsolatedCaller("newUriPermissionOwner");
5632         synchronized(this) {
5633             UriPermissionOwner owner = new UriPermissionOwner(this, name);
5634             return owner.getExternalTokenLocked();
5635         }
5636     }
5637 
5638     @Override
grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, int modeFlags)5639     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5640             Uri uri, int modeFlags) {
5641         synchronized(this) {
5642             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5643             if (owner == null) {
5644                 throw new IllegalArgumentException("Unknown owner: " + token);
5645             }
5646             if (fromUid != Binder.getCallingUid()) {
5647                 if (Binder.getCallingUid() != Process.myUid()) {
5648                     // Only system code can grant URI permissions on behalf
5649                     // of other users.
5650                     throw new SecurityException("nice try");
5651                 }
5652             }
5653             if (targetPkg == null) {
5654                 throw new IllegalArgumentException("null target");
5655             }
5656             if (uri == null) {
5657                 throw new IllegalArgumentException("null uri");
5658             }
5659 
5660             grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5661         }
5662     }
5663 
5664     @Override
revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode)5665     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5666         synchronized(this) {
5667             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5668             if (owner == null) {
5669                 throw new IllegalArgumentException("Unknown owner: " + token);
5670             }
5671 
5672             if (uri == null) {
5673                 owner.removeUriPermissionsLocked(mode);
5674             } else {
5675                 owner.removeUriPermissionLocked(uri, mode);
5676             }
5677         }
5678     }
5679 
showWaitingForDebugger(IApplicationThread who, boolean waiting)5680     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5681         synchronized (this) {
5682             ProcessRecord app =
5683                 who != null ? getRecordForAppLocked(who) : null;
5684             if (app == null) return;
5685 
5686             Message msg = Message.obtain();
5687             msg.what = WAIT_FOR_DEBUGGER_MSG;
5688             msg.obj = app;
5689             msg.arg1 = waiting ? 1 : 0;
5690             mHandler.sendMessage(msg);
5691         }
5692     }
5693 
getMemoryInfo(ActivityManager.MemoryInfo outInfo)5694     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5695         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5696         final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5697         outInfo.availMem = Process.getFreeMemory();
5698         outInfo.totalMem = Process.getTotalMemory();
5699         outInfo.threshold = homeAppMem;
5700         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5701         outInfo.hiddenAppThreshold = hiddenAppMem;
5702         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5703                 ProcessList.SERVICE_ADJ);
5704         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5705                 ProcessList.VISIBLE_APP_ADJ);
5706         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5707                 ProcessList.FOREGROUND_APP_ADJ);
5708     }
5709 
5710     // =========================================================
5711     // TASK MANAGEMENT
5712     // =========================================================
5713 
5714     public List getTasks(int maxNum, int flags,
5715                          IThumbnailReceiver receiver) {
5716         ArrayList list = new ArrayList();
5717 
5718         PendingThumbnailsRecord pending = null;
5719         IApplicationThread topThumbnail = null;
5720         ActivityRecord topRecord = null;
5721 
5722         synchronized(this) {
5723             if (localLOGV) Slog.v(
5724                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5725                 + ", receiver=" + receiver);
5726 
5727             if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5728                     != PackageManager.PERMISSION_GRANTED) {
5729                 if (receiver != null) {
5730                     // If the caller wants to wait for pending thumbnails,
5731                     // it ain't gonna get them.
5732                     try {
5733                         receiver.finished();
5734                     } catch (RemoteException ex) {
5735                     }
5736                 }
5737                 String msg = "Permission Denial: getTasks() from pid="
5738                         + Binder.getCallingPid()
5739                         + ", uid=" + Binder.getCallingUid()
5740                         + " requires " + android.Manifest.permission.GET_TASKS;
5741                 Slog.w(TAG, msg);
5742                 throw new SecurityException(msg);
5743             }
5744 
5745             int pos = mMainStack.mHistory.size()-1;
5746             ActivityRecord next =
5747                 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5748             ActivityRecord top = null;
5749             TaskRecord curTask = null;
5750             int numActivities = 0;
5751             int numRunning = 0;
5752             while (pos >= 0 && maxNum > 0) {
5753                 final ActivityRecord r = next;
5754                 pos--;
5755                 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5756 
5757                 // Initialize state for next task if needed.
5758                 if (top == null ||
5759                         (top.state == ActivityState.INITIALIZING
5760                             && top.task == r.task)) {
5761                     top = r;
5762                     curTask = r.task;
5763                     numActivities = numRunning = 0;
5764                 }
5765 
5766                 // Add 'r' into the current task.
5767                 numActivities++;
5768                 if (r.app != null && r.app.thread != null) {
5769                     numRunning++;
5770                 }
5771 
5772                 if (localLOGV) Slog.v(
5773                     TAG, r.intent.getComponent().flattenToShortString()
5774                     + ": task=" + r.task);
5775 
5776                 // If the next one is a different task, generate a new
5777                 // TaskInfo entry for what we have.
5778                 if (next == null || next.task != curTask) {
5779                     ActivityManager.RunningTaskInfo ci
5780                             = new ActivityManager.RunningTaskInfo();
5781                     ci.id = curTask.taskId;
5782                     ci.baseActivity = r.intent.getComponent();
5783                     ci.topActivity = top.intent.getComponent();
5784                     if (top.thumbHolder != null) {
5785                         ci.description = top.thumbHolder.lastDescription;
5786                     }
5787                     ci.numActivities = numActivities;
5788                     ci.numRunning = numRunning;
5789                     //System.out.println(
5790                     //    "#" + maxNum + ": " + " descr=" + ci.description);
5791                     if (ci.thumbnail == null && receiver != null) {
5792                         if (localLOGV) Slog.v(
5793                             TAG, "State=" + top.state + "Idle=" + top.idle
5794                             + " app=" + top.app
5795                             + " thr=" + (top.app != null ? top.app.thread : null));
5796                         if (top.state == ActivityState.RESUMED
5797                                 || top.state == ActivityState.PAUSING) {
5798                             if (top.idle && top.app != null
5799                                 && top.app.thread != null) {
5800                                 topRecord = top;
5801                                 topThumbnail = top.app.thread;
5802                             } else {
5803                                 top.thumbnailNeeded = true;
5804                             }
5805                         }
5806                         if (pending == null) {
5807                             pending = new PendingThumbnailsRecord(receiver);
5808                         }
5809                         pending.pendingRecords.add(top);
5810                     }
5811                     list.add(ci);
5812                     maxNum--;
5813                     top = null;
5814                 }
5815             }
5816 
5817             if (pending != null) {
5818                 mPendingThumbnails.add(pending);
5819             }
5820         }
5821 
Slog.v(TAG, "We have pending thumbnails: " + pending)5822         if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5823 
5824         if (topThumbnail != null) {
Slog.v(TAG, "Requesting top thumbnail")5825             if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5826             try {
5827                 topThumbnail.requestThumbnail(topRecord.appToken);
5828             } catch (Exception e) {
5829                 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5830                 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5831             }
5832         }
5833 
5834         if (pending == null && receiver != null) {
5835             // In this case all thumbnails were available and the client
5836             // is being asked to be told when the remaining ones come in...
5837             // which is unusually, since the top-most currently running
5838             // activity should never have a canned thumbnail!  Oh well.
5839             try {
receiver.finished()5840                 receiver.finished();
5841             } catch (RemoteException ex) {
5842             }
5843         }
5844 
5845         return list;
5846     }
5847 
getRecentTasks(int maxNum, int flags, int userId)5848     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5849             int flags, int userId) {
5850         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
5851                 false, true, "getRecentTasks", null);
5852 
5853         synchronized (this) {
5854             enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5855                     "getRecentTasks()");
5856             final boolean detailed = checkCallingPermission(
5857                     android.Manifest.permission.GET_DETAILED_TASKS)
5858                     == PackageManager.PERMISSION_GRANTED;
5859 
5860             IPackageManager pm = AppGlobals.getPackageManager();
5861 
5862             final int N = mRecentTasks.size();
5863             ArrayList<ActivityManager.RecentTaskInfo> res
5864                     = new ArrayList<ActivityManager.RecentTaskInfo>(
5865                             maxNum < N ? maxNum : N);
5866             for (int i=0; i<N && maxNum > 0; i++) {
5867                 TaskRecord tr = mRecentTasks.get(i);
5868                 // Only add calling user's recent tasks
5869                 if (tr.userId != userId) continue;
5870                 // Return the entry if desired by the caller.  We always return
5871                 // the first entry, because callers always expect this to be the
5872                 // foreground app.  We may filter others if the caller has
5873                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5874                 // we should exclude the entry.
5875 
5876                 if (i == 0
5877                         || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5878                         || (tr.intent == null)
5879                         || ((tr.intent.getFlags()
5880                                 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5881                     ActivityManager.RecentTaskInfo rti
5882                             = new ActivityManager.RecentTaskInfo();
5883                     rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5884                     rti.persistentId = tr.taskId;
5885                     rti.baseIntent = new Intent(
5886                             tr.intent != null ? tr.intent : tr.affinityIntent);
5887                     if (!detailed) {
5888                         rti.baseIntent.replaceExtras((Bundle)null);
5889                     }
5890                     rti.origActivity = tr.origActivity;
5891                     rti.description = tr.lastDescription;
5892 
5893                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5894                         // Check whether this activity is currently available.
5895                         try {
5896                             if (rti.origActivity != null) {
5897                                 if (pm.getActivityInfo(rti.origActivity, 0, userId)
5898                                         == null) {
5899                                     continue;
5900                                 }
5901                             } else if (rti.baseIntent != null) {
5902                                 if (pm.queryIntentActivities(rti.baseIntent,
5903                                         null, 0, userId) == null) {
5904                                     continue;
5905                                 }
5906                             }
5907                         } catch (RemoteException e) {
5908                             // Will never happen.
5909                         }
5910                     }
5911 
5912                     res.add(rti);
5913                     maxNum--;
5914                 }
5915             }
5916             return res;
5917         }
5918     }
5919 
taskForIdLocked(int id)5920     private TaskRecord taskForIdLocked(int id) {
5921         final int N = mRecentTasks.size();
5922         for (int i=0; i<N; i++) {
5923             TaskRecord tr = mRecentTasks.get(i);
5924             if (tr.taskId == id) {
5925                 return tr;
5926             }
5927         }
5928         return null;
5929     }
5930 
getTaskThumbnails(int id)5931     public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5932         synchronized (this) {
5933             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5934                     "getTaskThumbnails()");
5935             TaskRecord tr = taskForIdLocked(id);
5936             if (tr != null) {
5937                 return mMainStack.getTaskThumbnailsLocked(tr);
5938             }
5939         }
5940         return null;
5941     }
5942 
getTaskTopThumbnail(int id)5943     public Bitmap getTaskTopThumbnail(int id) {
5944         synchronized (this) {
5945             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5946                     "getTaskTopThumbnail()");
5947             TaskRecord tr = taskForIdLocked(id);
5948             if (tr != null) {
5949                 return mMainStack.getTaskTopThumbnailLocked(tr);
5950             }
5951         }
5952         return null;
5953     }
5954 
removeSubTask(int taskId, int subTaskIndex)5955     public boolean removeSubTask(int taskId, int subTaskIndex) {
5956         synchronized (this) {
5957             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5958                     "removeSubTask()");
5959             long ident = Binder.clearCallingIdentity();
5960             try {
5961                 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5962                         true) != null;
5963             } finally {
5964                 Binder.restoreCallingIdentity(ident);
5965             }
5966         }
5967     }
5968 
cleanUpRemovedTaskLocked(TaskRecord tr, int flags)5969     private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5970         final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5971         Intent baseIntent = new Intent(
5972                 tr.intent != null ? tr.intent : tr.affinityIntent);
5973         ComponentName component = baseIntent.getComponent();
5974         if (component == null) {
5975             Slog.w(TAG, "Now component for base intent of task: " + tr);
5976             return;
5977         }
5978 
5979         // Find any running services associated with this app.
5980         mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5981 
5982         if (killProcesses) {
5983             // Find any running processes associated with this app.
5984             final String pkg = component.getPackageName();
5985             ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5986             HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5987             for (SparseArray<ProcessRecord> uids : pmap.values()) {
5988                 for (int i=0; i<uids.size(); i++) {
5989                     ProcessRecord proc = uids.valueAt(i);
5990                     if (proc.userId != tr.userId) {
5991                         continue;
5992                     }
5993                     if (!proc.pkgList.contains(pkg)) {
5994                         continue;
5995                     }
5996                     procs.add(proc);
5997                 }
5998             }
5999 
6000             // Kill the running processes.
6001             for (int i=0; i<procs.size(); i++) {
6002                 ProcessRecord pr = procs.get(i);
6003                 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6004                     Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
6005                     EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6006                             pr.processName, pr.setAdj, "remove task");
6007                     pr.killedBackground = true;
6008                     Process.killProcessQuiet(pr.pid);
6009                 } else {
6010                     pr.waitingToKill = "remove task";
6011                 }
6012             }
6013         }
6014     }
6015 
removeTask(int taskId, int flags)6016     public boolean removeTask(int taskId, int flags) {
6017         synchronized (this) {
6018             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6019                     "removeTask()");
6020             long ident = Binder.clearCallingIdentity();
6021             try {
6022                 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
6023                         false);
6024                 if (r != null) {
6025                     mRecentTasks.remove(r.task);
6026                     cleanUpRemovedTaskLocked(r.task, flags);
6027                     return true;
6028                 } else {
6029                     TaskRecord tr = null;
6030                     int i=0;
6031                     while (i < mRecentTasks.size()) {
6032                         TaskRecord t = mRecentTasks.get(i);
6033                         if (t.taskId == taskId) {
6034                             tr = t;
6035                             break;
6036                         }
6037                         i++;
6038                     }
6039                     if (tr != null) {
6040                         if (tr.numActivities <= 0) {
6041                             // Caller is just removing a recent task that is
6042                             // not actively running.  That is easy!
6043                             mRecentTasks.remove(i);
6044                             cleanUpRemovedTaskLocked(tr, flags);
6045                             return true;
6046                         } else {
6047                             Slog.w(TAG, "removeTask: task " + taskId
6048                                     + " does not have activities to remove, "
6049                                     + " but numActivities=" + tr.numActivities
6050                                     + ": " + tr);
6051                         }
6052                     }
6053                 }
6054             } finally {
6055                 Binder.restoreCallingIdentity(ident);
6056             }
6057         }
6058         return false;
6059     }
6060 
findAffinityTaskTopLocked(int startIndex, String affinity)6061     private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
6062         int j;
6063         TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
6064         TaskRecord jt = startTask;
6065 
6066         // First look backwards
6067         for (j=startIndex-1; j>=0; j--) {
6068             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
6069             if (r.task != jt) {
6070                 jt = r.task;
6071                 if (affinity.equals(jt.affinity)) {
6072                     return j;
6073                 }
6074             }
6075         }
6076 
6077         // Now look forwards
6078         final int N = mMainStack.mHistory.size();
6079         jt = startTask;
6080         for (j=startIndex+1; j<N; j++) {
6081             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
6082             if (r.task != jt) {
6083                 if (affinity.equals(jt.affinity)) {
6084                     return j;
6085                 }
6086                 jt = r.task;
6087             }
6088         }
6089 
6090         // Might it be at the top?
6091         if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
6092             return N-1;
6093         }
6094 
6095         return -1;
6096     }
6097 
6098     /**
6099      * TODO: Add mController hook
6100      */
moveTaskToFront(int task, int flags, Bundle options)6101     public void moveTaskToFront(int task, int flags, Bundle options) {
6102         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6103                 "moveTaskToFront()");
6104 
6105         synchronized(this) {
6106             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6107                     Binder.getCallingUid(), "Task to front")) {
6108                 ActivityOptions.abort(options);
6109                 return;
6110             }
6111             final long origId = Binder.clearCallingIdentity();
6112             try {
6113                 TaskRecord tr = taskForIdLocked(task);
6114                 if (tr != null) {
6115                     if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6116                         mMainStack.mUserLeaving = true;
6117                     }
6118                     if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6119                         // Caller wants the home activity moved with it.  To accomplish this,
6120                         // we'll just move the home task to the top first.
6121                         mMainStack.moveHomeToFrontLocked();
6122                     }
6123                     mMainStack.moveTaskToFrontLocked(tr, null, options);
6124                     return;
6125                 }
6126                 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6127                     ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
6128                     if (hr.task.taskId == task) {
6129                         if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6130                             mMainStack.mUserLeaving = true;
6131                         }
6132                         if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6133                             // Caller wants the home activity moved with it.  To accomplish this,
6134                             // we'll just move the home task to the top first.
6135                             mMainStack.moveHomeToFrontLocked();
6136                         }
6137                         mMainStack.moveTaskToFrontLocked(hr.task, null, options);
6138                         return;
6139                     }
6140                 }
6141             } finally {
6142                 Binder.restoreCallingIdentity(origId);
6143             }
6144             ActivityOptions.abort(options);
6145         }
6146     }
6147 
moveTaskToBack(int task)6148     public void moveTaskToBack(int task) {
6149         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6150                 "moveTaskToBack()");
6151 
6152         synchronized(this) {
6153             if (mMainStack.mResumedActivity != null
6154                     && mMainStack.mResumedActivity.task.taskId == task) {
6155                 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6156                         Binder.getCallingUid(), "Task to back")) {
6157                     return;
6158                 }
6159             }
6160             final long origId = Binder.clearCallingIdentity();
6161             mMainStack.moveTaskToBackLocked(task, null);
6162             Binder.restoreCallingIdentity(origId);
6163         }
6164     }
6165 
6166     /**
6167      * Moves an activity, and all of the other activities within the same task, to the bottom
6168      * of the history stack.  The activity's order within the task is unchanged.
6169      *
6170      * @param token A reference to the activity we wish to move
6171      * @param nonRoot If false then this only works if the activity is the root
6172      *                of a task; if true it will work for any activity in a task.
6173      * @return Returns true if the move completed, false if not.
6174      */
moveActivityTaskToBack(IBinder token, boolean nonRoot)6175     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6176         enforceNotIsolatedCaller("moveActivityTaskToBack");
6177         synchronized(this) {
6178             final long origId = Binder.clearCallingIdentity();
6179             int taskId = getTaskForActivityLocked(token, !nonRoot);
6180             if (taskId >= 0) {
6181                 return mMainStack.moveTaskToBackLocked(taskId, null);
6182             }
6183             Binder.restoreCallingIdentity(origId);
6184         }
6185         return false;
6186     }
6187 
moveTaskBackwards(int task)6188     public void moveTaskBackwards(int task) {
6189         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6190                 "moveTaskBackwards()");
6191 
6192         synchronized(this) {
6193             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6194                     Binder.getCallingUid(), "Task backwards")) {
6195                 return;
6196             }
6197             final long origId = Binder.clearCallingIdentity();
6198             moveTaskBackwardsLocked(task);
6199             Binder.restoreCallingIdentity(origId);
6200         }
6201     }
6202 
moveTaskBackwardsLocked(int task)6203     private final void moveTaskBackwardsLocked(int task) {
6204         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
6205     }
6206 
getTaskForActivity(IBinder token, boolean onlyRoot)6207     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6208         synchronized(this) {
6209             return getTaskForActivityLocked(token, onlyRoot);
6210         }
6211     }
6212 
getTaskForActivityLocked(IBinder token, boolean onlyRoot)6213     int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
6214         final int N = mMainStack.mHistory.size();
6215         TaskRecord lastTask = null;
6216         for (int i=0; i<N; i++) {
6217             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6218             if (r.appToken == token) {
6219                 if (!onlyRoot || lastTask != r.task) {
6220                     return r.task.taskId;
6221                 }
6222                 return -1;
6223             }
6224             lastTask = r.task;
6225         }
6226 
6227         return -1;
6228     }
6229 
6230     // =========================================================
6231     // THUMBNAILS
6232     // =========================================================
6233 
reportThumbnail(IBinder token, Bitmap thumbnail, CharSequence description)6234     public void reportThumbnail(IBinder token,
6235             Bitmap thumbnail, CharSequence description) {
6236         //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6237         final long origId = Binder.clearCallingIdentity();
6238         sendPendingThumbnail(null, token, thumbnail, description, true);
6239         Binder.restoreCallingIdentity(origId);
6240     }
6241 
sendPendingThumbnail(ActivityRecord r, IBinder token, Bitmap thumbnail, CharSequence description, boolean always)6242     final void sendPendingThumbnail(ActivityRecord r, IBinder token,
6243             Bitmap thumbnail, CharSequence description, boolean always) {
6244         TaskRecord task = null;
6245         ArrayList receivers = null;
6246 
6247         //System.out.println("Send pending thumbnail: " + r);
6248 
6249         synchronized(this) {
6250             if (r == null) {
6251                 r = mMainStack.isInStackLocked(token);
6252                 if (r == null) {
6253                     return;
6254                 }
6255             }
6256             if (thumbnail == null && r.thumbHolder != null) {
6257                 thumbnail = r.thumbHolder.lastThumbnail;
6258                 description = r.thumbHolder.lastDescription;
6259             }
6260             if (thumbnail == null && !always) {
6261                 // If there is no thumbnail, and this entry is not actually
6262                 // going away, then abort for now and pick up the next
6263                 // thumbnail we get.
6264                 return;
6265             }
6266             task = r.task;
6267 
6268             int N = mPendingThumbnails.size();
6269             int i=0;
6270             while (i<N) {
6271                 PendingThumbnailsRecord pr =
6272                     (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6273                 //System.out.println("Looking in " + pr.pendingRecords);
6274                 if (pr.pendingRecords.remove(r)) {
6275                     if (receivers == null) {
6276                         receivers = new ArrayList();
6277                     }
6278                     receivers.add(pr);
6279                     if (pr.pendingRecords.size() == 0) {
6280                         pr.finished = true;
6281                         mPendingThumbnails.remove(i);
6282                         N--;
6283                         continue;
6284                     }
6285                 }
6286                 i++;
6287             }
6288         }
6289 
6290         if (receivers != null) {
6291             final int N = receivers.size();
6292             for (int i=0; i<N; i++) {
6293                 try {
6294                     PendingThumbnailsRecord pr =
6295                         (PendingThumbnailsRecord)receivers.get(i);
6296                     pr.receiver.newThumbnail(
6297                         task != null ? task.taskId : -1, thumbnail, description);
6298                     if (pr.finished) {
6299                         pr.receiver.finished();
6300                     }
6301                 } catch (Exception e) {
6302                     Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6303                 }
6304             }
6305         }
6306     }
6307 
6308     // =========================================================
6309     // CONTENT PROVIDERS
6310     // =========================================================
6311 
generateApplicationProvidersLocked(ProcessRecord app)6312     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6313         List<ProviderInfo> providers = null;
6314         try {
6315             providers = AppGlobals.getPackageManager().
6316                 queryContentProviders(app.processName, app.uid,
6317                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6318         } catch (RemoteException ex) {
6319         }
6320         if (DEBUG_MU)
6321             Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6322         int userId = app.userId;
6323         if (providers != null) {
6324             int N = providers.size();
6325             for (int i=0; i<N; i++) {
6326                 ProviderInfo cpi =
6327                     (ProviderInfo)providers.get(i);
6328                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6329                         cpi.name, cpi.flags);
6330                 if (singleton && UserHandle.getUserId(app.uid) != 0) {
6331                     // This is a singleton provider, but a user besides the
6332                     // default user is asking to initialize a process it runs
6333                     // in...  well, no, it doesn't actually run in this process,
6334                     // it runs in the process of the default user.  Get rid of it.
6335                     providers.remove(i);
6336                     N--;
6337                     continue;
6338                 }
6339 
6340                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6341                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6342                 if (cpr == null) {
6343                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6344                     mProviderMap.putProviderByClass(comp, cpr);
6345                 }
6346                 if (DEBUG_MU)
6347                     Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6348                 app.pubProviders.put(cpi.name, cpr);
6349                 app.addPackage(cpi.applicationInfo.packageName);
6350                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
6351             }
6352         }
6353         return providers;
6354     }
6355 
6356     /**
6357      * Check if {@link ProcessRecord} has a possible chance at accessing the
6358      * given {@link ProviderInfo}. Final permission checking is always done
6359      * in {@link ContentProvider}.
6360      */
checkContentProviderPermissionLocked( ProviderInfo cpi, ProcessRecord r)6361     private final String checkContentProviderPermissionLocked(
6362             ProviderInfo cpi, ProcessRecord r) {
6363         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6364         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6365         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6366                 cpi.applicationInfo.uid, cpi.exported)
6367                 == PackageManager.PERMISSION_GRANTED) {
6368             return null;
6369         }
6370         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6371                 cpi.applicationInfo.uid, cpi.exported)
6372                 == PackageManager.PERMISSION_GRANTED) {
6373             return null;
6374         }
6375 
6376         PathPermission[] pps = cpi.pathPermissions;
6377         if (pps != null) {
6378             int i = pps.length;
6379             while (i > 0) {
6380                 i--;
6381                 PathPermission pp = pps[i];
6382                 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6383                         cpi.applicationInfo.uid, cpi.exported)
6384                         == PackageManager.PERMISSION_GRANTED) {
6385                     return null;
6386                 }
6387                 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6388                         cpi.applicationInfo.uid, cpi.exported)
6389                         == PackageManager.PERMISSION_GRANTED) {
6390                     return null;
6391                 }
6392             }
6393         }
6394 
6395         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6396         if (perms != null) {
6397             for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6398                 if (uri.getKey().getAuthority().equals(cpi.authority)) {
6399                     return null;
6400                 }
6401             }
6402         }
6403 
6404         String msg;
6405         if (!cpi.exported) {
6406             msg = "Permission Denial: opening provider " + cpi.name
6407                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6408                     + ", uid=" + callingUid + ") that is not exported from uid "
6409                     + cpi.applicationInfo.uid;
6410         } else {
6411             msg = "Permission Denial: opening provider " + cpi.name
6412                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6413                     + ", uid=" + callingUid + ") requires "
6414                     + cpi.readPermission + " or " + cpi.writePermission;
6415         }
6416         Slog.w(TAG, msg);
6417         return msg;
6418     }
6419 
incProviderCountLocked(ProcessRecord r, final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable)6420     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6421             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6422         if (r != null) {
6423             for (int i=0; i<r.conProviders.size(); i++) {
6424                 ContentProviderConnection conn = r.conProviders.get(i);
6425                 if (conn.provider == cpr) {
6426                     if (DEBUG_PROVIDER) Slog.v(TAG,
6427                             "Adding provider requested by "
6428                             + r.processName + " from process "
6429                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6430                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6431                     if (stable) {
6432                         conn.stableCount++;
6433                         conn.numStableIncs++;
6434                     } else {
6435                         conn.unstableCount++;
6436                         conn.numUnstableIncs++;
6437                     }
6438                     return conn;
6439                 }
6440             }
6441             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6442             if (stable) {
6443                 conn.stableCount = 1;
6444                 conn.numStableIncs = 1;
6445             } else {
6446                 conn.unstableCount = 1;
6447                 conn.numUnstableIncs = 1;
6448             }
6449             cpr.connections.add(conn);
6450             r.conProviders.add(conn);
6451             return conn;
6452         }
6453         cpr.addExternalProcessHandleLocked(externalProcessToken);
6454         return null;
6455     }
6456 
decProviderCountLocked(ContentProviderConnection conn, ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable)6457     boolean decProviderCountLocked(ContentProviderConnection conn,
6458             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6459         if (conn != null) {
6460             cpr = conn.provider;
6461             if (DEBUG_PROVIDER) Slog.v(TAG,
6462                     "Removing provider requested by "
6463                     + conn.client.processName + " from process "
6464                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6465                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6466             if (stable) {
6467                 conn.stableCount--;
6468             } else {
6469                 conn.unstableCount--;
6470             }
6471             if (conn.stableCount == 0 && conn.unstableCount == 0) {
6472                 cpr.connections.remove(conn);
6473                 conn.client.conProviders.remove(conn);
6474                 return true;
6475             }
6476             return false;
6477         }
6478         cpr.removeExternalProcessHandleLocked(externalProcessToken);
6479         return false;
6480     }
6481 
getContentProviderImpl(IApplicationThread caller, String name, IBinder token, boolean stable, int userId)6482     private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6483             String name, IBinder token, boolean stable, int userId) {
6484         ContentProviderRecord cpr;
6485         ContentProviderConnection conn = null;
6486         ProviderInfo cpi = null;
6487 
6488         synchronized(this) {
6489             ProcessRecord r = null;
6490             if (caller != null) {
6491                 r = getRecordForAppLocked(caller);
6492                 if (r == null) {
6493                     throw new SecurityException(
6494                             "Unable to find app for caller " + caller
6495                           + " (pid=" + Binder.getCallingPid()
6496                           + ") when getting content provider " + name);
6497                 }
6498             }
6499 
6500             // First check if this content provider has been published...
6501             cpr = mProviderMap.getProviderByName(name, userId);
6502             boolean providerRunning = cpr != null;
6503             if (providerRunning) {
6504                 cpi = cpr.info;
6505                 String msg;
6506                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6507                     throw new SecurityException(msg);
6508                 }
6509 
6510                 if (r != null && cpr.canRunHere(r)) {
6511                     // This provider has been published or is in the process
6512                     // of being published...  but it is also allowed to run
6513                     // in the caller's process, so don't make a connection
6514                     // and just let the caller instantiate its own instance.
6515                     ContentProviderHolder holder = cpr.newHolder(null);
6516                     // don't give caller the provider object, it needs
6517                     // to make its own.
6518                     holder.provider = null;
6519                     return holder;
6520                 }
6521 
6522                 final long origId = Binder.clearCallingIdentity();
6523 
6524                 // In this case the provider instance already exists, so we can
6525                 // return it right away.
6526                 conn = incProviderCountLocked(r, cpr, token, stable);
6527                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6528                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6529                         // If this is a perceptible app accessing the provider,
6530                         // make sure to count it as being accessed and thus
6531                         // back up on the LRU list.  This is good because
6532                         // content providers are often expensive to start.
6533                         updateLruProcessLocked(cpr.proc, false);
6534                     }
6535                 }
6536 
6537                 if (cpr.proc != null) {
6538                     if (false) {
6539                         if (cpr.name.flattenToShortString().equals(
6540                                 "com.android.providers.calendar/.CalendarProvider2")) {
6541                             Slog.v(TAG, "****************** KILLING "
6542                                 + cpr.name.flattenToShortString());
6543                             Process.killProcess(cpr.proc.pid);
6544                         }
6545                     }
6546                     boolean success = updateOomAdjLocked(cpr.proc);
6547                     if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6548                     // NOTE: there is still a race here where a signal could be
6549                     // pending on the process even though we managed to update its
6550                     // adj level.  Not sure what to do about this, but at least
6551                     // the race is now smaller.
6552                     if (!success) {
6553                         // Uh oh...  it looks like the provider's process
6554                         // has been killed on us.  We need to wait for a new
6555                         // process to be started, and make sure its death
6556                         // doesn't kill our process.
6557                         Slog.i(TAG,
6558                                 "Existing provider " + cpr.name.flattenToShortString()
6559                                 + " is crashing; detaching " + r);
6560                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6561                         appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6562                         if (!lastRef) {
6563                             // This wasn't the last ref our process had on
6564                             // the provider...  we have now been killed, bail.
6565                             return null;
6566                         }
6567                         providerRunning = false;
6568                         conn = null;
6569                     }
6570                 }
6571 
6572                 Binder.restoreCallingIdentity(origId);
6573             }
6574 
6575             boolean singleton;
6576             if (!providerRunning) {
6577                 try {
6578                     cpi = AppGlobals.getPackageManager().
6579                         resolveContentProvider(name,
6580                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6581                 } catch (RemoteException ex) {
6582                 }
6583                 if (cpi == null) {
6584                     return null;
6585                 }
6586                 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6587                         cpi.name, cpi.flags);
6588                 if (singleton) {
6589                     userId = 0;
6590                 }
6591                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6592 
6593                 String msg;
6594                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6595                     throw new SecurityException(msg);
6596                 }
6597 
6598                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6599                         && !cpi.processName.equals("system")) {
6600                     // If this content provider does not run in the system
6601                     // process, and the system is not yet ready to run other
6602                     // processes, then fail fast instead of hanging.
6603                     throw new IllegalArgumentException(
6604                             "Attempt to launch content provider before system ready");
6605                 }
6606 
6607                 // Make sure that the user who owns this provider is started.  If not,
6608                 // we don't want to allow it to run.
6609                 if (mStartedUsers.get(userId) == null) {
6610                     Slog.w(TAG, "Unable to launch app "
6611                             + cpi.applicationInfo.packageName + "/"
6612                             + cpi.applicationInfo.uid + " for provider "
6613                             + name + ": user " + userId + " is stopped");
6614                     return null;
6615                 }
6616 
6617                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6618                 cpr = mProviderMap.getProviderByClass(comp, userId);
6619                 final boolean firstClass = cpr == null;
6620                 if (firstClass) {
6621                     try {
6622                         ApplicationInfo ai =
6623                             AppGlobals.getPackageManager().
6624                                 getApplicationInfo(
6625                                         cpi.applicationInfo.packageName,
6626                                         STOCK_PM_FLAGS, userId);
6627                         if (ai == null) {
6628                             Slog.w(TAG, "No package info for content provider "
6629                                     + cpi.name);
6630                             return null;
6631                         }
6632                         ai = getAppInfoForUser(ai, userId);
6633                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6634                     } catch (RemoteException ex) {
6635                         // pm is in same process, this will never happen.
6636                     }
6637                 }
6638 
6639                 if (r != null && cpr.canRunHere(r)) {
6640                     // If this is a multiprocess provider, then just return its
6641                     // info and allow the caller to instantiate it.  Only do
6642                     // this if the provider is the same user as the caller's
6643                     // process, or can run as root (so can be in any process).
6644                     return cpr.newHolder(null);
6645                 }
6646 
6647                 if (DEBUG_PROVIDER) {
6648                     RuntimeException e = new RuntimeException("here");
6649                     Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6650                           + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6651                 }
6652 
6653                 // This is single process, and our app is now connecting to it.
6654                 // See if we are already in the process of launching this
6655                 // provider.
6656                 final int N = mLaunchingProviders.size();
6657                 int i;
6658                 for (i=0; i<N; i++) {
6659                     if (mLaunchingProviders.get(i) == cpr) {
6660                         break;
6661                     }
6662                 }
6663 
6664                 // If the provider is not already being launched, then get it
6665                 // started.
6666                 if (i >= N) {
6667                     final long origId = Binder.clearCallingIdentity();
6668 
6669                     try {
6670                         // Content provider is now in use, its package can't be stopped.
6671                         try {
6672                             AppGlobals.getPackageManager().setPackageStoppedState(
6673                                     cpr.appInfo.packageName, false, userId);
6674                         } catch (RemoteException e) {
6675                         } catch (IllegalArgumentException e) {
6676                             Slog.w(TAG, "Failed trying to unstop package "
6677                                     + cpr.appInfo.packageName + ": " + e);
6678                         }
6679 
6680                         ProcessRecord proc = startProcessLocked(cpi.processName,
6681                                 cpr.appInfo, false, 0, "content provider",
6682                                 new ComponentName(cpi.applicationInfo.packageName,
6683                                         cpi.name), false, false);
6684                         if (proc == null) {
6685                             Slog.w(TAG, "Unable to launch app "
6686                                     + cpi.applicationInfo.packageName + "/"
6687                                     + cpi.applicationInfo.uid + " for provider "
6688                                     + name + ": process is bad");
6689                             return null;
6690                         }
6691                         cpr.launchingApp = proc;
6692                         mLaunchingProviders.add(cpr);
6693                     } finally {
6694                         Binder.restoreCallingIdentity(origId);
6695                     }
6696                 }
6697 
6698                 // Make sure the provider is published (the same provider class
6699                 // may be published under multiple names).
6700                 if (firstClass) {
6701                     mProviderMap.putProviderByClass(comp, cpr);
6702                 }
6703 
6704                 mProviderMap.putProviderByName(name, cpr);
6705                 conn = incProviderCountLocked(r, cpr, token, stable);
6706                 if (conn != null) {
6707                     conn.waiting = true;
6708                 }
6709             }
6710         }
6711 
6712         // Wait for the provider to be published...
6713         synchronized (cpr) {
6714             while (cpr.provider == null) {
6715                 if (cpr.launchingApp == null) {
6716                     Slog.w(TAG, "Unable to launch app "
6717                             + cpi.applicationInfo.packageName + "/"
6718                             + cpi.applicationInfo.uid + " for provider "
6719                             + name + ": launching app became null");
6720                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6721                             UserHandle.getUserId(cpi.applicationInfo.uid),
6722                             cpi.applicationInfo.packageName,
6723                             cpi.applicationInfo.uid, name);
6724                     return null;
6725                 }
6726                 try {
6727                     if (DEBUG_MU) {
6728                         Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6729                                 + cpr.launchingApp);
6730                     }
6731                     if (conn != null) {
6732                         conn.waiting = true;
6733                     }
6734                     cpr.wait();
6735                 } catch (InterruptedException ex) {
6736                 } finally {
6737                     if (conn != null) {
6738                         conn.waiting = false;
6739                     }
6740                 }
6741             }
6742         }
6743         return cpr != null ? cpr.newHolder(conn) : null;
6744     }
6745 
getContentProvider( IApplicationThread caller, String name, int userId, boolean stable)6746     public final ContentProviderHolder getContentProvider(
6747             IApplicationThread caller, String name, int userId, boolean stable) {
6748         enforceNotIsolatedCaller("getContentProvider");
6749         if (caller == null) {
6750             String msg = "null IApplicationThread when getting content provider "
6751                     + name;
6752             Slog.w(TAG, msg);
6753             throw new SecurityException(msg);
6754         }
6755 
6756         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6757                 false, true, "getContentProvider", null);
6758         return getContentProviderImpl(caller, name, null, stable, userId);
6759     }
6760 
getContentProviderExternal( String name, int userId, IBinder token)6761     public ContentProviderHolder getContentProviderExternal(
6762             String name, int userId, IBinder token) {
6763         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6764             "Do not have permission in call getContentProviderExternal()");
6765         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6766                 false, true, "getContentProvider", null);
6767         return getContentProviderExternalUnchecked(name, token, userId);
6768     }
6769 
getContentProviderExternalUnchecked(String name, IBinder token, int userId)6770     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6771             IBinder token, int userId) {
6772         return getContentProviderImpl(null, name, token, true, userId);
6773     }
6774 
6775     /**
6776      * Drop a content provider from a ProcessRecord's bookkeeping
6777      */
removeContentProvider(IBinder connection, boolean stable)6778     public void removeContentProvider(IBinder connection, boolean stable) {
6779         enforceNotIsolatedCaller("removeContentProvider");
6780         synchronized (this) {
6781             ContentProviderConnection conn;
6782             try {
6783                 conn = (ContentProviderConnection)connection;
6784             } catch (ClassCastException e) {
6785                 String msg ="removeContentProvider: " + connection
6786                         + " not a ContentProviderConnection";
6787                 Slog.w(TAG, msg);
6788                 throw new IllegalArgumentException(msg);
6789             }
6790             if (conn == null) {
6791                 throw new NullPointerException("connection is null");
6792             }
6793             if (decProviderCountLocked(conn, null, null, stable)) {
6794                 updateOomAdjLocked();
6795             }
6796         }
6797     }
6798 
removeContentProviderExternal(String name, IBinder token)6799     public void removeContentProviderExternal(String name, IBinder token) {
6800         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6801             "Do not have permission in call removeContentProviderExternal()");
6802         removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6803     }
6804 
removeContentProviderExternalUnchecked(String name, IBinder token, int userId)6805     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
6806         synchronized (this) {
6807             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6808             if(cpr == null) {
6809                 //remove from mProvidersByClass
6810                 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6811                 return;
6812             }
6813 
6814             //update content provider record entry info
6815             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6816             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6817             if (localCpr.hasExternalProcessHandles()) {
6818                 if (localCpr.removeExternalProcessHandleLocked(token)) {
6819                     updateOomAdjLocked();
6820                 } else {
6821                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6822                             + " with no external reference for token: "
6823                             + token + ".");
6824                 }
6825             } else {
6826                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6827                         + " with no external references.");
6828             }
6829         }
6830     }
6831 
publishContentProviders(IApplicationThread caller, List<ContentProviderHolder> providers)6832     public final void publishContentProviders(IApplicationThread caller,
6833             List<ContentProviderHolder> providers) {
6834         if (providers == null) {
6835             return;
6836         }
6837 
6838         enforceNotIsolatedCaller("publishContentProviders");
6839         synchronized (this) {
6840             final ProcessRecord r = getRecordForAppLocked(caller);
6841             if (DEBUG_MU)
6842                 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6843             if (r == null) {
6844                 throw new SecurityException(
6845                         "Unable to find app for caller " + caller
6846                       + " (pid=" + Binder.getCallingPid()
6847                       + ") when publishing content providers");
6848             }
6849 
6850             final long origId = Binder.clearCallingIdentity();
6851 
6852             final int N = providers.size();
6853             for (int i=0; i<N; i++) {
6854                 ContentProviderHolder src = providers.get(i);
6855                 if (src == null || src.info == null || src.provider == null) {
6856                     continue;
6857                 }
6858                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6859                 if (DEBUG_MU)
6860                     Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6861                 if (dst != null) {
6862                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6863                     mProviderMap.putProviderByClass(comp, dst);
6864                     String names[] = dst.info.authority.split(";");
6865                     for (int j = 0; j < names.length; j++) {
6866                         mProviderMap.putProviderByName(names[j], dst);
6867                     }
6868 
6869                     int NL = mLaunchingProviders.size();
6870                     int j;
6871                     for (j=0; j<NL; j++) {
6872                         if (mLaunchingProviders.get(j) == dst) {
6873                             mLaunchingProviders.remove(j);
6874                             j--;
6875                             NL--;
6876                         }
6877                     }
6878                     synchronized (dst) {
6879                         dst.provider = src.provider;
6880                         dst.proc = r;
6881                         dst.notifyAll();
6882                     }
6883                     updateOomAdjLocked(r);
6884                 }
6885             }
6886 
6887             Binder.restoreCallingIdentity(origId);
6888         }
6889     }
6890 
refContentProvider(IBinder connection, int stable, int unstable)6891     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6892         ContentProviderConnection conn;
6893         try {
6894             conn = (ContentProviderConnection)connection;
6895         } catch (ClassCastException e) {
6896             String msg ="refContentProvider: " + connection
6897                     + " not a ContentProviderConnection";
6898             Slog.w(TAG, msg);
6899             throw new IllegalArgumentException(msg);
6900         }
6901         if (conn == null) {
6902             throw new NullPointerException("connection is null");
6903         }
6904 
6905         synchronized (this) {
6906             if (stable > 0) {
6907                 conn.numStableIncs += stable;
6908             }
6909             stable = conn.stableCount + stable;
6910             if (stable < 0) {
6911                 throw new IllegalStateException("stableCount < 0: " + stable);
6912             }
6913 
6914             if (unstable > 0) {
6915                 conn.numUnstableIncs += unstable;
6916             }
6917             unstable = conn.unstableCount + unstable;
6918             if (unstable < 0) {
6919                 throw new IllegalStateException("unstableCount < 0: " + unstable);
6920             }
6921 
6922             if ((stable+unstable) <= 0) {
6923                 throw new IllegalStateException("ref counts can't go to zero here: stable="
6924                         + stable + " unstable=" + unstable);
6925             }
6926             conn.stableCount = stable;
6927             conn.unstableCount = unstable;
6928             return !conn.dead;
6929         }
6930     }
6931 
unstableProviderDied(IBinder connection)6932     public void unstableProviderDied(IBinder connection) {
6933         ContentProviderConnection conn;
6934         try {
6935             conn = (ContentProviderConnection)connection;
6936         } catch (ClassCastException e) {
6937             String msg ="refContentProvider: " + connection
6938                     + " not a ContentProviderConnection";
6939             Slog.w(TAG, msg);
6940             throw new IllegalArgumentException(msg);
6941         }
6942         if (conn == null) {
6943             throw new NullPointerException("connection is null");
6944         }
6945 
6946         // Safely retrieve the content provider associated with the connection.
6947         IContentProvider provider;
6948         synchronized (this) {
6949             provider = conn.provider.provider;
6950         }
6951 
6952         if (provider == null) {
6953             // Um, yeah, we're way ahead of you.
6954             return;
6955         }
6956 
6957         // Make sure the caller is being honest with us.
6958         if (provider.asBinder().pingBinder()) {
6959             // Er, no, still looks good to us.
6960             synchronized (this) {
6961                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6962                         + " says " + conn + " died, but we don't agree");
6963                 return;
6964             }
6965         }
6966 
6967         // Well look at that!  It's dead!
6968         synchronized (this) {
6969             if (conn.provider.provider != provider) {
6970                 // But something changed...  good enough.
6971                 return;
6972             }
6973 
6974             ProcessRecord proc = conn.provider.proc;
6975             if (proc == null || proc.thread == null) {
6976                 // Seems like the process is already cleaned up.
6977                 return;
6978             }
6979 
6980             // As far as we're concerned, this is just like receiving a
6981             // death notification...  just a bit prematurely.
6982             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6983                     + ") early provider death");
6984             final long ident = Binder.clearCallingIdentity();
6985             try {
6986                 appDiedLocked(proc, proc.pid, proc.thread);
6987             } finally {
6988                 Binder.restoreCallingIdentity(ident);
6989             }
6990         }
6991     }
6992 
installSystemProviders()6993     public static final void installSystemProviders() {
6994         List<ProviderInfo> providers;
6995         synchronized (mSelf) {
6996             ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6997             providers = mSelf.generateApplicationProvidersLocked(app);
6998             if (providers != null) {
6999                 for (int i=providers.size()-1; i>=0; i--) {
7000                     ProviderInfo pi = (ProviderInfo)providers.get(i);
7001                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
7002                         Slog.w(TAG, "Not installing system proc provider " + pi.name
7003                                 + ": not system .apk");
7004                         providers.remove(i);
7005                     }
7006                 }
7007             }
7008         }
7009         if (providers != null) {
7010             mSystemThread.installSystemProviders(providers);
7011         }
7012 
7013         mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
7014 
7015         mSelf.mUsageStatsService.monitorPackages();
7016     }
7017 
7018     /**
7019      * Allows app to retrieve the MIME type of a URI without having permission
7020      * to access its content provider.
7021      *
7022      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
7023      *
7024      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
7025      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
7026      */
getProviderMimeType(Uri uri, int userId)7027     public String getProviderMimeType(Uri uri, int userId) {
7028         enforceNotIsolatedCaller("getProviderMimeType");
7029         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7030                 userId, false, true, "getProviderMimeType", null);
7031         final String name = uri.getAuthority();
7032         final long ident = Binder.clearCallingIdentity();
7033         ContentProviderHolder holder = null;
7034 
7035         try {
7036             holder = getContentProviderExternalUnchecked(name, null, userId);
7037             if (holder != null) {
7038                 return holder.provider.getType(uri);
7039             }
7040         } catch (RemoteException e) {
7041             Log.w(TAG, "Content provider dead retrieving " + uri, e);
7042             return null;
7043         } finally {
7044             if (holder != null) {
7045                 removeContentProviderExternalUnchecked(name, null, userId);
7046             }
7047             Binder.restoreCallingIdentity(ident);
7048         }
7049 
7050         return null;
7051     }
7052 
7053     // =========================================================
7054     // GLOBAL MANAGEMENT
7055     // =========================================================
7056 
newProcessRecordLocked(IApplicationThread thread, ApplicationInfo info, String customProcess, boolean isolated)7057     final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
7058             ApplicationInfo info, String customProcess, boolean isolated) {
7059         String proc = customProcess != null ? customProcess : info.processName;
7060         BatteryStatsImpl.Uid.Proc ps = null;
7061         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7062         int uid = info.uid;
7063         if (isolated) {
7064             int userId = UserHandle.getUserId(uid);
7065             int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
7066             uid = 0;
7067             while (true) {
7068                 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
7069                         || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
7070                     mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
7071                 }
7072                 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
7073                 mNextIsolatedProcessUid++;
7074                 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
7075                     // No process for this uid, use it.
7076                     break;
7077                 }
7078                 stepsLeft--;
7079                 if (stepsLeft <= 0) {
7080                     return null;
7081                 }
7082             }
7083         }
7084         synchronized (stats) {
7085             ps = stats.getProcessStatsLocked(info.uid, proc);
7086         }
7087         return new ProcessRecord(ps, thread, info, proc, uid);
7088     }
7089 
addAppLocked(ApplicationInfo info, boolean isolated)7090     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
7091         ProcessRecord app;
7092         if (!isolated) {
7093             app = getProcessRecordLocked(info.processName, info.uid);
7094         } else {
7095             app = null;
7096         }
7097 
7098         if (app == null) {
7099             app = newProcessRecordLocked(null, info, null, isolated);
7100             mProcessNames.put(info.processName, app.uid, app);
7101             if (isolated) {
7102                 mIsolatedProcesses.put(app.uid, app);
7103             }
7104             updateLruProcessLocked(app, true);
7105         }
7106 
7107         // This package really, really can not be stopped.
7108         try {
7109             AppGlobals.getPackageManager().setPackageStoppedState(
7110                     info.packageName, false, UserHandle.getUserId(app.uid));
7111         } catch (RemoteException e) {
7112         } catch (IllegalArgumentException e) {
7113             Slog.w(TAG, "Failed trying to unstop package "
7114                     + info.packageName + ": " + e);
7115         }
7116 
7117         if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7118                 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7119             app.persistent = true;
7120             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
7121         }
7122         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7123             mPersistentStartingProcesses.add(app);
7124             startProcessLocked(app, "added application", app.processName);
7125         }
7126 
7127         return app;
7128     }
7129 
unhandledBack()7130     public void unhandledBack() {
7131         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7132                 "unhandledBack()");
7133 
7134         synchronized(this) {
7135             int count = mMainStack.mHistory.size();
7136             if (DEBUG_SWITCH) Slog.d(
7137                 TAG, "Performing unhandledBack(): stack size = " + count);
7138             if (count > 1) {
7139                 final long origId = Binder.clearCallingIdentity();
7140                 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
7141                         count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
7142                 Binder.restoreCallingIdentity(origId);
7143             }
7144         }
7145     }
7146 
openContentUri(Uri uri)7147     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7148         enforceNotIsolatedCaller("openContentUri");
7149         final int userId = UserHandle.getCallingUserId();
7150         String name = uri.getAuthority();
7151         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
7152         ParcelFileDescriptor pfd = null;
7153         if (cph != null) {
7154             // We record the binder invoker's uid in thread-local storage before
7155             // going to the content provider to open the file.  Later, in the code
7156             // that handles all permissions checks, we look for this uid and use
7157             // that rather than the Activity Manager's own uid.  The effect is that
7158             // we do the check against the caller's permissions even though it looks
7159             // to the content provider like the Activity Manager itself is making
7160             // the request.
7161             sCallerIdentity.set(new Identity(
7162                     Binder.getCallingPid(), Binder.getCallingUid()));
7163             try {
7164                 pfd = cph.provider.openFile(null, uri, "r");
7165             } catch (FileNotFoundException e) {
7166                 // do nothing; pfd will be returned null
7167             } finally {
7168                 // Ensure that whatever happens, we clean up the identity state
7169                 sCallerIdentity.remove();
7170             }
7171 
7172             // We've got the fd now, so we're done with the provider.
7173             removeContentProviderExternalUnchecked(name, null, userId);
7174         } else {
7175             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
7176         }
7177         return pfd;
7178     }
7179 
7180     // Actually is sleeping or shutting down or whatever else in the future
7181     // is an inactive state.
isSleeping()7182     public boolean isSleeping() {
7183         return mSleeping || mShuttingDown;
7184     }
7185 
goingToSleep()7186     public void goingToSleep() {
7187         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7188                 != PackageManager.PERMISSION_GRANTED) {
7189             throw new SecurityException("Requires permission "
7190                     + android.Manifest.permission.DEVICE_POWER);
7191         }
7192 
7193         synchronized(this) {
7194             mWentToSleep = true;
7195             updateEventDispatchingLocked();
7196 
7197             if (!mSleeping) {
7198                 mSleeping = true;
7199                 mMainStack.stopIfSleepingLocked();
7200 
7201                 // Initialize the wake times of all processes.
7202                 checkExcessivePowerUsageLocked(false);
7203                 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7204                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7205                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7206             }
7207         }
7208     }
7209 
shutdown(int timeout)7210     public boolean shutdown(int timeout) {
7211         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7212                 != PackageManager.PERMISSION_GRANTED) {
7213             throw new SecurityException("Requires permission "
7214                     + android.Manifest.permission.SHUTDOWN);
7215         }
7216 
7217         boolean timedout = false;
7218 
7219         synchronized(this) {
7220             mShuttingDown = true;
7221             updateEventDispatchingLocked();
7222 
7223             if (mMainStack.mResumedActivity != null) {
7224                 mMainStack.stopIfSleepingLocked();
7225                 final long endTime = System.currentTimeMillis() + timeout;
7226                 while (mMainStack.mResumedActivity != null
7227                         || mMainStack.mPausingActivity != null) {
7228                     long delay = endTime - System.currentTimeMillis();
7229                     if (delay <= 0) {
7230                         Slog.w(TAG, "Activity manager shutdown timed out");
7231                         timedout = true;
7232                         break;
7233                     }
7234                     try {
7235                         this.wait();
7236                     } catch (InterruptedException e) {
7237                     }
7238                 }
7239             }
7240         }
7241 
7242         mAppOpsService.shutdown();
7243         mUsageStatsService.shutdown();
7244         mBatteryStatsService.shutdown();
7245 
7246         return timedout;
7247     }
7248 
activitySlept(IBinder token)7249     public final void activitySlept(IBinder token) {
7250         if (localLOGV) Slog.v(
7251             TAG, "Activity slept: token=" + token);
7252 
7253         ActivityRecord r = null;
7254 
7255         final long origId = Binder.clearCallingIdentity();
7256 
7257         synchronized (this) {
7258             r = mMainStack.isInStackLocked(token);
7259             if (r != null) {
7260                 mMainStack.activitySleptLocked(r);
7261             }
7262         }
7263 
7264         Binder.restoreCallingIdentity(origId);
7265     }
7266 
comeOutOfSleepIfNeededLocked()7267     private void comeOutOfSleepIfNeededLocked() {
7268         if (!mWentToSleep && !mLockScreenShown) {
7269             if (mSleeping) {
7270                 mSleeping = false;
7271                 mMainStack.awakeFromSleepingLocked();
7272                 mMainStack.resumeTopActivityLocked(null);
7273             }
7274         }
7275     }
7276 
wakingUp()7277     public void wakingUp() {
7278         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7279                 != PackageManager.PERMISSION_GRANTED) {
7280             throw new SecurityException("Requires permission "
7281                     + android.Manifest.permission.DEVICE_POWER);
7282         }
7283 
7284         synchronized(this) {
7285             mWentToSleep = false;
7286             updateEventDispatchingLocked();
7287             comeOutOfSleepIfNeededLocked();
7288         }
7289     }
7290 
updateEventDispatchingLocked()7291     private void updateEventDispatchingLocked() {
7292         mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7293     }
7294 
setLockScreenShown(boolean shown)7295     public void setLockScreenShown(boolean shown) {
7296         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7297                 != PackageManager.PERMISSION_GRANTED) {
7298             throw new SecurityException("Requires permission "
7299                     + android.Manifest.permission.DEVICE_POWER);
7300         }
7301 
7302         synchronized(this) {
7303             mLockScreenShown = shown;
7304             comeOutOfSleepIfNeededLocked();
7305         }
7306     }
7307 
stopAppSwitches()7308     public void stopAppSwitches() {
7309         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7310                 != PackageManager.PERMISSION_GRANTED) {
7311             throw new SecurityException("Requires permission "
7312                     + android.Manifest.permission.STOP_APP_SWITCHES);
7313         }
7314 
7315         synchronized(this) {
7316             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7317                     + APP_SWITCH_DELAY_TIME;
7318             mDidAppSwitch = false;
7319             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7320             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7321             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7322         }
7323     }
7324 
resumeAppSwitches()7325     public void resumeAppSwitches() {
7326         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7327                 != PackageManager.PERMISSION_GRANTED) {
7328             throw new SecurityException("Requires permission "
7329                     + android.Manifest.permission.STOP_APP_SWITCHES);
7330         }
7331 
7332         synchronized(this) {
7333             // Note that we don't execute any pending app switches... we will
7334             // let those wait until either the timeout, or the next start
7335             // activity request.
7336             mAppSwitchesAllowedTime = 0;
7337         }
7338     }
7339 
checkAppSwitchAllowedLocked(int callingPid, int callingUid, String name)7340     boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7341             String name) {
7342         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7343             return true;
7344         }
7345 
7346         final int perm = checkComponentPermission(
7347                 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7348                 callingUid, -1, true);
7349         if (perm == PackageManager.PERMISSION_GRANTED) {
7350             return true;
7351         }
7352 
7353         Slog.w(TAG, name + " request from " + callingUid + " stopped");
7354         return false;
7355     }
7356 
setDebugApp(String packageName, boolean waitForDebugger, boolean persistent)7357     public void setDebugApp(String packageName, boolean waitForDebugger,
7358             boolean persistent) {
7359         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7360                 "setDebugApp()");
7361 
7362         // Note that this is not really thread safe if there are multiple
7363         // callers into it at the same time, but that's not a situation we
7364         // care about.
7365         if (persistent) {
7366             final ContentResolver resolver = mContext.getContentResolver();
7367             Settings.Global.putString(
7368                 resolver, Settings.Global.DEBUG_APP,
7369                 packageName);
7370             Settings.Global.putInt(
7371                 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
7372                 waitForDebugger ? 1 : 0);
7373         }
7374 
7375         synchronized (this) {
7376             if (!persistent) {
7377                 mOrigDebugApp = mDebugApp;
7378                 mOrigWaitForDebugger = mWaitForDebugger;
7379             }
7380             mDebugApp = packageName;
7381             mWaitForDebugger = waitForDebugger;
7382             mDebugTransient = !persistent;
7383             if (packageName != null) {
7384                 final long origId = Binder.clearCallingIdentity();
7385                 forceStopPackageLocked(packageName, -1, false, false, true, true,
7386                         UserHandle.USER_ALL);
7387                 Binder.restoreCallingIdentity(origId);
7388             }
7389         }
7390     }
7391 
setOpenGlTraceApp(ApplicationInfo app, String processName)7392     void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7393         synchronized (this) {
7394             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7395             if (!isDebuggable) {
7396                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7397                     throw new SecurityException("Process not debuggable: " + app.packageName);
7398                 }
7399             }
7400 
7401             mOpenGlTraceApp = processName;
7402         }
7403     }
7404 
setProfileApp(ApplicationInfo app, String processName, String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler)7405     void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7406             ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7407         synchronized (this) {
7408             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7409             if (!isDebuggable) {
7410                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7411                     throw new SecurityException("Process not debuggable: " + app.packageName);
7412                 }
7413             }
7414             mProfileApp = processName;
7415             mProfileFile = profileFile;
7416             if (mProfileFd != null) {
7417                 try {
7418                     mProfileFd.close();
7419                 } catch (IOException e) {
7420                 }
7421                 mProfileFd = null;
7422             }
7423             mProfileFd = profileFd;
7424             mProfileType = 0;
7425             mAutoStopProfiler = autoStopProfiler;
7426         }
7427     }
7428 
setAlwaysFinish(boolean enabled)7429     public void setAlwaysFinish(boolean enabled) {
7430         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7431                 "setAlwaysFinish()");
7432 
7433         Settings.Global.putInt(
7434                 mContext.getContentResolver(),
7435                 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7436 
7437         synchronized (this) {
7438             mAlwaysFinishActivities = enabled;
7439         }
7440     }
7441 
setActivityController(IActivityController controller)7442     public void setActivityController(IActivityController controller) {
7443         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7444                 "setActivityController()");
7445         synchronized (this) {
7446             mController = controller;
7447             Watchdog.getInstance().setActivityController(controller);
7448         }
7449     }
7450 
setUserIsMonkey(boolean userIsMonkey)7451     public void setUserIsMonkey(boolean userIsMonkey) {
7452         synchronized (this) {
7453             synchronized (mPidsSelfLocked) {
7454                 final int callingPid = Binder.getCallingPid();
7455                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
7456                 if (precessRecord == null) {
7457                     throw new SecurityException("Unknown process: " + callingPid);
7458                 }
7459                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
7460                     throw new SecurityException("Only an instrumentation process "
7461                             + "with a UiAutomation can call setUserIsMonkey");
7462                 }
7463             }
7464             mUserIsMonkey = userIsMonkey;
7465         }
7466     }
7467 
isUserAMonkey()7468     public boolean isUserAMonkey() {
7469         synchronized (this) {
7470             // If there is a controller also implies the user is a monkey.
7471             return (mUserIsMonkey || mController != null);
7472         }
7473     }
7474 
requestBugReport()7475     public void requestBugReport() {
7476         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
7477         SystemProperties.set("ctl.start", "bugreport");
7478     }
7479 
getInputDispatchingTimeoutLocked(ActivityRecord r)7480     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
7481         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
7482     }
7483 
getInputDispatchingTimeoutLocked(ProcessRecord r)7484     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
7485         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
7486             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
7487         }
7488         return KEY_DISPATCHING_TIMEOUT;
7489     }
7490 
7491 
inputDispatchingTimedOut(int pid, final boolean aboveSystem)7492     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem) {
7493         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
7494                 != PackageManager.PERMISSION_GRANTED) {
7495             throw new SecurityException("Requires permission "
7496                     + android.Manifest.permission.FILTER_EVENTS);
7497         }
7498         ProcessRecord proc;
7499         long timeout;
7500         synchronized (this) {
7501             synchronized (mPidsSelfLocked) {
7502                 proc = mPidsSelfLocked.get(pid);
7503             }
7504             timeout = getInputDispatchingTimeoutLocked(proc);
7505         }
7506 
7507         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem)) {
7508             return -1;
7509         }
7510 
7511         return timeout;
7512     }
7513 
7514     /**
7515      * Handle input dispatching timeouts.
7516      * Returns whether input dispatching should be aborted or not.
7517      */
inputDispatchingTimedOut(final ProcessRecord proc, final ActivityRecord activity, final ActivityRecord parent, final boolean aboveSystem)7518     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
7519             final ActivityRecord activity, final ActivityRecord parent,
7520             final boolean aboveSystem) {
7521         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
7522                 != PackageManager.PERMISSION_GRANTED) {
7523             throw new SecurityException("Requires permission "
7524                     + android.Manifest.permission.FILTER_EVENTS);
7525         }
7526 
7527         if (proc != null) {
7528             synchronized (this) {
7529                 if (proc.debugging) {
7530                     return false;
7531                 }
7532 
7533                 if (mDidDexOpt) {
7534                     // Give more time since we were dexopting.
7535                     mDidDexOpt = false;
7536                     return false;
7537                 }
7538 
7539                 if (proc.instrumentationClass != null) {
7540                     Bundle info = new Bundle();
7541                     info.putString("shortMsg", "keyDispatchingTimedOut");
7542                     info.putString("longMsg", "Timed out while dispatching key event");
7543                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
7544                     return true;
7545                 }
7546             }
7547             mHandler.post(new Runnable() {
7548                 @Override
7549                 public void run() {
7550                     appNotResponding(proc, activity, parent, aboveSystem, "keyDispatchingTimedOut");
7551                 }
7552             });
7553         }
7554 
7555         return true;
7556     }
7557 
getTopActivityExtras(int requestType)7558     public Bundle getTopActivityExtras(int requestType) {
7559         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
7560                 "getTopActivityExtras()");
7561         PendingActivityExtras pae;
7562         Bundle extras = new Bundle();
7563         synchronized (this) {
7564             ActivityRecord activity = mMainStack.mResumedActivity;
7565             if (activity == null) {
7566                 Slog.w(TAG, "getTopActivityExtras failed: no resumed activity");
7567                 return null;
7568             }
7569             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
7570             if (activity.app == null || activity.app.thread == null) {
7571                 Slog.w(TAG, "getTopActivityExtras failed: no process for " + activity);
7572                 return extras;
7573             }
7574             if (activity.app.pid == Binder.getCallingPid()) {
7575                 Slog.w(TAG, "getTopActivityExtras failed: request process same as " + activity);
7576                 return extras;
7577             }
7578             pae = new PendingActivityExtras(activity);
7579             try {
7580                 activity.app.thread.requestActivityExtras(activity.appToken, pae, requestType);
7581                 mPendingActivityExtras.add(pae);
7582                 mHandler.postDelayed(pae, PENDING_ACTIVITY_RESULT_TIMEOUT);
7583             } catch (RemoteException e) {
7584                 Slog.w(TAG, "getTopActivityExtras failed: crash calling " + activity);
7585                 return extras;
7586             }
7587         }
7588         synchronized (pae) {
7589             while (!pae.haveResult) {
7590                 try {
7591                     pae.wait();
7592                 } catch (InterruptedException e) {
7593                 }
7594             }
7595             if (pae.result != null) {
7596                 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
7597             }
7598         }
7599         synchronized (this) {
7600             mPendingActivityExtras.remove(pae);
7601             mHandler.removeCallbacks(pae);
7602         }
7603         return extras;
7604     }
7605 
reportTopActivityExtras(IBinder token, Bundle extras)7606     public void reportTopActivityExtras(IBinder token, Bundle extras) {
7607         PendingActivityExtras pae = (PendingActivityExtras)token;
7608         synchronized (pae) {
7609             pae.result = extras;
7610             pae.haveResult = true;
7611             pae.notifyAll();
7612         }
7613     }
7614 
registerProcessObserver(IProcessObserver observer)7615     public void registerProcessObserver(IProcessObserver observer) {
7616         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7617                 "registerProcessObserver()");
7618         synchronized (this) {
7619             mProcessObservers.register(observer);
7620         }
7621     }
7622 
unregisterProcessObserver(IProcessObserver observer)7623     public void unregisterProcessObserver(IProcessObserver observer) {
7624         synchronized (this) {
7625             mProcessObservers.unregister(observer);
7626         }
7627     }
7628 
setImmersive(IBinder token, boolean immersive)7629     public void setImmersive(IBinder token, boolean immersive) {
7630         synchronized(this) {
7631             final ActivityRecord r = mMainStack.isInStackLocked(token);
7632             if (r == null) {
7633                 throw new IllegalArgumentException();
7634             }
7635             r.immersive = immersive;
7636 
7637             // update associated state if we're frontmost
7638             if (r == mFocusedActivity) {
7639                 if (DEBUG_IMMERSIVE) {
7640                     Slog.d(TAG, "Frontmost changed immersion: "+ r);
7641                 }
7642                 applyUpdateLockStateLocked(r);
7643             }
7644         }
7645     }
7646 
isImmersive(IBinder token)7647     public boolean isImmersive(IBinder token) {
7648         synchronized (this) {
7649             ActivityRecord r = mMainStack.isInStackLocked(token);
7650             if (r == null) {
7651                 throw new IllegalArgumentException();
7652             }
7653             return r.immersive;
7654         }
7655     }
7656 
isTopActivityImmersive()7657     public boolean isTopActivityImmersive() {
7658         enforceNotIsolatedCaller("startActivity");
7659         synchronized (this) {
7660             ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7661             return (r != null) ? r.immersive : false;
7662         }
7663     }
7664 
enterSafeMode()7665     public final void enterSafeMode() {
7666         synchronized(this) {
7667             // It only makes sense to do this before the system is ready
7668             // and started launching other packages.
7669             if (!mSystemReady) {
7670                 try {
7671                     AppGlobals.getPackageManager().enterSafeMode();
7672                 } catch (RemoteException e) {
7673                 }
7674             }
7675         }
7676     }
7677 
showSafeModeOverlay()7678     public final void showSafeModeOverlay() {
7679         View v = LayoutInflater.from(mContext).inflate(
7680                 com.android.internal.R.layout.safe_mode, null);
7681         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7682         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7683         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7684         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7685         lp.gravity = Gravity.BOTTOM | Gravity.START;
7686         lp.format = v.getBackground().getOpacity();
7687         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7688                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7689         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
7690         ((WindowManager)mContext.getSystemService(
7691                 Context.WINDOW_SERVICE)).addView(v, lp);
7692     }
7693 
noteWakeupAlarm(IIntentSender sender)7694     public void noteWakeupAlarm(IIntentSender sender) {
7695         if (!(sender instanceof PendingIntentRecord)) {
7696             return;
7697         }
7698         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7699         synchronized (stats) {
7700             if (mBatteryStatsService.isOnBattery()) {
7701                 mBatteryStatsService.enforceCallingPermission();
7702                 PendingIntentRecord rec = (PendingIntentRecord)sender;
7703                 int MY_UID = Binder.getCallingUid();
7704                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7705                 BatteryStatsImpl.Uid.Pkg pkg =
7706                     stats.getPackageStatsLocked(uid, rec.key.packageName);
7707                 pkg.incWakeupsLocked();
7708             }
7709         }
7710     }
7711 
killPids(int[] pids, String pReason, boolean secure)7712     public boolean killPids(int[] pids, String pReason, boolean secure) {
7713         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7714             throw new SecurityException("killPids only available to the system");
7715         }
7716         String reason = (pReason == null) ? "Unknown" : pReason;
7717         // XXX Note: don't acquire main activity lock here, because the window
7718         // manager calls in with its locks held.
7719 
7720         boolean killed = false;
7721         synchronized (mPidsSelfLocked) {
7722             int[] types = new int[pids.length];
7723             int worstType = 0;
7724             for (int i=0; i<pids.length; i++) {
7725                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7726                 if (proc != null) {
7727                     int type = proc.setAdj;
7728                     types[i] = type;
7729                     if (type > worstType) {
7730                         worstType = type;
7731                     }
7732                 }
7733             }
7734 
7735             // If the worst oom_adj is somewhere in the hidden proc LRU range,
7736             // then constrain it so we will kill all hidden procs.
7737             if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7738                     && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7739                 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7740             }
7741 
7742             // If this is not a secure call, don't let it kill processes that
7743             // are important.
7744             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7745                 worstType = ProcessList.SERVICE_ADJ;
7746             }
7747 
7748             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7749             for (int i=0; i<pids.length; i++) {
7750                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7751                 if (proc == null) {
7752                     continue;
7753                 }
7754                 int adj = proc.setAdj;
7755                 if (adj >= worstType && !proc.killedBackground) {
7756                     Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7757                     EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid,
7758                             proc.processName, adj, reason);
7759                     killed = true;
7760                     proc.killedBackground = true;
7761                     Process.killProcessQuiet(pids[i]);
7762                 }
7763             }
7764         }
7765         return killed;
7766     }
7767 
7768     @Override
killUid(int uid, String reason)7769     public void killUid(int uid, String reason) {
7770         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7771             throw new SecurityException("killUid only available to the system");
7772         }
7773         synchronized (this) {
7774             killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
7775                     ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
7776                     reason != null ? reason : "kill uid");
7777         }
7778     }
7779 
7780     @Override
killProcessesBelowForeground(String reason)7781     public boolean killProcessesBelowForeground(String reason) {
7782         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7783             throw new SecurityException("killProcessesBelowForeground() only available to system");
7784         }
7785 
7786         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7787     }
7788 
killProcessesBelowAdj(int belowAdj, String reason)7789     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7790         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7791             throw new SecurityException("killProcessesBelowAdj() only available to system");
7792         }
7793 
7794         boolean killed = false;
7795         synchronized (mPidsSelfLocked) {
7796             final int size = mPidsSelfLocked.size();
7797             for (int i = 0; i < size; i++) {
7798                 final int pid = mPidsSelfLocked.keyAt(i);
7799                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7800                 if (proc == null) continue;
7801 
7802                 final int adj = proc.setAdj;
7803                 if (adj > belowAdj && !proc.killedBackground) {
7804                     Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7805                     EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId,
7806                             proc.pid, proc.processName, adj, reason);
7807                     killed = true;
7808                     proc.killedBackground = true;
7809                     Process.killProcessQuiet(pid);
7810                 }
7811             }
7812         }
7813         return killed;
7814     }
7815 
7816     @Override
hang(final IBinder who, boolean allowRestart)7817     public void hang(final IBinder who, boolean allowRestart) {
7818         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
7819                 != PackageManager.PERMISSION_GRANTED) {
7820             throw new SecurityException("Requires permission "
7821                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
7822         }
7823 
7824         final IBinder.DeathRecipient death = new DeathRecipient() {
7825             @Override
7826             public void binderDied() {
7827                 synchronized (this) {
7828                     notifyAll();
7829                 }
7830             }
7831         };
7832 
7833         try {
7834             who.linkToDeath(death, 0);
7835         } catch (RemoteException e) {
7836             Slog.w(TAG, "hang: given caller IBinder is already dead.");
7837             return;
7838         }
7839 
7840         synchronized (this) {
7841             Watchdog.getInstance().setAllowRestart(allowRestart);
7842             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
7843             synchronized (death) {
7844                 while (who.isBinderAlive()) {
7845                     try {
7846                         death.wait();
7847                     } catch (InterruptedException e) {
7848                     }
7849                 }
7850             }
7851             Watchdog.getInstance().setAllowRestart(true);
7852         }
7853     }
7854 
startRunning(String pkg, String cls, String action, String data)7855     public final void startRunning(String pkg, String cls, String action,
7856             String data) {
7857         synchronized(this) {
7858             if (mStartRunning) {
7859                 return;
7860             }
7861             mStartRunning = true;
7862             mTopComponent = pkg != null && cls != null
7863                     ? new ComponentName(pkg, cls) : null;
7864             mTopAction = action != null ? action : Intent.ACTION_MAIN;
7865             mTopData = data;
7866             if (!mSystemReady) {
7867                 return;
7868             }
7869         }
7870 
7871         systemReady(null);
7872     }
7873 
retrieveSettings()7874     private void retrieveSettings() {
7875         final ContentResolver resolver = mContext.getContentResolver();
7876         String debugApp = Settings.Global.getString(
7877             resolver, Settings.Global.DEBUG_APP);
7878         boolean waitForDebugger = Settings.Global.getInt(
7879             resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
7880         boolean alwaysFinishActivities = Settings.Global.getInt(
7881             resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7882 
7883         Configuration configuration = new Configuration();
7884         Settings.System.getConfiguration(resolver, configuration);
7885 
7886         synchronized (this) {
7887             mDebugApp = mOrigDebugApp = debugApp;
7888             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7889             mAlwaysFinishActivities = alwaysFinishActivities;
7890             // This happens before any activities are started, so we can
7891             // change mConfiguration in-place.
7892             updateConfigurationLocked(configuration, null, false, true);
7893             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7894         }
7895     }
7896 
testIsSystemReady()7897     public boolean testIsSystemReady() {
7898         // no need to synchronize(this) just to read & return the value
7899         return mSystemReady;
7900     }
7901 
getCalledPreBootReceiversFile()7902     private static File getCalledPreBootReceiversFile() {
7903         File dataDir = Environment.getDataDirectory();
7904         File systemDir = new File(dataDir, "system");
7905         File fname = new File(systemDir, "called_pre_boots.dat");
7906         return fname;
7907     }
7908 
7909     static final int LAST_DONE_VERSION = 10000;
7910 
readLastDonePreBootReceivers()7911     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7912         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7913         File file = getCalledPreBootReceiversFile();
7914         FileInputStream fis = null;
7915         try {
7916             fis = new FileInputStream(file);
7917             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7918             int fvers = dis.readInt();
7919             if (fvers == LAST_DONE_VERSION) {
7920                 String vers = dis.readUTF();
7921                 String codename = dis.readUTF();
7922                 String build = dis.readUTF();
7923                 if (android.os.Build.VERSION.RELEASE.equals(vers)
7924                         && android.os.Build.VERSION.CODENAME.equals(codename)
7925                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7926                     int num = dis.readInt();
7927                     while (num > 0) {
7928                         num--;
7929                         String pkg = dis.readUTF();
7930                         String cls = dis.readUTF();
7931                         lastDoneReceivers.add(new ComponentName(pkg, cls));
7932                     }
7933                 }
7934             }
7935         } catch (FileNotFoundException e) {
7936         } catch (IOException e) {
7937             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7938         } finally {
7939             if (fis != null) {
7940                 try {
7941                     fis.close();
7942                 } catch (IOException e) {
7943                 }
7944             }
7945         }
7946         return lastDoneReceivers;
7947     }
7948 
writeLastDonePreBootReceivers(ArrayList<ComponentName> list)7949     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7950         File file = getCalledPreBootReceiversFile();
7951         FileOutputStream fos = null;
7952         DataOutputStream dos = null;
7953         try {
7954             Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7955             fos = new FileOutputStream(file);
7956             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7957             dos.writeInt(LAST_DONE_VERSION);
7958             dos.writeUTF(android.os.Build.VERSION.RELEASE);
7959             dos.writeUTF(android.os.Build.VERSION.CODENAME);
7960             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7961             dos.writeInt(list.size());
7962             for (int i=0; i<list.size(); i++) {
7963                 dos.writeUTF(list.get(i).getPackageName());
7964                 dos.writeUTF(list.get(i).getClassName());
7965             }
7966         } catch (IOException e) {
7967             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7968             file.delete();
7969         } finally {
7970             FileUtils.sync(fos);
7971             if (dos != null) {
7972                 try {
7973                     dos.close();
7974                 } catch (IOException e) {
7975                     // TODO Auto-generated catch block
7976                     e.printStackTrace();
7977                 }
7978             }
7979         }
7980     }
7981 
systemReady(final Runnable goingCallback)7982     public void systemReady(final Runnable goingCallback) {
7983         synchronized(this) {
7984             if (mSystemReady) {
7985                 if (goingCallback != null) goingCallback.run();
7986                 return;
7987             }
7988 
7989             // Check to see if there are any update receivers to run.
7990             if (!mDidUpdate) {
7991                 if (mWaitingUpdate) {
7992                     return;
7993                 }
7994                 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7995                 List<ResolveInfo> ris = null;
7996                 try {
7997                     ris = AppGlobals.getPackageManager().queryIntentReceivers(
7998                             intent, null, 0, 0);
7999                 } catch (RemoteException e) {
8000                 }
8001                 if (ris != null) {
8002                     for (int i=ris.size()-1; i>=0; i--) {
8003                         if ((ris.get(i).activityInfo.applicationInfo.flags
8004                                 &ApplicationInfo.FLAG_SYSTEM) == 0) {
8005                             ris.remove(i);
8006                         }
8007                     }
8008                     intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
8009 
8010                     ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
8011 
8012                     final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
8013                     for (int i=0; i<ris.size(); i++) {
8014                         ActivityInfo ai = ris.get(i).activityInfo;
8015                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
8016                         if (lastDoneReceivers.contains(comp)) {
8017                             ris.remove(i);
8018                             i--;
8019                         }
8020                     }
8021 
8022                     final int[] users = getUsersLocked();
8023                     for (int i=0; i<ris.size(); i++) {
8024                         ActivityInfo ai = ris.get(i).activityInfo;
8025                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
8026                         doneReceivers.add(comp);
8027                         intent.setComponent(comp);
8028                         for (int j=0; j<users.length; j++) {
8029                             IIntentReceiver finisher = null;
8030                             if (i == ris.size()-1 && j == users.length-1) {
8031                                 finisher = new IIntentReceiver.Stub() {
8032                                     public void performReceive(Intent intent, int resultCode,
8033                                             String data, Bundle extras, boolean ordered,
8034                                             boolean sticky, int sendingUser) {
8035                                         // The raw IIntentReceiver interface is called
8036                                         // with the AM lock held, so redispatch to
8037                                         // execute our code without the lock.
8038                                         mHandler.post(new Runnable() {
8039                                             public void run() {
8040                                                 synchronized (ActivityManagerService.this) {
8041                                                     mDidUpdate = true;
8042                                                 }
8043                                                 writeLastDonePreBootReceivers(doneReceivers);
8044                                                 showBootMessage(mContext.getText(
8045                                                         R.string.android_upgrading_complete),
8046                                                         false);
8047                                                 systemReady(goingCallback);
8048                                             }
8049                                         });
8050                                     }
8051                                 };
8052                             }
8053                             Slog.i(TAG, "Sending system update to " + intent.getComponent()
8054                                     + " for user " + users[j]);
8055                             broadcastIntentLocked(null, null, intent, null, finisher,
8056                                     0, null, null, null, AppOpsManager.OP_NONE,
8057                                     true, false, MY_PID, Process.SYSTEM_UID,
8058                                     users[j]);
8059                             if (finisher != null) {
8060                                 mWaitingUpdate = true;
8061                             }
8062                         }
8063                     }
8064                 }
8065                 if (mWaitingUpdate) {
8066                     return;
8067                 }
8068                 mDidUpdate = true;
8069             }
8070 
8071             mAppOpsService.systemReady();
8072             mSystemReady = true;
8073             if (!mStartRunning) {
8074                 return;
8075             }
8076         }
8077 
8078         ArrayList<ProcessRecord> procsToKill = null;
8079         synchronized(mPidsSelfLocked) {
8080             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
8081                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8082                 if (!isAllowedWhileBooting(proc.info)){
8083                     if (procsToKill == null) {
8084                         procsToKill = new ArrayList<ProcessRecord>();
8085                     }
8086                     procsToKill.add(proc);
8087                 }
8088             }
8089         }
8090 
8091         synchronized(this) {
8092             if (procsToKill != null) {
8093                 for (int i=procsToKill.size()-1; i>=0; i--) {
8094                     ProcessRecord proc = procsToKill.get(i);
8095                     Slog.i(TAG, "Removing system update proc: " + proc);
8096                     removeProcessLocked(proc, true, false, "system update done");
8097                 }
8098             }
8099 
8100             // Now that we have cleaned up any update processes, we
8101             // are ready to start launching real processes and know that
8102             // we won't trample on them any more.
8103             mProcessesReady = true;
8104         }
8105 
8106         Slog.i(TAG, "System now ready");
8107         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
8108             SystemClock.uptimeMillis());
8109 
8110         synchronized(this) {
8111             // Make sure we have no pre-ready processes sitting around.
8112 
8113             if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
8114                 ResolveInfo ri = mContext.getPackageManager()
8115                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
8116                                 STOCK_PM_FLAGS);
8117                 CharSequence errorMsg = null;
8118                 if (ri != null) {
8119                     ActivityInfo ai = ri.activityInfo;
8120                     ApplicationInfo app = ai.applicationInfo;
8121                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8122                         mTopAction = Intent.ACTION_FACTORY_TEST;
8123                         mTopData = null;
8124                         mTopComponent = new ComponentName(app.packageName,
8125                                 ai.name);
8126                     } else {
8127                         errorMsg = mContext.getResources().getText(
8128                                 com.android.internal.R.string.factorytest_not_system);
8129                     }
8130                 } else {
8131                     errorMsg = mContext.getResources().getText(
8132                             com.android.internal.R.string.factorytest_no_action);
8133                 }
8134                 if (errorMsg != null) {
8135                     mTopAction = null;
8136                     mTopData = null;
8137                     mTopComponent = null;
8138                     Message msg = Message.obtain();
8139                     msg.what = SHOW_FACTORY_ERROR_MSG;
8140                     msg.getData().putCharSequence("msg", errorMsg);
8141                     mHandler.sendMessage(msg);
8142                 }
8143             }
8144         }
8145 
8146         retrieveSettings();
8147 
8148         if (goingCallback != null) goingCallback.run();
8149 
8150         synchronized (this) {
8151             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
8152                 try {
8153                     List apps = AppGlobals.getPackageManager().
8154                         getPersistentApplications(STOCK_PM_FLAGS);
8155                     if (apps != null) {
8156                         int N = apps.size();
8157                         int i;
8158                         for (i=0; i<N; i++) {
8159                             ApplicationInfo info
8160                                 = (ApplicationInfo)apps.get(i);
8161                             if (info != null &&
8162                                     !info.packageName.equals("android")) {
8163                                 addAppLocked(info, false);
8164                             }
8165                         }
8166                     }
8167                 } catch (RemoteException ex) {
8168                     // pm is in same process, this will never happen.
8169                 }
8170             }
8171 
8172             // Start up initial activity.
8173             mBooting = true;
8174 
8175             try {
8176                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
8177                     Message msg = Message.obtain();
8178                     msg.what = SHOW_UID_ERROR_MSG;
8179                     mHandler.sendMessage(msg);
8180                 }
8181             } catch (RemoteException e) {
8182             }
8183 
8184             long ident = Binder.clearCallingIdentity();
8185             try {
8186                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
8187                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
8188                         | Intent.FLAG_RECEIVER_FOREGROUND);
8189                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
8190                 broadcastIntentLocked(null, null, intent,
8191                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
8192                         false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
8193                 intent = new Intent(Intent.ACTION_USER_STARTING);
8194                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
8195                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
8196                 broadcastIntentLocked(null, null, intent,
8197                         null, new IIntentReceiver.Stub() {
8198                             @Override
8199                             public void performReceive(Intent intent, int resultCode, String data,
8200                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
8201                                     throws RemoteException {
8202                             }
8203                         }, 0, null, null,
8204                         android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
8205                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
8206             } finally {
8207                 Binder.restoreCallingIdentity(ident);
8208             }
8209             mMainStack.resumeTopActivityLocked(null);
8210             sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
8211         }
8212     }
8213 
makeAppCrashingLocked(ProcessRecord app, String shortMsg, String longMsg, String stackTrace)8214     private boolean makeAppCrashingLocked(ProcessRecord app,
8215             String shortMsg, String longMsg, String stackTrace) {
8216         app.crashing = true;
8217         app.crashingReport = generateProcessError(app,
8218                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
8219         startAppProblemLocked(app);
8220         app.stopFreezingAllLocked();
8221         return handleAppCrashLocked(app);
8222     }
8223 
makeAppNotRespondingLocked(ProcessRecord app, String activity, String shortMsg, String longMsg)8224     private void makeAppNotRespondingLocked(ProcessRecord app,
8225             String activity, String shortMsg, String longMsg) {
8226         app.notResponding = true;
8227         app.notRespondingReport = generateProcessError(app,
8228                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
8229                 activity, shortMsg, longMsg, null);
8230         startAppProblemLocked(app);
8231         app.stopFreezingAllLocked();
8232     }
8233 
8234     /**
8235      * Generate a process error record, suitable for attachment to a ProcessRecord.
8236      *
8237      * @param app The ProcessRecord in which the error occurred.
8238      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
8239      *                      ActivityManager.AppErrorStateInfo
8240      * @param activity The activity associated with the crash, if known.
8241      * @param shortMsg Short message describing the crash.
8242      * @param longMsg Long message describing the crash.
8243      * @param stackTrace Full crash stack trace, may be null.
8244      *
8245      * @return Returns a fully-formed AppErrorStateInfo record.
8246      */
generateProcessError(ProcessRecord app, int condition, String activity, String shortMsg, String longMsg, String stackTrace)8247     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
8248             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
8249         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
8250 
8251         report.condition = condition;
8252         report.processName = app.processName;
8253         report.pid = app.pid;
8254         report.uid = app.info.uid;
8255         report.tag = activity;
8256         report.shortMsg = shortMsg;
8257         report.longMsg = longMsg;
8258         report.stackTrace = stackTrace;
8259 
8260         return report;
8261     }
8262 
killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog)8263     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
8264         synchronized (this) {
8265             app.crashing = false;
8266             app.crashingReport = null;
8267             app.notResponding = false;
8268             app.notRespondingReport = null;
8269             if (app.anrDialog == fromDialog) {
8270                 app.anrDialog = null;
8271             }
8272             if (app.waitDialog == fromDialog) {
8273                 app.waitDialog = null;
8274             }
8275             if (app.pid > 0 && app.pid != MY_PID) {
8276                 handleAppCrashLocked(app);
8277                 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
8278                 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
8279                         app.processName, app.setAdj, "user's request after error");
8280                 Process.killProcessQuiet(app.pid);
8281             }
8282         }
8283     }
8284 
handleAppCrashLocked(ProcessRecord app)8285     private boolean handleAppCrashLocked(ProcessRecord app) {
8286         if (mHeadless) {
8287             Log.e(TAG, "handleAppCrashLocked: " + app.processName);
8288             return false;
8289         }
8290         long now = SystemClock.uptimeMillis();
8291 
8292         Long crashTime;
8293         if (!app.isolated) {
8294             crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
8295         } else {
8296             crashTime = null;
8297         }
8298         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
8299             // This process loses!
8300             Slog.w(TAG, "Process " + app.info.processName
8301                     + " has crashed too many times: killing!");
8302             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
8303                     app.userId, app.info.processName, app.uid);
8304             for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
8305                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
8306                 if (r.app == app) {
8307                     Slog.w(TAG, "  Force finishing activity "
8308                         + r.intent.getComponent().flattenToShortString());
8309                     r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
8310                             null, "crashed", false);
8311                 }
8312             }
8313             if (!app.persistent) {
8314                 // We don't want to start this process again until the user
8315                 // explicitly does so...  but for persistent process, we really
8316                 // need to keep it running.  If a persistent process is actually
8317                 // repeatedly crashing, then badness for everyone.
8318                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
8319                         app.info.processName);
8320                 if (!app.isolated) {
8321                     // XXX We don't have a way to mark isolated processes
8322                     // as bad, since they don't have a peristent identity.
8323                     mBadProcesses.put(app.info.processName, app.uid, now);
8324                     mProcessCrashTimes.remove(app.info.processName, app.uid);
8325                 }
8326                 app.bad = true;
8327                 app.removed = true;
8328                 // Don't let services in this process be restarted and potentially
8329                 // annoy the user repeatedly.  Unless it is persistent, since those
8330                 // processes run critical code.
8331                 removeProcessLocked(app, false, false, "crash");
8332                 mMainStack.resumeTopActivityLocked(null);
8333                 return false;
8334             }
8335             mMainStack.resumeTopActivityLocked(null);
8336         } else {
8337             ActivityRecord r = mMainStack.topRunningActivityLocked(null);
8338             if (r != null && r.app == app) {
8339                 // If the top running activity is from this crashing
8340                 // process, then terminate it to avoid getting in a loop.
8341                 Slog.w(TAG, "  Force finishing activity "
8342                         + r.intent.getComponent().flattenToShortString());
8343                 int index = mMainStack.indexOfActivityLocked(r);
8344                 r.stack.finishActivityLocked(r, index,
8345                         Activity.RESULT_CANCELED, null, "crashed", false);
8346                 // Also terminate any activities below it that aren't yet
8347                 // stopped, to avoid a situation where one will get
8348                 // re-start our crashing activity once it gets resumed again.
8349                 index--;
8350                 if (index >= 0) {
8351                     r = (ActivityRecord)mMainStack.mHistory.get(index);
8352                     if (r.state == ActivityState.RESUMED
8353                             || r.state == ActivityState.PAUSING
8354                             || r.state == ActivityState.PAUSED) {
8355                         if (!r.isHomeActivity || mHomeProcess != r.app) {
8356                             Slog.w(TAG, "  Force finishing activity "
8357                                     + r.intent.getComponent().flattenToShortString());
8358                             r.stack.finishActivityLocked(r, index,
8359                                     Activity.RESULT_CANCELED, null, "crashed", false);
8360                         }
8361                     }
8362                 }
8363             }
8364         }
8365 
8366         // Bump up the crash count of any services currently running in the proc.
8367         if (app.services.size() != 0) {
8368             // Any services running in the application need to be placed
8369             // back in the pending list.
8370             Iterator<ServiceRecord> it = app.services.iterator();
8371             while (it.hasNext()) {
8372                 ServiceRecord sr = it.next();
8373                 sr.crashCount++;
8374             }
8375         }
8376 
8377         // If the crashing process is what we consider to be the "home process" and it has been
8378         // replaced by a third-party app, clear the package preferred activities from packages
8379         // with a home activity running in the process to prevent a repeatedly crashing app
8380         // from blocking the user to manually clear the list.
8381         if (app == mHomeProcess && mHomeProcess.activities.size() > 0
8382                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
8383             Iterator it = mHomeProcess.activities.iterator();
8384             while (it.hasNext()) {
8385                 ActivityRecord r = (ActivityRecord)it.next();
8386                 if (r.isHomeActivity) {
8387                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
8388                     try {
8389                         ActivityThread.getPackageManager()
8390                                 .clearPackagePreferredActivities(r.packageName);
8391                     } catch (RemoteException c) {
8392                         // pm is in same process, this will never happen.
8393                     }
8394                 }
8395             }
8396         }
8397 
8398         if (!app.isolated) {
8399             // XXX Can't keep track of crash times for isolated processes,
8400             // because they don't have a perisistent identity.
8401             mProcessCrashTimes.put(app.info.processName, app.uid, now);
8402         }
8403 
8404         return true;
8405     }
8406 
startAppProblemLocked(ProcessRecord app)8407     void startAppProblemLocked(ProcessRecord app) {
8408         if (app.userId == mCurrentUserId) {
8409             app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8410                     mContext, app.info.packageName, app.info.flags);
8411         } else {
8412             // If this app is not running under the current user, then we
8413             // can't give it a report button because that would require
8414             // launching the report UI under a different user.
8415             app.errorReportReceiver = null;
8416         }
8417         skipCurrentReceiverLocked(app);
8418     }
8419 
skipCurrentReceiverLocked(ProcessRecord app)8420     void skipCurrentReceiverLocked(ProcessRecord app) {
8421         for (BroadcastQueue queue : mBroadcastQueues) {
8422             queue.skipCurrentReceiverLocked(app);
8423         }
8424     }
8425 
8426     /**
8427      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8428      * The application process will exit immediately after this call returns.
8429      * @param app object of the crashing app, null for the system server
8430      * @param crashInfo describing the exception
8431      */
handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo)8432     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
8433         ProcessRecord r = findAppProcess(app, "Crash");
8434         final String processName = app == null ? "system_server"
8435                 : (r == null ? "unknown" : r.processName);
8436 
8437         handleApplicationCrashInner("crash", r, processName, crashInfo);
8438     }
8439 
8440     /* Native crash reporting uses this inner version because it needs to be somewhat
8441      * decoupled from the AM-managed cleanup lifecycle
8442      */
handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, ApplicationErrorReport.CrashInfo crashInfo)8443     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
8444             ApplicationErrorReport.CrashInfo crashInfo) {
8445         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
8446                 UserHandle.getUserId(Binder.getCallingUid()), processName,
8447                 r == null ? -1 : r.info.flags,
8448                 crashInfo.exceptionClassName,
8449                 crashInfo.exceptionMessage,
8450                 crashInfo.throwFileName,
8451                 crashInfo.throwLineNumber);
8452 
8453         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
8454 
8455         crashApplication(r, crashInfo);
8456     }
8457 
handleApplicationStrictModeViolation( IBinder app, int violationMask, StrictMode.ViolationInfo info)8458     public void handleApplicationStrictModeViolation(
8459             IBinder app,
8460             int violationMask,
8461             StrictMode.ViolationInfo info) {
8462         ProcessRecord r = findAppProcess(app, "StrictMode");
8463         if (r == null) {
8464             return;
8465         }
8466 
8467         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
8468             Integer stackFingerprint = info.hashCode();
8469             boolean logIt = true;
8470             synchronized (mAlreadyLoggedViolatedStacks) {
8471                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8472                     logIt = false;
8473                     // TODO: sub-sample into EventLog for these, with
8474                     // the info.durationMillis?  Then we'd get
8475                     // the relative pain numbers, without logging all
8476                     // the stack traces repeatedly.  We'd want to do
8477                     // likewise in the client code, which also does
8478                     // dup suppression, before the Binder call.
8479                 } else {
8480                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8481                         mAlreadyLoggedViolatedStacks.clear();
8482                     }
8483                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8484                 }
8485             }
8486             if (logIt) {
8487                 logStrictModeViolationToDropBox(r, info);
8488             }
8489         }
8490 
8491         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8492             AppErrorResult result = new AppErrorResult();
8493             synchronized (this) {
8494                 final long origId = Binder.clearCallingIdentity();
8495 
8496                 Message msg = Message.obtain();
8497                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8498                 HashMap<String, Object> data = new HashMap<String, Object>();
8499                 data.put("result", result);
8500                 data.put("app", r);
8501                 data.put("violationMask", violationMask);
8502                 data.put("info", info);
8503                 msg.obj = data;
8504                 mHandler.sendMessage(msg);
8505 
8506                 Binder.restoreCallingIdentity(origId);
8507             }
8508             int res = result.get();
8509             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
8510         }
8511     }
8512 
8513     // Depending on the policy in effect, there could be a bunch of
8514     // these in quick succession so we try to batch these together to
8515     // minimize disk writes, number of dropbox entries, and maximize
8516     // compression, by having more fewer, larger records.
logStrictModeViolationToDropBox( ProcessRecord process, StrictMode.ViolationInfo info)8517     private void logStrictModeViolationToDropBox(
8518             ProcessRecord process,
8519             StrictMode.ViolationInfo info) {
8520         if (info == null) {
8521             return;
8522         }
8523         final boolean isSystemApp = process == null ||
8524                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8525                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8526         final String processName = process == null ? "unknown" : process.processName;
8527         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8528         final DropBoxManager dbox = (DropBoxManager)
8529                 mContext.getSystemService(Context.DROPBOX_SERVICE);
8530 
8531         // Exit early if the dropbox isn't configured to accept this report type.
8532         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8533 
8534         boolean bufferWasEmpty;
8535         boolean needsFlush;
8536         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8537         synchronized (sb) {
8538             bufferWasEmpty = sb.length() == 0;
8539             appendDropBoxProcessHeaders(process, processName, sb);
8540             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8541             sb.append("System-App: ").append(isSystemApp).append("\n");
8542             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8543             if (info.violationNumThisLoop != 0) {
8544                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8545             }
8546             if (info.numAnimationsRunning != 0) {
8547                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8548             }
8549             if (info.broadcastIntentAction != null) {
8550                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8551             }
8552             if (info.durationMillis != -1) {
8553                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8554             }
8555             if (info.numInstances != -1) {
8556                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8557             }
8558             if (info.tags != null) {
8559                 for (String tag : info.tags) {
8560                     sb.append("Span-Tag: ").append(tag).append("\n");
8561                 }
8562             }
8563             sb.append("\n");
8564             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8565                 sb.append(info.crashInfo.stackTrace);
8566             }
8567             sb.append("\n");
8568 
8569             // Only buffer up to ~64k.  Various logging bits truncate
8570             // things at 128k.
8571             needsFlush = (sb.length() > 64 * 1024);
8572         }
8573 
8574         // Flush immediately if the buffer's grown too large, or this
8575         // is a non-system app.  Non-system apps are isolated with a
8576         // different tag & policy and not batched.
8577         //
8578         // Batching is useful during internal testing with
8579         // StrictMode settings turned up high.  Without batching,
8580         // thousands of separate files could be created on boot.
8581         if (!isSystemApp || needsFlush) {
8582             new Thread("Error dump: " + dropboxTag) {
8583                 @Override
8584                 public void run() {
8585                     String report;
8586                     synchronized (sb) {
8587                         report = sb.toString();
8588                         sb.delete(0, sb.length());
8589                         sb.trimToSize();
8590                     }
8591                     if (report.length() != 0) {
8592                         dbox.addText(dropboxTag, report);
8593                     }
8594                 }
8595             }.start();
8596             return;
8597         }
8598 
8599         // System app batching:
8600         if (!bufferWasEmpty) {
8601             // An existing dropbox-writing thread is outstanding, so
8602             // we don't need to start it up.  The existing thread will
8603             // catch the buffer appends we just did.
8604             return;
8605         }
8606 
8607         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8608         // (After this point, we shouldn't access AMS internal data structures.)
8609         new Thread("Error dump: " + dropboxTag) {
8610             @Override
8611             public void run() {
8612                 // 5 second sleep to let stacks arrive and be batched together
8613                 try {
8614                     Thread.sleep(5000);  // 5 seconds
8615                 } catch (InterruptedException e) {}
8616 
8617                 String errorReport;
8618                 synchronized (mStrictModeBuffer) {
8619                     errorReport = mStrictModeBuffer.toString();
8620                     if (errorReport.length() == 0) {
8621                         return;
8622                     }
8623                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8624                     mStrictModeBuffer.trimToSize();
8625                 }
8626                 dbox.addText(dropboxTag, errorReport);
8627             }
8628         }.start();
8629     }
8630 
8631     /**
8632      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8633      * @param app object of the crashing app, null for the system server
8634      * @param tag reported by the caller
8635      * @param crashInfo describing the context of the error
8636      * @return true if the process should exit immediately (WTF is fatal)
8637      */
handleApplicationWtf(IBinder app, String tag, ApplicationErrorReport.CrashInfo crashInfo)8638     public boolean handleApplicationWtf(IBinder app, String tag,
8639             ApplicationErrorReport.CrashInfo crashInfo) {
8640         ProcessRecord r = findAppProcess(app, "WTF");
8641         final String processName = app == null ? "system_server"
8642                 : (r == null ? "unknown" : r.processName);
8643 
8644         EventLog.writeEvent(EventLogTags.AM_WTF,
8645                 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
8646                 processName,
8647                 r == null ? -1 : r.info.flags,
8648                 tag, crashInfo.exceptionMessage);
8649 
8650         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8651 
8652         if (r != null && r.pid != Process.myPid() &&
8653                 Settings.Global.getInt(mContext.getContentResolver(),
8654                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
8655             crashApplication(r, crashInfo);
8656             return true;
8657         } else {
8658             return false;
8659         }
8660     }
8661 
8662     /**
8663      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8664      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8665      */
findAppProcess(IBinder app, String reason)8666     private ProcessRecord findAppProcess(IBinder app, String reason) {
8667         if (app == null) {
8668             return null;
8669         }
8670 
8671         synchronized (this) {
8672             for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8673                 final int NA = apps.size();
8674                 for (int ia=0; ia<NA; ia++) {
8675                     ProcessRecord p = apps.valueAt(ia);
8676                     if (p.thread != null && p.thread.asBinder() == app) {
8677                         return p;
8678                     }
8679                 }
8680             }
8681 
8682             Slog.w(TAG, "Can't find mystery application for " + reason
8683                     + " from pid=" + Binder.getCallingPid()
8684                     + " uid=" + Binder.getCallingUid() + ": " + app);
8685             return null;
8686         }
8687     }
8688 
8689     /**
8690      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8691      * to append various headers to the dropbox log text.
8692      */
appendDropBoxProcessHeaders(ProcessRecord process, String processName, StringBuilder sb)8693     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8694             StringBuilder sb) {
8695         // Watchdog thread ends up invoking this function (with
8696         // a null ProcessRecord) to add the stack file to dropbox.
8697         // Do not acquire a lock on this (am) in such cases, as it
8698         // could cause a potential deadlock, if and when watchdog
8699         // is invoked due to unavailability of lock on am and it
8700         // would prevent watchdog from killing system_server.
8701         if (process == null) {
8702             sb.append("Process: ").append(processName).append("\n");
8703             return;
8704         }
8705         // Note: ProcessRecord 'process' is guarded by the service
8706         // instance.  (notably process.pkgList, which could otherwise change
8707         // concurrently during execution of this method)
8708         synchronized (this) {
8709             sb.append("Process: ").append(processName).append("\n");
8710             int flags = process.info.flags;
8711             IPackageManager pm = AppGlobals.getPackageManager();
8712             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8713             for (String pkg : process.pkgList) {
8714                 sb.append("Package: ").append(pkg);
8715                 try {
8716                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
8717                     if (pi != null) {
8718                         sb.append(" v").append(pi.versionCode);
8719                         if (pi.versionName != null) {
8720                             sb.append(" (").append(pi.versionName).append(")");
8721                         }
8722                     }
8723                 } catch (RemoteException e) {
8724                     Slog.e(TAG, "Error getting package info: " + pkg, e);
8725                 }
8726                 sb.append("\n");
8727             }
8728         }
8729     }
8730 
processClass(ProcessRecord process)8731     private static String processClass(ProcessRecord process) {
8732         if (process == null || process.pid == MY_PID) {
8733             return "system_server";
8734         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8735             return "system_app";
8736         } else {
8737             return "data_app";
8738         }
8739     }
8740 
8741     /**
8742      * Write a description of an error (crash, WTF, ANR) to the drop box.
8743      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8744      * @param process which caused the error, null means the system server
8745      * @param activity which triggered the error, null if unknown
8746      * @param parent activity related to the error, null if unknown
8747      * @param subject line related to the error, null if absent
8748      * @param report in long form describing the error, null if absent
8749      * @param logFile to include in the report, null if none
8750      * @param crashInfo giving an application stack trace, null if absent
8751      */
addErrorToDropBox(String eventType, ProcessRecord process, String processName, ActivityRecord activity, ActivityRecord parent, String subject, final String report, final File logFile, final ApplicationErrorReport.CrashInfo crashInfo)8752     public void addErrorToDropBox(String eventType,
8753             ProcessRecord process, String processName, ActivityRecord activity,
8754             ActivityRecord parent, String subject,
8755             final String report, final File logFile,
8756             final ApplicationErrorReport.CrashInfo crashInfo) {
8757         // NOTE -- this must never acquire the ActivityManagerService lock,
8758         // otherwise the watchdog may be prevented from resetting the system.
8759 
8760         final String dropboxTag = processClass(process) + "_" + eventType;
8761         final DropBoxManager dbox = (DropBoxManager)
8762                 mContext.getSystemService(Context.DROPBOX_SERVICE);
8763 
8764         // Exit early if the dropbox isn't configured to accept this report type.
8765         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8766 
8767         final StringBuilder sb = new StringBuilder(1024);
8768         appendDropBoxProcessHeaders(process, processName, sb);
8769         if (activity != null) {
8770             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8771         }
8772         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8773             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8774         }
8775         if (parent != null && parent != activity) {
8776             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8777         }
8778         if (subject != null) {
8779             sb.append("Subject: ").append(subject).append("\n");
8780         }
8781         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8782         if (Debug.isDebuggerConnected()) {
8783             sb.append("Debugger: Connected\n");
8784         }
8785         sb.append("\n");
8786 
8787         // Do the rest in a worker thread to avoid blocking the caller on I/O
8788         // (After this point, we shouldn't access AMS internal data structures.)
8789         Thread worker = new Thread("Error dump: " + dropboxTag) {
8790             @Override
8791             public void run() {
8792                 if (report != null) {
8793                     sb.append(report);
8794                 }
8795                 if (logFile != null) {
8796                     try {
8797                         sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8798                     } catch (IOException e) {
8799                         Slog.e(TAG, "Error reading " + logFile, e);
8800                     }
8801                 }
8802                 if (crashInfo != null && crashInfo.stackTrace != null) {
8803                     sb.append(crashInfo.stackTrace);
8804                 }
8805 
8806                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
8807                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
8808                 if (lines > 0) {
8809                     sb.append("\n");
8810 
8811                     // Merge several logcat streams, and take the last N lines
8812                     InputStreamReader input = null;
8813                     try {
8814                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8815                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8816                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8817 
8818                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
8819                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
8820                         input = new InputStreamReader(logcat.getInputStream());
8821 
8822                         int num;
8823                         char[] buf = new char[8192];
8824                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8825                     } catch (IOException e) {
8826                         Slog.e(TAG, "Error running logcat", e);
8827                     } finally {
8828                         if (input != null) try { input.close(); } catch (IOException e) {}
8829                     }
8830                 }
8831 
8832                 dbox.addText(dropboxTag, sb.toString());
8833             }
8834         };
8835 
8836         if (process == null) {
8837             // If process is null, we are being called from some internal code
8838             // and may be about to die -- run this synchronously.
8839             worker.run();
8840         } else {
8841             worker.start();
8842         }
8843     }
8844 
8845     /**
8846      * Bring up the "unexpected error" dialog box for a crashing app.
8847      * Deal with edge cases (intercepts from instrumented applications,
8848      * ActivityController, error intent receivers, that sort of thing).
8849      * @param r the application crashing
8850      * @param crashInfo describing the failure
8851      */
crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo)8852     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8853         long timeMillis = System.currentTimeMillis();
8854         String shortMsg = crashInfo.exceptionClassName;
8855         String longMsg = crashInfo.exceptionMessage;
8856         String stackTrace = crashInfo.stackTrace;
8857         if (shortMsg != null && longMsg != null) {
8858             longMsg = shortMsg + ": " + longMsg;
8859         } else if (shortMsg != null) {
8860             longMsg = shortMsg;
8861         }
8862 
8863         AppErrorResult result = new AppErrorResult();
8864         synchronized (this) {
8865             if (mController != null) {
8866                 try {
8867                     String name = r != null ? r.processName : null;
8868                     int pid = r != null ? r.pid : Binder.getCallingPid();
8869                     if (!mController.appCrashed(name, pid,
8870                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8871                         Slog.w(TAG, "Force-killing crashed app " + name
8872                                 + " at watcher's request");
8873                         Process.killProcess(pid);
8874                         return;
8875                     }
8876                 } catch (RemoteException e) {
8877                     mController = null;
8878                     Watchdog.getInstance().setActivityController(null);
8879                 }
8880             }
8881 
8882             final long origId = Binder.clearCallingIdentity();
8883 
8884             // If this process is running instrumentation, finish it.
8885             if (r != null && r.instrumentationClass != null) {
8886                 Slog.w(TAG, "Error in app " + r.processName
8887                       + " running instrumentation " + r.instrumentationClass + ":");
8888                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8889                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8890                 Bundle info = new Bundle();
8891                 info.putString("shortMsg", shortMsg);
8892                 info.putString("longMsg", longMsg);
8893                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8894                 Binder.restoreCallingIdentity(origId);
8895                 return;
8896             }
8897 
8898             // If we can't identify the process or it's already exceeded its crash quota,
8899             // quit right away without showing a crash dialog.
8900             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8901                 Binder.restoreCallingIdentity(origId);
8902                 return;
8903             }
8904 
8905             Message msg = Message.obtain();
8906             msg.what = SHOW_ERROR_MSG;
8907             HashMap data = new HashMap();
8908             data.put("result", result);
8909             data.put("app", r);
8910             msg.obj = data;
8911             mHandler.sendMessage(msg);
8912 
8913             Binder.restoreCallingIdentity(origId);
8914         }
8915 
8916         int res = result.get();
8917 
8918         Intent appErrorIntent = null;
8919         synchronized (this) {
8920             if (r != null && !r.isolated) {
8921                 // XXX Can't keep track of crash time for isolated processes,
8922                 // since they don't have a persistent identity.
8923                 mProcessCrashTimes.put(r.info.processName, r.uid,
8924                         SystemClock.uptimeMillis());
8925             }
8926             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8927                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8928             }
8929         }
8930 
8931         if (appErrorIntent != null) {
8932             try {
8933                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
8934             } catch (ActivityNotFoundException e) {
8935                 Slog.w(TAG, "bug report receiver dissappeared", e);
8936             }
8937         }
8938     }
8939 
createAppErrorIntentLocked(ProcessRecord r, long timeMillis, ApplicationErrorReport.CrashInfo crashInfo)8940     Intent createAppErrorIntentLocked(ProcessRecord r,
8941             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8942         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8943         if (report == null) {
8944             return null;
8945         }
8946         Intent result = new Intent(Intent.ACTION_APP_ERROR);
8947         result.setComponent(r.errorReportReceiver);
8948         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8949         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8950         return result;
8951     }
8952 
createAppErrorReportLocked(ProcessRecord r, long timeMillis, ApplicationErrorReport.CrashInfo crashInfo)8953     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8954             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8955         if (r.errorReportReceiver == null) {
8956             return null;
8957         }
8958 
8959         if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
8960             return null;
8961         }
8962 
8963         ApplicationErrorReport report = new ApplicationErrorReport();
8964         report.packageName = r.info.packageName;
8965         report.installerPackageName = r.errorReportReceiver.getPackageName();
8966         report.processName = r.processName;
8967         report.time = timeMillis;
8968         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8969 
8970         if (r.crashing || r.forceCrashReport) {
8971             report.type = ApplicationErrorReport.TYPE_CRASH;
8972             report.crashInfo = crashInfo;
8973         } else if (r.notResponding) {
8974             report.type = ApplicationErrorReport.TYPE_ANR;
8975             report.anrInfo = new ApplicationErrorReport.AnrInfo();
8976 
8977             report.anrInfo.activity = r.notRespondingReport.tag;
8978             report.anrInfo.cause = r.notRespondingReport.shortMsg;
8979             report.anrInfo.info = r.notRespondingReport.longMsg;
8980         }
8981 
8982         return report;
8983     }
8984 
getProcessesInErrorState()8985     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8986         enforceNotIsolatedCaller("getProcessesInErrorState");
8987         // assume our apps are happy - lazy create the list
8988         List<ActivityManager.ProcessErrorStateInfo> errList = null;
8989 
8990         final boolean allUsers = ActivityManager.checkUidPermission(
8991                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8992                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8993         int userId = UserHandle.getUserId(Binder.getCallingUid());
8994 
8995         synchronized (this) {
8996 
8997             // iterate across all processes
8998             for (int i=mLruProcesses.size()-1; i>=0; i--) {
8999                 ProcessRecord app = mLruProcesses.get(i);
9000                 if (!allUsers && app.userId != userId) {
9001                     continue;
9002                 }
9003                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
9004                     // This one's in trouble, so we'll generate a report for it
9005                     // crashes are higher priority (in case there's a crash *and* an anr)
9006                     ActivityManager.ProcessErrorStateInfo report = null;
9007                     if (app.crashing) {
9008                         report = app.crashingReport;
9009                     } else if (app.notResponding) {
9010                         report = app.notRespondingReport;
9011                     }
9012 
9013                     if (report != null) {
9014                         if (errList == null) {
9015                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
9016                         }
9017                         errList.add(report);
9018                     } else {
9019                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
9020                                 " crashing = " + app.crashing +
9021                                 " notResponding = " + app.notResponding);
9022                     }
9023                 }
9024             }
9025         }
9026 
9027         return errList;
9028     }
9029 
oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp)9030     static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
9031         if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9032             if (currApp != null) {
9033                 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
9034             }
9035             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
9036         } else if (adj >= ProcessList.SERVICE_B_ADJ) {
9037             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
9038         } else if (adj >= ProcessList.HOME_APP_ADJ) {
9039             if (currApp != null) {
9040                 currApp.lru = 0;
9041             }
9042             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
9043         } else if (adj >= ProcessList.SERVICE_ADJ) {
9044             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
9045         } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9046             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
9047         } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9048             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
9049         } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
9050             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
9051         } else {
9052             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
9053         }
9054     }
9055 
fillInProcMemInfo(ProcessRecord app, ActivityManager.RunningAppProcessInfo outInfo)9056     private void fillInProcMemInfo(ProcessRecord app,
9057             ActivityManager.RunningAppProcessInfo outInfo) {
9058         outInfo.pid = app.pid;
9059         outInfo.uid = app.info.uid;
9060         if (mHeavyWeightProcess == app) {
9061             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
9062         }
9063         if (app.persistent) {
9064             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
9065         }
9066         if (app.hasActivities) {
9067             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
9068         }
9069         outInfo.lastTrimLevel = app.trimMemoryLevel;
9070         int adj = app.curAdj;
9071         outInfo.importance = oomAdjToImportance(adj, outInfo);
9072         outInfo.importanceReasonCode = app.adjTypeCode;
9073     }
9074 
getRunningAppProcesses()9075     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
9076         enforceNotIsolatedCaller("getRunningAppProcesses");
9077         // Lazy instantiation of list
9078         List<ActivityManager.RunningAppProcessInfo> runList = null;
9079         final boolean allUsers = ActivityManager.checkUidPermission(
9080                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9081                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
9082         int userId = UserHandle.getUserId(Binder.getCallingUid());
9083         synchronized (this) {
9084             // Iterate across all processes
9085             for (int i=mLruProcesses.size()-1; i>=0; i--) {
9086                 ProcessRecord app = mLruProcesses.get(i);
9087                 if (!allUsers && app.userId != userId) {
9088                     continue;
9089                 }
9090                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
9091                     // Generate process state info for running application
9092                     ActivityManager.RunningAppProcessInfo currApp =
9093                         new ActivityManager.RunningAppProcessInfo(app.processName,
9094                                 app.pid, app.getPackageList());
9095                     fillInProcMemInfo(app, currApp);
9096                     if (app.adjSource instanceof ProcessRecord) {
9097                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
9098                         currApp.importanceReasonImportance = oomAdjToImportance(
9099                                 app.adjSourceOom, null);
9100                     } else if (app.adjSource instanceof ActivityRecord) {
9101                         ActivityRecord r = (ActivityRecord)app.adjSource;
9102                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
9103                     }
9104                     if (app.adjTarget instanceof ComponentName) {
9105                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
9106                     }
9107                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
9108                     //        + " lru=" + currApp.lru);
9109                     if (runList == null) {
9110                         runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
9111                     }
9112                     runList.add(currApp);
9113                 }
9114             }
9115         }
9116         return runList;
9117     }
9118 
getRunningExternalApplications()9119     public List<ApplicationInfo> getRunningExternalApplications() {
9120         enforceNotIsolatedCaller("getRunningExternalApplications");
9121         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
9122         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
9123         if (runningApps != null && runningApps.size() > 0) {
9124             Set<String> extList = new HashSet<String>();
9125             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
9126                 if (app.pkgList != null) {
9127                     for (String pkg : app.pkgList) {
9128                         extList.add(pkg);
9129                     }
9130                 }
9131             }
9132             IPackageManager pm = AppGlobals.getPackageManager();
9133             for (String pkg : extList) {
9134                 try {
9135                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
9136                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
9137                         retList.add(info);
9138                     }
9139                 } catch (RemoteException e) {
9140                 }
9141             }
9142         }
9143         return retList;
9144     }
9145 
9146     @Override
getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo)9147     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
9148         enforceNotIsolatedCaller("getMyMemoryState");
9149         synchronized (this) {
9150             ProcessRecord proc;
9151             synchronized (mPidsSelfLocked) {
9152                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
9153             }
9154             fillInProcMemInfo(proc, outInfo);
9155         }
9156     }
9157 
9158     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)9159     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
9160         if (checkCallingPermission(android.Manifest.permission.DUMP)
9161                 != PackageManager.PERMISSION_GRANTED) {
9162             pw.println("Permission Denial: can't dump ActivityManager from from pid="
9163                     + Binder.getCallingPid()
9164                     + ", uid=" + Binder.getCallingUid()
9165                     + " without permission "
9166                     + android.Manifest.permission.DUMP);
9167             return;
9168         }
9169 
9170         boolean dumpAll = false;
9171         boolean dumpClient = false;
9172         String dumpPackage = null;
9173 
9174         int opti = 0;
9175         while (opti < args.length) {
9176             String opt = args[opti];
9177             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9178                 break;
9179             }
9180             opti++;
9181             if ("-a".equals(opt)) {
9182                 dumpAll = true;
9183             } else if ("-c".equals(opt)) {
9184                 dumpClient = true;
9185             } else if ("-h".equals(opt)) {
9186                 pw.println("Activity manager dump options:");
9187                 pw.println("  [-a] [-c] [-h] [cmd] ...");
9188                 pw.println("  cmd may be one of:");
9189                 pw.println("    a[ctivities]: activity stack state");
9190                 pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
9191                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
9192                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
9193                 pw.println("    o[om]: out of memory management");
9194                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
9195                 pw.println("    provider [COMP_SPEC]: provider client-side state");
9196                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
9197                 pw.println("    service [COMP_SPEC]: service client-side state");
9198                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
9199                 pw.println("    all: dump all activities");
9200                 pw.println("    top: dump the top activity");
9201                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
9202                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
9203                 pw.println("    a partial substring in a component name, a");
9204                 pw.println("    hex object identifier.");
9205                 pw.println("  -a: include all available server state.");
9206                 pw.println("  -c: include client state.");
9207                 return;
9208             } else {
9209                 pw.println("Unknown argument: " + opt + "; use -h for help");
9210             }
9211         }
9212 
9213         long origId = Binder.clearCallingIdentity();
9214         boolean more = false;
9215         // Is the caller requesting to dump a particular piece of data?
9216         if (opti < args.length) {
9217             String cmd = args[opti];
9218             opti++;
9219             if ("activities".equals(cmd) || "a".equals(cmd)) {
9220                 synchronized (this) {
9221                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
9222                 }
9223             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
9224                 String[] newArgs;
9225                 String name;
9226                 if (opti >= args.length) {
9227                     name = null;
9228                     newArgs = EMPTY_STRING_ARRAY;
9229                 } else {
9230                     name = args[opti];
9231                     opti++;
9232                     newArgs = new String[args.length - opti];
9233                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9234                             args.length - opti);
9235                 }
9236                 synchronized (this) {
9237                     dumpBroadcastsLocked(fd, pw, args, opti, true, name);
9238                 }
9239             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
9240                 String[] newArgs;
9241                 String name;
9242                 if (opti >= args.length) {
9243                     name = null;
9244                     newArgs = EMPTY_STRING_ARRAY;
9245                 } else {
9246                     name = args[opti];
9247                     opti++;
9248                     newArgs = new String[args.length - opti];
9249                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9250                             args.length - opti);
9251                 }
9252                 synchronized (this) {
9253                     dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
9254                 }
9255             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
9256                 String[] newArgs;
9257                 String name;
9258                 if (opti >= args.length) {
9259                     name = null;
9260                     newArgs = EMPTY_STRING_ARRAY;
9261                 } else {
9262                     name = args[opti];
9263                     opti++;
9264                     newArgs = new String[args.length - opti];
9265                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9266                             args.length - opti);
9267                 }
9268                 synchronized (this) {
9269                     dumpProcessesLocked(fd, pw, args, opti, true, name);
9270                 }
9271             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
9272                 synchronized (this) {
9273                     dumpOomLocked(fd, pw, args, opti, true);
9274                 }
9275             } else if ("provider".equals(cmd)) {
9276                 String[] newArgs;
9277                 String name;
9278                 if (opti >= args.length) {
9279                     name = null;
9280                     newArgs = EMPTY_STRING_ARRAY;
9281                 } else {
9282                     name = args[opti];
9283                     opti++;
9284                     newArgs = new String[args.length - opti];
9285                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9286                 }
9287                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
9288                     pw.println("No providers match: " + name);
9289                     pw.println("Use -h for help.");
9290                 }
9291             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
9292                 synchronized (this) {
9293                     dumpProvidersLocked(fd, pw, args, opti, true, null);
9294                 }
9295             } else if ("service".equals(cmd)) {
9296                 String[] newArgs;
9297                 String name;
9298                 if (opti >= args.length) {
9299                     name = null;
9300                     newArgs = EMPTY_STRING_ARRAY;
9301                 } else {
9302                     name = args[opti];
9303                     opti++;
9304                     newArgs = new String[args.length - opti];
9305                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9306                             args.length - opti);
9307                 }
9308                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
9309                     pw.println("No services match: " + name);
9310                     pw.println("Use -h for help.");
9311                 }
9312             } else if ("package".equals(cmd)) {
9313                 String[] newArgs;
9314                 if (opti >= args.length) {
9315                     pw.println("package: no package name specified");
9316                     pw.println("Use -h for help.");
9317                 } else {
9318                     dumpPackage = args[opti];
9319                     opti++;
9320                     newArgs = new String[args.length - opti];
9321                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9322                             args.length - opti);
9323                     args = newArgs;
9324                     opti = 0;
9325                     more = true;
9326                 }
9327             } else if ("services".equals(cmd) || "s".equals(cmd)) {
9328                 synchronized (this) {
9329                     mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
9330                 }
9331             } else {
9332                 // Dumping a single activity?
9333                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
9334                     pw.println("Bad activity command, or no activities match: " + cmd);
9335                     pw.println("Use -h for help.");
9336                 }
9337             }
9338             if (!more) {
9339                 Binder.restoreCallingIdentity(origId);
9340                 return;
9341             }
9342         }
9343 
9344         // No piece of data specified, dump everything.
9345         synchronized (this) {
9346             boolean needSep;
9347             needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9348             if (needSep) {
9349                 pw.println(" ");
9350             }
9351             if (dumpAll) {
9352                 pw.println("-------------------------------------------------------------------------------");
9353             }
9354             needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9355             if (needSep) {
9356                 pw.println(" ");
9357             }
9358             if (dumpAll) {
9359                 pw.println("-------------------------------------------------------------------------------");
9360             }
9361             needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9362             if (needSep) {
9363                 pw.println(" ");
9364             }
9365             if (dumpAll) {
9366                 pw.println("-------------------------------------------------------------------------------");
9367             }
9368             needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9369             if (needSep) {
9370                 pw.println(" ");
9371             }
9372             if (dumpAll) {
9373                 pw.println("-------------------------------------------------------------------------------");
9374             }
9375             needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9376             if (needSep) {
9377                 pw.println(" ");
9378             }
9379             if (dumpAll) {
9380                 pw.println("-------------------------------------------------------------------------------");
9381             }
9382             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9383         }
9384         Binder.restoreCallingIdentity(origId);
9385     }
9386 
dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, boolean dumpClient, String dumpPackage)9387     boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9388             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
9389         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
9390         pw.println("  Main stack:");
9391         dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
9392                 dumpPackage);
9393         pw.println(" ");
9394         pw.println("  Running activities (most recent first):");
9395         dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
9396                 dumpPackage);
9397         if (mMainStack.mWaitingVisibleActivities.size() > 0) {
9398             pw.println(" ");
9399             pw.println("  Activities waiting for another to become visible:");
9400             dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
9401                     !dumpAll, false, dumpPackage);
9402         }
9403         if (mMainStack.mStoppingActivities.size() > 0) {
9404             pw.println(" ");
9405             pw.println("  Activities waiting to stop:");
9406             dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
9407                     !dumpAll, false, dumpPackage);
9408         }
9409         if (mMainStack.mGoingToSleepActivities.size() > 0) {
9410             pw.println(" ");
9411             pw.println("  Activities waiting to sleep:");
9412             dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
9413                     !dumpAll, false, dumpPackage);
9414         }
9415         if (mMainStack.mFinishingActivities.size() > 0) {
9416             pw.println(" ");
9417             pw.println("  Activities waiting to finish:");
9418             dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
9419                     !dumpAll, false, dumpPackage);
9420         }
9421 
9422         pw.println(" ");
9423         if (mMainStack.mPausingActivity != null) {
9424             pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
9425         }
9426         pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
9427         pw.println("  mFocusedActivity: " + mFocusedActivity);
9428         if (dumpAll) {
9429             pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9430             pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
9431             pw.println("  mDismissKeyguardOnNextActivity: "
9432                     + mMainStack.mDismissKeyguardOnNextActivity);
9433         }
9434 
9435         if (mRecentTasks.size() > 0) {
9436             pw.println();
9437             pw.println("  Recent tasks:");
9438 
9439             final int N = mRecentTasks.size();
9440             for (int i=0; i<N; i++) {
9441                 TaskRecord tr = mRecentTasks.get(i);
9442                 if (dumpPackage != null) {
9443                     if (tr.realActivity == null ||
9444                             !dumpPackage.equals(tr.realActivity)) {
9445                         continue;
9446                     }
9447                 }
9448                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9449                         pw.println(tr);
9450                 if (dumpAll) {
9451                     mRecentTasks.get(i).dump(pw, "    ");
9452                 }
9453             }
9454         }
9455 
9456         if (dumpAll) {
9457             pw.println(" ");
9458             pw.println("  mCurTask: " + mCurTask);
9459         }
9460 
9461         return true;
9462     }
9463 
dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)9464     boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9465             int opti, boolean dumpAll, String dumpPackage) {
9466         boolean needSep = false;
9467         int numPers = 0;
9468 
9469         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9470 
9471         if (dumpAll) {
9472             for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9473                 final int NA = procs.size();
9474                 for (int ia=0; ia<NA; ia++) {
9475                     ProcessRecord r = procs.valueAt(ia);
9476                     if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9477                         continue;
9478                     }
9479                     if (!needSep) {
9480                         pw.println("  All known processes:");
9481                         needSep = true;
9482                     }
9483                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9484                         pw.print(" UID "); pw.print(procs.keyAt(ia));
9485                         pw.print(" "); pw.println(r);
9486                     r.dump(pw, "    ");
9487                     if (r.persistent) {
9488                         numPers++;
9489                     }
9490                 }
9491             }
9492         }
9493 
9494         if (mIsolatedProcesses.size() > 0) {
9495             if (needSep) pw.println(" ");
9496             needSep = true;
9497             pw.println("  Isolated process list (sorted by uid):");
9498             for (int i=0; i<mIsolatedProcesses.size(); i++) {
9499                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
9500                 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9501                     continue;
9502                 }
9503                 pw.println(String.format("%sIsolated #%2d: %s",
9504                         "    ", i, r.toString()));
9505             }
9506         }
9507 
9508         if (mLruProcesses.size() > 0) {
9509             if (needSep) pw.println(" ");
9510             needSep = true;
9511             pw.println("  Process LRU list (sorted by oom_adj):");
9512             dumpProcessOomList(pw, this, mLruProcesses, "    ",
9513                     "Proc", "PERS", false, dumpPackage);
9514             needSep = true;
9515         }
9516 
9517         if (dumpAll) {
9518             synchronized (mPidsSelfLocked) {
9519                 boolean printed = false;
9520                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
9521                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
9522                     if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9523                         continue;
9524                     }
9525                     if (!printed) {
9526                         if (needSep) pw.println(" ");
9527                         needSep = true;
9528                         pw.println("  PID mappings:");
9529                         printed = true;
9530                     }
9531                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9532                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9533                 }
9534             }
9535         }
9536 
9537         if (mForegroundProcesses.size() > 0) {
9538             synchronized (mPidsSelfLocked) {
9539                 boolean printed = false;
9540                 for (int i=0; i<mForegroundProcesses.size(); i++) {
9541                     ProcessRecord r = mPidsSelfLocked.get(
9542                             mForegroundProcesses.valueAt(i).pid);
9543                     if (dumpPackage != null && (r == null
9544                             || !dumpPackage.equals(r.info.packageName))) {
9545                         continue;
9546                     }
9547                     if (!printed) {
9548                         if (needSep) pw.println(" ");
9549                         needSep = true;
9550                         pw.println("  Foreground Processes:");
9551                         printed = true;
9552                     }
9553                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9554                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9555                 }
9556             }
9557         }
9558 
9559         if (mPersistentStartingProcesses.size() > 0) {
9560             if (needSep) pw.println(" ");
9561             needSep = true;
9562             pw.println("  Persisent processes that are starting:");
9563             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9564                     "Starting Norm", "Restarting PERS", dumpPackage);
9565         }
9566 
9567         if (mRemovedProcesses.size() > 0) {
9568             if (needSep) pw.println(" ");
9569             needSep = true;
9570             pw.println("  Processes that are being removed:");
9571             dumpProcessList(pw, this, mRemovedProcesses, "    ",
9572                     "Removed Norm", "Removed PERS", dumpPackage);
9573         }
9574 
9575         if (mProcessesOnHold.size() > 0) {
9576             if (needSep) pw.println(" ");
9577             needSep = true;
9578             pw.println("  Processes that are on old until the system is ready:");
9579             dumpProcessList(pw, this, mProcessesOnHold, "    ",
9580                     "OnHold Norm", "OnHold PERS", dumpPackage);
9581         }
9582 
9583         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9584 
9585         if (mProcessCrashTimes.getMap().size() > 0) {
9586             boolean printed = false;
9587             long now = SystemClock.uptimeMillis();
9588             for (Map.Entry<String, SparseArray<Long>> procs
9589                     : mProcessCrashTimes.getMap().entrySet()) {
9590                 String pname = procs.getKey();
9591                 SparseArray<Long> uids = procs.getValue();
9592                 final int N = uids.size();
9593                 for (int i=0; i<N; i++) {
9594                     int puid = uids.keyAt(i);
9595                     ProcessRecord r = mProcessNames.get(pname, puid);
9596                     if (dumpPackage != null && (r == null
9597                             || !dumpPackage.equals(r.info.packageName))) {
9598                         continue;
9599                     }
9600                     if (!printed) {
9601                         if (needSep) pw.println(" ");
9602                         needSep = true;
9603                         pw.println("  Time since processes crashed:");
9604                         printed = true;
9605                     }
9606                     pw.print("    Process "); pw.print(pname);
9607                             pw.print(" uid "); pw.print(puid);
9608                             pw.print(": last crashed ");
9609                             TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9610                             pw.println(" ago");
9611                 }
9612             }
9613         }
9614 
9615         if (mBadProcesses.getMap().size() > 0) {
9616             boolean printed = false;
9617             for (Map.Entry<String, SparseArray<Long>> procs
9618                     : mBadProcesses.getMap().entrySet()) {
9619                 String pname = procs.getKey();
9620                 SparseArray<Long> uids = procs.getValue();
9621                 final int N = uids.size();
9622                 for (int i=0; i<N; i++) {
9623                     int puid = uids.keyAt(i);
9624                     ProcessRecord r = mProcessNames.get(pname, puid);
9625                     if (dumpPackage != null && (r == null
9626                             || !dumpPackage.equals(r.info.packageName))) {
9627                         continue;
9628                     }
9629                     if (!printed) {
9630                         if (needSep) pw.println(" ");
9631                         needSep = true;
9632                         pw.println("  Bad processes:");
9633                     }
9634                     pw.print("    Bad process "); pw.print(pname);
9635                             pw.print(" uid "); pw.print(puid);
9636                             pw.print(": crashed at time ");
9637                             pw.println(uids.valueAt(i));
9638                 }
9639             }
9640         }
9641 
9642         pw.println();
9643         pw.println("  mStartedUsers:");
9644         for (int i=0; i<mStartedUsers.size(); i++) {
9645             UserStartedState uss = mStartedUsers.valueAt(i);
9646             pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9647                     pw.print(": "); uss.dump("", pw);
9648         }
9649         pw.print("  mStartedUserArray: [");
9650         for (int i=0; i<mStartedUserArray.length; i++) {
9651             if (i > 0) pw.print(", ");
9652             pw.print(mStartedUserArray[i]);
9653         }
9654         pw.println("]");
9655         pw.print("  mUserLru: [");
9656         for (int i=0; i<mUserLru.size(); i++) {
9657             if (i > 0) pw.print(", ");
9658             pw.print(mUserLru.get(i));
9659         }
9660         pw.println("]");
9661         if (dumpAll) {
9662             pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
9663         }
9664         pw.println("  mHomeProcess: " + mHomeProcess);
9665         pw.println("  mPreviousProcess: " + mPreviousProcess);
9666         if (dumpAll) {
9667             StringBuilder sb = new StringBuilder(128);
9668             sb.append("  mPreviousProcessVisibleTime: ");
9669             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9670             pw.println(sb);
9671         }
9672         if (mHeavyWeightProcess != null) {
9673             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9674         }
9675         pw.println("  mConfiguration: " + mConfiguration);
9676         if (dumpAll) {
9677             pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9678             if (mCompatModePackages.getPackages().size() > 0) {
9679                 boolean printed = false;
9680                 for (Map.Entry<String, Integer> entry
9681                         : mCompatModePackages.getPackages().entrySet()) {
9682                     String pkg = entry.getKey();
9683                     int mode = entry.getValue();
9684                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9685                         continue;
9686                     }
9687                     if (!printed) {
9688                         pw.println("  mScreenCompatPackages:");
9689                         printed = true;
9690                     }
9691                     pw.print("    "); pw.print(pkg); pw.print(": ");
9692                             pw.print(mode); pw.println();
9693                 }
9694             }
9695         }
9696         if (mSleeping || mWentToSleep || mLockScreenShown) {
9697             pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9698                     + " mLockScreenShown " + mLockScreenShown);
9699         }
9700         if (mShuttingDown) {
9701             pw.println("  mShuttingDown=" + mShuttingDown);
9702         }
9703         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9704                 || mOrigWaitForDebugger) {
9705             pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9706                     + " mDebugTransient=" + mDebugTransient
9707                     + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9708         }
9709         if (mOpenGlTraceApp != null) {
9710             pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9711         }
9712         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9713                 || mProfileFd != null) {
9714             pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9715             pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9716             pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9717                     + mAutoStopProfiler);
9718         }
9719         if (mAlwaysFinishActivities || mController != null) {
9720             pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9721                     + " mController=" + mController);
9722         }
9723         if (dumpAll) {
9724             pw.println("  Total persistent processes: " + numPers);
9725             pw.println("  mStartRunning=" + mStartRunning
9726                     + " mProcessesReady=" + mProcessesReady
9727                     + " mSystemReady=" + mSystemReady);
9728             pw.println("  mBooting=" + mBooting
9729                     + " mBooted=" + mBooted
9730                     + " mFactoryTest=" + mFactoryTest);
9731             pw.print("  mLastPowerCheckRealtime=");
9732                     TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9733                     pw.println("");
9734             pw.print("  mLastPowerCheckUptime=");
9735                     TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9736                     pw.println("");
9737             pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9738             pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9739             pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9740             pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9741                     + " mNumHiddenProcs=" + mNumHiddenProcs
9742                     + " mNumServiceProcs=" + mNumServiceProcs
9743                     + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9744         }
9745 
9746         return true;
9747     }
9748 
dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean needSep, boolean dumpAll, String dumpPackage)9749     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9750             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9751         if (mProcessesToGc.size() > 0) {
9752             boolean printed = false;
9753             long now = SystemClock.uptimeMillis();
9754             for (int i=0; i<mProcessesToGc.size(); i++) {
9755                 ProcessRecord proc = mProcessesToGc.get(i);
9756                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9757                     continue;
9758                 }
9759                 if (!printed) {
9760                     if (needSep) pw.println(" ");
9761                     needSep = true;
9762                     pw.println("  Processes that are waiting to GC:");
9763                     printed = true;
9764                 }
9765                 pw.print("    Process "); pw.println(proc);
9766                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9767                         pw.print(", last gced=");
9768                         pw.print(now-proc.lastRequestedGc);
9769                         pw.print(" ms ago, last lowMem=");
9770                         pw.print(now-proc.lastLowMemory);
9771                         pw.println(" ms ago");
9772 
9773             }
9774         }
9775         return needSep;
9776     }
9777 
dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll)9778     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9779             int opti, boolean dumpAll) {
9780         boolean needSep = false;
9781 
9782         if (mLruProcesses.size() > 0) {
9783             if (needSep) pw.println(" ");
9784             needSep = true;
9785             pw.println("  OOM levels:");
9786             pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9787             pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9788             pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9789             pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9790             pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9791             pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9792             pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9793             pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9794             pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9795             pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9796             pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9797             pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9798             pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9799 
9800             if (needSep) pw.println(" ");
9801             needSep = true;
9802             pw.println("  Process OOM control:");
9803             dumpProcessOomList(pw, this, mLruProcesses, "    ",
9804                     "Proc", "PERS", true, null);
9805             needSep = true;
9806         }
9807 
9808         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9809 
9810         pw.println();
9811         pw.println("  mHomeProcess: " + mHomeProcess);
9812         pw.println("  mPreviousProcess: " + mPreviousProcess);
9813         if (mHeavyWeightProcess != null) {
9814             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9815         }
9816 
9817         return true;
9818     }
9819 
9820     /**
9821      * There are three ways to call this:
9822      *  - no provider specified: dump all the providers
9823      *  - a flattened component name that matched an existing provider was specified as the
9824      *    first arg: dump that one provider
9825      *  - the first arg isn't the flattened component name of an existing provider:
9826      *    dump all providers whose component contains the first arg as a substring
9827      */
dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, int opti, boolean dumpAll)9828     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9829             int opti, boolean dumpAll) {
9830         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9831     }
9832 
9833     static class ItemMatcher {
9834         ArrayList<ComponentName> components;
9835         ArrayList<String> strings;
9836         ArrayList<Integer> objects;
9837         boolean all;
9838 
ItemMatcher()9839         ItemMatcher() {
9840             all = true;
9841         }
9842 
build(String name)9843         void build(String name) {
9844             ComponentName componentName = ComponentName.unflattenFromString(name);
9845             if (componentName != null) {
9846                 if (components == null) {
9847                     components = new ArrayList<ComponentName>();
9848                 }
9849                 components.add(componentName);
9850                 all = false;
9851             } else {
9852                 int objectId = 0;
9853                 // Not a '/' separated full component name; maybe an object ID?
9854                 try {
9855                     objectId = Integer.parseInt(name, 16);
9856                     if (objects == null) {
9857                         objects = new ArrayList<Integer>();
9858                     }
9859                     objects.add(objectId);
9860                     all = false;
9861                 } catch (RuntimeException e) {
9862                     // Not an integer; just do string match.
9863                     if (strings == null) {
9864                         strings = new ArrayList<String>();
9865                     }
9866                     strings.add(name);
9867                     all = false;
9868                 }
9869             }
9870         }
9871 
build(String[] args, int opti)9872         int build(String[] args, int opti) {
9873             for (; opti<args.length; opti++) {
9874                 String name = args[opti];
9875                 if ("--".equals(name)) {
9876                     return opti+1;
9877                 }
9878                 build(name);
9879             }
9880             return opti;
9881         }
9882 
match(Object object, ComponentName comp)9883         boolean match(Object object, ComponentName comp) {
9884             if (all) {
9885                 return true;
9886             }
9887             if (components != null) {
9888                 for (int i=0; i<components.size(); i++) {
9889                     if (components.get(i).equals(comp)) {
9890                         return true;
9891                     }
9892                 }
9893             }
9894             if (objects != null) {
9895                 for (int i=0; i<objects.size(); i++) {
9896                     if (System.identityHashCode(object) == objects.get(i)) {
9897                         return true;
9898                     }
9899                 }
9900             }
9901             if (strings != null) {
9902                 String flat = comp.flattenToString();
9903                 for (int i=0; i<strings.size(); i++) {
9904                     if (flat.contains(strings.get(i))) {
9905                         return true;
9906                     }
9907                 }
9908             }
9909             return false;
9910         }
9911     }
9912 
9913     /**
9914      * There are three things that cmd can be:
9915      *  - a flattened component name that matches an existing activity
9916      *  - the cmd arg isn't the flattened component name of an existing activity:
9917      *    dump all activity whose component contains the cmd as a substring
9918      *  - A hex number of the ActivityRecord object instance.
9919      */
dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, int opti, boolean dumpAll)9920     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9921             int opti, boolean dumpAll) {
9922         ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9923 
9924         if ("all".equals(name)) {
9925             synchronized (this) {
9926                 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9927                     activities.add(r1);
9928                 }
9929             }
9930         } else if ("top".equals(name)) {
9931             synchronized (this) {
9932                 final int N = mMainStack.mHistory.size();
9933                 if (N > 0) {
9934                     activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9935                 }
9936             }
9937         } else {
9938             ItemMatcher matcher = new ItemMatcher();
9939             matcher.build(name);
9940 
9941             synchronized (this) {
9942                 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9943                     if (matcher.match(r1, r1.intent.getComponent())) {
9944                         activities.add(r1);
9945                     }
9946                 }
9947             }
9948         }
9949 
9950         if (activities.size() <= 0) {
9951             return false;
9952         }
9953 
9954         String[] newArgs = new String[args.length - opti];
9955         if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9956 
9957         TaskRecord lastTask = null;
9958         boolean needSep = false;
9959         for (int i=activities.size()-1; i>=0; i--) {
9960             ActivityRecord r = (ActivityRecord)activities.get(i);
9961             if (needSep) {
9962                 pw.println();
9963             }
9964             needSep = true;
9965             synchronized (this) {
9966                 if (lastTask != r.task) {
9967                     lastTask = r.task;
9968                     pw.print("TASK "); pw.print(lastTask.affinity);
9969                             pw.print(" id="); pw.println(lastTask.taskId);
9970                     if (dumpAll) {
9971                         lastTask.dump(pw, "  ");
9972                     }
9973                 }
9974             }
9975             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9976         }
9977         return true;
9978     }
9979 
9980     /**
9981      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9982      * there is a thread associated with the activity.
9983      */
dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, final ActivityRecord r, String[] args, boolean dumpAll)9984     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9985             final ActivityRecord r, String[] args, boolean dumpAll) {
9986         String innerPrefix = prefix + "  ";
9987         synchronized (this) {
9988             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9989                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9990                     pw.print(" pid=");
9991                     if (r.app != null) pw.println(r.app.pid);
9992                     else pw.println("(not running)");
9993             if (dumpAll) {
9994                 r.dump(pw, innerPrefix);
9995             }
9996         }
9997         if (r.app != null && r.app.thread != null) {
9998             // flush anything that is already in the PrintWriter since the thread is going
9999             // to write to the file descriptor directly
10000             pw.flush();
10001             try {
10002                 TransferPipe tp = new TransferPipe();
10003                 try {
10004                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
10005                             r.appToken, innerPrefix, args);
10006                     tp.go(fd);
10007                 } finally {
10008                     tp.kill();
10009                 }
10010             } catch (IOException e) {
10011                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
10012             } catch (RemoteException e) {
10013                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
10014             }
10015         }
10016     }
10017 
dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)10018     boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10019             int opti, boolean dumpAll, String dumpPackage) {
10020         boolean needSep = false;
10021         boolean onlyHistory = false;
10022 
10023         if ("history".equals(dumpPackage)) {
10024             if (opti < args.length && "-s".equals(args[opti])) {
10025                 dumpAll = false;
10026             }
10027             onlyHistory = true;
10028             dumpPackage = null;
10029         }
10030 
10031         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
10032         if (!onlyHistory && dumpAll) {
10033             if (mRegisteredReceivers.size() > 0) {
10034                 boolean printed = false;
10035                 Iterator it = mRegisteredReceivers.values().iterator();
10036                 while (it.hasNext()) {
10037                     ReceiverList r = (ReceiverList)it.next();
10038                     if (dumpPackage != null && (r.app == null ||
10039                             !dumpPackage.equals(r.app.info.packageName))) {
10040                         continue;
10041                     }
10042                     if (!printed) {
10043                         pw.println("  Registered Receivers:");
10044                         needSep = true;
10045                         printed = true;
10046                     }
10047                     pw.print("  * "); pw.println(r);
10048                     r.dump(pw, "    ");
10049                 }
10050             }
10051 
10052             if (mReceiverResolver.dump(pw, needSep ?
10053                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
10054                     "    ", dumpPackage, false)) {
10055                 needSep = true;
10056             }
10057         }
10058 
10059         for (BroadcastQueue q : mBroadcastQueues) {
10060             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
10061         }
10062 
10063         needSep = true;
10064 
10065         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
10066             for (int user=0; user<mStickyBroadcasts.size(); user++) {
10067                 if (needSep) {
10068                     pw.println();
10069                 }
10070                 needSep = true;
10071                 pw.print("  Sticky broadcasts for user ");
10072                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
10073                 StringBuilder sb = new StringBuilder(128);
10074                 for (Map.Entry<String, ArrayList<Intent>> ent
10075                         : mStickyBroadcasts.valueAt(user).entrySet()) {
10076                     pw.print("  * Sticky action "); pw.print(ent.getKey());
10077                     if (dumpAll) {
10078                         pw.println(":");
10079                         ArrayList<Intent> intents = ent.getValue();
10080                         final int N = intents.size();
10081                         for (int i=0; i<N; i++) {
10082                             sb.setLength(0);
10083                             sb.append("    Intent: ");
10084                             intents.get(i).toShortString(sb, false, true, false, false);
10085                             pw.println(sb.toString());
10086                             Bundle bundle = intents.get(i).getExtras();
10087                             if (bundle != null) {
10088                                 pw.print("      ");
10089                                 pw.println(bundle.toString());
10090                             }
10091                         }
10092                     } else {
10093                         pw.println("");
10094                     }
10095                 }
10096             }
10097         }
10098 
10099         if (!onlyHistory && dumpAll) {
10100             pw.println();
10101             for (BroadcastQueue queue : mBroadcastQueues) {
10102                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
10103                         + queue.mBroadcastsScheduled);
10104             }
10105             pw.println("  mHandler:");
10106             mHandler.dump(new PrintWriterPrinter(pw), "    ");
10107             needSep = true;
10108         }
10109 
10110         return needSep;
10111     }
10112 
dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)10113     boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10114             int opti, boolean dumpAll, String dumpPackage) {
10115         boolean needSep = true;
10116 
10117         ItemMatcher matcher = new ItemMatcher();
10118         matcher.build(args, opti);
10119 
10120         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
10121 
10122         mProviderMap.dumpProvidersLocked(pw, dumpAll);
10123 
10124         if (mLaunchingProviders.size() > 0) {
10125             boolean printed = false;
10126             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
10127                 ContentProviderRecord r = mLaunchingProviders.get(i);
10128                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
10129                     continue;
10130                 }
10131                 if (!printed) {
10132                     if (needSep) pw.println(" ");
10133                     needSep = true;
10134                     pw.println("  Launching content providers:");
10135                     printed = true;
10136                 }
10137                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
10138                         pw.println(r);
10139             }
10140         }
10141 
10142         if (mGrantedUriPermissions.size() > 0) {
10143             if (needSep) pw.println();
10144             needSep = true;
10145             pw.println("Granted Uri Permissions:");
10146             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
10147                 int uid = mGrantedUriPermissions.keyAt(i);
10148                 HashMap<Uri, UriPermission> perms
10149                         = mGrantedUriPermissions.valueAt(i);
10150                 pw.print("  * UID "); pw.print(uid);
10151                         pw.println(" holds:");
10152                 for (UriPermission perm : perms.values()) {
10153                     pw.print("    "); pw.println(perm);
10154                     if (dumpAll) {
10155                         perm.dump(pw, "      ");
10156                     }
10157                 }
10158             }
10159             needSep = true;
10160         }
10161 
10162         return needSep;
10163     }
10164 
dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)10165     boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10166             int opti, boolean dumpAll, String dumpPackage) {
10167         boolean needSep = false;
10168 
10169         if (mIntentSenderRecords.size() > 0) {
10170             boolean printed = false;
10171             Iterator<WeakReference<PendingIntentRecord>> it
10172                     = mIntentSenderRecords.values().iterator();
10173             while (it.hasNext()) {
10174                 WeakReference<PendingIntentRecord> ref = it.next();
10175                 PendingIntentRecord rec = ref != null ? ref.get(): null;
10176                 if (dumpPackage != null && (rec == null
10177                         || !dumpPackage.equals(rec.key.packageName))) {
10178                     continue;
10179                 }
10180                 if (!printed) {
10181                     pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
10182                     printed = true;
10183                 }
10184                 needSep = true;
10185                 if (rec != null) {
10186                     pw.print("  * "); pw.println(rec);
10187                     if (dumpAll) {
10188                         rec.dump(pw, "    ");
10189                     }
10190                 } else {
10191                     pw.print("  * "); pw.println(ref);
10192                 }
10193             }
10194         }
10195 
10196         return needSep;
10197     }
10198 
dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, String prefix, String label, boolean complete, boolean brief, boolean client, String dumpPackage)10199     private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
10200             String prefix, String label, boolean complete, boolean brief, boolean client,
10201             String dumpPackage) {
10202         TaskRecord lastTask = null;
10203         boolean needNL = false;
10204         final String innerPrefix = prefix + "      ";
10205         final String[] args = new String[0];
10206         for (int i=list.size()-1; i>=0; i--) {
10207             final ActivityRecord r = (ActivityRecord)list.get(i);
10208             if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
10209                 continue;
10210             }
10211             final boolean full = !brief && (complete || !r.isInHistory());
10212             if (needNL) {
10213                 pw.println(" ");
10214                 needNL = false;
10215             }
10216             if (lastTask != r.task) {
10217                 lastTask = r.task;
10218                 pw.print(prefix);
10219                 pw.print(full ? "* " : "  ");
10220                 pw.println(lastTask);
10221                 if (full) {
10222                     lastTask.dump(pw, prefix + "  ");
10223                 } else if (complete) {
10224                     // Complete + brief == give a summary.  Isn't that obvious?!?
10225                     if (lastTask.intent != null) {
10226                         pw.print(prefix); pw.print("  ");
10227                                 pw.println(lastTask.intent.toInsecureStringWithClip());
10228                     }
10229                 }
10230             }
10231             pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
10232             pw.print(" #"); pw.print(i); pw.print(": ");
10233             pw.println(r);
10234             if (full) {
10235                 r.dump(pw, innerPrefix);
10236             } else if (complete) {
10237                 // Complete + brief == give a summary.  Isn't that obvious?!?
10238                 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
10239                 if (r.app != null) {
10240                     pw.print(innerPrefix); pw.println(r.app);
10241                 }
10242             }
10243             if (client && r.app != null && r.app.thread != null) {
10244                 // flush anything that is already in the PrintWriter since the thread is going
10245                 // to write to the file descriptor directly
10246                 pw.flush();
10247                 try {
10248                     TransferPipe tp = new TransferPipe();
10249                     try {
10250                         r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
10251                                 r.appToken, innerPrefix, args);
10252                         // Short timeout, since blocking here can
10253                         // deadlock with the application.
10254                         tp.go(fd, 2000);
10255                     } finally {
10256                         tp.kill();
10257                     }
10258                 } catch (IOException e) {
10259                     pw.println(innerPrefix + "Failure while dumping the activity: " + e);
10260                 } catch (RemoteException e) {
10261                     pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
10262                 }
10263                 needNL = true;
10264             }
10265         }
10266     }
10267 
buildOomTag(String prefix, String space, int val, int base)10268     private static String buildOomTag(String prefix, String space, int val, int base) {
10269         if (val == base) {
10270             if (space == null) return prefix;
10271             return prefix + "  ";
10272         }
10273         return prefix + "+" + Integer.toString(val-base);
10274     }
10275 
dumpProcessList(PrintWriter pw, ActivityManagerService service, List list, String prefix, String normalLabel, String persistentLabel, String dumpPackage)10276     private static final int dumpProcessList(PrintWriter pw,
10277             ActivityManagerService service, List list,
10278             String prefix, String normalLabel, String persistentLabel,
10279             String dumpPackage) {
10280         int numPers = 0;
10281         final int N = list.size()-1;
10282         for (int i=N; i>=0; i--) {
10283             ProcessRecord r = (ProcessRecord)list.get(i);
10284             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10285                 continue;
10286             }
10287             pw.println(String.format("%s%s #%2d: %s",
10288                     prefix, (r.persistent ? persistentLabel : normalLabel),
10289                     i, r.toString()));
10290             if (r.persistent) {
10291                 numPers++;
10292             }
10293         }
10294         return numPers;
10295     }
10296 
dumpProcessOomList(PrintWriter pw, ActivityManagerService service, List<ProcessRecord> origList, String prefix, String normalLabel, String persistentLabel, boolean inclDetails, String dumpPackage)10297     private static final boolean dumpProcessOomList(PrintWriter pw,
10298             ActivityManagerService service, List<ProcessRecord> origList,
10299             String prefix, String normalLabel, String persistentLabel,
10300             boolean inclDetails, String dumpPackage) {
10301 
10302         ArrayList<Pair<ProcessRecord, Integer>> list
10303                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
10304         for (int i=0; i<origList.size(); i++) {
10305             ProcessRecord r = origList.get(i);
10306             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10307                 continue;
10308             }
10309             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
10310         }
10311 
10312         if (list.size() <= 0) {
10313             return false;
10314         }
10315 
10316         Comparator<Pair<ProcessRecord, Integer>> comparator
10317                 = new Comparator<Pair<ProcessRecord, Integer>>() {
10318             @Override
10319             public int compare(Pair<ProcessRecord, Integer> object1,
10320                     Pair<ProcessRecord, Integer> object2) {
10321                 if (object1.first.setAdj != object2.first.setAdj) {
10322                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
10323                 }
10324                 if (object1.second.intValue() != object2.second.intValue()) {
10325                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
10326                 }
10327                 return 0;
10328             }
10329         };
10330 
10331         Collections.sort(list, comparator);
10332 
10333         final long curRealtime = SystemClock.elapsedRealtime();
10334         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
10335         final long curUptime = SystemClock.uptimeMillis();
10336         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
10337 
10338         for (int i=list.size()-1; i>=0; i--) {
10339             ProcessRecord r = list.get(i).first;
10340             String oomAdj;
10341             if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
10342                 oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
10343             } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
10344                 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
10345             } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
10346                 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
10347             } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
10348                 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
10349             } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10350                 oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
10351             } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
10352                 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
10353             } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10354                 oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10355             } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10356                 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10357             } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10358                 oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10359             } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10360                 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
10361             } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10362                 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
10363             } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10364                 oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
10365             } else {
10366                 oomAdj = Integer.toString(r.setAdj);
10367             }
10368             String schedGroup;
10369             switch (r.setSchedGroup) {
10370                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10371                     schedGroup = "B";
10372                     break;
10373                 case Process.THREAD_GROUP_DEFAULT:
10374                     schedGroup = "F";
10375                     break;
10376                 default:
10377                     schedGroup = Integer.toString(r.setSchedGroup);
10378                     break;
10379             }
10380             String foreground;
10381             if (r.foregroundActivities) {
10382                 foreground = "A";
10383             } else if (r.foregroundServices) {
10384                 foreground = "S";
10385             } else {
10386                 foreground = " ";
10387             }
10388             pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
10389                     prefix, (r.persistent ? persistentLabel : normalLabel),
10390                     (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10391                     foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
10392             if (r.adjSource != null || r.adjTarget != null) {
10393                 pw.print(prefix);
10394                 pw.print("    ");
10395                 if (r.adjTarget instanceof ComponentName) {
10396                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10397                 } else if (r.adjTarget != null) {
10398                     pw.print(r.adjTarget.toString());
10399                 } else {
10400                     pw.print("{null}");
10401                 }
10402                 pw.print("<=");
10403                 if (r.adjSource instanceof ProcessRecord) {
10404                     pw.print("Proc{");
10405                     pw.print(((ProcessRecord)r.adjSource).toShortString());
10406                     pw.println("}");
10407                 } else if (r.adjSource != null) {
10408                     pw.println(r.adjSource.toString());
10409                 } else {
10410                     pw.println("{null}");
10411                 }
10412             }
10413             if (inclDetails) {
10414                 pw.print(prefix);
10415                 pw.print("    ");
10416                 pw.print("oom: max="); pw.print(r.maxAdj);
10417                 pw.print(" hidden="); pw.print(r.hiddenAdj);
10418                 pw.print(" client="); pw.print(r.clientHiddenAdj);
10419                 pw.print(" empty="); pw.print(r.emptyAdj);
10420                 pw.print(" curRaw="); pw.print(r.curRawAdj);
10421                 pw.print(" setRaw="); pw.print(r.setRawAdj);
10422                 pw.print(" cur="); pw.print(r.curAdj);
10423                 pw.print(" set="); pw.println(r.setAdj);
10424                 pw.print(prefix);
10425                 pw.print("    ");
10426                 pw.print("keeping="); pw.print(r.keeping);
10427                 pw.print(" hidden="); pw.print(r.hidden);
10428                 pw.print(" empty="); pw.print(r.empty);
10429                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
10430 
10431                 if (!r.keeping) {
10432                     if (r.lastWakeTime != 0) {
10433                         long wtime;
10434                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10435                         synchronized (stats) {
10436                             wtime = stats.getProcessWakeTime(r.info.uid,
10437                                     r.pid, curRealtime);
10438                         }
10439                         long timeUsed = wtime - r.lastWakeTime;
10440                         pw.print(prefix);
10441                         pw.print("    ");
10442                         pw.print("keep awake over ");
10443                         TimeUtils.formatDuration(realtimeSince, pw);
10444                         pw.print(" used ");
10445                         TimeUtils.formatDuration(timeUsed, pw);
10446                         pw.print(" (");
10447                         pw.print((timeUsed*100)/realtimeSince);
10448                         pw.println("%)");
10449                     }
10450                     if (r.lastCpuTime != 0) {
10451                         long timeUsed = r.curCpuTime - r.lastCpuTime;
10452                         pw.print(prefix);
10453                         pw.print("    ");
10454                         pw.print("run cpu over ");
10455                         TimeUtils.formatDuration(uptimeSince, pw);
10456                         pw.print(" used ");
10457                         TimeUtils.formatDuration(timeUsed, pw);
10458                         pw.print(" (");
10459                         pw.print((timeUsed*100)/uptimeSince);
10460                         pw.println("%)");
10461                     }
10462                 }
10463             }
10464         }
10465         return true;
10466     }
10467 
collectProcesses(PrintWriter pw, int start, String[] args)10468     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10469         ArrayList<ProcessRecord> procs;
10470         synchronized (this) {
10471             if (args != null && args.length > start
10472                     && args[start].charAt(0) != '-') {
10473                 procs = new ArrayList<ProcessRecord>();
10474                 int pid = -1;
10475                 try {
10476                     pid = Integer.parseInt(args[start]);
10477                 } catch (NumberFormatException e) {
10478 
10479                 }
10480                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
10481                     ProcessRecord proc = mLruProcesses.get(i);
10482                     if (proc.pid == pid) {
10483                         procs.add(proc);
10484                     } else if (proc.processName.equals(args[start])) {
10485                         procs.add(proc);
10486                     }
10487                 }
10488                 if (procs.size() <= 0) {
10489                     pw.println("No process found for: " + args[start]);
10490                     return null;
10491                 }
10492             } else {
10493                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
10494             }
10495         }
10496         return procs;
10497     }
10498 
dumpGraphicsHardwareUsage(FileDescriptor fd, PrintWriter pw, String[] args)10499     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10500             PrintWriter pw, String[] args) {
10501         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10502         if (procs == null) {
10503             return;
10504         }
10505 
10506         long uptime = SystemClock.uptimeMillis();
10507         long realtime = SystemClock.elapsedRealtime();
10508         pw.println("Applications Graphics Acceleration Info:");
10509         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10510 
10511         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10512             ProcessRecord r = procs.get(i);
10513             if (r.thread != null) {
10514                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10515                 pw.flush();
10516                 try {
10517                     TransferPipe tp = new TransferPipe();
10518                     try {
10519                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10520                         tp.go(fd);
10521                     } finally {
10522                         tp.kill();
10523                     }
10524                 } catch (IOException e) {
10525                     pw.println("Failure while dumping the app: " + r);
10526                     pw.flush();
10527                 } catch (RemoteException e) {
10528                     pw.println("Got a RemoteException while dumping the app " + r);
10529                     pw.flush();
10530                 }
10531             }
10532         }
10533     }
10534 
dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args)10535     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10536         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10537         if (procs == null) {
10538             return;
10539         }
10540 
10541         pw.println("Applications Database Info:");
10542 
10543         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10544             ProcessRecord r = procs.get(i);
10545             if (r.thread != null) {
10546                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10547                 pw.flush();
10548                 try {
10549                     TransferPipe tp = new TransferPipe();
10550                     try {
10551                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10552                         tp.go(fd);
10553                     } finally {
10554                         tp.kill();
10555                     }
10556                 } catch (IOException e) {
10557                     pw.println("Failure while dumping the app: " + r);
10558                     pw.flush();
10559                 } catch (RemoteException e) {
10560                     pw.println("Got a RemoteException while dumping the app " + r);
10561                     pw.flush();
10562                 }
10563             }
10564         }
10565     }
10566 
10567     final static class MemItem {
10568         final String label;
10569         final String shortLabel;
10570         final long pss;
10571         final int id;
10572         ArrayList<MemItem> subitems;
10573 
MemItem(String _label, String _shortLabel, long _pss, int _id)10574         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10575             label = _label;
10576             shortLabel = _shortLabel;
10577             pss = _pss;
10578             id = _id;
10579         }
10580     }
10581 
dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, boolean sort)10582     static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10583             boolean sort) {
10584         if (sort) {
10585             Collections.sort(items, new Comparator<MemItem>() {
10586                 @Override
10587                 public int compare(MemItem lhs, MemItem rhs) {
10588                     if (lhs.pss < rhs.pss) {
10589                         return 1;
10590                     } else if (lhs.pss > rhs.pss) {
10591                         return -1;
10592                     }
10593                     return 0;
10594                 }
10595             });
10596         }
10597 
10598         for (int i=0; i<items.size(); i++) {
10599             MemItem mi = items.get(i);
10600             pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10601             if (mi.subitems != null) {
10602                 dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10603             }
10604         }
10605     }
10606 
10607     // These are in KB.
10608     static final long[] DUMP_MEM_BUCKETS = new long[] {
10609         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10610         120*1024, 160*1024, 200*1024,
10611         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10612         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10613     };
10614 
appendMemBucket(StringBuilder out, long memKB, String label, boolean stackLike)10615     static final void appendMemBucket(StringBuilder out, long memKB, String label,
10616             boolean stackLike) {
10617         int start = label.lastIndexOf('.');
10618         if (start >= 0) start++;
10619         else start = 0;
10620         int end = label.length();
10621         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10622             if (DUMP_MEM_BUCKETS[i] >= memKB) {
10623                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
10624                 out.append(bucket);
10625                 out.append(stackLike ? "MB." : "MB ");
10626                 out.append(label, start, end);
10627                 return;
10628             }
10629         }
10630         out.append(memKB/1024);
10631         out.append(stackLike ? "MB." : "MB ");
10632         out.append(label, start, end);
10633     }
10634 
10635     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10636             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10637             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10638             ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10639             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10640     };
10641     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10642             "System", "Persistent", "Foreground",
10643             "Visible", "Perceptible", "Heavy Weight",
10644             "Backup", "A Services", "Home", "Previous",
10645             "B Services", "Background"
10646     };
10647 
dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack)10648     final void dumpApplicationMemoryUsage(FileDescriptor fd,
10649             PrintWriter pw, String prefix, String[] args, boolean brief,
10650             PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10651         boolean dumpAll = false;
10652         boolean oomOnly = false;
10653 
10654         int opti = 0;
10655         while (opti < args.length) {
10656             String opt = args[opti];
10657             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10658                 break;
10659             }
10660             opti++;
10661             if ("-a".equals(opt)) {
10662                 dumpAll = true;
10663             } else if ("--oom".equals(opt)) {
10664                 oomOnly = true;
10665             } else if ("-h".equals(opt)) {
10666                 pw.println("meminfo dump options: [-a] [--oom] [process]");
10667                 pw.println("  -a: include all available information for each process.");
10668                 pw.println("  --oom: only show processes organized by oom adj.");
10669                 pw.println("If [process] is specified it can be the name or ");
10670                 pw.println("pid of a specific process to dump.");
10671                 return;
10672             } else {
10673                 pw.println("Unknown argument: " + opt + "; use -h for help");
10674             }
10675         }
10676 
10677         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10678         if (procs == null) {
10679             return;
10680         }
10681 
10682         final boolean isCheckinRequest = scanArgs(args, "--checkin");
10683         long uptime = SystemClock.uptimeMillis();
10684         long realtime = SystemClock.elapsedRealtime();
10685 
10686         if (procs.size() == 1 || isCheckinRequest) {
10687             dumpAll = true;
10688         }
10689 
10690         if (isCheckinRequest) {
10691             // short checkin version
10692             pw.println(uptime + "," + realtime);
10693             pw.flush();
10694         } else {
10695             pw.println("Applications Memory Usage (kB):");
10696             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10697         }
10698 
10699         String[] innerArgs = new String[args.length-opti];
10700         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10701 
10702         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10703         long nativePss=0, dalvikPss=0, otherPss=0;
10704         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10705 
10706         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10707         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10708                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
10709 
10710         long totalPss = 0;
10711 
10712         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10713             ProcessRecord r = procs.get(i);
10714             if (r.thread != null) {
10715                 if (!isCheckinRequest && dumpAll) {
10716                     pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10717                     pw.flush();
10718                 }
10719                 Debug.MemoryInfo mi = null;
10720                 if (dumpAll) {
10721                     try {
10722                         mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10723                     } catch (RemoteException e) {
10724                         if (!isCheckinRequest) {
10725                             pw.println("Got RemoteException!");
10726                             pw.flush();
10727                         }
10728                     }
10729                 } else {
10730                     mi = new Debug.MemoryInfo();
10731                     Debug.getMemoryInfo(r.pid, mi);
10732                 }
10733 
10734                 if (!isCheckinRequest && mi != null) {
10735                     long myTotalPss = mi.getTotalPss();
10736                     totalPss += myTotalPss;
10737                     MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10738                             r.processName, myTotalPss, 0);
10739                     procMems.add(pssItem);
10740 
10741                     nativePss += mi.nativePss;
10742                     dalvikPss += mi.dalvikPss;
10743                     otherPss += mi.otherPss;
10744                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10745                         long mem = mi.getOtherPss(j);
10746                         miscPss[j] += mem;
10747                         otherPss -= mem;
10748                     }
10749 
10750                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10751                         if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10752                                 || oomIndex == (oomPss.length-1)) {
10753                             oomPss[oomIndex] += myTotalPss;
10754                             if (oomProcs[oomIndex] == null) {
10755                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
10756                             }
10757                             oomProcs[oomIndex].add(pssItem);
10758                             break;
10759                         }
10760                     }
10761                 }
10762             }
10763         }
10764 
10765         if (!isCheckinRequest && procs.size() > 1) {
10766             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10767 
10768             catMems.add(new MemItem("Native", "Native", nativePss, -1));
10769             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10770             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10771             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10772                 String label = Debug.MemoryInfo.getOtherLabel(j);
10773                 catMems.add(new MemItem(label, label, miscPss[j], j));
10774             }
10775 
10776             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10777             for (int j=0; j<oomPss.length; j++) {
10778                 if (oomPss[j] != 0) {
10779                     String label = DUMP_MEM_OOM_LABEL[j];
10780                     MemItem item = new MemItem(label, label, oomPss[j],
10781                             DUMP_MEM_OOM_ADJ[j]);
10782                     item.subitems = oomProcs[j];
10783                     oomMems.add(item);
10784                 }
10785             }
10786 
10787             if (outTag != null || outStack != null) {
10788                 if (outTag != null) {
10789                     appendMemBucket(outTag, totalPss, "total", false);
10790                 }
10791                 if (outStack != null) {
10792                     appendMemBucket(outStack, totalPss, "total", true);
10793                 }
10794                 boolean firstLine = true;
10795                 for (int i=0; i<oomMems.size(); i++) {
10796                     MemItem miCat = oomMems.get(i);
10797                     if (miCat.subitems == null || miCat.subitems.size() < 1) {
10798                         continue;
10799                     }
10800                     if (miCat.id < ProcessList.SERVICE_ADJ
10801                             || miCat.id == ProcessList.HOME_APP_ADJ
10802                             || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10803                         if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10804                             outTag.append(" / ");
10805                         }
10806                         if (outStack != null) {
10807                             if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10808                                 if (firstLine) {
10809                                     outStack.append(":");
10810                                     firstLine = false;
10811                                 }
10812                                 outStack.append("\n\t at ");
10813                             } else {
10814                                 outStack.append("$");
10815                             }
10816                         }
10817                         for (int j=0; j<miCat.subitems.size(); j++) {
10818                             MemItem mi = miCat.subitems.get(j);
10819                             if (j > 0) {
10820                                 if (outTag != null) {
10821                                     outTag.append(" ");
10822                                 }
10823                                 if (outStack != null) {
10824                                     outStack.append("$");
10825                                 }
10826                             }
10827                             if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10828                                 appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10829                             }
10830                             if (outStack != null) {
10831                                 appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10832                             }
10833                         }
10834                         if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10835                             outStack.append("(");
10836                             for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10837                                 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10838                                     outStack.append(DUMP_MEM_OOM_LABEL[k]);
10839                                     outStack.append(":");
10840                                     outStack.append(DUMP_MEM_OOM_ADJ[k]);
10841                                 }
10842                             }
10843                             outStack.append(")");
10844                         }
10845                     }
10846                 }
10847             }
10848 
10849             if (!brief && !oomOnly) {
10850                 pw.println();
10851                 pw.println("Total PSS by process:");
10852                 dumpMemItems(pw, "  ", procMems, true);
10853                 pw.println();
10854             }
10855             pw.println("Total PSS by OOM adjustment:");
10856             dumpMemItems(pw, "  ", oomMems, false);
10857             if (!oomOnly) {
10858                 PrintWriter out = categoryPw != null ? categoryPw : pw;
10859                 out.println();
10860                 out.println("Total PSS by category:");
10861                 dumpMemItems(out, "  ", catMems, true);
10862             }
10863             pw.println();
10864             pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10865             final int[] SINGLE_LONG_FORMAT = new int[] {
10866                 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10867             };
10868             long[] longOut = new long[1];
10869             Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10870                     SINGLE_LONG_FORMAT, null, longOut, null);
10871             long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10872             longOut[0] = 0;
10873             Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10874                     SINGLE_LONG_FORMAT, null, longOut, null);
10875             long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10876             longOut[0] = 0;
10877             Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10878                     SINGLE_LONG_FORMAT, null, longOut, null);
10879             long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10880             longOut[0] = 0;
10881             Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10882                     SINGLE_LONG_FORMAT, null, longOut, null);
10883             long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10884             pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10885                     pw.print(shared); pw.println(" kB");
10886             pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10887                     pw.print(voltile); pw.println(" kB volatile");
10888         }
10889     }
10890 
10891     /**
10892      * Searches array of arguments for the specified string
10893      * @param args array of argument strings
10894      * @param value value to search for
10895      * @return true if the value is contained in the array
10896      */
scanArgs(String[] args, String value)10897     private static boolean scanArgs(String[] args, String value) {
10898         if (args != null) {
10899             for (String arg : args) {
10900                 if (value.equals(arg)) {
10901                     return true;
10902                 }
10903             }
10904         }
10905         return false;
10906     }
10907 
removeDyingProviderLocked(ProcessRecord proc, ContentProviderRecord cpr, boolean always)10908     private final boolean removeDyingProviderLocked(ProcessRecord proc,
10909             ContentProviderRecord cpr, boolean always) {
10910         final boolean inLaunching = mLaunchingProviders.contains(cpr);
10911 
10912         if (!inLaunching || always) {
10913             synchronized (cpr) {
10914                 cpr.launchingApp = null;
10915                 cpr.notifyAll();
10916             }
10917             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10918             String names[] = cpr.info.authority.split(";");
10919             for (int j = 0; j < names.length; j++) {
10920                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10921             }
10922         }
10923 
10924         for (int i=0; i<cpr.connections.size(); i++) {
10925             ContentProviderConnection conn = cpr.connections.get(i);
10926             if (conn.waiting) {
10927                 // If this connection is waiting for the provider, then we don't
10928                 // need to mess with its process unless we are always removing
10929                 // or for some reason the provider is not currently launching.
10930                 if (inLaunching && !always) {
10931                     continue;
10932                 }
10933             }
10934             ProcessRecord capp = conn.client;
10935             conn.dead = true;
10936             if (conn.stableCount > 0) {
10937                 if (!capp.persistent && capp.thread != null
10938                         && capp.pid != 0
10939                         && capp.pid != MY_PID) {
10940                     Slog.i(TAG, "Kill " + capp.processName
10941                             + " (pid " + capp.pid + "): provider " + cpr.info.name
10942                             + " in dying process " + (proc != null ? proc.processName : "??"));
10943                     EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid,
10944                             capp.processName, capp.setAdj, "dying provider "
10945                                     + cpr.name.toShortString());
10946                     Process.killProcessQuiet(capp.pid);
10947                 }
10948             } else if (capp.thread != null && conn.provider.provider != null) {
10949                 try {
10950                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10951                 } catch (RemoteException e) {
10952                 }
10953                 // In the protocol here, we don't expect the client to correctly
10954                 // clean up this connection, we'll just remove it.
10955                 cpr.connections.remove(i);
10956                 conn.client.conProviders.remove(conn);
10957             }
10958         }
10959 
10960         if (inLaunching && always) {
10961             mLaunchingProviders.remove(cpr);
10962         }
10963         return inLaunching;
10964     }
10965 
10966     /**
10967      * Main code for cleaning up a process when it has gone away.  This is
10968      * called both as a result of the process dying, or directly when stopping
10969      * a process when running in single process mode.
10970      */
cleanUpApplicationRecordLocked(ProcessRecord app, boolean restarting, boolean allowRestart, int index)10971     private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10972             boolean restarting, boolean allowRestart, int index) {
10973         if (index >= 0) {
10974             mLruProcesses.remove(index);
10975         }
10976 
10977         mProcessesToGc.remove(app);
10978 
10979         // Dismiss any open dialogs.
10980         if (app.crashDialog != null && !app.forceCrashReport) {
10981             app.crashDialog.dismiss();
10982             app.crashDialog = null;
10983         }
10984         if (app.anrDialog != null) {
10985             app.anrDialog.dismiss();
10986             app.anrDialog = null;
10987         }
10988         if (app.waitDialog != null) {
10989             app.waitDialog.dismiss();
10990             app.waitDialog = null;
10991         }
10992 
10993         app.crashing = false;
10994         app.notResponding = false;
10995 
10996         app.resetPackageList();
10997         app.unlinkDeathRecipient();
10998         app.thread = null;
10999         app.forcingToForeground = null;
11000         app.foregroundServices = false;
11001         app.foregroundActivities = false;
11002         app.hasShownUi = false;
11003         app.hasAboveClient = false;
11004 
11005         mServices.killServicesLocked(app, allowRestart);
11006 
11007         boolean restart = false;
11008 
11009         // Remove published content providers.
11010         if (!app.pubProviders.isEmpty()) {
11011             Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
11012             while (it.hasNext()) {
11013                 ContentProviderRecord cpr = it.next();
11014 
11015                 final boolean always = app.bad || !allowRestart;
11016                 if (removeDyingProviderLocked(app, cpr, always) || always) {
11017                     // We left the provider in the launching list, need to
11018                     // restart it.
11019                     restart = true;
11020                 }
11021 
11022                 cpr.provider = null;
11023                 cpr.proc = null;
11024             }
11025             app.pubProviders.clear();
11026         }
11027 
11028         // Take care of any launching providers waiting for this process.
11029         if (checkAppInLaunchingProvidersLocked(app, false)) {
11030             restart = true;
11031         }
11032 
11033         // Unregister from connected content providers.
11034         if (!app.conProviders.isEmpty()) {
11035             for (int i=0; i<app.conProviders.size(); i++) {
11036                 ContentProviderConnection conn = app.conProviders.get(i);
11037                 conn.provider.connections.remove(conn);
11038             }
11039             app.conProviders.clear();
11040         }
11041 
11042         // At this point there may be remaining entries in mLaunchingProviders
11043         // where we were the only one waiting, so they are no longer of use.
11044         // Look for these and clean up if found.
11045         // XXX Commented out for now.  Trying to figure out a way to reproduce
11046         // the actual situation to identify what is actually going on.
11047         if (false) {
11048             for (int i=0; i<mLaunchingProviders.size(); i++) {
11049                 ContentProviderRecord cpr = (ContentProviderRecord)
11050                         mLaunchingProviders.get(i);
11051                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
11052                     synchronized (cpr) {
11053                         cpr.launchingApp = null;
11054                         cpr.notifyAll();
11055                     }
11056                 }
11057             }
11058         }
11059 
11060         skipCurrentReceiverLocked(app);
11061 
11062         // Unregister any receivers.
11063         if (app.receivers.size() > 0) {
11064             Iterator<ReceiverList> it = app.receivers.iterator();
11065             while (it.hasNext()) {
11066                 removeReceiverLocked(it.next());
11067             }
11068             app.receivers.clear();
11069         }
11070 
11071         // If the app is undergoing backup, tell the backup manager about it
11072         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
11073             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
11074                     + mBackupTarget.appInfo + " died during backup");
11075             try {
11076                 IBackupManager bm = IBackupManager.Stub.asInterface(
11077                         ServiceManager.getService(Context.BACKUP_SERVICE));
11078                 bm.agentDisconnected(app.info.packageName);
11079             } catch (RemoteException e) {
11080                 // can't happen; backup manager is local
11081             }
11082         }
11083 
11084         for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
11085             ProcessChangeItem item = mPendingProcessChanges.get(i);
11086             if (item.pid == app.pid) {
11087                 mPendingProcessChanges.remove(i);
11088                 mAvailProcessChanges.add(item);
11089             }
11090         }
11091         mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
11092 
11093         // If the caller is restarting this app, then leave it in its
11094         // current lists and let the caller take care of it.
11095         if (restarting) {
11096             return;
11097         }
11098 
11099         if (!app.persistent || app.isolated) {
11100             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
11101                     "Removing non-persistent process during cleanup: " + app);
11102             mProcessNames.remove(app.processName, app.uid);
11103             mIsolatedProcesses.remove(app.uid);
11104             if (mHeavyWeightProcess == app) {
11105                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
11106                         mHeavyWeightProcess.userId, 0));
11107                 mHeavyWeightProcess = null;
11108             }
11109         } else if (!app.removed) {
11110             // This app is persistent, so we need to keep its record around.
11111             // If it is not already on the pending app list, add it there
11112             // and start a new process for it.
11113             if (mPersistentStartingProcesses.indexOf(app) < 0) {
11114                 mPersistentStartingProcesses.add(app);
11115                 restart = true;
11116             }
11117         }
11118         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
11119                 "Clean-up removing on hold: " + app);
11120         mProcessesOnHold.remove(app);
11121 
11122         if (app == mHomeProcess) {
11123             mHomeProcess = null;
11124         }
11125         if (app == mPreviousProcess) {
11126             mPreviousProcess = null;
11127         }
11128 
11129         if (restart && !app.isolated) {
11130             // We have components that still need to be running in the
11131             // process, so re-launch it.
11132             mProcessNames.put(app.processName, app.uid, app);
11133             startProcessLocked(app, "restart", app.processName);
11134         } else if (app.pid > 0 && app.pid != MY_PID) {
11135             // Goodbye!
11136             synchronized (mPidsSelfLocked) {
11137                 mPidsSelfLocked.remove(app.pid);
11138                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
11139             }
11140             app.setPid(0);
11141         }
11142     }
11143 
checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad)11144     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
11145         // Look through the content providers we are waiting to have launched,
11146         // and if any run in this process then either schedule a restart of
11147         // the process or kill the client waiting for it if this process has
11148         // gone bad.
11149         int NL = mLaunchingProviders.size();
11150         boolean restart = false;
11151         for (int i=0; i<NL; i++) {
11152             ContentProviderRecord cpr = mLaunchingProviders.get(i);
11153             if (cpr.launchingApp == app) {
11154                 if (!alwaysBad && !app.bad) {
11155                     restart = true;
11156                 } else {
11157                     removeDyingProviderLocked(app, cpr, true);
11158                     // cpr should have been removed from mLaunchingProviders
11159                     NL = mLaunchingProviders.size();
11160                     i--;
11161                 }
11162             }
11163         }
11164         return restart;
11165     }
11166 
11167     // =========================================================
11168     // SERVICES
11169     // =========================================================
11170 
getServices(int maxNum, int flags)11171     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
11172             int flags) {
11173         enforceNotIsolatedCaller("getServices");
11174         synchronized (this) {
11175             return mServices.getRunningServiceInfoLocked(maxNum, flags);
11176         }
11177     }
11178 
getRunningServiceControlPanel(ComponentName name)11179     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
11180         enforceNotIsolatedCaller("getRunningServiceControlPanel");
11181         synchronized (this) {
11182             return mServices.getRunningServiceControlPanelLocked(name);
11183         }
11184     }
11185 
startService(IApplicationThread caller, Intent service, String resolvedType, int userId)11186     public ComponentName startService(IApplicationThread caller, Intent service,
11187             String resolvedType, int userId) {
11188         enforceNotIsolatedCaller("startService");
11189         // Refuse possible leaked file descriptors
11190         if (service != null && service.hasFileDescriptors() == true) {
11191             throw new IllegalArgumentException("File descriptors passed in Intent");
11192         }
11193 
11194         if (DEBUG_SERVICE)
11195             Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
11196         synchronized(this) {
11197             final int callingPid = Binder.getCallingPid();
11198             final int callingUid = Binder.getCallingUid();
11199             checkValidCaller(callingUid, userId);
11200             final long origId = Binder.clearCallingIdentity();
11201             ComponentName res = mServices.startServiceLocked(caller, service,
11202                     resolvedType, callingPid, callingUid, userId);
11203             Binder.restoreCallingIdentity(origId);
11204             return res;
11205         }
11206     }
11207 
startServiceInPackage(int uid, Intent service, String resolvedType, int userId)11208     ComponentName startServiceInPackage(int uid,
11209             Intent service, String resolvedType, int userId) {
11210         synchronized(this) {
11211             if (DEBUG_SERVICE)
11212                 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
11213             final long origId = Binder.clearCallingIdentity();
11214             ComponentName res = mServices.startServiceLocked(null, service,
11215                     resolvedType, -1, uid, userId);
11216             Binder.restoreCallingIdentity(origId);
11217             return res;
11218         }
11219     }
11220 
stopService(IApplicationThread caller, Intent service, String resolvedType, int userId)11221     public int stopService(IApplicationThread caller, Intent service,
11222             String resolvedType, int userId) {
11223         enforceNotIsolatedCaller("stopService");
11224         // Refuse possible leaked file descriptors
11225         if (service != null && service.hasFileDescriptors() == true) {
11226             throw new IllegalArgumentException("File descriptors passed in Intent");
11227         }
11228 
11229         checkValidCaller(Binder.getCallingUid(), userId);
11230 
11231         synchronized(this) {
11232             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
11233         }
11234     }
11235 
peekService(Intent service, String resolvedType)11236     public IBinder peekService(Intent service, String resolvedType) {
11237         enforceNotIsolatedCaller("peekService");
11238         // Refuse possible leaked file descriptors
11239         if (service != null && service.hasFileDescriptors() == true) {
11240             throw new IllegalArgumentException("File descriptors passed in Intent");
11241         }
11242         synchronized(this) {
11243             return mServices.peekServiceLocked(service, resolvedType);
11244         }
11245     }
11246 
stopServiceToken(ComponentName className, IBinder token, int startId)11247     public boolean stopServiceToken(ComponentName className, IBinder token,
11248             int startId) {
11249         synchronized(this) {
11250             return mServices.stopServiceTokenLocked(className, token, startId);
11251         }
11252     }
11253 
setServiceForeground(ComponentName className, IBinder token, int id, Notification notification, boolean removeNotification)11254     public void setServiceForeground(ComponentName className, IBinder token,
11255             int id, Notification notification, boolean removeNotification) {
11256         synchronized(this) {
11257             mServices.setServiceForegroundLocked(className, token, id, notification,
11258                     removeNotification);
11259         }
11260     }
11261 
handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, boolean requireFull, String name, String callerPackage)11262     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
11263             boolean requireFull, String name, String callerPackage) {
11264         final int callingUserId = UserHandle.getUserId(callingUid);
11265         if (callingUserId != userId) {
11266             if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
11267                 if ((requireFull || checkComponentPermission(
11268                         android.Manifest.permission.INTERACT_ACROSS_USERS,
11269                         callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
11270                         && checkComponentPermission(
11271                                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
11272                                 callingPid, callingUid, -1, true)
11273                                 != PackageManager.PERMISSION_GRANTED) {
11274                     if (userId == UserHandle.USER_CURRENT_OR_SELF) {
11275                         // In this case, they would like to just execute as their
11276                         // owner user instead of failing.
11277                         userId = callingUserId;
11278                     } else {
11279                         StringBuilder builder = new StringBuilder(128);
11280                         builder.append("Permission Denial: ");
11281                         builder.append(name);
11282                         if (callerPackage != null) {
11283                             builder.append(" from ");
11284                             builder.append(callerPackage);
11285                         }
11286                         builder.append(" asks to run as user ");
11287                         builder.append(userId);
11288                         builder.append(" but is calling from user ");
11289                         builder.append(UserHandle.getUserId(callingUid));
11290                         builder.append("; this requires ");
11291                         builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
11292                         if (!requireFull) {
11293                             builder.append(" or ");
11294                             builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
11295                         }
11296                         String msg = builder.toString();
11297                         Slog.w(TAG, msg);
11298                         throw new SecurityException(msg);
11299                     }
11300                 }
11301             }
11302             if (userId == UserHandle.USER_CURRENT
11303                     || userId == UserHandle.USER_CURRENT_OR_SELF) {
11304                 // Note that we may be accessing this outside of a lock...
11305                 // shouldn't be a big deal, if this is being called outside
11306                 // of a locked context there is intrinsically a race with
11307                 // the value the caller will receive and someone else changing it.
11308                 userId = mCurrentUserId;
11309             }
11310             if (!allowAll && userId < 0) {
11311                 throw new IllegalArgumentException(
11312                         "Call does not support special user #" + userId);
11313             }
11314         }
11315         return userId;
11316     }
11317 
isSingleton(String componentProcessName, ApplicationInfo aInfo, String className, int flags)11318     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
11319             String className, int flags) {
11320         boolean result = false;
11321         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
11322             if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
11323                 if (ActivityManager.checkUidPermission(
11324                         android.Manifest.permission.INTERACT_ACROSS_USERS,
11325                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
11326                     ComponentName comp = new ComponentName(aInfo.packageName, className);
11327                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
11328                             + " requests FLAG_SINGLE_USER, but app does not hold "
11329                             + android.Manifest.permission.INTERACT_ACROSS_USERS;
11330                     Slog.w(TAG, msg);
11331                     throw new SecurityException(msg);
11332                 }
11333                 result = true;
11334             }
11335         } else if (componentProcessName == aInfo.packageName) {
11336             result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
11337         } else if ("system".equals(componentProcessName)) {
11338             result = true;
11339         }
11340         if (DEBUG_MU) {
11341             Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
11342                     + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
11343         }
11344         return result;
11345     }
11346 
bindService(IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags, int userId)11347     public int bindService(IApplicationThread caller, IBinder token,
11348             Intent service, String resolvedType,
11349             IServiceConnection connection, int flags, int userId) {
11350         enforceNotIsolatedCaller("bindService");
11351         // Refuse possible leaked file descriptors
11352         if (service != null && service.hasFileDescriptors() == true) {
11353             throw new IllegalArgumentException("File descriptors passed in Intent");
11354         }
11355 
11356         synchronized(this) {
11357             return mServices.bindServiceLocked(caller, token, service, resolvedType,
11358                     connection, flags, userId);
11359         }
11360     }
11361 
unbindService(IServiceConnection connection)11362     public boolean unbindService(IServiceConnection connection) {
11363         synchronized (this) {
11364             return mServices.unbindServiceLocked(connection);
11365         }
11366     }
11367 
publishService(IBinder token, Intent intent, IBinder service)11368     public void publishService(IBinder token, Intent intent, IBinder service) {
11369         // Refuse possible leaked file descriptors
11370         if (intent != null && intent.hasFileDescriptors() == true) {
11371             throw new IllegalArgumentException("File descriptors passed in Intent");
11372         }
11373 
11374         synchronized(this) {
11375             if (!(token instanceof ServiceRecord)) {
11376                 throw new IllegalArgumentException("Invalid service token");
11377             }
11378             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
11379         }
11380     }
11381 
unbindFinished(IBinder token, Intent intent, boolean doRebind)11382     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11383         // Refuse possible leaked file descriptors
11384         if (intent != null && intent.hasFileDescriptors() == true) {
11385             throw new IllegalArgumentException("File descriptors passed in Intent");
11386         }
11387 
11388         synchronized(this) {
11389             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
11390         }
11391     }
11392 
serviceDoneExecuting(IBinder token, int type, int startId, int res)11393     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11394         synchronized(this) {
11395             if (!(token instanceof ServiceRecord)) {
11396                 throw new IllegalArgumentException("Invalid service token");
11397             }
11398             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
11399         }
11400     }
11401 
11402     // =========================================================
11403     // BACKUP AND RESTORE
11404     // =========================================================
11405 
11406     // Cause the target app to be launched if necessary and its backup agent
11407     // instantiated.  The backup agent will invoke backupAgentCreated() on the
11408     // activity manager to announce its creation.
bindBackupAgent(ApplicationInfo app, int backupMode)11409     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11410         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
11411         enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
11412 
11413         synchronized(this) {
11414             // !!! TODO: currently no check here that we're already bound
11415             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11416             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11417             synchronized (stats) {
11418                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11419             }
11420 
11421             // Backup agent is now in use, its package can't be stopped.
11422             try {
11423                 AppGlobals.getPackageManager().setPackageStoppedState(
11424                         app.packageName, false, UserHandle.getUserId(app.uid));
11425             } catch (RemoteException e) {
11426             } catch (IllegalArgumentException e) {
11427                 Slog.w(TAG, "Failed trying to unstop package "
11428                         + app.packageName + ": " + e);
11429             }
11430 
11431             BackupRecord r = new BackupRecord(ss, app, backupMode);
11432             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11433                     ? new ComponentName(app.packageName, app.backupAgentName)
11434                     : new ComponentName("android", "FullBackupAgent");
11435             // startProcessLocked() returns existing proc's record if it's already running
11436             ProcessRecord proc = startProcessLocked(app.processName, app,
11437                     false, 0, "backup", hostingName, false, false);
11438             if (proc == null) {
11439                 Slog.e(TAG, "Unable to start backup agent process " + r);
11440                 return false;
11441             }
11442 
11443             r.app = proc;
11444             mBackupTarget = r;
11445             mBackupAppName = app.packageName;
11446 
11447             // Try not to kill the process during backup
11448             updateOomAdjLocked(proc);
11449 
11450             // If the process is already attached, schedule the creation of the backup agent now.
11451             // If it is not yet live, this will be done when it attaches to the framework.
11452             if (proc.thread != null) {
11453                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
11454                 try {
11455                     proc.thread.scheduleCreateBackupAgent(app,
11456                             compatibilityInfoForPackageLocked(app), backupMode);
11457                 } catch (RemoteException e) {
11458                     // Will time out on the backup manager side
11459                 }
11460             } else {
11461                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
11462             }
11463             // Invariants: at this point, the target app process exists and the application
11464             // is either already running or in the process of coming up.  mBackupTarget and
11465             // mBackupAppName describe the app, so that when it binds back to the AM we
11466             // know that it's scheduled for a backup-agent operation.
11467         }
11468 
11469         return true;
11470     }
11471 
11472     @Override
clearPendingBackup()11473     public void clearPendingBackup() {
11474         if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
11475         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
11476 
11477         synchronized (this) {
11478             mBackupTarget = null;
11479             mBackupAppName = null;
11480         }
11481     }
11482 
11483     // A backup agent has just come up
backupAgentCreated(String agentPackageName, IBinder agent)11484     public void backupAgentCreated(String agentPackageName, IBinder agent) {
11485         if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
11486                 + " = " + agent);
11487 
11488         synchronized(this) {
11489             if (!agentPackageName.equals(mBackupAppName)) {
11490                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11491                 return;
11492             }
11493         }
11494 
11495         long oldIdent = Binder.clearCallingIdentity();
11496         try {
11497             IBackupManager bm = IBackupManager.Stub.asInterface(
11498                     ServiceManager.getService(Context.BACKUP_SERVICE));
11499             bm.agentConnected(agentPackageName, agent);
11500         } catch (RemoteException e) {
11501             // can't happen; the backup manager service is local
11502         } catch (Exception e) {
11503             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11504             e.printStackTrace();
11505         } finally {
11506             Binder.restoreCallingIdentity(oldIdent);
11507         }
11508     }
11509 
11510     // done with this agent
unbindBackupAgent(ApplicationInfo appInfo)11511     public void unbindBackupAgent(ApplicationInfo appInfo) {
11512         if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
11513         if (appInfo == null) {
11514             Slog.w(TAG, "unbind backup agent for null app");
11515             return;
11516         }
11517 
11518         synchronized(this) {
11519             try {
11520                 if (mBackupAppName == null) {
11521                     Slog.w(TAG, "Unbinding backup agent with no active backup");
11522                     return;
11523                 }
11524 
11525                 if (!mBackupAppName.equals(appInfo.packageName)) {
11526                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11527                     return;
11528                 }
11529 
11530                 // Not backing this app up any more; reset its OOM adjustment
11531                 final ProcessRecord proc = mBackupTarget.app;
11532                 updateOomAdjLocked(proc);
11533 
11534                 // If the app crashed during backup, 'thread' will be null here
11535                 if (proc.thread != null) {
11536                     try {
11537                         proc.thread.scheduleDestroyBackupAgent(appInfo,
11538                                 compatibilityInfoForPackageLocked(appInfo));
11539                     } catch (Exception e) {
11540                         Slog.e(TAG, "Exception when unbinding backup agent:");
11541                         e.printStackTrace();
11542                     }
11543                 }
11544             } finally {
11545                 mBackupTarget = null;
11546                 mBackupAppName = null;
11547             }
11548         }
11549     }
11550     // =========================================================
11551     // BROADCASTS
11552     // =========================================================
11553 
getStickiesLocked(String action, IntentFilter filter, List cur, int userId)11554     private final List getStickiesLocked(String action, IntentFilter filter,
11555             List cur, int userId) {
11556         final ContentResolver resolver = mContext.getContentResolver();
11557         HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11558         if (stickies == null) {
11559             return cur;
11560         }
11561         final ArrayList<Intent> list = stickies.get(action);
11562         if (list == null) {
11563             return cur;
11564         }
11565         int N = list.size();
11566         for (int i=0; i<N; i++) {
11567             Intent intent = list.get(i);
11568             if (filter.match(resolver, intent, true, TAG) >= 0) {
11569                 if (cur == null) {
11570                     cur = new ArrayList<Intent>();
11571                 }
11572                 cur.add(intent);
11573             }
11574         }
11575         return cur;
11576     }
11577 
isPendingBroadcastProcessLocked(int pid)11578     boolean isPendingBroadcastProcessLocked(int pid) {
11579         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11580                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11581     }
11582 
skipPendingBroadcastLocked(int pid)11583     void skipPendingBroadcastLocked(int pid) {
11584             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11585             for (BroadcastQueue queue : mBroadcastQueues) {
11586                 queue.skipPendingBroadcastLocked(pid);
11587             }
11588     }
11589 
11590     // The app just attached; send any pending broadcasts that it should receive
sendPendingBroadcastsLocked(ProcessRecord app)11591     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11592         boolean didSomething = false;
11593         for (BroadcastQueue queue : mBroadcastQueues) {
11594             didSomething |= queue.sendPendingBroadcastsLocked(app);
11595         }
11596         return didSomething;
11597     }
11598 
registerReceiver(IApplicationThread caller, String callerPackage, IIntentReceiver receiver, IntentFilter filter, String permission, int userId)11599     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11600             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
11601         enforceNotIsolatedCaller("registerReceiver");
11602         int callingUid;
11603         int callingPid;
11604         synchronized(this) {
11605             ProcessRecord callerApp = null;
11606             if (caller != null) {
11607                 callerApp = getRecordForAppLocked(caller);
11608                 if (callerApp == null) {
11609                     throw new SecurityException(
11610                             "Unable to find app for caller " + caller
11611                             + " (pid=" + Binder.getCallingPid()
11612                             + ") when registering receiver " + receiver);
11613                 }
11614                 if (callerApp.info.uid != Process.SYSTEM_UID &&
11615                         !callerApp.pkgList.contains(callerPackage)) {
11616                     throw new SecurityException("Given caller package " + callerPackage
11617                             + " is not running in process " + callerApp);
11618                 }
11619                 callingUid = callerApp.info.uid;
11620                 callingPid = callerApp.pid;
11621             } else {
11622                 callerPackage = null;
11623                 callingUid = Binder.getCallingUid();
11624                 callingPid = Binder.getCallingPid();
11625             }
11626 
11627             userId = this.handleIncomingUser(callingPid, callingUid, userId,
11628                     true, true, "registerReceiver", callerPackage);
11629 
11630             List allSticky = null;
11631 
11632             // Look for any matching sticky broadcasts...
11633             Iterator actions = filter.actionsIterator();
11634             if (actions != null) {
11635                 while (actions.hasNext()) {
11636                     String action = (String)actions.next();
11637                     allSticky = getStickiesLocked(action, filter, allSticky,
11638                             UserHandle.USER_ALL);
11639                     allSticky = getStickiesLocked(action, filter, allSticky,
11640                             UserHandle.getUserId(callingUid));
11641                 }
11642             } else {
11643                 allSticky = getStickiesLocked(null, filter, allSticky,
11644                         UserHandle.USER_ALL);
11645                 allSticky = getStickiesLocked(null, filter, allSticky,
11646                         UserHandle.getUserId(callingUid));
11647             }
11648 
11649             // The first sticky in the list is returned directly back to
11650             // the client.
11651             Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11652 
11653             if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11654                     + ": " + sticky);
11655 
11656             if (receiver == null) {
11657                 return sticky;
11658             }
11659 
11660             ReceiverList rl
11661                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11662             if (rl == null) {
11663                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11664                         userId, receiver);
11665                 if (rl.app != null) {
11666                     rl.app.receivers.add(rl);
11667                 } else {
11668                     try {
11669                         receiver.asBinder().linkToDeath(rl, 0);
11670                     } catch (RemoteException e) {
11671                         return sticky;
11672                     }
11673                     rl.linkedToDeath = true;
11674                 }
11675                 mRegisteredReceivers.put(receiver.asBinder(), rl);
11676             } else if (rl.uid != callingUid) {
11677                 throw new IllegalArgumentException(
11678                         "Receiver requested to register for uid " + callingUid
11679                         + " was previously registered for uid " + rl.uid);
11680             } else if (rl.pid != callingPid) {
11681                 throw new IllegalArgumentException(
11682                         "Receiver requested to register for pid " + callingPid
11683                         + " was previously registered for pid " + rl.pid);
11684             } else if (rl.userId != userId) {
11685                 throw new IllegalArgumentException(
11686                         "Receiver requested to register for user " + userId
11687                         + " was previously registered for user " + rl.userId);
11688             }
11689             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11690                     permission, callingUid, userId);
11691             rl.add(bf);
11692             if (!bf.debugCheck()) {
11693                 Slog.w(TAG, "==> For Dynamic broadast");
11694             }
11695             mReceiverResolver.addFilter(bf);
11696 
11697             // Enqueue broadcasts for all existing stickies that match
11698             // this filter.
11699             if (allSticky != null) {
11700                 ArrayList receivers = new ArrayList();
11701                 receivers.add(bf);
11702 
11703                 int N = allSticky.size();
11704                 for (int i=0; i<N; i++) {
11705                     Intent intent = (Intent)allSticky.get(i);
11706                     BroadcastQueue queue = broadcastQueueForIntent(intent);
11707                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11708                             null, -1, -1, null, AppOpsManager.OP_NONE, receivers, null, 0,
11709                             null, null, false, true, true, -1);
11710                     queue.enqueueParallelBroadcastLocked(r);
11711                     queue.scheduleBroadcastsLocked();
11712                 }
11713             }
11714 
11715             return sticky;
11716         }
11717     }
11718 
unregisterReceiver(IIntentReceiver receiver)11719     public void unregisterReceiver(IIntentReceiver receiver) {
11720         if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11721 
11722         final long origId = Binder.clearCallingIdentity();
11723         try {
11724             boolean doTrim = false;
11725 
11726             synchronized(this) {
11727                 ReceiverList rl
11728                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11729                 if (rl != null) {
11730                     if (rl.curBroadcast != null) {
11731                         BroadcastRecord r = rl.curBroadcast;
11732                         final boolean doNext = finishReceiverLocked(
11733                                 receiver.asBinder(), r.resultCode, r.resultData,
11734                                 r.resultExtras, r.resultAbort, true);
11735                         if (doNext) {
11736                             doTrim = true;
11737                             r.queue.processNextBroadcast(false);
11738                         }
11739                     }
11740 
11741                     if (rl.app != null) {
11742                         rl.app.receivers.remove(rl);
11743                     }
11744                     removeReceiverLocked(rl);
11745                     if (rl.linkedToDeath) {
11746                         rl.linkedToDeath = false;
11747                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
11748                     }
11749                 }
11750             }
11751 
11752             // If we actually concluded any broadcasts, we might now be able
11753             // to trim the recipients' apps from our working set
11754             if (doTrim) {
11755                 trimApplications();
11756                 return;
11757             }
11758 
11759         } finally {
11760             Binder.restoreCallingIdentity(origId);
11761         }
11762     }
11763 
removeReceiverLocked(ReceiverList rl)11764     void removeReceiverLocked(ReceiverList rl) {
11765         mRegisteredReceivers.remove(rl.receiver.asBinder());
11766         int N = rl.size();
11767         for (int i=0; i<N; i++) {
11768             mReceiverResolver.removeFilter(rl.get(i));
11769         }
11770     }
11771 
sendPackageBroadcastLocked(int cmd, String[] packages, int userId)11772     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
11773         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11774             ProcessRecord r = mLruProcesses.get(i);
11775             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
11776                 try {
11777                     r.thread.dispatchPackageBroadcast(cmd, packages);
11778                 } catch (RemoteException ex) {
11779                 }
11780             }
11781         }
11782     }
11783 
collectReceiverComponents(Intent intent, String resolvedType, int[] users)11784     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11785             int[] users) {
11786         List<ResolveInfo> receivers = null;
11787         try {
11788             HashSet<ComponentName> singleUserReceivers = null;
11789             boolean scannedFirstReceivers = false;
11790             for (int user : users) {
11791                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11792                         .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11793                 if (user != 0 && newReceivers != null) {
11794                     // If this is not the primary user, we need to check for
11795                     // any receivers that should be filtered out.
11796                     for (int i=0; i<newReceivers.size(); i++) {
11797                         ResolveInfo ri = newReceivers.get(i);
11798                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
11799                             newReceivers.remove(i);
11800                             i--;
11801                         }
11802                     }
11803                 }
11804                 if (newReceivers != null && newReceivers.size() == 0) {
11805                     newReceivers = null;
11806                 }
11807                 if (receivers == null) {
11808                     receivers = newReceivers;
11809                 } else if (newReceivers != null) {
11810                     // We need to concatenate the additional receivers
11811                     // found with what we have do far.  This would be easy,
11812                     // but we also need to de-dup any receivers that are
11813                     // singleUser.
11814                     if (!scannedFirstReceivers) {
11815                         // Collect any single user receivers we had already retrieved.
11816                         scannedFirstReceivers = true;
11817                         for (int i=0; i<receivers.size(); i++) {
11818                             ResolveInfo ri = receivers.get(i);
11819                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11820                                 ComponentName cn = new ComponentName(
11821                                         ri.activityInfo.packageName, ri.activityInfo.name);
11822                                 if (singleUserReceivers == null) {
11823                                     singleUserReceivers = new HashSet<ComponentName>();
11824                                 }
11825                                 singleUserReceivers.add(cn);
11826                             }
11827                         }
11828                     }
11829                     // Add the new results to the existing results, tracking
11830                     // and de-dupping single user receivers.
11831                     for (int i=0; i<newReceivers.size(); i++) {
11832                         ResolveInfo ri = newReceivers.get(i);
11833                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11834                             ComponentName cn = new ComponentName(
11835                                     ri.activityInfo.packageName, ri.activityInfo.name);
11836                             if (singleUserReceivers == null) {
11837                                 singleUserReceivers = new HashSet<ComponentName>();
11838                             }
11839                             if (!singleUserReceivers.contains(cn)) {
11840                                 singleUserReceivers.add(cn);
11841                                 receivers.add(ri);
11842                             }
11843                         } else {
11844                             receivers.add(ri);
11845                         }
11846                     }
11847                 }
11848             }
11849         } catch (RemoteException ex) {
11850             // pm is in same process, this will never happen.
11851         }
11852         return receivers;
11853     }
11854 
broadcastIntentLocked(ProcessRecord callerApp, String callerPackage, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String requiredPermission, int appOp, boolean ordered, boolean sticky, int callingPid, int callingUid, int userId)11855     private final int broadcastIntentLocked(ProcessRecord callerApp,
11856             String callerPackage, Intent intent, String resolvedType,
11857             IIntentReceiver resultTo, int resultCode, String resultData,
11858             Bundle map, String requiredPermission, int appOp,
11859             boolean ordered, boolean sticky, int callingPid, int callingUid,
11860             int userId) {
11861         intent = new Intent(intent);
11862 
11863         // By default broadcasts do not go to stopped apps.
11864         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11865 
11866         if (DEBUG_BROADCAST_LIGHT) Slog.v(
11867             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11868             + " ordered=" + ordered + " userid=" + userId);
11869         if ((resultTo != null) && !ordered) {
11870             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11871         }
11872 
11873         userId = handleIncomingUser(callingPid, callingUid, userId,
11874                 true, false, "broadcast", callerPackage);
11875 
11876         // Make sure that the user who is receiving this broadcast is started.
11877         // If not, we will just skip it.
11878         if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
11879             if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
11880                     & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
11881                 Slog.w(TAG, "Skipping broadcast of " + intent
11882                         + ": user " + userId + " is stopped");
11883                 return ActivityManager.BROADCAST_SUCCESS;
11884             }
11885         }
11886 
11887         /*
11888          * Prevent non-system code (defined here to be non-persistent
11889          * processes) from sending protected broadcasts.
11890          */
11891         int callingAppId = UserHandle.getAppId(callingUid);
11892         if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
11893             || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
11894             callingUid == 0) {
11895             // Always okay.
11896         } else if (callerApp == null || !callerApp.persistent) {
11897             try {
11898                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
11899                         intent.getAction())) {
11900                     String msg = "Permission Denial: not allowed to send broadcast "
11901                             + intent.getAction() + " from pid="
11902                             + callingPid + ", uid=" + callingUid;
11903                     Slog.w(TAG, msg);
11904                     throw new SecurityException(msg);
11905                 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
11906                     // Special case for compatibility: we don't want apps to send this,
11907                     // but historically it has not been protected and apps may be using it
11908                     // to poke their own app widget.  So, instead of making it protected,
11909                     // just limit it to the caller.
11910                     if (callerApp == null) {
11911                         String msg = "Permission Denial: not allowed to send broadcast "
11912                                 + intent.getAction() + " from unknown caller.";
11913                         Slog.w(TAG, msg);
11914                         throw new SecurityException(msg);
11915                     } else if (intent.getComponent() != null) {
11916                         // They are good enough to send to an explicit component...  verify
11917                         // it is being sent to the calling app.
11918                         if (!intent.getComponent().getPackageName().equals(
11919                                 callerApp.info.packageName)) {
11920                             String msg = "Permission Denial: not allowed to send broadcast "
11921                                     + intent.getAction() + " to "
11922                                     + intent.getComponent().getPackageName() + " from "
11923                                     + callerApp.info.packageName;
11924                             Slog.w(TAG, msg);
11925                             throw new SecurityException(msg);
11926                         }
11927                     } else {
11928                         // Limit broadcast to their own package.
11929                         intent.setPackage(callerApp.info.packageName);
11930                     }
11931                 }
11932             } catch (RemoteException e) {
11933                 Slog.w(TAG, "Remote exception", e);
11934                 return ActivityManager.BROADCAST_SUCCESS;
11935             }
11936         }
11937 
11938         // Handle special intents: if this broadcast is from the package
11939         // manager about a package being removed, we need to remove all of
11940         // its activities from the history stack.
11941         final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11942                 intent.getAction());
11943         if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11944                 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11945                 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11946                 || uidRemoved) {
11947             if (checkComponentPermission(
11948                     android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11949                     callingPid, callingUid, -1, true)
11950                     == PackageManager.PERMISSION_GRANTED) {
11951                 if (uidRemoved) {
11952                     final Bundle intentExtras = intent.getExtras();
11953                     final int uid = intentExtras != null
11954                             ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11955                     if (uid >= 0) {
11956                         BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11957                         synchronized (bs) {
11958                             bs.removeUidStatsLocked(uid);
11959                         }
11960                         mAppOpsService.uidRemoved(uid);
11961                     }
11962                 } else {
11963                     // If resources are unavailable just force stop all
11964                     // those packages and flush the attribute cache as well.
11965                     if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11966                         String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11967                         if (list != null && (list.length > 0)) {
11968                             for (String pkg : list) {
11969                                 forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11970                             }
11971                             sendPackageBroadcastLocked(
11972                                     IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
11973                         }
11974                     } else {
11975                         Uri data = intent.getData();
11976                         String ssp;
11977                         if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11978                             if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11979                                 forceStopPackageLocked(ssp,
11980                                         intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11981                                         false, userId);
11982                             }
11983                             if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11984                                 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11985                                         new String[] {ssp}, userId);
11986                                 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
11987                                     mAppOpsService.packageRemoved(
11988                                             intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
11989                                 }
11990                             }
11991                         }
11992                     }
11993                 }
11994             } else {
11995                 String msg = "Permission Denial: " + intent.getAction()
11996                         + " broadcast from " + callerPackage + " (pid=" + callingPid
11997                         + ", uid=" + callingUid + ")"
11998                         + " requires "
11999                         + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
12000                 Slog.w(TAG, msg);
12001                 throw new SecurityException(msg);
12002             }
12003 
12004         // Special case for adding a package: by default turn on compatibility
12005         // mode.
12006         } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
12007             Uri data = intent.getData();
12008             String ssp;
12009             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12010                 mCompatModePackages.handlePackageAddedLocked(ssp,
12011                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
12012             }
12013         }
12014 
12015         /*
12016          * If this is the time zone changed action, queue up a message that will reset the timezone
12017          * of all currently running processes. This message will get queued up before the broadcast
12018          * happens.
12019          */
12020         if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
12021             mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
12022         }
12023 
12024         if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
12025             mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
12026         }
12027 
12028         if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
12029             ProxyProperties proxy = intent.getParcelableExtra("proxy");
12030             mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
12031         }
12032 
12033         // Add to the sticky list if requested.
12034         if (sticky) {
12035             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
12036                     callingPid, callingUid)
12037                     != PackageManager.PERMISSION_GRANTED) {
12038                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
12039                         + callingPid + ", uid=" + callingUid
12040                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
12041                 Slog.w(TAG, msg);
12042                 throw new SecurityException(msg);
12043             }
12044             if (requiredPermission != null) {
12045                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
12046                         + " and enforce permission " + requiredPermission);
12047                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
12048             }
12049             if (intent.getComponent() != null) {
12050                 throw new SecurityException(
12051                         "Sticky broadcasts can't target a specific component");
12052             }
12053             // We use userId directly here, since the "all" target is maintained
12054             // as a separate set of sticky broadcasts.
12055             if (userId != UserHandle.USER_ALL) {
12056                 // But first, if this is not a broadcast to all users, then
12057                 // make sure it doesn't conflict with an existing broadcast to
12058                 // all users.
12059                 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
12060                         UserHandle.USER_ALL);
12061                 if (stickies != null) {
12062                     ArrayList<Intent> list = stickies.get(intent.getAction());
12063                     if (list != null) {
12064                         int N = list.size();
12065                         int i;
12066                         for (i=0; i<N; i++) {
12067                             if (intent.filterEquals(list.get(i))) {
12068                                 throw new IllegalArgumentException(
12069                                         "Sticky broadcast " + intent + " for user "
12070                                         + userId + " conflicts with existing global broadcast");
12071                             }
12072                         }
12073                     }
12074                 }
12075             }
12076             HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12077             if (stickies == null) {
12078                 stickies = new HashMap<String, ArrayList<Intent>>();
12079                 mStickyBroadcasts.put(userId, stickies);
12080             }
12081             ArrayList<Intent> list = stickies.get(intent.getAction());
12082             if (list == null) {
12083                 list = new ArrayList<Intent>();
12084                 stickies.put(intent.getAction(), list);
12085             }
12086             int N = list.size();
12087             int i;
12088             for (i=0; i<N; i++) {
12089                 if (intent.filterEquals(list.get(i))) {
12090                     // This sticky already exists, replace it.
12091                     list.set(i, new Intent(intent));
12092                     break;
12093                 }
12094             }
12095             if (i >= N) {
12096                 list.add(new Intent(intent));
12097             }
12098         }
12099 
12100         int[] users;
12101         if (userId == UserHandle.USER_ALL) {
12102             // Caller wants broadcast to go to all started users.
12103             users = mStartedUserArray;
12104         } else {
12105             // Caller wants broadcast to go to one specific user.
12106             users = new int[] {userId};
12107         }
12108 
12109         // Figure out who all will receive this broadcast.
12110         List receivers = null;
12111         List<BroadcastFilter> registeredReceivers = null;
12112         // Need to resolve the intent to interested receivers...
12113         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
12114                  == 0) {
12115             receivers = collectReceiverComponents(intent, resolvedType, users);
12116         }
12117         if (intent.getComponent() == null) {
12118             registeredReceivers = mReceiverResolver.queryIntent(intent,
12119                     resolvedType, false, userId);
12120         }
12121 
12122         final boolean replacePending =
12123                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
12124 
12125         if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
12126                 + " replacePending=" + replacePending);
12127 
12128         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
12129         if (!ordered && NR > 0) {
12130             // If we are not serializing this broadcast, then send the
12131             // registered receivers separately so they don't wait for the
12132             // components to be launched.
12133             final BroadcastQueue queue = broadcastQueueForIntent(intent);
12134             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
12135                     callerPackage, callingPid, callingUid, requiredPermission, appOp,
12136                     registeredReceivers, resultTo, resultCode, resultData, map,
12137                     ordered, sticky, false, userId);
12138             if (DEBUG_BROADCAST) Slog.v(
12139                     TAG, "Enqueueing parallel broadcast " + r);
12140             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
12141             if (!replaced) {
12142                 queue.enqueueParallelBroadcastLocked(r);
12143                 queue.scheduleBroadcastsLocked();
12144             }
12145             registeredReceivers = null;
12146             NR = 0;
12147         }
12148 
12149         // Merge into one list.
12150         int ir = 0;
12151         if (receivers != null) {
12152             // A special case for PACKAGE_ADDED: do not allow the package
12153             // being added to see this broadcast.  This prevents them from
12154             // using this as a back door to get run as soon as they are
12155             // installed.  Maybe in the future we want to have a special install
12156             // broadcast or such for apps, but we'd like to deliberately make
12157             // this decision.
12158             String skipPackages[] = null;
12159             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
12160                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
12161                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
12162                 Uri data = intent.getData();
12163                 if (data != null) {
12164                     String pkgName = data.getSchemeSpecificPart();
12165                     if (pkgName != null) {
12166                         skipPackages = new String[] { pkgName };
12167                     }
12168                 }
12169             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
12170                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
12171             }
12172             if (skipPackages != null && (skipPackages.length > 0)) {
12173                 for (String skipPackage : skipPackages) {
12174                     if (skipPackage != null) {
12175                         int NT = receivers.size();
12176                         for (int it=0; it<NT; it++) {
12177                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
12178                             if (curt.activityInfo.packageName.equals(skipPackage)) {
12179                                 receivers.remove(it);
12180                                 it--;
12181                                 NT--;
12182                             }
12183                         }
12184                     }
12185                 }
12186             }
12187 
12188             int NT = receivers != null ? receivers.size() : 0;
12189             int it = 0;
12190             ResolveInfo curt = null;
12191             BroadcastFilter curr = null;
12192             while (it < NT && ir < NR) {
12193                 if (curt == null) {
12194                     curt = (ResolveInfo)receivers.get(it);
12195                 }
12196                 if (curr == null) {
12197                     curr = registeredReceivers.get(ir);
12198                 }
12199                 if (curr.getPriority() >= curt.priority) {
12200                     // Insert this broadcast record into the final list.
12201                     receivers.add(it, curr);
12202                     ir++;
12203                     curr = null;
12204                     it++;
12205                     NT++;
12206                 } else {
12207                     // Skip to the next ResolveInfo in the final list.
12208                     it++;
12209                     curt = null;
12210                 }
12211             }
12212         }
12213         while (ir < NR) {
12214             if (receivers == null) {
12215                 receivers = new ArrayList();
12216             }
12217             receivers.add(registeredReceivers.get(ir));
12218             ir++;
12219         }
12220 
12221         if ((receivers != null && receivers.size() > 0)
12222                 || resultTo != null) {
12223             BroadcastQueue queue = broadcastQueueForIntent(intent);
12224             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
12225                     callerPackage, callingPid, callingUid, requiredPermission, appOp,
12226                     receivers, resultTo, resultCode, resultData, map, ordered,
12227                     sticky, false, userId);
12228             if (DEBUG_BROADCAST) Slog.v(
12229                     TAG, "Enqueueing ordered broadcast " + r
12230                     + ": prev had " + queue.mOrderedBroadcasts.size());
12231             if (DEBUG_BROADCAST) {
12232                 int seq = r.intent.getIntExtra("seq", -1);
12233                 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
12234             }
12235             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
12236             if (!replaced) {
12237                 queue.enqueueOrderedBroadcastLocked(r);
12238                 queue.scheduleBroadcastsLocked();
12239             }
12240         }
12241 
12242         return ActivityManager.BROADCAST_SUCCESS;
12243     }
12244 
verifyBroadcastLocked(Intent intent)12245     final Intent verifyBroadcastLocked(Intent intent) {
12246         // Refuse possible leaked file descriptors
12247         if (intent != null && intent.hasFileDescriptors() == true) {
12248             throw new IllegalArgumentException("File descriptors passed in Intent");
12249         }
12250 
12251         int flags = intent.getFlags();
12252 
12253         if (!mProcessesReady) {
12254             // if the caller really truly claims to know what they're doing, go
12255             // ahead and allow the broadcast without launching any receivers
12256             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
12257                 intent = new Intent(intent);
12258                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12259             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
12260                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
12261                         + " before boot completion");
12262                 throw new IllegalStateException("Cannot broadcast before boot completed");
12263             }
12264         }
12265 
12266         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
12267             throw new IllegalArgumentException(
12268                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
12269         }
12270 
12271         return intent;
12272     }
12273 
broadcastIntent(IApplicationThread caller, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId)12274     public final int broadcastIntent(IApplicationThread caller,
12275             Intent intent, String resolvedType, IIntentReceiver resultTo,
12276             int resultCode, String resultData, Bundle map,
12277             String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
12278         enforceNotIsolatedCaller("broadcastIntent");
12279         synchronized(this) {
12280             intent = verifyBroadcastLocked(intent);
12281 
12282             final ProcessRecord callerApp = getRecordForAppLocked(caller);
12283             final int callingPid = Binder.getCallingPid();
12284             final int callingUid = Binder.getCallingUid();
12285             final long origId = Binder.clearCallingIdentity();
12286             int res = broadcastIntentLocked(callerApp,
12287                     callerApp != null ? callerApp.info.packageName : null,
12288                     intent, resolvedType, resultTo,
12289                     resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
12290                     callingPid, callingUid, userId);
12291             Binder.restoreCallingIdentity(origId);
12292             return res;
12293         }
12294     }
12295 
broadcastIntentInPackage(String packageName, int uid, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String requiredPermission, boolean serialized, boolean sticky, int userId)12296     int broadcastIntentInPackage(String packageName, int uid,
12297             Intent intent, String resolvedType, IIntentReceiver resultTo,
12298             int resultCode, String resultData, Bundle map,
12299             String requiredPermission, boolean serialized, boolean sticky, int userId) {
12300         synchronized(this) {
12301             intent = verifyBroadcastLocked(intent);
12302 
12303             final long origId = Binder.clearCallingIdentity();
12304             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
12305                     resultTo, resultCode, resultData, map, requiredPermission,
12306                     AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
12307             Binder.restoreCallingIdentity(origId);
12308             return res;
12309         }
12310     }
12311 
unbroadcastIntent(IApplicationThread caller, Intent intent, int userId)12312     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
12313         // Refuse possible leaked file descriptors
12314         if (intent != null && intent.hasFileDescriptors() == true) {
12315             throw new IllegalArgumentException("File descriptors passed in Intent");
12316         }
12317 
12318         userId = handleIncomingUser(Binder.getCallingPid(),
12319                 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
12320 
12321         synchronized(this) {
12322             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
12323                     != PackageManager.PERMISSION_GRANTED) {
12324                 String msg = "Permission Denial: unbroadcastIntent() from pid="
12325                         + Binder.getCallingPid()
12326                         + ", uid=" + Binder.getCallingUid()
12327                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
12328                 Slog.w(TAG, msg);
12329                 throw new SecurityException(msg);
12330             }
12331             HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12332             if (stickies != null) {
12333                 ArrayList<Intent> list = stickies.get(intent.getAction());
12334                 if (list != null) {
12335                     int N = list.size();
12336                     int i;
12337                     for (i=0; i<N; i++) {
12338                         if (intent.filterEquals(list.get(i))) {
12339                             list.remove(i);
12340                             break;
12341                         }
12342                     }
12343                     if (list.size() <= 0) {
12344                         stickies.remove(intent.getAction());
12345                     }
12346                 }
12347                 if (stickies.size() <= 0) {
12348                     mStickyBroadcasts.remove(userId);
12349                 }
12350             }
12351         }
12352     }
12353 
finishReceiverLocked(IBinder receiver, int resultCode, String resultData, Bundle resultExtras, boolean resultAbort, boolean explicit)12354     private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12355             String resultData, Bundle resultExtras, boolean resultAbort,
12356             boolean explicit) {
12357         final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
12358         if (r == null) {
12359             Slog.w(TAG, "finishReceiver called but not found on queue");
12360             return false;
12361         }
12362 
12363         return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
12364                 explicit);
12365     }
12366 
finishReceiver(IBinder who, int resultCode, String resultData, Bundle resultExtras, boolean resultAbort)12367     public void finishReceiver(IBinder who, int resultCode, String resultData,
12368             Bundle resultExtras, boolean resultAbort) {
12369         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
12370 
12371         // Refuse possible leaked file descriptors
12372         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12373             throw new IllegalArgumentException("File descriptors passed in Bundle");
12374         }
12375 
12376         final long origId = Binder.clearCallingIdentity();
12377         try {
12378             boolean doNext = false;
12379             BroadcastRecord r = null;
12380 
12381             synchronized(this) {
12382                 r = broadcastRecordForReceiverLocked(who);
12383                 if (r != null) {
12384                     doNext = r.queue.finishReceiverLocked(r, resultCode,
12385                         resultData, resultExtras, resultAbort, true);
12386                 }
12387             }
12388 
12389             if (doNext) {
12390                 r.queue.processNextBroadcast(false);
12391             }
12392             trimApplications();
12393         } finally {
12394             Binder.restoreCallingIdentity(origId);
12395         }
12396     }
12397 
12398     // =========================================================
12399     // INSTRUMENTATION
12400     // =========================================================
12401 
startInstrumentation(ComponentName className, String profileFile, int flags, Bundle arguments, IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, int userId)12402     public boolean startInstrumentation(ComponentName className,
12403             String profileFile, int flags, Bundle arguments,
12404             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
12405             int userId) {
12406         enforceNotIsolatedCaller("startInstrumentation");
12407         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12408                 userId, false, true, "startInstrumentation", null);
12409         // Refuse possible leaked file descriptors
12410         if (arguments != null && arguments.hasFileDescriptors()) {
12411             throw new IllegalArgumentException("File descriptors passed in Bundle");
12412         }
12413 
12414         synchronized(this) {
12415             InstrumentationInfo ii = null;
12416             ApplicationInfo ai = null;
12417             try {
12418                 ii = mContext.getPackageManager().getInstrumentationInfo(
12419                     className, STOCK_PM_FLAGS);
12420                 ai = AppGlobals.getPackageManager().getApplicationInfo(
12421                         ii.targetPackage, STOCK_PM_FLAGS, userId);
12422             } catch (PackageManager.NameNotFoundException e) {
12423             } catch (RemoteException e) {
12424             }
12425             if (ii == null) {
12426                 reportStartInstrumentationFailure(watcher, className,
12427                         "Unable to find instrumentation info for: " + className);
12428                 return false;
12429             }
12430             if (ai == null) {
12431                 reportStartInstrumentationFailure(watcher, className,
12432                         "Unable to find instrumentation target package: " + ii.targetPackage);
12433                 return false;
12434             }
12435 
12436             int match = mContext.getPackageManager().checkSignatures(
12437                     ii.targetPackage, ii.packageName);
12438             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12439                 String msg = "Permission Denial: starting instrumentation "
12440                         + className + " from pid="
12441                         + Binder.getCallingPid()
12442                         + ", uid=" + Binder.getCallingPid()
12443                         + " not allowed because package " + ii.packageName
12444                         + " does not have a signature matching the target "
12445                         + ii.targetPackage;
12446                 reportStartInstrumentationFailure(watcher, className, msg);
12447                 throw new SecurityException(msg);
12448             }
12449 
12450             final long origId = Binder.clearCallingIdentity();
12451             // Instrumentation can kill and relaunch even persistent processes
12452             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
12453             ProcessRecord app = addAppLocked(ai, false);
12454             app.instrumentationClass = className;
12455             app.instrumentationInfo = ai;
12456             app.instrumentationProfileFile = profileFile;
12457             app.instrumentationArguments = arguments;
12458             app.instrumentationWatcher = watcher;
12459             app.instrumentationUiAutomationConnection = uiAutomationConnection;
12460             app.instrumentationResultClass = className;
12461             Binder.restoreCallingIdentity(origId);
12462         }
12463 
12464         return true;
12465     }
12466 
12467     /**
12468      * Report errors that occur while attempting to start Instrumentation.  Always writes the
12469      * error to the logs, but if somebody is watching, send the report there too.  This enables
12470      * the "am" command to report errors with more information.
12471      *
12472      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12473      * @param cn The component name of the instrumentation.
12474      * @param report The error report.
12475      */
reportStartInstrumentationFailure(IInstrumentationWatcher watcher, ComponentName cn, String report)12476     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12477             ComponentName cn, String report) {
12478         Slog.w(TAG, report);
12479         try {
12480             if (watcher != null) {
12481                 Bundle results = new Bundle();
12482                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12483                 results.putString("Error", report);
12484                 watcher.instrumentationStatus(cn, -1, results);
12485             }
12486         } catch (RemoteException e) {
12487             Slog.w(TAG, e);
12488         }
12489     }
12490 
finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results)12491     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12492         if (app.instrumentationWatcher != null) {
12493             try {
12494                 // NOTE:  IInstrumentationWatcher *must* be oneway here
12495                 app.instrumentationWatcher.instrumentationFinished(
12496                     app.instrumentationClass,
12497                     resultCode,
12498                     results);
12499             } catch (RemoteException e) {
12500             }
12501         }
12502         if (app.instrumentationUiAutomationConnection != null) {
12503             try {
12504                 app.instrumentationUiAutomationConnection.shutdown();
12505             } catch (RemoteException re) {
12506                 /* ignore */
12507             }
12508             // Only a UiAutomation can set this flag and now that
12509             // it is finished we make sure it is reset to its default.
12510             mUserIsMonkey = false;
12511         }
12512         app.instrumentationWatcher = null;
12513         app.instrumentationUiAutomationConnection = null;
12514         app.instrumentationClass = null;
12515         app.instrumentationInfo = null;
12516         app.instrumentationProfileFile = null;
12517         app.instrumentationArguments = null;
12518 
12519         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
12520     }
12521 
finishInstrumentation(IApplicationThread target, int resultCode, Bundle results)12522     public void finishInstrumentation(IApplicationThread target,
12523             int resultCode, Bundle results) {
12524         int userId = UserHandle.getCallingUserId();
12525         // Refuse possible leaked file descriptors
12526         if (results != null && results.hasFileDescriptors()) {
12527             throw new IllegalArgumentException("File descriptors passed in Intent");
12528         }
12529 
12530         synchronized(this) {
12531             ProcessRecord app = getRecordForAppLocked(target);
12532             if (app == null) {
12533                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
12534                 return;
12535             }
12536             final long origId = Binder.clearCallingIdentity();
12537             finishInstrumentationLocked(app, resultCode, results);
12538             Binder.restoreCallingIdentity(origId);
12539         }
12540     }
12541 
12542     // =========================================================
12543     // CONFIGURATION
12544     // =========================================================
12545 
getDeviceConfigurationInfo()12546     public ConfigurationInfo getDeviceConfigurationInfo() {
12547         ConfigurationInfo config = new ConfigurationInfo();
12548         synchronized (this) {
12549             config.reqTouchScreen = mConfiguration.touchscreen;
12550             config.reqKeyboardType = mConfiguration.keyboard;
12551             config.reqNavigation = mConfiguration.navigation;
12552             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12553                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12554                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12555             }
12556             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12557                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12558                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12559             }
12560             config.reqGlEsVersion = GL_ES_VERSION;
12561         }
12562         return config;
12563     }
12564 
getConfiguration()12565     public Configuration getConfiguration() {
12566         Configuration ci;
12567         synchronized(this) {
12568             ci = new Configuration(mConfiguration);
12569         }
12570         return ci;
12571     }
12572 
updatePersistentConfiguration(Configuration values)12573     public void updatePersistentConfiguration(Configuration values) {
12574         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12575                 "updateConfiguration()");
12576         enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12577                 "updateConfiguration()");
12578         if (values == null) {
12579             throw new NullPointerException("Configuration must not be null");
12580         }
12581 
12582         synchronized(this) {
12583             final long origId = Binder.clearCallingIdentity();
12584             updateConfigurationLocked(values, null, true, false);
12585             Binder.restoreCallingIdentity(origId);
12586         }
12587     }
12588 
updateConfiguration(Configuration values)12589     public void updateConfiguration(Configuration values) {
12590         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12591                 "updateConfiguration()");
12592 
12593         synchronized(this) {
12594             if (values == null && mWindowManager != null) {
12595                 // sentinel: fetch the current configuration from the window manager
12596                 values = mWindowManager.computeNewConfiguration();
12597             }
12598 
12599             if (mWindowManager != null) {
12600                 mProcessList.applyDisplaySize(mWindowManager);
12601             }
12602 
12603             final long origId = Binder.clearCallingIdentity();
12604             if (values != null) {
12605                 Settings.System.clearConfiguration(values);
12606             }
12607             updateConfigurationLocked(values, null, false, false);
12608             Binder.restoreCallingIdentity(origId);
12609         }
12610     }
12611 
12612     /**
12613      * Do either or both things: (1) change the current configuration, and (2)
12614      * make sure the given activity is running with the (now) current
12615      * configuration.  Returns true if the activity has been left running, or
12616      * false if <var>starting</var> is being destroyed to match the new
12617      * configuration.
12618      * @param persistent TODO
12619      */
updateConfigurationLocked(Configuration values, ActivityRecord starting, boolean persistent, boolean initLocale)12620     boolean updateConfigurationLocked(Configuration values,
12621             ActivityRecord starting, boolean persistent, boolean initLocale) {
12622         // do nothing if we are headless
12623         if (mHeadless) return true;
12624 
12625         int changes = 0;
12626 
12627         boolean kept = true;
12628 
12629         if (values != null) {
12630             Configuration newConfig = new Configuration(mConfiguration);
12631             changes = newConfig.updateFrom(values);
12632             if (changes != 0) {
12633                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12634                     Slog.i(TAG, "Updating configuration to: " + values);
12635                 }
12636 
12637                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12638 
12639                 if (values.locale != null && !initLocale) {
12640                     saveLocaleLocked(values.locale,
12641                                      !values.locale.equals(mConfiguration.locale),
12642                                      values.userSetLocale);
12643                 }
12644 
12645                 mConfigurationSeq++;
12646                 if (mConfigurationSeq <= 0) {
12647                     mConfigurationSeq = 1;
12648                 }
12649                 newConfig.seq = mConfigurationSeq;
12650                 mConfiguration = newConfig;
12651                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
12652 
12653                 final Configuration configCopy = new Configuration(mConfiguration);
12654 
12655                 // TODO: If our config changes, should we auto dismiss any currently
12656                 // showing dialogs?
12657                 mShowDialogs = shouldShowDialogs(newConfig);
12658 
12659                 AttributeCache ac = AttributeCache.instance();
12660                 if (ac != null) {
12661                     ac.updateConfiguration(configCopy);
12662                 }
12663 
12664                 // Make sure all resources in our process are updated
12665                 // right now, so that anyone who is going to retrieve
12666                 // resource values after we return will be sure to get
12667                 // the new ones.  This is especially important during
12668                 // boot, where the first config change needs to guarantee
12669                 // all resources have that config before following boot
12670                 // code is executed.
12671                 mSystemThread.applyConfigurationToResources(configCopy);
12672 
12673                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
12674                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12675                     msg.obj = new Configuration(configCopy);
12676                     mHandler.sendMessage(msg);
12677                 }
12678 
12679                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12680                     ProcessRecord app = mLruProcesses.get(i);
12681                     try {
12682                         if (app.thread != null) {
12683                             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12684                                     + app.processName + " new config " + mConfiguration);
12685                             app.thread.scheduleConfigurationChanged(configCopy);
12686                         }
12687                     } catch (Exception e) {
12688                     }
12689                 }
12690                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12691                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12692                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
12693                         | Intent.FLAG_RECEIVER_FOREGROUND);
12694                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12695                         null, AppOpsManager.OP_NONE, false, false, MY_PID,
12696                         Process.SYSTEM_UID, UserHandle.USER_ALL);
12697                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12698                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
12699                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12700                     broadcastIntentLocked(null, null, intent,
12701                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12702                             false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12703                 }
12704             }
12705         }
12706 
12707         if (changes != 0 && starting == null) {
12708             // If the configuration changed, and the caller is not already
12709             // in the process of starting an activity, then find the top
12710             // activity to check if its configuration needs to change.
12711             starting = mMainStack.topRunningActivityLocked(null);
12712         }
12713 
12714         if (starting != null) {
12715             kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12716             // And we need to make sure at this point that all other activities
12717             // are made visible with the correct configuration.
12718             mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12719         }
12720 
12721         if (values != null && mWindowManager != null) {
12722             mWindowManager.setNewConfiguration(mConfiguration);
12723         }
12724 
12725         return kept;
12726     }
12727 
12728     /**
12729      * Decide based on the configuration whether we should shouw the ANR,
12730      * crash, etc dialogs.  The idea is that if there is no affordnace to
12731      * press the on-screen buttons, we shouldn't show the dialog.
12732      *
12733      * A thought: SystemUI might also want to get told about this, the Power
12734      * dialog / global actions also might want different behaviors.
12735      */
shouldShowDialogs(Configuration config)12736     private static final boolean shouldShowDialogs(Configuration config) {
12737         return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12738                 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12739     }
12740 
12741     /**
12742      * Save the locale.  You must be inside a synchronized (this) block.
12743      */
saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist)12744     private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12745         if(isDiff) {
12746             SystemProperties.set("user.language", l.getLanguage());
12747             SystemProperties.set("user.region", l.getCountry());
12748         }
12749 
12750         if(isPersist) {
12751             SystemProperties.set("persist.sys.language", l.getLanguage());
12752             SystemProperties.set("persist.sys.country", l.getCountry());
12753             SystemProperties.set("persist.sys.localevar", l.getVariant());
12754         }
12755     }
12756 
12757     @Override
targetTaskAffinityMatchesActivity(IBinder token, String destAffinity)12758     public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12759         ActivityRecord srec = ActivityRecord.forToken(token);
12760         return srec != null && srec.task.affinity != null &&
12761                 srec.task.affinity.equals(destAffinity);
12762     }
12763 
navigateUpTo(IBinder token, Intent destIntent, int resultCode, Intent resultData)12764     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12765             Intent resultData) {
12766         ComponentName dest = destIntent.getComponent();
12767 
12768         synchronized (this) {
12769             ActivityRecord srec = ActivityRecord.forToken(token);
12770             if (srec == null) {
12771                 return false;
12772             }
12773             ArrayList<ActivityRecord> history = srec.stack.mHistory;
12774             final int start = history.indexOf(srec);
12775             if (start < 0) {
12776                 // Current activity is not in history stack; do nothing.
12777                 return false;
12778             }
12779             int finishTo = start - 1;
12780             ActivityRecord parent = null;
12781             boolean foundParentInTask = false;
12782             if (dest != null) {
12783                 TaskRecord tr = srec.task;
12784                 for (int i = start - 1; i >= 0; i--) {
12785                     ActivityRecord r = history.get(i);
12786                     if (tr != r.task) {
12787                         // Couldn't find parent in the same task; stop at the one above this.
12788                         // (Root of current task; in-app "home" behavior)
12789                         // Always at least finish the current activity.
12790                         finishTo = Math.min(start - 1, i + 1);
12791                         parent = history.get(finishTo);
12792                         break;
12793                     } else if (r.info.packageName.equals(dest.getPackageName()) &&
12794                             r.info.name.equals(dest.getClassName())) {
12795                         finishTo = i;
12796                         parent = r;
12797                         foundParentInTask = true;
12798                         break;
12799                     }
12800                 }
12801             }
12802 
12803             if (mController != null) {
12804                 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12805                 if (next != null) {
12806                     // ask watcher if this is allowed
12807                     boolean resumeOK = true;
12808                     try {
12809                         resumeOK = mController.activityResuming(next.packageName);
12810                     } catch (RemoteException e) {
12811                         mController = null;
12812                         Watchdog.getInstance().setActivityController(null);
12813                     }
12814 
12815                     if (!resumeOK) {
12816                         return false;
12817                     }
12818                 }
12819             }
12820             final long origId = Binder.clearCallingIdentity();
12821             for (int i = start; i > finishTo; i--) {
12822                 ActivityRecord r = history.get(i);
12823                 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12824                         "navigate-up", true);
12825                 // Only return the supplied result for the first activity finished
12826                 resultCode = Activity.RESULT_CANCELED;
12827                 resultData = null;
12828             }
12829 
12830             if (parent != null && foundParentInTask) {
12831                 final int parentLaunchMode = parent.info.launchMode;
12832                 final int destIntentFlags = destIntent.getFlags();
12833                 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12834                         parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12835                         parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12836                         (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12837                     parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12838                 } else {
12839                     try {
12840                         ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12841                                 destIntent.getComponent(), 0, srec.userId);
12842                         int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12843                                 null, aInfo, parent.appToken, null,
12844                                 0, -1, parent.launchedFromUid, parent.launchedFromPackage,
12845                                 0, null, true, null);
12846                         foundParentInTask = res == ActivityManager.START_SUCCESS;
12847                     } catch (RemoteException e) {
12848                         foundParentInTask = false;
12849                     }
12850                     mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12851                             resultData, "navigate-up", true);
12852                 }
12853             }
12854             Binder.restoreCallingIdentity(origId);
12855             return foundParentInTask;
12856         }
12857     }
12858 
getLaunchedFromUid(IBinder activityToken)12859     public int getLaunchedFromUid(IBinder activityToken) {
12860         ActivityRecord srec = ActivityRecord.forToken(activityToken);
12861         if (srec == null) {
12862             return -1;
12863         }
12864         return srec.launchedFromUid;
12865     }
12866 
getLaunchedFromPackage(IBinder activityToken)12867     public String getLaunchedFromPackage(IBinder activityToken) {
12868         ActivityRecord srec = ActivityRecord.forToken(activityToken);
12869         if (srec == null) {
12870             return null;
12871         }
12872         return srec.launchedFromPackage;
12873     }
12874 
12875     // =========================================================
12876     // LIFETIME MANAGEMENT
12877     // =========================================================
12878 
12879     // Returns which broadcast queue the app is the current [or imminent] receiver
12880     // on, or 'null' if the app is not an active broadcast recipient.
isReceivingBroadcast(ProcessRecord app)12881     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12882         BroadcastRecord r = app.curReceiver;
12883         if (r != null) {
12884             return r.queue;
12885         }
12886 
12887         // It's not the current receiver, but it might be starting up to become one
12888         synchronized (this) {
12889             for (BroadcastQueue queue : mBroadcastQueues) {
12890                 r = queue.mPendingBroadcast;
12891                 if (r != null && r.curApp == app) {
12892                     // found it; report which queue it's in
12893                     return queue;
12894                 }
12895             }
12896         }
12897 
12898         return null;
12899     }
12900 
computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll)12901     private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj,
12902             int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12903         if (mAdjSeq == app.adjSeq) {
12904             // This adjustment has already been computed.  If we are calling
12905             // from the top, we may have already computed our adjustment with
12906             // an earlier hidden adjustment that isn't really for us... if
12907             // so, use the new hidden adjustment.
12908             if (!recursed && app.hidden) {
12909                 if (app.hasActivities) {
12910                     app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
12911                 } else if (app.hasClientActivities) {
12912                     app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj;
12913                 } else {
12914                     app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj;
12915                 }
12916             }
12917             return app.curRawAdj;
12918         }
12919 
12920         if (app.thread == null) {
12921             app.adjSeq = mAdjSeq;
12922             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12923             return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12924         }
12925 
12926         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12927         app.adjSource = null;
12928         app.adjTarget = null;
12929         app.empty = false;
12930         app.hidden = false;
12931         app.hasClientActivities = false;
12932 
12933         final int activitiesSize = app.activities.size();
12934 
12935         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12936             // The max adjustment doesn't allow this app to be anything
12937             // below foreground, so it is not worth doing work for it.
12938             app.adjType = "fixed";
12939             app.adjSeq = mAdjSeq;
12940             app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12941             app.hasActivities = false;
12942             app.foregroundActivities = false;
12943             app.keeping = true;
12944             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12945             // System process can do UI, and when they do we want to have
12946             // them trim their memory after the user leaves the UI.  To
12947             // facilitate this, here we need to determine whether or not it
12948             // is currently showing UI.
12949             app.systemNoUi = true;
12950             if (app == TOP_APP) {
12951                 app.systemNoUi = false;
12952                 app.hasActivities = true;
12953             } else if (activitiesSize > 0) {
12954                 for (int j = 0; j < activitiesSize; j++) {
12955                     final ActivityRecord r = app.activities.get(j);
12956                     if (r.visible) {
12957                         app.systemNoUi = false;
12958                     }
12959                     if (r.app == app) {
12960                         app.hasActivities = true;
12961                     }
12962                 }
12963             }
12964             return (app.curAdj=app.maxAdj);
12965         }
12966 
12967         app.keeping = false;
12968         app.systemNoUi = false;
12969         app.hasActivities = false;
12970 
12971         // Determine the importance of the process, starting with most
12972         // important to least, and assign an appropriate OOM adjustment.
12973         int adj;
12974         int schedGroup;
12975         boolean foregroundActivities = false;
12976         boolean interesting = false;
12977         BroadcastQueue queue;
12978         if (app == TOP_APP) {
12979             // The last app on the list is the foreground app.
12980             adj = ProcessList.FOREGROUND_APP_ADJ;
12981             schedGroup = Process.THREAD_GROUP_DEFAULT;
12982             app.adjType = "top-activity";
12983             foregroundActivities = true;
12984             interesting = true;
12985             app.hasActivities = true;
12986         } else if (app.instrumentationClass != null) {
12987             // Don't want to kill running instrumentation.
12988             adj = ProcessList.FOREGROUND_APP_ADJ;
12989             schedGroup = Process.THREAD_GROUP_DEFAULT;
12990             app.adjType = "instrumentation";
12991             interesting = true;
12992         } else if ((queue = isReceivingBroadcast(app)) != null) {
12993             // An app that is currently receiving a broadcast also
12994             // counts as being in the foreground for OOM killer purposes.
12995             // It's placed in a sched group based on the nature of the
12996             // broadcast as reflected by which queue it's active in.
12997             adj = ProcessList.FOREGROUND_APP_ADJ;
12998             schedGroup = (queue == mFgBroadcastQueue)
12999                     ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
13000             app.adjType = "broadcast";
13001         } else if (app.executingServices.size() > 0) {
13002             // An app that is currently executing a service callback also
13003             // counts as being in the foreground.
13004             adj = ProcessList.FOREGROUND_APP_ADJ;
13005             schedGroup = Process.THREAD_GROUP_DEFAULT;
13006             app.adjType = "exec-service";
13007         } else {
13008             // Assume process is hidden (has activities); we will correct
13009             // later if this is not the case.
13010             adj = hiddenAdj;
13011             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13012             app.hidden = true;
13013             app.adjType = "bg-act";
13014         }
13015 
13016         boolean hasStoppingActivities = false;
13017 
13018         // Examine all activities if not already foreground.
13019         if (!foregroundActivities && activitiesSize > 0) {
13020             for (int j = 0; j < activitiesSize; j++) {
13021                 final ActivityRecord r = app.activities.get(j);
13022                 if (r.visible) {
13023                     // App has a visible activity; only upgrade adjustment.
13024                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
13025                         adj = ProcessList.VISIBLE_APP_ADJ;
13026                         app.adjType = "visible";
13027                     }
13028                     schedGroup = Process.THREAD_GROUP_DEFAULT;
13029                     app.hidden = false;
13030                     app.hasActivities = true;
13031                     foregroundActivities = true;
13032                     break;
13033                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
13034                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13035                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13036                         app.adjType = "pausing";
13037                     }
13038                     app.hidden = false;
13039                     foregroundActivities = true;
13040                 } else if (r.state == ActivityState.STOPPING) {
13041                     // We will apply the actual adjustment later, because
13042                     // we want to allow this process to immediately go through
13043                     // any memory trimming that is in effect.
13044                     app.hidden = false;
13045                     foregroundActivities = true;
13046                     hasStoppingActivities = true;
13047                 }
13048                 if (r.app == app) {
13049                     app.hasActivities = true;
13050                 }
13051             }
13052         }
13053 
13054         if (adj == hiddenAdj && !app.hasActivities) {
13055             if (app.hasClientActivities) {
13056                 adj = clientHiddenAdj;
13057                 app.adjType = "bg-client-act";
13058             } else {
13059                 // Whoops, this process is completely empty as far as we know
13060                 // at this point.
13061                 adj = emptyAdj;
13062                 app.empty = true;
13063                 app.adjType = "bg-empty";
13064             }
13065         }
13066 
13067         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13068             if (app.foregroundServices) {
13069                 // The user is aware of this app, so make it visible.
13070                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13071                 app.hidden = false;
13072                 app.adjType = "fg-service";
13073                 schedGroup = Process.THREAD_GROUP_DEFAULT;
13074             } else if (app.forcingToForeground != null) {
13075                 // The user is aware of this app, so make it visible.
13076                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13077                 app.hidden = false;
13078                 app.adjType = "force-fg";
13079                 app.adjSource = app.forcingToForeground;
13080                 schedGroup = Process.THREAD_GROUP_DEFAULT;
13081             }
13082         }
13083 
13084         if (app.foregroundServices) {
13085             interesting = true;
13086         }
13087 
13088         if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
13089             // We don't want to kill the current heavy-weight process.
13090             adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
13091             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13092             app.hidden = false;
13093             app.adjType = "heavy";
13094         }
13095 
13096         if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
13097             // This process is hosting what we currently consider to be the
13098             // home app, so we don't want to let it go into the background.
13099             adj = ProcessList.HOME_APP_ADJ;
13100             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13101             app.hidden = false;
13102             app.adjType = "home";
13103         }
13104 
13105         if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
13106                 && app.activities.size() > 0) {
13107             // This was the previous process that showed UI to the user.
13108             // We want to try to keep it around more aggressively, to give
13109             // a good experience around switching between two apps.
13110             adj = ProcessList.PREVIOUS_APP_ADJ;
13111             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13112             app.hidden = false;
13113             app.adjType = "previous";
13114         }
13115 
13116         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
13117                 + " reason=" + app.adjType);
13118 
13119         // By default, we use the computed adjustment.  It may be changed if
13120         // there are applications dependent on our services or providers, but
13121         // this gives us a baseline and makes sure we don't get into an
13122         // infinite recursion.
13123         app.adjSeq = mAdjSeq;
13124         app.curRawAdj = app.nonStoppingAdj = adj;
13125 
13126         if (mBackupTarget != null && app == mBackupTarget.app) {
13127             // If possible we want to avoid killing apps while they're being backed up
13128             if (adj > ProcessList.BACKUP_APP_ADJ) {
13129                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
13130                 adj = ProcessList.BACKUP_APP_ADJ;
13131                 app.adjType = "backup";
13132                 app.hidden = false;
13133             }
13134         }
13135 
13136         if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13137                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13138             final long now = SystemClock.uptimeMillis();
13139             // This process is more important if the top activity is
13140             // bound to the service.
13141             Iterator<ServiceRecord> jt = app.services.iterator();
13142             while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
13143                 ServiceRecord s = jt.next();
13144                 if (s.startRequested) {
13145                     if (app.hasShownUi && app != mHomeProcess) {
13146                         // If this process has shown some UI, let it immediately
13147                         // go to the LRU list because it may be pretty heavy with
13148                         // UI stuff.  We'll tag it with a label just to help
13149                         // debug and understand what is going on.
13150                         if (adj > ProcessList.SERVICE_ADJ) {
13151                             app.adjType = "started-bg-ui-services";
13152                         }
13153                     } else {
13154                         if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
13155                             // This service has seen some activity within
13156                             // recent memory, so we will keep its process ahead
13157                             // of the background processes.
13158                             if (adj > ProcessList.SERVICE_ADJ) {
13159                                 adj = ProcessList.SERVICE_ADJ;
13160                                 app.adjType = "started-services";
13161                                 app.hidden = false;
13162                             }
13163                         }
13164                         // If we have let the service slide into the background
13165                         // state, still have some text describing what it is doing
13166                         // even though the service no longer has an impact.
13167                         if (adj > ProcessList.SERVICE_ADJ) {
13168                             app.adjType = "started-bg-services";
13169                         }
13170                     }
13171                     // Don't kill this process because it is doing work; it
13172                     // has said it is doing work.
13173                     app.keeping = true;
13174                 }
13175                 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13176                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13177                     Iterator<ArrayList<ConnectionRecord>> kt
13178                             = s.connections.values().iterator();
13179                     while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
13180                         ArrayList<ConnectionRecord> clist = kt.next();
13181                         for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
13182                             // XXX should compute this based on the max of
13183                             // all connected clients.
13184                             ConnectionRecord cr = clist.get(i);
13185                             if (cr.binding.client == app) {
13186                                 // Binding to ourself is not interesting.
13187                                 continue;
13188                             }
13189                             if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
13190                                 ProcessRecord client = cr.binding.client;
13191                                 int clientAdj = adj;
13192                                 int myHiddenAdj = hiddenAdj;
13193                                 if (myHiddenAdj > client.hiddenAdj) {
13194                                     if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
13195                                         myHiddenAdj = client.hiddenAdj;
13196                                     } else {
13197                                         myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
13198                                     }
13199                                 }
13200                                 int myClientHiddenAdj = clientHiddenAdj;
13201                                 if (myClientHiddenAdj > client.clientHiddenAdj) {
13202                                     if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
13203                                         myClientHiddenAdj = client.clientHiddenAdj;
13204                                     } else {
13205                                         myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
13206                                     }
13207                                 }
13208                                 int myEmptyAdj = emptyAdj;
13209                                 if (myEmptyAdj > client.emptyAdj) {
13210                                     if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
13211                                         myEmptyAdj = client.emptyAdj;
13212                                     } else {
13213                                         myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
13214                                     }
13215                                 }
13216                                 clientAdj = computeOomAdjLocked(client, myHiddenAdj,
13217                                         myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
13218                                 String adjType = null;
13219                                 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13220                                     // Not doing bind OOM management, so treat
13221                                     // this guy more like a started service.
13222                                     if (app.hasShownUi && app != mHomeProcess) {
13223                                         // If this process has shown some UI, let it immediately
13224                                         // go to the LRU list because it may be pretty heavy with
13225                                         // UI stuff.  We'll tag it with a label just to help
13226                                         // debug and understand what is going on.
13227                                         if (adj > clientAdj) {
13228                                             adjType = "bound-bg-ui-services";
13229                                         }
13230                                         app.hidden = false;
13231                                         clientAdj = adj;
13232                                     } else {
13233                                         if (now >= (s.lastActivity
13234                                                 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
13235                                             // This service has not seen activity within
13236                                             // recent memory, so allow it to drop to the
13237                                             // LRU list if there is no other reason to keep
13238                                             // it around.  We'll also tag it with a label just
13239                                             // to help debug and undertand what is going on.
13240                                             if (adj > clientAdj) {
13241                                                 adjType = "bound-bg-services";
13242                                             }
13243                                             clientAdj = adj;
13244                                         }
13245                                     }
13246                                 } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
13247                                     if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
13248                                         // If this connection is keeping the service
13249                                         // created, then we want to try to better follow
13250                                         // its memory management semantics for activities.
13251                                         // That is, if it is sitting in the background
13252                                         // LRU list as a hidden process (with activities),
13253                                         // we don't want the service it is connected to
13254                                         // to go into the empty LRU and quickly get killed,
13255                                         // because I'll we'll do is just end up restarting
13256                                         // the service.
13257                                         app.hasClientActivities |= client.hasActivities;
13258                                     }
13259                                 }
13260                                 if (adj > clientAdj) {
13261                                     // If this process has recently shown UI, and
13262                                     // the process that is binding to it is less
13263                                     // important than being visible, then we don't
13264                                     // care about the binding as much as we care
13265                                     // about letting this process get into the LRU
13266                                     // list to be killed and restarted if needed for
13267                                     // memory.
13268                                     if (app.hasShownUi && app != mHomeProcess
13269                                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13270                                         adjType = "bound-bg-ui-services";
13271                                     } else {
13272                                         if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13273                                                 |Context.BIND_IMPORTANT)) != 0) {
13274                                             adj = clientAdj;
13275                                         } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
13276                                                 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
13277                                                 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13278                                             adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13279                                         } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
13280                                             adj = clientAdj;
13281                                         } else {
13282                                             app.pendingUiClean = true;
13283                                             if (adj > ProcessList.VISIBLE_APP_ADJ) {
13284                                                 adj = ProcessList.VISIBLE_APP_ADJ;
13285                                             }
13286                                         }
13287                                         if (!client.hidden) {
13288                                             app.hidden = false;
13289                                         }
13290                                         if (client.keeping) {
13291                                             app.keeping = true;
13292                                         }
13293                                         adjType = "service";
13294                                     }
13295                                 }
13296                                 if (adjType != null) {
13297                                     app.adjType = adjType;
13298                                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13299                                             .REASON_SERVICE_IN_USE;
13300                                     app.adjSource = cr.binding.client;
13301                                     app.adjSourceOom = clientAdj;
13302                                     app.adjTarget = s.name;
13303                                 }
13304                                 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13305                                     if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13306                                         schedGroup = Process.THREAD_GROUP_DEFAULT;
13307                                     }
13308                                 }
13309                             }
13310                             final ActivityRecord a = cr.activity;
13311                             if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13312                                 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
13313                                         (a.visible || a.state == ActivityState.RESUMED
13314                                          || a.state == ActivityState.PAUSING)) {
13315                                     adj = ProcessList.FOREGROUND_APP_ADJ;
13316                                     if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13317                                         schedGroup = Process.THREAD_GROUP_DEFAULT;
13318                                     }
13319                                     app.hidden = false;
13320                                     app.adjType = "service";
13321                                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13322                                             .REASON_SERVICE_IN_USE;
13323                                     app.adjSource = a;
13324                                     app.adjSourceOom = adj;
13325                                     app.adjTarget = s.name;
13326                                 }
13327                             }
13328                         }
13329                     }
13330                 }
13331             }
13332 
13333             // Finally, if this process has active services running in it, we
13334             // would like to avoid killing it unless it would prevent the current
13335             // application from running.  By default we put the process in
13336             // with the rest of the background processes; as we scan through
13337             // its services we may bump it up from there.
13338             if (adj > hiddenAdj) {
13339                 adj = hiddenAdj;
13340                 app.hidden = false;
13341                 app.adjType = "bg-services";
13342             }
13343         }
13344 
13345         if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13346                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13347             Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
13348             while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
13349                     || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13350                 ContentProviderRecord cpr = jt.next();
13351                 for (int i = cpr.connections.size()-1;
13352                         i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13353                                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
13354                         i--) {
13355                     ContentProviderConnection conn = cpr.connections.get(i);
13356                     ProcessRecord client = conn.client;
13357                     if (client == app) {
13358                         // Being our own client is not interesting.
13359                         continue;
13360                     }
13361                     int myHiddenAdj = hiddenAdj;
13362                     if (myHiddenAdj > client.hiddenAdj) {
13363                         if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
13364                             myHiddenAdj = client.hiddenAdj;
13365                         } else {
13366                             myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
13367                         }
13368                     }
13369                     int myClientHiddenAdj = clientHiddenAdj;
13370                     if (myClientHiddenAdj > client.clientHiddenAdj) {
13371                         if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) {
13372                             myClientHiddenAdj = client.clientHiddenAdj;
13373                         } else {
13374                             myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
13375                         }
13376                     }
13377                     int myEmptyAdj = emptyAdj;
13378                     if (myEmptyAdj > client.emptyAdj) {
13379                         if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
13380                             myEmptyAdj = client.emptyAdj;
13381                         } else {
13382                             myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
13383                         }
13384                     }
13385                     int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
13386                             myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
13387                     if (adj > clientAdj) {
13388                         if (app.hasShownUi && app != mHomeProcess
13389                                 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13390                             app.adjType = "bg-ui-provider";
13391                         } else {
13392                             adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13393                                     ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
13394                             app.adjType = "provider";
13395                         }
13396                         if (!client.hidden) {
13397                             app.hidden = false;
13398                         }
13399                         if (client.keeping) {
13400                             app.keeping = true;
13401                         }
13402                         app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13403                                 .REASON_PROVIDER_IN_USE;
13404                         app.adjSource = client;
13405                         app.adjSourceOom = clientAdj;
13406                         app.adjTarget = cpr.name;
13407                     }
13408                     if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13409                         schedGroup = Process.THREAD_GROUP_DEFAULT;
13410                     }
13411                 }
13412                 // If the provider has external (non-framework) process
13413                 // dependencies, ensure that its adjustment is at least
13414                 // FOREGROUND_APP_ADJ.
13415                 if (cpr.hasExternalProcessHandles()) {
13416                     if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13417                         adj = ProcessList.FOREGROUND_APP_ADJ;
13418                         schedGroup = Process.THREAD_GROUP_DEFAULT;
13419                         app.hidden = false;
13420                         app.keeping = true;
13421                         app.adjType = "provider";
13422                         app.adjTarget = cpr.name;
13423                     }
13424                 }
13425             }
13426         }
13427 
13428         if (adj == ProcessList.SERVICE_ADJ) {
13429             if (doingAll) {
13430                 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
13431                 mNewNumServiceProcs++;
13432             }
13433             if (app.serviceb) {
13434                 adj = ProcessList.SERVICE_B_ADJ;
13435             }
13436         } else {
13437             app.serviceb = false;
13438         }
13439 
13440         app.nonStoppingAdj = adj;
13441 
13442         if (hasStoppingActivities) {
13443             // Only upgrade adjustment.
13444             if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13445                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13446                 app.adjType = "stopping";
13447             }
13448         }
13449 
13450         app.curRawAdj = adj;
13451 
13452         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
13453         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13454         if (adj > app.maxAdj) {
13455             adj = app.maxAdj;
13456             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
13457                 schedGroup = Process.THREAD_GROUP_DEFAULT;
13458             }
13459         }
13460         if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13461             app.keeping = true;
13462         }
13463 
13464         if (app.hasAboveClient) {
13465             // If this process has bound to any services with BIND_ABOVE_CLIENT,
13466             // then we need to drop its adjustment to be lower than the service's
13467             // in order to honor the request.  We want to drop it by one adjustment
13468             // level...  but there is special meaning applied to various levels so
13469             // we will skip some of them.
13470             if (adj < ProcessList.FOREGROUND_APP_ADJ) {
13471                 // System process will not get dropped, ever
13472             } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13473                 adj = ProcessList.VISIBLE_APP_ADJ;
13474             } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13475                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13476             } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13477                 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13478             } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
13479                 adj++;
13480             }
13481         }
13482 
13483         int importance = app.memImportance;
13484         if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
13485             app.curAdj = adj;
13486             app.curSchedGroup = schedGroup;
13487             if (!interesting) {
13488                 // For this reporting, if there is not something explicitly
13489                 // interesting in this process then we will push it to the
13490                 // background importance.
13491                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13492             } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13493                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13494             } else if (adj >= ProcessList.SERVICE_B_ADJ) {
13495                 importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13496             } else if (adj >= ProcessList.HOME_APP_ADJ) {
13497                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13498             } else if (adj >= ProcessList.SERVICE_ADJ) {
13499                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13500             } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13501                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
13502             } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
13503                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
13504             } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
13505                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
13506             } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
13507                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
13508             } else {
13509                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
13510             }
13511         }
13512 
13513         int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
13514         if (foregroundActivities != app.foregroundActivities) {
13515             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
13516         }
13517         if (changes != 0) {
13518             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
13519             app.memImportance = importance;
13520             app.foregroundActivities = foregroundActivities;
13521             int i = mPendingProcessChanges.size()-1;
13522             ProcessChangeItem item = null;
13523             while (i >= 0) {
13524                 item = mPendingProcessChanges.get(i);
13525                 if (item.pid == app.pid) {
13526                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
13527                     break;
13528                 }
13529                 i--;
13530             }
13531             if (i < 0) {
13532                 // No existing item in pending changes; need a new one.
13533                 final int NA = mAvailProcessChanges.size();
13534                 if (NA > 0) {
13535                     item = mAvailProcessChanges.remove(NA-1);
13536                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
13537                 } else {
13538                     item = new ProcessChangeItem();
13539                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
13540                 }
13541                 item.changes = 0;
13542                 item.pid = app.pid;
13543                 item.uid = app.info.uid;
13544                 if (mPendingProcessChanges.size() == 0) {
13545                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
13546                             "*** Enqueueing dispatch processes changed!");
13547                     mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
13548                 }
13549                 mPendingProcessChanges.add(item);
13550             }
13551             item.changes |= changes;
13552             item.importance = importance;
13553             item.foregroundActivities = foregroundActivities;
13554             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
13555                     + Integer.toHexString(System.identityHashCode(item))
13556                     + " " + app.toShortString() + ": changes=" + item.changes
13557                     + " importance=" + item.importance
13558                     + " foreground=" + item.foregroundActivities
13559                     + " type=" + app.adjType + " source=" + app.adjSource
13560                     + " target=" + app.adjTarget);
13561         }
13562 
13563         return app.curRawAdj;
13564     }
13565 
13566     /**
13567      * Ask a given process to GC right now.
13568      */
performAppGcLocked(ProcessRecord app)13569     final void performAppGcLocked(ProcessRecord app) {
13570         try {
13571             app.lastRequestedGc = SystemClock.uptimeMillis();
13572             if (app.thread != null) {
13573                 if (app.reportLowMemory) {
13574                     app.reportLowMemory = false;
13575                     app.thread.scheduleLowMemory();
13576                 } else {
13577                     app.thread.processInBackground();
13578                 }
13579             }
13580         } catch (Exception e) {
13581             // whatever.
13582         }
13583     }
13584 
13585     /**
13586      * Returns true if things are idle enough to perform GCs.
13587      */
canGcNowLocked()13588     private final boolean canGcNowLocked() {
13589         boolean processingBroadcasts = false;
13590         for (BroadcastQueue q : mBroadcastQueues) {
13591             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
13592                 processingBroadcasts = true;
13593             }
13594         }
13595         return !processingBroadcasts
13596                 && (mSleeping || (mMainStack.mResumedActivity != null &&
13597                         mMainStack.mResumedActivity.idle));
13598     }
13599 
13600     /**
13601      * Perform GCs on all processes that are waiting for it, but only
13602      * if things are idle.
13603      */
performAppGcsLocked()13604     final void performAppGcsLocked() {
13605         final int N = mProcessesToGc.size();
13606         if (N <= 0) {
13607             return;
13608         }
13609         if (canGcNowLocked()) {
13610             while (mProcessesToGc.size() > 0) {
13611                 ProcessRecord proc = mProcessesToGc.remove(0);
13612                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
13613                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13614                             <= SystemClock.uptimeMillis()) {
13615                         // To avoid spamming the system, we will GC processes one
13616                         // at a time, waiting a few seconds between each.
13617                         performAppGcLocked(proc);
13618                         scheduleAppGcsLocked();
13619                         return;
13620                     } else {
13621                         // It hasn't been long enough since we last GCed this
13622                         // process...  put it in the list to wait for its time.
13623                         addProcessToGcListLocked(proc);
13624                         break;
13625                     }
13626                 }
13627             }
13628 
13629             scheduleAppGcsLocked();
13630         }
13631     }
13632 
13633     /**
13634      * If all looks good, perform GCs on all processes waiting for them.
13635      */
performAppGcsIfAppropriateLocked()13636     final void performAppGcsIfAppropriateLocked() {
13637         if (canGcNowLocked()) {
13638             performAppGcsLocked();
13639             return;
13640         }
13641         // Still not idle, wait some more.
13642         scheduleAppGcsLocked();
13643     }
13644 
13645     /**
13646      * Schedule the execution of all pending app GCs.
13647      */
scheduleAppGcsLocked()13648     final void scheduleAppGcsLocked() {
13649         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13650 
13651         if (mProcessesToGc.size() > 0) {
13652             // Schedule a GC for the time to the next process.
13653             ProcessRecord proc = mProcessesToGc.get(0);
13654             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13655 
13656             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
13657             long now = SystemClock.uptimeMillis();
13658             if (when < (now+GC_TIMEOUT)) {
13659                 when = now + GC_TIMEOUT;
13660             }
13661             mHandler.sendMessageAtTime(msg, when);
13662         }
13663     }
13664 
13665     /**
13666      * Add a process to the array of processes waiting to be GCed.  Keeps the
13667      * list in sorted order by the last GC time.  The process can't already be
13668      * on the list.
13669      */
addProcessToGcListLocked(ProcessRecord proc)13670     final void addProcessToGcListLocked(ProcessRecord proc) {
13671         boolean added = false;
13672         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13673             if (mProcessesToGc.get(i).lastRequestedGc <
13674                     proc.lastRequestedGc) {
13675                 added = true;
13676                 mProcessesToGc.add(i+1, proc);
13677                 break;
13678             }
13679         }
13680         if (!added) {
13681             mProcessesToGc.add(0, proc);
13682         }
13683     }
13684 
13685     /**
13686      * Set up to ask a process to GC itself.  This will either do it
13687      * immediately, or put it on the list of processes to gc the next
13688      * time things are idle.
13689      */
scheduleAppGcLocked(ProcessRecord app)13690     final void scheduleAppGcLocked(ProcessRecord app) {
13691         long now = SystemClock.uptimeMillis();
13692         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13693             return;
13694         }
13695         if (!mProcessesToGc.contains(app)) {
13696             addProcessToGcListLocked(app);
13697             scheduleAppGcsLocked();
13698         }
13699     }
13700 
checkExcessivePowerUsageLocked(boolean doKills)13701     final void checkExcessivePowerUsageLocked(boolean doKills) {
13702         updateCpuStatsNow();
13703 
13704         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13705         boolean doWakeKills = doKills;
13706         boolean doCpuKills = doKills;
13707         if (mLastPowerCheckRealtime == 0) {
13708             doWakeKills = false;
13709         }
13710         if (mLastPowerCheckUptime == 0) {
13711             doCpuKills = false;
13712         }
13713         if (stats.isScreenOn()) {
13714             doWakeKills = false;
13715         }
13716         final long curRealtime = SystemClock.elapsedRealtime();
13717         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13718         final long curUptime = SystemClock.uptimeMillis();
13719         final long uptimeSince = curUptime - mLastPowerCheckUptime;
13720         mLastPowerCheckRealtime = curRealtime;
13721         mLastPowerCheckUptime = curUptime;
13722         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13723             doWakeKills = false;
13724         }
13725         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13726             doCpuKills = false;
13727         }
13728         int i = mLruProcesses.size();
13729         while (i > 0) {
13730             i--;
13731             ProcessRecord app = mLruProcesses.get(i);
13732             if (!app.keeping) {
13733                 long wtime;
13734                 synchronized (stats) {
13735                     wtime = stats.getProcessWakeTime(app.info.uid,
13736                             app.pid, curRealtime);
13737                 }
13738                 long wtimeUsed = wtime - app.lastWakeTime;
13739                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13740                 if (DEBUG_POWER) {
13741                     StringBuilder sb = new StringBuilder(128);
13742                     sb.append("Wake for ");
13743                     app.toShortString(sb);
13744                     sb.append(": over ");
13745                     TimeUtils.formatDuration(realtimeSince, sb);
13746                     sb.append(" used ");
13747                     TimeUtils.formatDuration(wtimeUsed, sb);
13748                     sb.append(" (");
13749                     sb.append((wtimeUsed*100)/realtimeSince);
13750                     sb.append("%)");
13751                     Slog.i(TAG, sb.toString());
13752                     sb.setLength(0);
13753                     sb.append("CPU for ");
13754                     app.toShortString(sb);
13755                     sb.append(": over ");
13756                     TimeUtils.formatDuration(uptimeSince, sb);
13757                     sb.append(" used ");
13758                     TimeUtils.formatDuration(cputimeUsed, sb);
13759                     sb.append(" (");
13760                     sb.append((cputimeUsed*100)/uptimeSince);
13761                     sb.append("%)");
13762                     Slog.i(TAG, sb.toString());
13763                 }
13764                 // If a process has held a wake lock for more
13765                 // than 50% of the time during this period,
13766                 // that sounds bad.  Kill!
13767                 if (doWakeKills && realtimeSince > 0
13768                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
13769                     synchronized (stats) {
13770                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13771                                 realtimeSince, wtimeUsed);
13772                     }
13773                     Slog.w(TAG, "Excessive wake lock in " + app.processName
13774                             + " (pid " + app.pid + "): held " + wtimeUsed
13775                             + " during " + realtimeSince);
13776                     EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13777                             app.processName, app.setAdj, "excessive wake lock");
13778                     Process.killProcessQuiet(app.pid);
13779                 } else if (doCpuKills && uptimeSince > 0
13780                         && ((cputimeUsed*100)/uptimeSince) >= 50) {
13781                     synchronized (stats) {
13782                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13783                                 uptimeSince, cputimeUsed);
13784                     }
13785                     Slog.w(TAG, "Excessive CPU in " + app.processName
13786                             + " (pid " + app.pid + "): used " + cputimeUsed
13787                             + " during " + uptimeSince);
13788                     EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13789                             app.processName, app.setAdj, "excessive cpu");
13790                     Process.killProcessQuiet(app.pid);
13791                 } else {
13792                     app.lastWakeTime = wtime;
13793                     app.lastCpuTime = app.curCpuTime;
13794                 }
13795             }
13796         }
13797     }
13798 
updateOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll)13799     private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13800             int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
13801         app.hiddenAdj = hiddenAdj;
13802         app.clientHiddenAdj = clientHiddenAdj;
13803         app.emptyAdj = emptyAdj;
13804 
13805         if (app.thread == null) {
13806             return false;
13807         }
13808 
13809         final boolean wasKeeping = app.keeping;
13810 
13811         boolean success = true;
13812 
13813         computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll);
13814 
13815         if (app.curRawAdj != app.setRawAdj) {
13816             if (wasKeeping && !app.keeping) {
13817                 // This app is no longer something we want to keep.  Note
13818                 // its current wake lock time to later know to kill it if
13819                 // it is not behaving well.
13820                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13821                 synchronized (stats) {
13822                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13823                             app.pid, SystemClock.elapsedRealtime());
13824                 }
13825                 app.lastCpuTime = app.curCpuTime;
13826             }
13827 
13828             app.setRawAdj = app.curRawAdj;
13829         }
13830 
13831         if (app.curAdj != app.setAdj) {
13832             if (Process.setOomAdj(app.pid, app.curAdj)) {
13833                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13834                     TAG, "Set " + app.pid + " " + app.processName +
13835                     " adj " + app.curAdj + ": " + app.adjType);
13836                 app.setAdj = app.curAdj;
13837             } else {
13838                 success = false;
13839                 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13840             }
13841         }
13842         if (app.setSchedGroup != app.curSchedGroup) {
13843             app.setSchedGroup = app.curSchedGroup;
13844             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13845                     "Setting process group of " + app.processName
13846                     + " to " + app.curSchedGroup);
13847             if (app.waitingToKill != null &&
13848                     app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13849                 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13850                 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13851                         app.processName, app.setAdj, app.waitingToKill);
13852                 app.killedBackground = true;
13853                 Process.killProcessQuiet(app.pid);
13854                 success = false;
13855             } else {
13856                 if (true) {
13857                     long oldId = Binder.clearCallingIdentity();
13858                     try {
13859                         Process.setProcessGroup(app.pid, app.curSchedGroup);
13860                     } catch (Exception e) {
13861                         Slog.w(TAG, "Failed setting process group of " + app.pid
13862                                 + " to " + app.curSchedGroup);
13863                         e.printStackTrace();
13864                     } finally {
13865                         Binder.restoreCallingIdentity(oldId);
13866                     }
13867                 } else {
13868                     if (app.thread != null) {
13869                         try {
13870                             app.thread.setSchedulingGroup(app.curSchedGroup);
13871                         } catch (RemoteException e) {
13872                         }
13873                     }
13874                 }
13875             }
13876         }
13877         return success;
13878     }
13879 
resumedAppLocked()13880     private final ActivityRecord resumedAppLocked() {
13881         ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13882         if (resumedActivity == null || resumedActivity.app == null) {
13883             resumedActivity = mMainStack.mPausingActivity;
13884             if (resumedActivity == null || resumedActivity.app == null) {
13885                 resumedActivity = mMainStack.topRunningActivityLocked(null);
13886             }
13887         }
13888         return resumedActivity;
13889     }
13890 
updateOomAdjLocked(ProcessRecord app)13891     final boolean updateOomAdjLocked(ProcessRecord app) {
13892         final ActivityRecord TOP_ACT = resumedAppLocked();
13893         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13894         int curAdj = app.curAdj;
13895         final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13896             && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13897 
13898         mAdjSeq++;
13899 
13900         boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj,
13901                 app.emptyAdj, TOP_APP, false);
13902         final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13903             && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13904         if (nowHidden != wasHidden) {
13905             // Changed to/from hidden state, so apps after it in the LRU
13906             // list may also be changed.
13907             updateOomAdjLocked();
13908         }
13909         return success;
13910     }
13911 
updateOomAdjLocked()13912     final void updateOomAdjLocked() {
13913         final ActivityRecord TOP_ACT = resumedAppLocked();
13914         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13915         final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME;
13916 
13917         if (false) {
13918             RuntimeException e = new RuntimeException();
13919             e.fillInStackTrace();
13920             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13921         }
13922 
13923         mAdjSeq++;
13924         mNewNumServiceProcs = 0;
13925 
13926         final int emptyProcessLimit;
13927         final int hiddenProcessLimit;
13928         if (mProcessLimit <= 0) {
13929             emptyProcessLimit = hiddenProcessLimit = 0;
13930         } else if (mProcessLimit == 1) {
13931             emptyProcessLimit = 1;
13932             hiddenProcessLimit = 0;
13933         } else {
13934             emptyProcessLimit = (mProcessLimit*2)/3;
13935             hiddenProcessLimit = mProcessLimit - emptyProcessLimit;
13936         }
13937 
13938         // Let's determine how many processes we have running vs.
13939         // how many slots we have for background processes; we may want
13940         // to put multiple processes in a slot of there are enough of
13941         // them.
13942         int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13943                 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13944         int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs;
13945         if (numEmptyProcs > hiddenProcessLimit) {
13946             // If there are more empty processes than our limit on hidden
13947             // processes, then use the hidden process limit for the factor.
13948             // This ensures that the really old empty processes get pushed
13949             // down to the bottom, so if we are running low on memory we will
13950             // have a better chance at keeping around more hidden processes
13951             // instead of a gazillion empty processes.
13952             numEmptyProcs = hiddenProcessLimit;
13953         }
13954         int emptyFactor = numEmptyProcs/numSlots;
13955         if (emptyFactor < 1) emptyFactor = 1;
13956         int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13957         if (hiddenFactor < 1) hiddenFactor = 1;
13958         int stepHidden = 0;
13959         int stepEmpty = 0;
13960         int numHidden = 0;
13961         int numEmpty = 0;
13962         int numTrimming = 0;
13963 
13964         mNumNonHiddenProcs = 0;
13965         mNumHiddenProcs = 0;
13966 
13967         // First update the OOM adjustment for each of the
13968         // application processes based on their current state.
13969         int i = mLruProcesses.size();
13970         int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13971         int nextHiddenAdj = curHiddenAdj+1;
13972         int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13973         int nextEmptyAdj = curEmptyAdj+2;
13974         int curClientHiddenAdj = curEmptyAdj;
13975         while (i > 0) {
13976             i--;
13977             ProcessRecord app = mLruProcesses.get(i);
13978             //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13979             updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true);
13980             if (!app.killedBackground) {
13981                 if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13982                     // This process was assigned as a hidden process...  step the
13983                     // hidden level.
13984                     mNumHiddenProcs++;
13985                     if (curHiddenAdj != nextHiddenAdj) {
13986                         stepHidden++;
13987                         if (stepHidden >= hiddenFactor) {
13988                             stepHidden = 0;
13989                             curHiddenAdj = nextHiddenAdj;
13990                             nextHiddenAdj += 2;
13991                             if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13992                                 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13993                             }
13994                             if (curClientHiddenAdj <= curHiddenAdj) {
13995                                 curClientHiddenAdj = curHiddenAdj + 1;
13996                                 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13997                                     curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13998                                 }
13999                             }
14000                         }
14001                     }
14002                     numHidden++;
14003                     if (numHidden > hiddenProcessLimit) {
14004                         Slog.i(TAG, "No longer want " + app.processName
14005                                 + " (pid " + app.pid + "): hidden #" + numHidden);
14006                         EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
14007                                 app.processName, app.setAdj, "too many background");
14008                         app.killedBackground = true;
14009                         Process.killProcessQuiet(app.pid);
14010                     }
14011                 } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) {
14012                     // This process has a client that has activities.  We will have
14013                     // given it the current hidden adj; here we will just leave it
14014                     // without stepping the hidden adj.
14015                     curClientHiddenAdj++;
14016                     if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
14017                         curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
14018                     }
14019                 } else {
14020                     if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
14021                         // This process was assigned as an empty process...  step the
14022                         // empty level.
14023                         if (curEmptyAdj != nextEmptyAdj) {
14024                             stepEmpty++;
14025                             if (stepEmpty >= emptyFactor) {
14026                                 stepEmpty = 0;
14027                                 curEmptyAdj = nextEmptyAdj;
14028                                 nextEmptyAdj += 2;
14029                                 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
14030                                     nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
14031                                 }
14032                             }
14033                         }
14034                     } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14035                         mNumNonHiddenProcs++;
14036                     }
14037                     if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14038                             && !app.hasClientActivities) {
14039                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
14040                                 && app.lastActivityTime < oldTime) {
14041                             Slog.i(TAG, "No longer want " + app.processName
14042                                     + " (pid " + app.pid + "): empty for "
14043                                     + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime)
14044                                             / 1000) + "s");
14045                             EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
14046                                     app.processName, app.setAdj, "old background process");
14047                             app.killedBackground = true;
14048                             Process.killProcessQuiet(app.pid);
14049                         } else {
14050                             numEmpty++;
14051                             if (numEmpty > emptyProcessLimit) {
14052                                 Slog.i(TAG, "No longer want " + app.processName
14053                                         + " (pid " + app.pid + "): empty #" + numEmpty);
14054                                 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
14055                                         app.processName, app.setAdj, "too many background");
14056                                 app.killedBackground = true;
14057                                 Process.killProcessQuiet(app.pid);
14058                             }
14059                         }
14060                     }
14061                 }
14062                 if (app.isolated && app.services.size() <= 0) {
14063                     // If this is an isolated process, and there are no
14064                     // services running in it, then the process is no longer
14065                     // needed.  We agressively kill these because we can by
14066                     // definition not re-use the same process again, and it is
14067                     // good to avoid having whatever code was running in them
14068                     // left sitting around after no longer needed.
14069                     Slog.i(TAG, "Isolated process " + app.processName
14070                             + " (pid " + app.pid + ") no longer needed");
14071                     EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
14072                             app.processName, app.setAdj, "isolated not needed");
14073                     app.killedBackground = true;
14074                     Process.killProcessQuiet(app.pid);
14075                 }
14076                 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
14077                         && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
14078                         && !app.killedBackground) {
14079                     numTrimming++;
14080                 }
14081             }
14082         }
14083 
14084         mNumServiceProcs = mNewNumServiceProcs;
14085 
14086         // Now determine the memory trimming level of background processes.
14087         // Unfortunately we need to start at the back of the list to do this
14088         // properly.  We only do this if the number of background apps we
14089         // are managing to keep around is less than half the maximum we desire;
14090         // if we are keeping a good number around, we'll let them use whatever
14091         // memory they want.
14092         if (numHidden <= ProcessList.TRIM_HIDDEN_APPS
14093                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
14094             final int numHiddenAndEmpty = numHidden + numEmpty;
14095             final int N = mLruProcesses.size();
14096             int factor = numTrimming/3;
14097             int minFactor = 2;
14098             if (mHomeProcess != null) minFactor++;
14099             if (mPreviousProcess != null) minFactor++;
14100             if (factor < minFactor) factor = minFactor;
14101             int step = 0;
14102             int fgTrimLevel;
14103             if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
14104                 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
14105             } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
14106                 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
14107             } else {
14108                 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
14109             }
14110             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
14111             for (i=0; i<N; i++) {
14112                 ProcessRecord app = mLruProcesses.get(i);
14113                 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
14114                         && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
14115                         && !app.killedBackground) {
14116                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
14117                         try {
14118                             app.thread.scheduleTrimMemory(curLevel);
14119                         } catch (RemoteException e) {
14120                         }
14121                         if (false) {
14122                             // For now we won't do this; our memory trimming seems
14123                             // to be good enough at this point that destroying
14124                             // activities causes more harm than good.
14125                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
14126                                     && app != mHomeProcess && app != mPreviousProcess) {
14127                                 // Need to do this on its own message because the stack may not
14128                                 // be in a consistent state at this point.
14129                                 // For these apps we will also finish their activities
14130                                 // to help them free memory.
14131                                 mMainStack.scheduleDestroyActivities(app, false, "trim");
14132                             }
14133                         }
14134                     }
14135                     app.trimMemoryLevel = curLevel;
14136                     step++;
14137                     if (step >= factor) {
14138                         step = 0;
14139                         switch (curLevel) {
14140                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
14141                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
14142                                 break;
14143                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
14144                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
14145                                 break;
14146                         }
14147                     }
14148                 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14149                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
14150                             && app.thread != null) {
14151                         try {
14152                             app.thread.scheduleTrimMemory(
14153                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
14154                         } catch (RemoteException e) {
14155                         }
14156                     }
14157                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
14158                 } else {
14159                     if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
14160                             && app.pendingUiClean) {
14161                         // If this application is now in the background and it
14162                         // had done UI, then give it the special trim level to
14163                         // have it free UI resources.
14164                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14165                         if (app.trimMemoryLevel < level && app.thread != null) {
14166                             try {
14167                                 app.thread.scheduleTrimMemory(level);
14168                             } catch (RemoteException e) {
14169                             }
14170                         }
14171                         app.pendingUiClean = false;
14172                     }
14173                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
14174                         try {
14175                             app.thread.scheduleTrimMemory(fgTrimLevel);
14176                         } catch (RemoteException e) {
14177                         }
14178                     }
14179                     app.trimMemoryLevel = fgTrimLevel;
14180                 }
14181             }
14182         } else {
14183             final int N = mLruProcesses.size();
14184             for (i=0; i<N; i++) {
14185                 ProcessRecord app = mLruProcesses.get(i);
14186                 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
14187                         && app.pendingUiClean) {
14188                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14189                             && app.thread != null) {
14190                         try {
14191                             app.thread.scheduleTrimMemory(
14192                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14193                         } catch (RemoteException e) {
14194                         }
14195                     }
14196                     app.pendingUiClean = false;
14197                 }
14198                 app.trimMemoryLevel = 0;
14199             }
14200         }
14201 
14202         if (mAlwaysFinishActivities) {
14203             // Need to do this on its own message because the stack may not
14204             // be in a consistent state at this point.
14205             mMainStack.scheduleDestroyActivities(null, false, "always-finish");
14206         }
14207     }
14208 
trimApplications()14209     final void trimApplications() {
14210         synchronized (this) {
14211             int i;
14212 
14213             // First remove any unused application processes whose package
14214             // has been removed.
14215             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
14216                 final ProcessRecord app = mRemovedProcesses.get(i);
14217                 if (app.activities.size() == 0
14218                         && app.curReceiver == null && app.services.size() == 0) {
14219                     Slog.i(
14220                         TAG, "Exiting empty application process "
14221                         + app.processName + " ("
14222                         + (app.thread != null ? app.thread.asBinder() : null)
14223                         + ")\n");
14224                     if (app.pid > 0 && app.pid != MY_PID) {
14225                         EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
14226                                 app.processName, app.setAdj, "empty");
14227                         Process.killProcessQuiet(app.pid);
14228                     } else {
14229                         try {
14230                             app.thread.scheduleExit();
14231                         } catch (Exception e) {
14232                             // Ignore exceptions.
14233                         }
14234                     }
14235                     cleanUpApplicationRecordLocked(app, false, true, -1);
14236                     mRemovedProcesses.remove(i);
14237 
14238                     if (app.persistent) {
14239                         if (app.persistent) {
14240                             addAppLocked(app.info, false);
14241                         }
14242                     }
14243                 }
14244             }
14245 
14246             // Now update the oom adj for all processes.
14247             updateOomAdjLocked();
14248         }
14249     }
14250 
14251     /** This method sends the specified signal to each of the persistent apps */
signalPersistentProcesses(int sig)14252     public void signalPersistentProcesses(int sig) throws RemoteException {
14253         if (sig != Process.SIGNAL_USR1) {
14254             throw new SecurityException("Only SIGNAL_USR1 is allowed");
14255         }
14256 
14257         synchronized (this) {
14258             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
14259                     != PackageManager.PERMISSION_GRANTED) {
14260                 throw new SecurityException("Requires permission "
14261                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
14262             }
14263 
14264             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14265                 ProcessRecord r = mLruProcesses.get(i);
14266                 if (r.thread != null && r.persistent) {
14267                     Process.sendSignal(r.pid, sig);
14268                 }
14269             }
14270         }
14271     }
14272 
stopProfilerLocked(ProcessRecord proc, String path, int profileType)14273     private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
14274         if (proc == null || proc == mProfileProc) {
14275             proc = mProfileProc;
14276             path = mProfileFile;
14277             profileType = mProfileType;
14278             clearProfilerLocked();
14279         }
14280         if (proc == null) {
14281             return;
14282         }
14283         try {
14284             proc.thread.profilerControl(false, path, null, profileType);
14285         } catch (RemoteException e) {
14286             throw new IllegalStateException("Process disappeared");
14287         }
14288     }
14289 
clearProfilerLocked()14290     private void clearProfilerLocked() {
14291         if (mProfileFd != null) {
14292             try {
14293                 mProfileFd.close();
14294             } catch (IOException e) {
14295             }
14296         }
14297         mProfileApp = null;
14298         mProfileProc = null;
14299         mProfileFile = null;
14300         mProfileType = 0;
14301         mAutoStopProfiler = false;
14302     }
14303 
profileControl(String process, int userId, boolean start, String path, ParcelFileDescriptor fd, int profileType)14304     public boolean profileControl(String process, int userId, boolean start,
14305             String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
14306 
14307         try {
14308             synchronized (this) {
14309                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14310                 // its own permission.
14311                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14312                         != PackageManager.PERMISSION_GRANTED) {
14313                     throw new SecurityException("Requires permission "
14314                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14315                 }
14316 
14317                 if (start && fd == null) {
14318                     throw new IllegalArgumentException("null fd");
14319                 }
14320 
14321                 ProcessRecord proc = null;
14322                 if (process != null) {
14323                     proc = findProcessLocked(process, userId, "profileControl");
14324                 }
14325 
14326                 if (start && (proc == null || proc.thread == null)) {
14327                     throw new IllegalArgumentException("Unknown process: " + process);
14328                 }
14329 
14330                 if (start) {
14331                     stopProfilerLocked(null, null, 0);
14332                     setProfileApp(proc.info, proc.processName, path, fd, false);
14333                     mProfileProc = proc;
14334                     mProfileType = profileType;
14335                     try {
14336                         fd = fd.dup();
14337                     } catch (IOException e) {
14338                         fd = null;
14339                     }
14340                     proc.thread.profilerControl(start, path, fd, profileType);
14341                     fd = null;
14342                     mProfileFd = null;
14343                 } else {
14344                     stopProfilerLocked(proc, path, profileType);
14345                     if (fd != null) {
14346                         try {
14347                             fd.close();
14348                         } catch (IOException e) {
14349                         }
14350                     }
14351                 }
14352 
14353                 return true;
14354             }
14355         } catch (RemoteException e) {
14356             throw new IllegalStateException("Process disappeared");
14357         } finally {
14358             if (fd != null) {
14359                 try {
14360                     fd.close();
14361                 } catch (IOException e) {
14362                 }
14363             }
14364         }
14365     }
14366 
findProcessLocked(String process, int userId, String callName)14367     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
14368         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14369                 userId, true, true, callName, null);
14370         ProcessRecord proc = null;
14371         try {
14372             int pid = Integer.parseInt(process);
14373             synchronized (mPidsSelfLocked) {
14374                 proc = mPidsSelfLocked.get(pid);
14375             }
14376         } catch (NumberFormatException e) {
14377         }
14378 
14379         if (proc == null) {
14380             HashMap<String, SparseArray<ProcessRecord>> all
14381                     = mProcessNames.getMap();
14382             SparseArray<ProcessRecord> procs = all.get(process);
14383             if (procs != null && procs.size() > 0) {
14384                 proc = procs.valueAt(0);
14385                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
14386                     for (int i=1; i<procs.size(); i++) {
14387                         ProcessRecord thisProc = procs.valueAt(i);
14388                         if (thisProc.userId == userId) {
14389                             proc = thisProc;
14390                             break;
14391                         }
14392                     }
14393                 }
14394             }
14395         }
14396 
14397         return proc;
14398     }
14399 
dumpHeap(String process, int userId, boolean managed, String path, ParcelFileDescriptor fd)14400     public boolean dumpHeap(String process, int userId, boolean managed,
14401             String path, ParcelFileDescriptor fd) throws RemoteException {
14402 
14403         try {
14404             synchronized (this) {
14405                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14406                 // its own permission (same as profileControl).
14407                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14408                         != PackageManager.PERMISSION_GRANTED) {
14409                     throw new SecurityException("Requires permission "
14410                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14411                 }
14412 
14413                 if (fd == null) {
14414                     throw new IllegalArgumentException("null fd");
14415                 }
14416 
14417                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
14418                 if (proc == null || proc.thread == null) {
14419                     throw new IllegalArgumentException("Unknown process: " + process);
14420                 }
14421 
14422                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14423                 if (!isDebuggable) {
14424                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14425                         throw new SecurityException("Process not debuggable: " + proc);
14426                     }
14427                 }
14428 
14429                 proc.thread.dumpHeap(managed, path, fd);
14430                 fd = null;
14431                 return true;
14432             }
14433         } catch (RemoteException e) {
14434             throw new IllegalStateException("Process disappeared");
14435         } finally {
14436             if (fd != null) {
14437                 try {
14438                     fd.close();
14439                 } catch (IOException e) {
14440                 }
14441             }
14442         }
14443     }
14444 
14445     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
monitor()14446     public void monitor() {
14447         synchronized (this) { }
14448     }
14449 
onCoreSettingsChange(Bundle settings)14450     void onCoreSettingsChange(Bundle settings) {
14451         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14452             ProcessRecord processRecord = mLruProcesses.get(i);
14453             try {
14454                 if (processRecord.thread != null) {
14455                     processRecord.thread.setCoreSettings(settings);
14456                 }
14457             } catch (RemoteException re) {
14458                 /* ignore */
14459             }
14460         }
14461     }
14462 
14463     // Multi-user methods
14464 
14465     @Override
switchUser(final int userId)14466     public boolean switchUser(final int userId) {
14467         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14468                 != PackageManager.PERMISSION_GRANTED) {
14469             String msg = "Permission Denial: switchUser() from pid="
14470                     + Binder.getCallingPid()
14471                     + ", uid=" + Binder.getCallingUid()
14472                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14473             Slog.w(TAG, msg);
14474             throw new SecurityException(msg);
14475         }
14476 
14477         final long ident = Binder.clearCallingIdentity();
14478         try {
14479             synchronized (this) {
14480                 final int oldUserId = mCurrentUserId;
14481                 if (oldUserId == userId) {
14482                     return true;
14483                 }
14484 
14485                 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
14486                 if (userInfo == null) {
14487                     Slog.w(TAG, "No user info for user #" + userId);
14488                     return false;
14489                 }
14490 
14491                 mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
14492                         R.anim.screen_user_enter);
14493 
14494                 boolean needStart = false;
14495 
14496                 // If the user we are switching to is not currently started, then
14497                 // we need to start it now.
14498                 if (mStartedUsers.get(userId) == null) {
14499                     mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
14500                     updateStartedUserArrayLocked();
14501                     needStart = true;
14502                 }
14503 
14504                 mCurrentUserId = userId;
14505                 mCurrentUserArray = new int[] { userId };
14506                 final Integer userIdInt = Integer.valueOf(userId);
14507                 mUserLru.remove(userIdInt);
14508                 mUserLru.add(userIdInt);
14509 
14510                 mWindowManager.setCurrentUser(userId);
14511 
14512                 // Once the internal notion of the active user has switched, we lock the device
14513                 // with the option to show the user switcher on the keyguard.
14514                 mWindowManager.lockNow(null);
14515 
14516                 final UserStartedState uss = mStartedUsers.get(userId);
14517 
14518                 // Make sure user is in the started state.  If it is currently
14519                 // stopping, we need to knock that off.
14520                 if (uss.mState == UserStartedState.STATE_STOPPING) {
14521                     // If we are stopping, we haven't sent ACTION_SHUTDOWN,
14522                     // so we can just fairly silently bring the user back from
14523                     // the almost-dead.
14524                     uss.mState = UserStartedState.STATE_RUNNING;
14525                     updateStartedUserArrayLocked();
14526                     needStart = true;
14527                 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
14528                     // This means ACTION_SHUTDOWN has been sent, so we will
14529                     // need to treat this as a new boot of the user.
14530                     uss.mState = UserStartedState.STATE_BOOTING;
14531                     updateStartedUserArrayLocked();
14532                     needStart = true;
14533                 }
14534 
14535                 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
14536                 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14537                 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
14538                         oldUserId, userId, uss));
14539                 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
14540                         oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
14541                 if (needStart) {
14542                     Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14543                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14544                             | Intent.FLAG_RECEIVER_FOREGROUND);
14545                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14546                     broadcastIntentLocked(null, null, intent,
14547                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14548                             false, false, MY_PID, Process.SYSTEM_UID, userId);
14549                 }
14550 
14551                 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
14552                     if (userId != 0) {
14553                         Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
14554                         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14555                         broadcastIntentLocked(null, null, intent, null,
14556                                 new IIntentReceiver.Stub() {
14557                                     public void performReceive(Intent intent, int resultCode,
14558                                             String data, Bundle extras, boolean ordered,
14559                                             boolean sticky, int sendingUser) {
14560                                         userInitialized(uss, userId);
14561                                     }
14562                                 }, 0, null, null, null, AppOpsManager.OP_NONE,
14563                                 true, false, MY_PID, Process.SYSTEM_UID,
14564                                 userId);
14565                         uss.initializing = true;
14566                     } else {
14567                         getUserManagerLocked().makeInitialized(userInfo.id);
14568                     }
14569                 }
14570 
14571                 boolean haveActivities = mMainStack.switchUserLocked(userId, uss);
14572                 if (!haveActivities) {
14573                     startHomeActivityLocked(userId);
14574                 }
14575 
14576                 EventLogTags.writeAmSwitchUser(userId);
14577                 getUserManagerLocked().userForeground(userId);
14578                 sendUserSwitchBroadcastsLocked(oldUserId, userId);
14579                 if (needStart) {
14580                     Intent intent = new Intent(Intent.ACTION_USER_STARTING);
14581                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14582                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14583                     broadcastIntentLocked(null, null, intent,
14584                             null, new IIntentReceiver.Stub() {
14585                                 @Override
14586                                 public void performReceive(Intent intent, int resultCode, String data,
14587                                         Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14588                                         throws RemoteException {
14589                                 }
14590                             }, 0, null, null,
14591                             android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
14592                             true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14593                 }
14594             }
14595         } finally {
14596             Binder.restoreCallingIdentity(ident);
14597         }
14598 
14599         return true;
14600     }
14601 
sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId)14602     void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
14603         long ident = Binder.clearCallingIdentity();
14604         try {
14605             Intent intent;
14606             if (oldUserId >= 0) {
14607                 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
14608                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14609                         | Intent.FLAG_RECEIVER_FOREGROUND);
14610                 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
14611                 broadcastIntentLocked(null, null, intent,
14612                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14613                         false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
14614             }
14615             if (newUserId >= 0) {
14616                 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
14617                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14618                         | Intent.FLAG_RECEIVER_FOREGROUND);
14619                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14620                 broadcastIntentLocked(null, null, intent,
14621                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14622                         false, false, MY_PID, Process.SYSTEM_UID, newUserId);
14623                 intent = new Intent(Intent.ACTION_USER_SWITCHED);
14624                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14625                         | Intent.FLAG_RECEIVER_FOREGROUND);
14626                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14627                 broadcastIntentLocked(null, null, intent,
14628                         null, null, 0, null, null,
14629                         android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
14630                         false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14631             }
14632         } finally {
14633             Binder.restoreCallingIdentity(ident);
14634         }
14635     }
14636 
dispatchUserSwitch(final UserStartedState uss, final int oldUserId, final int newUserId)14637     void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
14638             final int newUserId) {
14639         final int N = mUserSwitchObservers.beginBroadcast();
14640         if (N > 0) {
14641             final IRemoteCallback callback = new IRemoteCallback.Stub() {
14642                 int mCount = 0;
14643                 @Override
14644                 public void sendResult(Bundle data) throws RemoteException {
14645                     synchronized (ActivityManagerService.this) {
14646                         if (mCurUserSwitchCallback == this) {
14647                             mCount++;
14648                             if (mCount == N) {
14649                                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14650                             }
14651                         }
14652                     }
14653                 }
14654             };
14655             synchronized (this) {
14656                 uss.switching = true;
14657                 mCurUserSwitchCallback = callback;
14658             }
14659             for (int i=0; i<N; i++) {
14660                 try {
14661                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
14662                             newUserId, callback);
14663                 } catch (RemoteException e) {
14664                 }
14665             }
14666         } else {
14667             synchronized (this) {
14668                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14669             }
14670         }
14671         mUserSwitchObservers.finishBroadcast();
14672     }
14673 
timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId)14674     void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14675         synchronized (this) {
14676             Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
14677             sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14678         }
14679     }
14680 
sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId)14681     void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
14682         mCurUserSwitchCallback = null;
14683         mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14684         mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
14685                 oldUserId, newUserId, uss));
14686     }
14687 
userInitialized(UserStartedState uss, int newUserId)14688     void userInitialized(UserStartedState uss, int newUserId) {
14689         completeSwitchAndInitalize(uss, newUserId, true, false);
14690     }
14691 
continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId)14692     void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14693         completeSwitchAndInitalize(uss, newUserId, false, true);
14694     }
14695 
completeSwitchAndInitalize(UserStartedState uss, int newUserId, boolean clearInitializing, boolean clearSwitching)14696     void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
14697             boolean clearInitializing, boolean clearSwitching) {
14698         boolean unfrozen = false;
14699         synchronized (this) {
14700             if (clearInitializing) {
14701                 uss.initializing = false;
14702                 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
14703             }
14704             if (clearSwitching) {
14705                 uss.switching = false;
14706             }
14707             if (!uss.switching && !uss.initializing) {
14708                 mWindowManager.stopFreezingScreen();
14709                 unfrozen = true;
14710             }
14711         }
14712         if (unfrozen) {
14713             final int N = mUserSwitchObservers.beginBroadcast();
14714             for (int i=0; i<N; i++) {
14715                 try {
14716                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
14717                 } catch (RemoteException e) {
14718                 }
14719             }
14720             mUserSwitchObservers.finishBroadcast();
14721         }
14722     }
14723 
finishUserSwitch(UserStartedState uss)14724     void finishUserSwitch(UserStartedState uss) {
14725         synchronized (this) {
14726             if (uss.mState == UserStartedState.STATE_BOOTING
14727                     && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
14728                 uss.mState = UserStartedState.STATE_RUNNING;
14729                 final int userId = uss.mHandle.getIdentifier();
14730                 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
14731                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14732                 broadcastIntentLocked(null, null, intent,
14733                         null, null, 0, null, null,
14734                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
14735                         false, false, MY_PID, Process.SYSTEM_UID, userId);
14736             }
14737             int num = mUserLru.size();
14738             int i = 0;
14739             while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
14740                 Integer oldUserId = mUserLru.get(i);
14741                 UserStartedState oldUss = mStartedUsers.get(oldUserId);
14742                 if (oldUss == null) {
14743                     // Shouldn't happen, but be sane if it does.
14744                     mUserLru.remove(i);
14745                     num--;
14746                     continue;
14747                 }
14748                 if (oldUss.mState == UserStartedState.STATE_STOPPING
14749                         || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
14750                     // This user is already stopping, doesn't count.
14751                     num--;
14752                     i++;
14753                     continue;
14754                 }
14755                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
14756                     // Owner and current can't be stopped, but count as running.
14757                     i++;
14758                     continue;
14759                 }
14760                 // This is a user to be stopped.
14761                 stopUserLocked(oldUserId, null);
14762                 num--;
14763                 i++;
14764             }
14765         }
14766     }
14767 
14768     @Override
stopUser(final int userId, final IStopUserCallback callback)14769     public int stopUser(final int userId, final IStopUserCallback callback) {
14770         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14771                 != PackageManager.PERMISSION_GRANTED) {
14772             String msg = "Permission Denial: switchUser() from pid="
14773                     + Binder.getCallingPid()
14774                     + ", uid=" + Binder.getCallingUid()
14775                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14776             Slog.w(TAG, msg);
14777             throw new SecurityException(msg);
14778         }
14779         if (userId <= 0) {
14780             throw new IllegalArgumentException("Can't stop primary user " + userId);
14781         }
14782         synchronized (this) {
14783             return stopUserLocked(userId, callback);
14784         }
14785     }
14786 
stopUserLocked(final int userId, final IStopUserCallback callback)14787     private int stopUserLocked(final int userId, final IStopUserCallback callback) {
14788         if (mCurrentUserId == userId) {
14789             return ActivityManager.USER_OP_IS_CURRENT;
14790         }
14791 
14792         final UserStartedState uss = mStartedUsers.get(userId);
14793         if (uss == null) {
14794             // User is not started, nothing to do...  but we do need to
14795             // callback if requested.
14796             if (callback != null) {
14797                 mHandler.post(new Runnable() {
14798                     @Override
14799                     public void run() {
14800                         try {
14801                             callback.userStopped(userId);
14802                         } catch (RemoteException e) {
14803                         }
14804                     }
14805                 });
14806             }
14807             return ActivityManager.USER_OP_SUCCESS;
14808         }
14809 
14810         if (callback != null) {
14811             uss.mStopCallbacks.add(callback);
14812         }
14813 
14814         if (uss.mState != UserStartedState.STATE_STOPPING
14815                 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14816             uss.mState = UserStartedState.STATE_STOPPING;
14817             updateStartedUserArrayLocked();
14818 
14819             long ident = Binder.clearCallingIdentity();
14820             try {
14821                 // We are going to broadcast ACTION_USER_STOPPING and then
14822                 // once that is done send a final ACTION_SHUTDOWN and then
14823                 // stop the user.
14824                 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
14825                 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14826                 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14827                 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
14828                 // This is the result receiver for the final shutdown broadcast.
14829                 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
14830                     @Override
14831                     public void performReceive(Intent intent, int resultCode, String data,
14832                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14833                         finishUserStop(uss);
14834                     }
14835                 };
14836                 // This is the result receiver for the initial stopping broadcast.
14837                 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
14838                     @Override
14839                     public void performReceive(Intent intent, int resultCode, String data,
14840                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14841                         // On to the next.
14842                         synchronized (ActivityManagerService.this) {
14843                             if (uss.mState != UserStartedState.STATE_STOPPING) {
14844                                 // Whoops, we are being started back up.  Abort, abort!
14845                                 return;
14846                             }
14847                             uss.mState = UserStartedState.STATE_SHUTDOWN;
14848                         }
14849                         broadcastIntentLocked(null, null, shutdownIntent,
14850                                 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
14851                                 true, false, MY_PID, Process.SYSTEM_UID, userId);
14852                     }
14853                 };
14854                 // Kick things off.
14855                 broadcastIntentLocked(null, null, stoppingIntent,
14856                         null, stoppingReceiver, 0, null, null,
14857                         android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
14858                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14859             } finally {
14860                 Binder.restoreCallingIdentity(ident);
14861             }
14862         }
14863 
14864         return ActivityManager.USER_OP_SUCCESS;
14865     }
14866 
finishUserStop(UserStartedState uss)14867     void finishUserStop(UserStartedState uss) {
14868         final int userId = uss.mHandle.getIdentifier();
14869         boolean stopped;
14870         ArrayList<IStopUserCallback> callbacks;
14871         synchronized (this) {
14872             callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
14873             if (mStartedUsers.get(userId) != uss) {
14874                 stopped = false;
14875             } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
14876                 stopped = false;
14877             } else {
14878                 stopped = true;
14879                 // User can no longer run.
14880                 mStartedUsers.remove(userId);
14881                 mUserLru.remove(Integer.valueOf(userId));
14882                 updateStartedUserArrayLocked();
14883 
14884                 // Clean up all state and processes associated with the user.
14885                 // Kill all the processes for the user.
14886                 forceStopUserLocked(userId);
14887             }
14888         }
14889 
14890         for (int i=0; i<callbacks.size(); i++) {
14891             try {
14892                 if (stopped) callbacks.get(i).userStopped(userId);
14893                 else callbacks.get(i).userStopAborted(userId);
14894             } catch (RemoteException e) {
14895             }
14896         }
14897     }
14898 
14899     @Override
getCurrentUser()14900     public UserInfo getCurrentUser() {
14901         if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14902                 != PackageManager.PERMISSION_GRANTED) && (
14903                 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14904                 != PackageManager.PERMISSION_GRANTED)) {
14905             String msg = "Permission Denial: getCurrentUser() from pid="
14906                     + Binder.getCallingPid()
14907                     + ", uid=" + Binder.getCallingUid()
14908                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14909             Slog.w(TAG, msg);
14910             throw new SecurityException(msg);
14911         }
14912         synchronized (this) {
14913             return getUserManagerLocked().getUserInfo(mCurrentUserId);
14914         }
14915     }
14916 
getCurrentUserIdLocked()14917     int getCurrentUserIdLocked() {
14918         return mCurrentUserId;
14919     }
14920 
14921     @Override
isUserRunning(int userId, boolean orStopped)14922     public boolean isUserRunning(int userId, boolean orStopped) {
14923         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14924                 != PackageManager.PERMISSION_GRANTED) {
14925             String msg = "Permission Denial: isUserRunning() from pid="
14926                     + Binder.getCallingPid()
14927                     + ", uid=" + Binder.getCallingUid()
14928                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14929             Slog.w(TAG, msg);
14930             throw new SecurityException(msg);
14931         }
14932         synchronized (this) {
14933             return isUserRunningLocked(userId, orStopped);
14934         }
14935     }
14936 
isUserRunningLocked(int userId, boolean orStopped)14937     boolean isUserRunningLocked(int userId, boolean orStopped) {
14938         UserStartedState state = mStartedUsers.get(userId);
14939         if (state == null) {
14940             return false;
14941         }
14942         if (orStopped) {
14943             return true;
14944         }
14945         return state.mState != UserStartedState.STATE_STOPPING
14946                 && state.mState != UserStartedState.STATE_SHUTDOWN;
14947     }
14948 
14949     @Override
getRunningUserIds()14950     public int[] getRunningUserIds() {
14951         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14952                 != PackageManager.PERMISSION_GRANTED) {
14953             String msg = "Permission Denial: isUserRunning() from pid="
14954                     + Binder.getCallingPid()
14955                     + ", uid=" + Binder.getCallingUid()
14956                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14957             Slog.w(TAG, msg);
14958             throw new SecurityException(msg);
14959         }
14960         synchronized (this) {
14961             return mStartedUserArray;
14962         }
14963     }
14964 
updateStartedUserArrayLocked()14965     private void updateStartedUserArrayLocked() {
14966         int num = 0;
14967         for (int i=0; i<mStartedUsers.size();  i++) {
14968             UserStartedState uss = mStartedUsers.valueAt(i);
14969             // This list does not include stopping users.
14970             if (uss.mState != UserStartedState.STATE_STOPPING
14971                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14972                 num++;
14973             }
14974         }
14975         mStartedUserArray = new int[num];
14976         num = 0;
14977         for (int i=0; i<mStartedUsers.size();  i++) {
14978             UserStartedState uss = mStartedUsers.valueAt(i);
14979             if (uss.mState != UserStartedState.STATE_STOPPING
14980                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14981                 mStartedUserArray[num] = mStartedUsers.keyAt(i);
14982                 num++;
14983             }
14984         }
14985     }
14986 
14987     @Override
registerUserSwitchObserver(IUserSwitchObserver observer)14988     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
14989         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14990                 != PackageManager.PERMISSION_GRANTED) {
14991             String msg = "Permission Denial: registerUserSwitchObserver() from pid="
14992                     + Binder.getCallingPid()
14993                     + ", uid=" + Binder.getCallingUid()
14994                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14995             Slog.w(TAG, msg);
14996             throw new SecurityException(msg);
14997         }
14998 
14999         mUserSwitchObservers.register(observer);
15000     }
15001 
15002     @Override
unregisterUserSwitchObserver(IUserSwitchObserver observer)15003     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
15004         mUserSwitchObservers.unregister(observer);
15005     }
15006 
userExists(int userId)15007     private boolean userExists(int userId) {
15008         if (userId == 0) {
15009             return true;
15010         }
15011         UserManagerService ums = getUserManagerLocked();
15012         return ums != null ? (ums.getUserInfo(userId) != null) : false;
15013     }
15014 
getUsersLocked()15015     int[] getUsersLocked() {
15016         UserManagerService ums = getUserManagerLocked();
15017         return ums != null ? ums.getUserIds() : new int[] { 0 };
15018     }
15019 
getUserManagerLocked()15020     UserManagerService getUserManagerLocked() {
15021         if (mUserManager == null) {
15022             IBinder b = ServiceManager.getService(Context.USER_SERVICE);
15023             mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
15024         }
15025         return mUserManager;
15026     }
15027 
checkValidCaller(int uid, int userId)15028     private void checkValidCaller(int uid, int userId) {
15029         if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
15030 
15031         throw new SecurityException("Caller uid=" + uid
15032                 + " is not privileged to communicate with user=" + userId);
15033     }
15034 
applyUserId(int uid, int userId)15035     private int applyUserId(int uid, int userId) {
15036         return UserHandle.getUid(userId, uid);
15037     }
15038 
getAppInfoForUser(ApplicationInfo info, int userId)15039     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
15040         if (info == null) return null;
15041         ApplicationInfo newInfo = new ApplicationInfo(info);
15042         newInfo.uid = applyUserId(info.uid, userId);
15043         newInfo.dataDir = USER_DATA_DIR + userId + "/"
15044                 + info.packageName;
15045         return newInfo;
15046     }
15047 
getActivityInfoForUser(ActivityInfo aInfo, int userId)15048     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
15049         if (aInfo == null
15050                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
15051             return aInfo;
15052         }
15053 
15054         ActivityInfo info = new ActivityInfo(aInfo);
15055         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
15056         return info;
15057     }
15058 }
15059