• 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 com.android.internal.R;
22 import com.android.internal.os.BatteryStatsImpl;
23 import com.android.internal.os.ProcessStats;
24 import com.android.server.AttributeCache;
25 import com.android.server.IntentResolver;
26 import com.android.server.ProcessMap;
27 import com.android.server.SystemServer;
28 import com.android.server.Watchdog;
29 import com.android.server.am.ActivityStack.ActivityState;
30 import com.android.server.pm.UserManagerService;
31 import com.android.server.wm.WindowManagerService;
32 
33 import dalvik.system.Zygote;
34 
35 import android.app.Activity;
36 import android.app.ActivityManager;
37 import android.app.ActivityManagerNative;
38 import android.app.ActivityOptions;
39 import android.app.ActivityThread;
40 import android.app.AlertDialog;
41 import android.app.AppGlobals;
42 import android.app.ApplicationErrorReport;
43 import android.app.Dialog;
44 import android.app.IActivityController;
45 import android.app.IApplicationThread;
46 import android.app.IInstrumentationWatcher;
47 import android.app.INotificationManager;
48 import android.app.IProcessObserver;
49 import android.app.IServiceConnection;
50 import android.app.IStopUserCallback;
51 import android.app.IThumbnailReceiver;
52 import android.app.IUserSwitchObserver;
53 import android.app.Instrumentation;
54 import android.app.Notification;
55 import android.app.NotificationManager;
56 import android.app.PendingIntent;
57 import android.app.backup.IBackupManager;
58 import android.content.ActivityNotFoundException;
59 import android.content.BroadcastReceiver;
60 import android.content.ClipData;
61 import android.content.ComponentCallbacks2;
62 import android.content.ComponentName;
63 import android.content.ContentProvider;
64 import android.content.ContentResolver;
65 import android.content.Context;
66 import android.content.DialogInterface;
67 import android.content.IContentProvider;
68 import android.content.IIntentReceiver;
69 import android.content.IIntentSender;
70 import android.content.Intent;
71 import android.content.IntentFilter;
72 import android.content.IntentSender;
73 import android.content.pm.ActivityInfo;
74 import android.content.pm.ApplicationInfo;
75 import android.content.pm.ConfigurationInfo;
76 import android.content.pm.IPackageDataObserver;
77 import android.content.pm.IPackageManager;
78 import android.content.pm.InstrumentationInfo;
79 import android.content.pm.PackageInfo;
80 import android.content.pm.PackageManager;
81 import android.content.pm.UserInfo;
82 import android.content.pm.PackageManager.NameNotFoundException;
83 import android.content.pm.PathPermission;
84 import android.content.pm.ProviderInfo;
85 import android.content.pm.ResolveInfo;
86 import android.content.pm.ServiceInfo;
87 import android.content.res.CompatibilityInfo;
88 import android.content.res.Configuration;
89 import android.graphics.Bitmap;
90 import android.net.Proxy;
91 import android.net.ProxyProperties;
92 import android.net.Uri;
93 import android.os.Binder;
94 import android.os.Build;
95 import android.os.Bundle;
96 import android.os.Debug;
97 import android.os.DropBoxManager;
98 import android.os.Environment;
99 import android.os.FileObserver;
100 import android.os.FileUtils;
101 import android.os.Handler;
102 import android.os.IBinder;
103 import android.os.IPermissionController;
104 import android.os.IRemoteCallback;
105 import android.os.IUserManager;
106 import android.os.Looper;
107 import android.os.Message;
108 import android.os.Parcel;
109 import android.os.ParcelFileDescriptor;
110 import android.os.Process;
111 import android.os.RemoteCallbackList;
112 import android.os.RemoteException;
113 import android.os.SELinux;
114 import android.os.ServiceManager;
115 import android.os.StrictMode;
116 import android.os.SystemClock;
117 import android.os.SystemProperties;
118 import android.os.UserHandle;
119 import android.provider.Settings;
120 import android.text.format.Time;
121 import android.util.EventLog;
122 import android.util.Log;
123 import android.util.Pair;
124 import android.util.PrintWriterPrinter;
125 import android.util.Slog;
126 import android.util.SparseArray;
127 import android.util.TimeUtils;
128 import android.view.Gravity;
129 import android.view.LayoutInflater;
130 import android.view.View;
131 import android.view.WindowManager;
132 import android.view.WindowManagerPolicy;
133 
134 import java.io.BufferedInputStream;
135 import java.io.BufferedOutputStream;
136 import java.io.BufferedReader;
137 import java.io.DataInputStream;
138 import java.io.DataOutputStream;
139 import java.io.File;
140 import java.io.FileDescriptor;
141 import java.io.FileInputStream;
142 import java.io.FileNotFoundException;
143 import java.io.FileOutputStream;
144 import java.io.IOException;
145 import java.io.InputStreamReader;
146 import java.io.PrintWriter;
147 import java.io.StringWriter;
148 import java.lang.ref.WeakReference;
149 import java.util.ArrayList;
150 import java.util.Arrays;
151 import java.util.Collections;
152 import java.util.Comparator;
153 import java.util.HashMap;
154 import java.util.HashSet;
155 import java.util.Iterator;
156 import java.util.List;
157 import java.util.Locale;
158 import java.util.Map;
159 import java.util.Set;
160 import java.util.concurrent.atomic.AtomicBoolean;
161 import java.util.concurrent.atomic.AtomicLong;
162 
163 public final class ActivityManagerService extends ActivityManagerNative
164         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
165     private static final String USER_DATA_DIR = "/data/user/";
166     static final String TAG = "ActivityManager";
167     static final String TAG_MU = "ActivityManagerServiceMU";
168     static final boolean DEBUG = false;
169     static final boolean localLOGV = DEBUG;
170     static final boolean DEBUG_SWITCH = localLOGV || false;
171     static final boolean DEBUG_TASKS = localLOGV || false;
172     static final boolean DEBUG_THUMBNAILS = localLOGV || false;
173     static final boolean DEBUG_PAUSE = localLOGV || false;
174     static final boolean DEBUG_OOM_ADJ = localLOGV || false;
175     static final boolean DEBUG_TRANSITION = localLOGV || false;
176     static final boolean DEBUG_BROADCAST = localLOGV || false;
177     static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
178     static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
179     static final boolean DEBUG_SERVICE = localLOGV || false;
180     static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
181     static final boolean DEBUG_VISBILITY = localLOGV || false;
182     static final boolean DEBUG_PROCESSES = localLOGV || false;
183     static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
184     static final boolean DEBUG_CLEANUP = localLOGV || false;
185     static final boolean DEBUG_PROVIDER = localLOGV || false;
186     static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
187     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
188     static final boolean DEBUG_RESULTS = localLOGV || false;
189     static final boolean DEBUG_BACKUP = localLOGV || false;
190     static final boolean DEBUG_CONFIGURATION = localLOGV || false;
191     static final boolean DEBUG_POWER = localLOGV || false;
192     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
193     static final boolean DEBUG_MU = localLOGV || false;
194     static final boolean VALIDATE_TOKENS = false;
195     static final boolean SHOW_ACTIVITY_START_TIME = true;
196 
197     // Control over CPU and battery monitoring.
198     static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
199     static final boolean MONITOR_CPU_USAGE = true;
200     static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
201     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
202     static final boolean MONITOR_THREAD_CPU_USAGE = false;
203 
204     // The flags that are set for all calls we make to the package manager.
205     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
206 
207     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
208 
209     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
210 
211     // Maximum number of recent tasks that we can remember.
212     static final int MAX_RECENT_TASKS = 20;
213 
214     // Amount of time after a call to stopAppSwitches() during which we will
215     // prevent further untrusted switches from happening.
216     static final long APP_SWITCH_DELAY_TIME = 5*1000;
217 
218     // How long we wait for a launched process to attach to the activity manager
219     // before we decide it's never going to come up for real.
220     static final int PROC_START_TIMEOUT = 10*1000;
221 
222     // How long we wait for a launched process to attach to the activity manager
223     // before we decide it's never going to come up for real, when the process was
224     // started with a wrapper for instrumentation (such as Valgrind) because it
225     // could take much longer than usual.
226     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
227 
228     // How long to wait after going idle before forcing apps to GC.
229     static final int GC_TIMEOUT = 5*1000;
230 
231     // The minimum amount of time between successive GC requests for a process.
232     static final int GC_MIN_INTERVAL = 60*1000;
233 
234     // The rate at which we check for apps using excessive power -- 15 mins.
235     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
236 
237     // The minimum sample duration we will allow before deciding we have
238     // enough data on wake locks to start killing things.
239     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
240 
241     // The minimum sample duration we will allow before deciding we have
242     // enough data on CPU usage to start killing things.
243     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
244 
245     // How long we allow a receiver to run before giving up on it.
246     static final int BROADCAST_FG_TIMEOUT = 10*1000;
247     static final int BROADCAST_BG_TIMEOUT = 60*1000;
248 
249     // How long we wait until we timeout on key dispatching.
250     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
251 
252     // How long we wait until we timeout on key dispatching during instrumentation.
253     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
254 
255     // Amount of time we wait for observers to handle a user switch before
256     // giving up on them and unfreezing the screen.
257     static final int USER_SWITCH_TIMEOUT = 2*1000;
258 
259     // Maximum number of users we allow to be running at a time.
260     static final int MAX_RUNNING_USERS = 3;
261 
262     static final int MY_PID = Process.myPid();
263 
264     static final String[] EMPTY_STRING_ARRAY = new String[0];
265 
266     public ActivityStack mMainStack;
267 
268     private final boolean mHeadless;
269 
270     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
271     // default actuion automatically.  Important for devices without direct input
272     // devices.
273     private boolean mShowDialogs = true;
274 
275     /**
276      * Description of a request to start a new activity, which has been held
277      * due to app switches being disabled.
278      */
279     static class PendingActivityLaunch {
280         ActivityRecord r;
281         ActivityRecord sourceRecord;
282         int startFlags;
283     }
284 
285     final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
286             = new ArrayList<PendingActivityLaunch>();
287 
288 
289     BroadcastQueue mFgBroadcastQueue;
290     BroadcastQueue mBgBroadcastQueue;
291     // Convenient for easy iteration over the queues. Foreground is first
292     // so that dispatch of foreground broadcasts gets precedence.
293     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
294 
broadcastQueueForIntent(Intent intent)295     BroadcastQueue broadcastQueueForIntent(Intent intent) {
296         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
297         if (DEBUG_BACKGROUND_BROADCAST) {
298             Slog.i(TAG, "Broadcast intent " + intent + " on "
299                     + (isFg ? "foreground" : "background")
300                     + " queue");
301         }
302         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
303     }
304 
broadcastRecordForReceiverLocked(IBinder receiver)305     BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
306         for (BroadcastQueue queue : mBroadcastQueues) {
307             BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
308             if (r != null) {
309                 return r;
310             }
311         }
312         return null;
313     }
314 
315     /**
316      * Activity we have told the window manager to have key focus.
317      */
318     ActivityRecord mFocusedActivity = null;
319     /**
320      * List of intents that were used to start the most recent tasks.
321      */
322     final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
323 
324     /**
325      * Process management.
326      */
327     final ProcessList mProcessList = new ProcessList();
328 
329     /**
330      * All of the applications we currently have running organized by name.
331      * The keys are strings of the application package name (as
332      * returned by the package manager), and the keys are ApplicationRecord
333      * objects.
334      */
335     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
336 
337     /**
338      * The currently running isolated processes.
339      */
340     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
341 
342     /**
343      * Counter for assigning isolated process uids, to avoid frequently reusing the
344      * same ones.
345      */
346     int mNextIsolatedProcessUid = 0;
347 
348     /**
349      * The currently running heavy-weight process, if any.
350      */
351     ProcessRecord mHeavyWeightProcess = null;
352 
353     /**
354      * The last time that various processes have crashed.
355      */
356     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
357 
358     /**
359      * Set of applications that we consider to be bad, and will reject
360      * incoming broadcasts from (which the user has no control over).
361      * Processes are added to this set when they have crashed twice within
362      * a minimum amount of time; they are removed from it when they are
363      * later restarted (hopefully due to some user action).  The value is the
364      * time it was added to the list.
365      */
366     final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
367 
368     /**
369      * All of the processes we currently have running organized by pid.
370      * The keys are the pid running the application.
371      *
372      * <p>NOTE: This object is protected by its own lock, NOT the global
373      * activity manager lock!
374      */
375     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
376 
377     /**
378      * All of the processes that have been forced to be foreground.  The key
379      * is the pid of the caller who requested it (we hold a death
380      * link on it).
381      */
382     abstract class ForegroundToken implements IBinder.DeathRecipient {
383         int pid;
384         IBinder token;
385     }
386     final SparseArray<ForegroundToken> mForegroundProcesses
387             = new SparseArray<ForegroundToken>();
388 
389     /**
390      * List of records for processes that someone had tried to start before the
391      * system was ready.  We don't start them at that point, but ensure they
392      * are started by the time booting is complete.
393      */
394     final ArrayList<ProcessRecord> mProcessesOnHold
395             = new ArrayList<ProcessRecord>();
396 
397     /**
398      * List of persistent applications that are in the process
399      * of being started.
400      */
401     final ArrayList<ProcessRecord> mPersistentStartingProcesses
402             = new ArrayList<ProcessRecord>();
403 
404     /**
405      * Processes that are being forcibly torn down.
406      */
407     final ArrayList<ProcessRecord> mRemovedProcesses
408             = new ArrayList<ProcessRecord>();
409 
410     /**
411      * List of running applications, sorted by recent usage.
412      * The first entry in the list is the least recently used.
413      * It contains ApplicationRecord objects.  This list does NOT include
414      * any persistent application records (since we never want to exit them).
415      */
416     final ArrayList<ProcessRecord> mLruProcesses
417             = new ArrayList<ProcessRecord>();
418 
419     /**
420      * List of processes that should gc as soon as things are idle.
421      */
422     final ArrayList<ProcessRecord> mProcessesToGc
423             = new ArrayList<ProcessRecord>();
424 
425     /**
426      * This is the process holding what we currently consider to be
427      * the "home" activity.
428      */
429     ProcessRecord mHomeProcess;
430 
431     /**
432      * This is the process holding the activity the user last visited that
433      * is in a different process from the one they are currently in.
434      */
435     ProcessRecord mPreviousProcess;
436 
437     /**
438      * The time at which the previous process was last visible.
439      */
440     long mPreviousProcessVisibleTime;
441 
442     /**
443      * Which uses have been started, so are allowed to run code.
444      */
445     final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
446 
447     /**
448      * LRU list of history of current users.  Most recently current is at the end.
449      */
450     final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
451 
452     /**
453      * Constant array of the users that are currently started.
454      */
455     int[] mStartedUserArray = new int[] { 0 };
456 
457     /**
458      * Registered observers of the user switching mechanics.
459      */
460     final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
461             = new RemoteCallbackList<IUserSwitchObserver>();
462 
463     /**
464      * Currently active user switch.
465      */
466     Object mCurUserSwitchCallback;
467 
468     /**
469      * Packages that the user has asked to have run in screen size
470      * compatibility mode instead of filling the screen.
471      */
472     final CompatModePackages mCompatModePackages;
473 
474     /**
475      * Set of PendingResultRecord objects that are currently active.
476      */
477     final HashSet mPendingResultRecords = new HashSet();
478 
479     /**
480      * Set of IntentSenderRecord objects that are currently active.
481      */
482     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
483             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
484 
485     /**
486      * Fingerprints (hashCode()) of stack traces that we've
487      * already logged DropBox entries for.  Guarded by itself.  If
488      * something (rogue user app) forces this over
489      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
490      */
491     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
492     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
493 
494     /**
495      * Strict Mode background batched logging state.
496      *
497      * The string buffer is guarded by itself, and its lock is also
498      * used to determine if another batched write is already
499      * in-flight.
500      */
501     private final StringBuilder mStrictModeBuffer = new StringBuilder();
502 
503     /**
504      * Keeps track of all IIntentReceivers that have been registered for
505      * broadcasts.  Hash keys are the receiver IBinder, hash value is
506      * a ReceiverList.
507      */
508     final HashMap mRegisteredReceivers = new HashMap();
509 
510     /**
511      * Resolver for broadcast intents to registered receivers.
512      * Holds BroadcastFilter (subclass of IntentFilter).
513      */
514     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
515             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
516         @Override
517         protected boolean allowFilterResult(
518                 BroadcastFilter filter, List<BroadcastFilter> dest) {
519             IBinder target = filter.receiverList.receiver.asBinder();
520             for (int i=dest.size()-1; i>=0; i--) {
521                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
522                     return false;
523                 }
524             }
525             return true;
526         }
527 
528         @Override
529         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
530             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
531                     || userId == filter.owningUserId) {
532                 return super.newResult(filter, match, userId);
533             }
534             return null;
535         }
536 
537         @Override
538         protected BroadcastFilter[] newArray(int size) {
539             return new BroadcastFilter[size];
540         }
541 
542         @Override
543         protected String packageForFilter(BroadcastFilter filter) {
544             return filter.packageName;
545         }
546     };
547 
548     /**
549      * State of all active sticky broadcasts per user.  Keys are the action of the
550      * sticky Intent, values are an ArrayList of all broadcasted intents with
551      * that action (which should usually be one).  The SparseArray is keyed
552      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
553      * for stickies that are sent to all users.
554      */
555     final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
556             new SparseArray<HashMap<String, ArrayList<Intent>>>();
557 
558     final ActiveServices mServices;
559 
560     /**
561      * Backup/restore process management
562      */
563     String mBackupAppName = null;
564     BackupRecord mBackupTarget = null;
565 
566     /**
567      * List of PendingThumbnailsRecord objects of clients who are still
568      * waiting to receive all of the thumbnails for a task.
569      */
570     final ArrayList mPendingThumbnails = new ArrayList();
571 
572     /**
573      * List of HistoryRecord objects that have been finished and must
574      * still report back to a pending thumbnail receiver.
575      */
576     final ArrayList mCancelledThumbnails = new ArrayList();
577 
578     final ProviderMap mProviderMap;
579 
580     /**
581      * List of content providers who have clients waiting for them.  The
582      * application is currently being launched and the provider will be
583      * removed from this list once it is published.
584      */
585     final ArrayList<ContentProviderRecord> mLaunchingProviders
586             = new ArrayList<ContentProviderRecord>();
587 
588     /**
589      * Global set of specific Uri permissions that have been granted.
590      */
591     final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
592             = new SparseArray<HashMap<Uri, UriPermission>>();
593 
594     CoreSettingsObserver mCoreSettingsObserver;
595 
596     /**
597      * Thread-local storage used to carry caller permissions over through
598      * indirect content-provider access.
599      * @see #ActivityManagerService.openContentUri()
600      */
601     private class Identity {
602         public int pid;
603         public int uid;
604 
Identity(int _pid, int _uid)605         Identity(int _pid, int _uid) {
606             pid = _pid;
607             uid = _uid;
608         }
609     }
610 
611     private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
612 
613     /**
614      * All information we have collected about the runtime performance of
615      * any user id that can impact battery performance.
616      */
617     final BatteryStatsService mBatteryStatsService;
618 
619     /**
620      * information about component usage
621      */
622     final UsageStatsService mUsageStatsService;
623 
624     /**
625      * Current configuration information.  HistoryRecord objects are given
626      * a reference to this object to indicate which configuration they are
627      * currently running in, so this object must be kept immutable.
628      */
629     Configuration mConfiguration = new Configuration();
630 
631     /**
632      * Current sequencing integer of the configuration, for skipping old
633      * configurations.
634      */
635     int mConfigurationSeq = 0;
636 
637     /**
638      * Hardware-reported OpenGLES version.
639      */
640     final int GL_ES_VERSION;
641 
642     /**
643      * List of initialization arguments to pass to all processes when binding applications to them.
644      * For example, references to the commonly used services.
645      */
646     HashMap<String, IBinder> mAppBindArgs;
647 
648     /**
649      * Temporary to avoid allocations.  Protected by main lock.
650      */
651     final StringBuilder mStringBuilder = new StringBuilder(256);
652 
653     /**
654      * Used to control how we initialize the service.
655      */
656     boolean mStartRunning = false;
657     ComponentName mTopComponent;
658     String mTopAction;
659     String mTopData;
660     boolean mProcessesReady = false;
661     boolean mSystemReady = false;
662     boolean mBooting = false;
663     boolean mWaitingUpdate = false;
664     boolean mDidUpdate = false;
665     boolean mOnBattery = false;
666     boolean mLaunchWarningShown = false;
667 
668     Context mContext;
669 
670     int mFactoryTest;
671 
672     boolean mCheckedForSetup;
673 
674     /**
675      * The time at which we will allow normal application switches again,
676      * after a call to {@link #stopAppSwitches()}.
677      */
678     long mAppSwitchesAllowedTime;
679 
680     /**
681      * This is set to true after the first switch after mAppSwitchesAllowedTime
682      * is set; any switches after that will clear the time.
683      */
684     boolean mDidAppSwitch;
685 
686     /**
687      * Last time (in realtime) at which we checked for power usage.
688      */
689     long mLastPowerCheckRealtime;
690 
691     /**
692      * Last time (in uptime) at which we checked for power usage.
693      */
694     long mLastPowerCheckUptime;
695 
696     /**
697      * Set while we are wanting to sleep, to prevent any
698      * activities from being started/resumed.
699      */
700     boolean mSleeping = false;
701 
702     /**
703      * State of external calls telling us if the device is asleep.
704      */
705     boolean mWentToSleep = false;
706 
707     /**
708      * State of external call telling us if the lock screen is shown.
709      */
710     boolean mLockScreenShown = false;
711 
712     /**
713      * Set if we are shutting down the system, similar to sleeping.
714      */
715     boolean mShuttingDown = false;
716 
717     /**
718      * Task identifier that activities are currently being started
719      * in.  Incremented each time a new task is created.
720      * todo: Replace this with a TokenSpace class that generates non-repeating
721      * integers that won't wrap.
722      */
723     int mCurTask = 1;
724 
725     /**
726      * Current sequence id for oom_adj computation traversal.
727      */
728     int mAdjSeq = 0;
729 
730     /**
731      * Current sequence id for process LRU updating.
732      */
733     int mLruSeq = 0;
734 
735     /**
736      * Keep track of the non-hidden/empty process we last found, to help
737      * determine how to distribute hidden/empty processes next time.
738      */
739     int mNumNonHiddenProcs = 0;
740 
741     /**
742      * Keep track of the number of hidden procs, to balance oom adj
743      * distribution between those and empty procs.
744      */
745     int mNumHiddenProcs = 0;
746 
747     /**
748      * Keep track of the number of service processes we last found, to
749      * determine on the next iteration which should be B services.
750      */
751     int mNumServiceProcs = 0;
752     int mNewNumServiceProcs = 0;
753 
754     /**
755      * System monitoring: number of processes that died since the last
756      * N procs were started.
757      */
758     int[] mProcDeaths = new int[20];
759 
760     /**
761      * This is set if we had to do a delayed dexopt of an app before launching
762      * it, to increasing the ANR timeouts in that case.
763      */
764     boolean mDidDexOpt;
765 
766     String mDebugApp = null;
767     boolean mWaitForDebugger = false;
768     boolean mDebugTransient = false;
769     String mOrigDebugApp = null;
770     boolean mOrigWaitForDebugger = false;
771     boolean mAlwaysFinishActivities = false;
772     IActivityController mController = null;
773     String mProfileApp = null;
774     ProcessRecord mProfileProc = null;
775     String mProfileFile;
776     ParcelFileDescriptor mProfileFd;
777     int mProfileType = 0;
778     boolean mAutoStopProfiler = false;
779     String mOpenGlTraceApp = null;
780 
781     static class ProcessChangeItem {
782         static final int CHANGE_ACTIVITIES = 1<<0;
783         static final int CHANGE_IMPORTANCE= 1<<1;
784         int changes;
785         int uid;
786         int pid;
787         int importance;
788         boolean foregroundActivities;
789     }
790 
791     final RemoteCallbackList<IProcessObserver> mProcessObservers
792             = new RemoteCallbackList<IProcessObserver>();
793     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
794 
795     final ArrayList<ProcessChangeItem> mPendingProcessChanges
796             = new ArrayList<ProcessChangeItem>();
797     final ArrayList<ProcessChangeItem> mAvailProcessChanges
798             = new ArrayList<ProcessChangeItem>();
799 
800     /**
801      * Callback of last caller to {@link #requestPss}.
802      */
803     Runnable mRequestPssCallback;
804 
805     /**
806      * Remaining processes for which we are waiting results from the last
807      * call to {@link #requestPss}.
808      */
809     final ArrayList<ProcessRecord> mRequestPssList
810             = new ArrayList<ProcessRecord>();
811 
812     /**
813      * Runtime statistics collection thread.  This object's lock is used to
814      * protect all related state.
815      */
816     final Thread mProcessStatsThread;
817 
818     /**
819      * Used to collect process stats when showing not responding dialog.
820      * Protected by mProcessStatsThread.
821      */
822     final ProcessStats mProcessStats = new ProcessStats(
823             MONITOR_THREAD_CPU_USAGE);
824     final AtomicLong mLastCpuTime = new AtomicLong(0);
825     final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
826 
827     long mLastWriteTime = 0;
828 
829     /**
830      * Set to true after the system has finished booting.
831      */
832     boolean mBooted = false;
833 
834     int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
835     int mProcessLimitOverride = -1;
836 
837     WindowManagerService mWindowManager;
838 
839     static ActivityManagerService mSelf;
840     static ActivityThread mSystemThread;
841 
842     private int mCurrentUserId = 0;
843     private int[] mCurrentUserArray = new int[] { 0 };
844     private UserManagerService mUserManager;
845 
846     private final class AppDeathRecipient implements IBinder.DeathRecipient {
847         final ProcessRecord mApp;
848         final int mPid;
849         final IApplicationThread mAppThread;
850 
AppDeathRecipient(ProcessRecord app, int pid, IApplicationThread thread)851         AppDeathRecipient(ProcessRecord app, int pid,
852                 IApplicationThread thread) {
853             if (localLOGV) Slog.v(
854                 TAG, "New death recipient " + this
855                 + " for thread " + thread.asBinder());
856             mApp = app;
857             mPid = pid;
858             mAppThread = thread;
859         }
860 
binderDied()861         public void binderDied() {
862             if (localLOGV) Slog.v(
863                 TAG, "Death received in " + this
864                 + " for thread " + mAppThread.asBinder());
865             synchronized(ActivityManagerService.this) {
866                 appDiedLocked(mApp, mPid, mAppThread);
867             }
868         }
869     }
870 
871     static final int SHOW_ERROR_MSG = 1;
872     static final int SHOW_NOT_RESPONDING_MSG = 2;
873     static final int SHOW_FACTORY_ERROR_MSG = 3;
874     static final int UPDATE_CONFIGURATION_MSG = 4;
875     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
876     static final int WAIT_FOR_DEBUGGER_MSG = 6;
877     static final int SERVICE_TIMEOUT_MSG = 12;
878     static final int UPDATE_TIME_ZONE = 13;
879     static final int SHOW_UID_ERROR_MSG = 14;
880     static final int IM_FEELING_LUCKY_MSG = 15;
881     static final int PROC_START_TIMEOUT_MSG = 20;
882     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
883     static final int KILL_APPLICATION_MSG = 22;
884     static final int FINALIZE_PENDING_INTENT_MSG = 23;
885     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
886     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
887     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
888     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
889     static final int CLEAR_DNS_CACHE = 28;
890     static final int UPDATE_HTTP_PROXY = 29;
891     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
892     static final int DISPATCH_PROCESSES_CHANGED = 31;
893     static final int DISPATCH_PROCESS_DIED = 32;
894     static final int REPORT_MEM_USAGE = 33;
895     static final int REPORT_USER_SWITCH_MSG = 34;
896     static final int CONTINUE_USER_SWITCH_MSG = 35;
897     static final int USER_SWITCH_TIMEOUT_MSG = 36;
898 
899     static final int FIRST_ACTIVITY_STACK_MSG = 100;
900     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
901     static final int FIRST_COMPAT_MODE_MSG = 300;
902 
903     AlertDialog mUidAlert;
904     CompatModeDialog mCompatModeDialog;
905     long mLastMemUsageReportTime = 0;
906 
907     final Handler mHandler = new Handler() {
908         //public Handler() {
909         //    if (localLOGV) Slog.v(TAG, "Handler started!");
910         //}
911 
912         public void handleMessage(Message msg) {
913             switch (msg.what) {
914             case SHOW_ERROR_MSG: {
915                 HashMap data = (HashMap) msg.obj;
916                 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
917                         Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
918                 synchronized (ActivityManagerService.this) {
919                     ProcessRecord proc = (ProcessRecord)data.get("app");
920                     AppErrorResult res = (AppErrorResult) data.get("result");
921                     if (proc != null && proc.crashDialog != null) {
922                         Slog.e(TAG, "App already has crash dialog: " + proc);
923                         if (res != null) {
924                             res.set(0);
925                         }
926                         return;
927                     }
928                     if (!showBackground && UserHandle.getAppId(proc.uid)
929                             >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
930                             && proc.pid != MY_PID) {
931                         Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
932                         if (res != null) {
933                             res.set(0);
934                         }
935                         return;
936                     }
937                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
938                         Dialog d = new AppErrorDialog(mContext,
939                                 ActivityManagerService.this, res, proc);
940                         d.show();
941                         proc.crashDialog = d;
942                     } else {
943                         // The device is asleep, so just pretend that the user
944                         // saw a crash dialog and hit "force quit".
945                         if (res != null) {
946                             res.set(0);
947                         }
948                     }
949                 }
950 
951                 ensureBootCompleted();
952             } break;
953             case SHOW_NOT_RESPONDING_MSG: {
954                 synchronized (ActivityManagerService.this) {
955                     HashMap data = (HashMap) msg.obj;
956                     ProcessRecord proc = (ProcessRecord)data.get("app");
957                     if (proc != null && proc.anrDialog != null) {
958                         Slog.e(TAG, "App already has anr dialog: " + proc);
959                         return;
960                     }
961 
962                     Intent intent = new Intent("android.intent.action.ANR");
963                     if (!mProcessesReady) {
964                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
965                                 | Intent.FLAG_RECEIVER_FOREGROUND);
966                     }
967                     broadcastIntentLocked(null, null, intent,
968                             null, null, 0, null, null, null,
969                             false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
970 
971                     if (mShowDialogs) {
972                         Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
973                                 mContext, proc, (ActivityRecord)data.get("activity"),
974                                 msg.arg1 != 0);
975                         d.show();
976                         proc.anrDialog = d;
977                     } else {
978                         // Just kill the app if there is no dialog to be shown.
979                         killAppAtUsersRequest(proc, null);
980                     }
981                 }
982 
983                 ensureBootCompleted();
984             } break;
985             case SHOW_STRICT_MODE_VIOLATION_MSG: {
986                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
987                 synchronized (ActivityManagerService.this) {
988                     ProcessRecord proc = (ProcessRecord) data.get("app");
989                     if (proc == null) {
990                         Slog.e(TAG, "App not found when showing strict mode dialog.");
991                         break;
992                     }
993                     if (proc.crashDialog != null) {
994                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
995                         return;
996                     }
997                     AppErrorResult res = (AppErrorResult) data.get("result");
998                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
999                         Dialog d = new StrictModeViolationDialog(mContext,
1000                                 ActivityManagerService.this, res, proc);
1001                         d.show();
1002                         proc.crashDialog = d;
1003                     } else {
1004                         // The device is asleep, so just pretend that the user
1005                         // saw a crash dialog and hit "force quit".
1006                         res.set(0);
1007                     }
1008                 }
1009                 ensureBootCompleted();
1010             } break;
1011             case SHOW_FACTORY_ERROR_MSG: {
1012                 Dialog d = new FactoryErrorDialog(
1013                     mContext, msg.getData().getCharSequence("msg"));
1014                 d.show();
1015                 ensureBootCompleted();
1016             } break;
1017             case UPDATE_CONFIGURATION_MSG: {
1018                 final ContentResolver resolver = mContext.getContentResolver();
1019                 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1020             } break;
1021             case GC_BACKGROUND_PROCESSES_MSG: {
1022                 synchronized (ActivityManagerService.this) {
1023                     performAppGcsIfAppropriateLocked();
1024                 }
1025             } break;
1026             case WAIT_FOR_DEBUGGER_MSG: {
1027                 synchronized (ActivityManagerService.this) {
1028                     ProcessRecord app = (ProcessRecord)msg.obj;
1029                     if (msg.arg1 != 0) {
1030                         if (!app.waitedForDebugger) {
1031                             Dialog d = new AppWaitingForDebuggerDialog(
1032                                     ActivityManagerService.this,
1033                                     mContext, app);
1034                             app.waitDialog = d;
1035                             app.waitedForDebugger = true;
1036                             d.show();
1037                         }
1038                     } else {
1039                         if (app.waitDialog != null) {
1040                             app.waitDialog.dismiss();
1041                             app.waitDialog = null;
1042                         }
1043                     }
1044                 }
1045             } break;
1046             case SERVICE_TIMEOUT_MSG: {
1047                 if (mDidDexOpt) {
1048                     mDidDexOpt = false;
1049                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1050                     nmsg.obj = msg.obj;
1051                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1052                     return;
1053                 }
1054                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1055             } break;
1056             case UPDATE_TIME_ZONE: {
1057                 synchronized (ActivityManagerService.this) {
1058                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1059                         ProcessRecord r = mLruProcesses.get(i);
1060                         if (r.thread != null) {
1061                             try {
1062                                 r.thread.updateTimeZone();
1063                             } catch (RemoteException ex) {
1064                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1065                             }
1066                         }
1067                     }
1068                 }
1069             } break;
1070             case CLEAR_DNS_CACHE: {
1071                 synchronized (ActivityManagerService.this) {
1072                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1073                         ProcessRecord r = mLruProcesses.get(i);
1074                         if (r.thread != null) {
1075                             try {
1076                                 r.thread.clearDnsCache();
1077                             } catch (RemoteException ex) {
1078                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1079                             }
1080                         }
1081                     }
1082                 }
1083             } break;
1084             case UPDATE_HTTP_PROXY: {
1085                 ProxyProperties proxy = (ProxyProperties)msg.obj;
1086                 String host = "";
1087                 String port = "";
1088                 String exclList = "";
1089                 if (proxy != null) {
1090                     host = proxy.getHost();
1091                     port = Integer.toString(proxy.getPort());
1092                     exclList = proxy.getExclusionList();
1093                 }
1094                 synchronized (ActivityManagerService.this) {
1095                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1096                         ProcessRecord r = mLruProcesses.get(i);
1097                         if (r.thread != null) {
1098                             try {
1099                                 r.thread.setHttpProxy(host, port, exclList);
1100                             } catch (RemoteException ex) {
1101                                 Slog.w(TAG, "Failed to update http proxy for: " +
1102                                         r.info.processName);
1103                             }
1104                         }
1105                     }
1106                 }
1107             } break;
1108             case SHOW_UID_ERROR_MSG: {
1109                 String title = "System UIDs Inconsistent";
1110                 String text = "UIDs on the system are inconsistent, you need to wipe your"
1111                         + " data partition or your device will be unstable.";
1112                 Log.e(TAG, title + ": " + text);
1113                 if (mShowDialogs) {
1114                     // XXX This is a temporary dialog, no need to localize.
1115                     AlertDialog d = new BaseErrorDialog(mContext);
1116                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1117                     d.setCancelable(false);
1118                     d.setTitle(title);
1119                     d.setMessage(text);
1120                     d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1121                             mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1122                     mUidAlert = d;
1123                     d.show();
1124                 }
1125             } break;
1126             case IM_FEELING_LUCKY_MSG: {
1127                 if (mUidAlert != null) {
1128                     mUidAlert.dismiss();
1129                     mUidAlert = null;
1130                 }
1131             } break;
1132             case PROC_START_TIMEOUT_MSG: {
1133                 if (mDidDexOpt) {
1134                     mDidDexOpt = false;
1135                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1136                     nmsg.obj = msg.obj;
1137                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1138                     return;
1139                 }
1140                 ProcessRecord app = (ProcessRecord)msg.obj;
1141                 synchronized (ActivityManagerService.this) {
1142                     processStartTimedOutLocked(app);
1143                 }
1144             } break;
1145             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1146                 synchronized (ActivityManagerService.this) {
1147                     doPendingActivityLaunchesLocked(true);
1148                 }
1149             } break;
1150             case KILL_APPLICATION_MSG: {
1151                 synchronized (ActivityManagerService.this) {
1152                     int appid = msg.arg1;
1153                     boolean restart = (msg.arg2 == 1);
1154                     String pkg = (String) msg.obj;
1155                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
1156                             UserHandle.USER_ALL);
1157                 }
1158             } break;
1159             case FINALIZE_PENDING_INTENT_MSG: {
1160                 ((PendingIntentRecord)msg.obj).completeFinalize();
1161             } break;
1162             case POST_HEAVY_NOTIFICATION_MSG: {
1163                 INotificationManager inm = NotificationManager.getService();
1164                 if (inm == null) {
1165                     return;
1166                 }
1167 
1168                 ActivityRecord root = (ActivityRecord)msg.obj;
1169                 ProcessRecord process = root.app;
1170                 if (process == null) {
1171                     return;
1172                 }
1173 
1174                 try {
1175                     Context context = mContext.createPackageContext(process.info.packageName, 0);
1176                     String text = mContext.getString(R.string.heavy_weight_notification,
1177                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
1178                     Notification notification = new Notification();
1179                     notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1180                     notification.when = 0;
1181                     notification.flags = Notification.FLAG_ONGOING_EVENT;
1182                     notification.tickerText = text;
1183                     notification.defaults = 0; // please be quiet
1184                     notification.sound = null;
1185                     notification.vibrate = null;
1186                     notification.setLatestEventInfo(context, text,
1187                             mContext.getText(R.string.heavy_weight_notification_detail),
1188                             PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1189                                     PendingIntent.FLAG_CANCEL_CURRENT, null,
1190                                     new UserHandle(root.userId)));
1191 
1192                     try {
1193                         int[] outId = new int[1];
1194                         inm.enqueueNotificationWithTag("android", null,
1195                                 R.string.heavy_weight_notification,
1196                                 notification, outId, root.userId);
1197                     } catch (RuntimeException e) {
1198                         Slog.w(ActivityManagerService.TAG,
1199                                 "Error showing notification for heavy-weight app", e);
1200                     } catch (RemoteException e) {
1201                     }
1202                 } catch (NameNotFoundException e) {
1203                     Slog.w(TAG, "Unable to create context for heavy notification", e);
1204                 }
1205             } break;
1206             case CANCEL_HEAVY_NOTIFICATION_MSG: {
1207                 INotificationManager inm = NotificationManager.getService();
1208                 if (inm == null) {
1209                     return;
1210                 }
1211                 try {
1212                     inm.cancelNotificationWithTag("android", null,
1213                             R.string.heavy_weight_notification,  msg.arg1);
1214                 } catch (RuntimeException e) {
1215                     Slog.w(ActivityManagerService.TAG,
1216                             "Error canceling notification for service", e);
1217                 } catch (RemoteException e) {
1218                 }
1219             } break;
1220             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1221                 synchronized (ActivityManagerService.this) {
1222                     checkExcessivePowerUsageLocked(true);
1223                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1224                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1225                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1226                 }
1227             } break;
1228             case SHOW_COMPAT_MODE_DIALOG_MSG: {
1229                 synchronized (ActivityManagerService.this) {
1230                     ActivityRecord ar = (ActivityRecord)msg.obj;
1231                     if (mCompatModeDialog != null) {
1232                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1233                                 ar.info.applicationInfo.packageName)) {
1234                             return;
1235                         }
1236                         mCompatModeDialog.dismiss();
1237                         mCompatModeDialog = null;
1238                     }
1239                     if (ar != null && false) {
1240                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1241                                 ar.packageName)) {
1242                             int mode = mCompatModePackages.computeCompatModeLocked(
1243                                     ar.info.applicationInfo);
1244                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1245                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1246                                 mCompatModeDialog = new CompatModeDialog(
1247                                         ActivityManagerService.this, mContext,
1248                                         ar.info.applicationInfo);
1249                                 mCompatModeDialog.show();
1250                             }
1251                         }
1252                     }
1253                 }
1254                 break;
1255             }
1256             case DISPATCH_PROCESSES_CHANGED: {
1257                 dispatchProcessesChanged();
1258                 break;
1259             }
1260             case DISPATCH_PROCESS_DIED: {
1261                 final int pid = msg.arg1;
1262                 final int uid = msg.arg2;
1263                 dispatchProcessDied(pid, uid);
1264                 break;
1265             }
1266             case REPORT_MEM_USAGE: {
1267                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1268                 if (!isDebuggable) {
1269                     return;
1270                 }
1271                 synchronized (ActivityManagerService.this) {
1272                     long now = SystemClock.uptimeMillis();
1273                     if (now < (mLastMemUsageReportTime+5*60*1000)) {
1274                         // Don't report more than every 5 minutes to somewhat
1275                         // avoid spamming.
1276                         return;
1277                     }
1278                     mLastMemUsageReportTime = now;
1279                 }
1280                 Thread thread = new Thread() {
1281                     @Override public void run() {
1282                         StringBuilder dropBuilder = new StringBuilder(1024);
1283                         StringBuilder logBuilder = new StringBuilder(1024);
1284                         StringWriter oomSw = new StringWriter();
1285                         PrintWriter oomPw = new PrintWriter(oomSw);
1286                         StringWriter catSw = new StringWriter();
1287                         PrintWriter catPw = new PrintWriter(catSw);
1288                         String[] emptyArgs = new String[] { };
1289                         StringBuilder tag = new StringBuilder(128);
1290                         StringBuilder stack = new StringBuilder(128);
1291                         tag.append("Low on memory -- ");
1292                         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1293                                 tag, stack);
1294                         dropBuilder.append(stack);
1295                         dropBuilder.append('\n');
1296                         dropBuilder.append('\n');
1297                         String oomString = oomSw.toString();
1298                         dropBuilder.append(oomString);
1299                         dropBuilder.append('\n');
1300                         logBuilder.append(oomString);
1301                         try {
1302                             java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1303                                     "procrank", });
1304                             final InputStreamReader converter = new InputStreamReader(
1305                                     proc.getInputStream());
1306                             BufferedReader in = new BufferedReader(converter);
1307                             String line;
1308                             while (true) {
1309                                 line = in.readLine();
1310                                 if (line == null) {
1311                                     break;
1312                                 }
1313                                 if (line.length() > 0) {
1314                                     logBuilder.append(line);
1315                                     logBuilder.append('\n');
1316                                 }
1317                                 dropBuilder.append(line);
1318                                 dropBuilder.append('\n');
1319                             }
1320                             converter.close();
1321                         } catch (IOException e) {
1322                         }
1323                         synchronized (ActivityManagerService.this) {
1324                             catPw.println();
1325                             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1326                             catPw.println();
1327                             mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1328                                     false, false, null);
1329                             catPw.println();
1330                             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1331                         }
1332                         dropBuilder.append(catSw.toString());
1333                         addErrorToDropBox("lowmem", null, "system_server", null,
1334                                 null, tag.toString(), dropBuilder.toString(), null, null);
1335                         Slog.i(TAG, logBuilder.toString());
1336                         synchronized (ActivityManagerService.this) {
1337                             long now = SystemClock.uptimeMillis();
1338                             if (mLastMemUsageReportTime < now) {
1339                                 mLastMemUsageReportTime = now;
1340                             }
1341                         }
1342                     }
1343                 };
1344                 thread.start();
1345                 break;
1346             }
1347             case REPORT_USER_SWITCH_MSG: {
1348                 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1349                 break;
1350             }
1351             case CONTINUE_USER_SWITCH_MSG: {
1352                 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1353                 break;
1354             }
1355             case USER_SWITCH_TIMEOUT_MSG: {
1356                 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1357                 break;
1358             }
1359             }
1360         }
1361     };
1362 
setSystemProcess()1363     public static void setSystemProcess() {
1364         try {
1365             ActivityManagerService m = mSelf;
1366 
1367             ServiceManager.addService("activity", m, true);
1368             ServiceManager.addService("meminfo", new MemBinder(m));
1369             ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1370             ServiceManager.addService("dbinfo", new DbBinder(m));
1371             if (MONITOR_CPU_USAGE) {
1372                 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1373             }
1374             ServiceManager.addService("permission", new PermissionController(m));
1375 
1376             ApplicationInfo info =
1377                 mSelf.mContext.getPackageManager().getApplicationInfo(
1378                             "android", STOCK_PM_FLAGS);
1379             mSystemThread.installSystemApplicationInfo(info);
1380 
1381             synchronized (mSelf) {
1382                 ProcessRecord app = mSelf.newProcessRecordLocked(
1383                         mSystemThread.getApplicationThread(), info,
1384                         info.processName, false);
1385                 app.persistent = true;
1386                 app.pid = MY_PID;
1387                 app.maxAdj = ProcessList.SYSTEM_ADJ;
1388                 mSelf.mProcessNames.put(app.processName, app.uid, app);
1389                 synchronized (mSelf.mPidsSelfLocked) {
1390                     mSelf.mPidsSelfLocked.put(app.pid, app);
1391                 }
1392                 mSelf.updateLruProcessLocked(app, true);
1393             }
1394         } catch (PackageManager.NameNotFoundException e) {
1395             throw new RuntimeException(
1396                     "Unable to find android system package", e);
1397         }
1398     }
1399 
setWindowManager(WindowManagerService wm)1400     public void setWindowManager(WindowManagerService wm) {
1401         mWindowManager = wm;
1402     }
1403 
main(int factoryTest)1404     public static final Context main(int factoryTest) {
1405         AThread thr = new AThread();
1406         thr.start();
1407 
1408         synchronized (thr) {
1409             while (thr.mService == null) {
1410                 try {
1411                     thr.wait();
1412                 } catch (InterruptedException e) {
1413                 }
1414             }
1415         }
1416 
1417         ActivityManagerService m = thr.mService;
1418         mSelf = m;
1419         ActivityThread at = ActivityThread.systemMain();
1420         mSystemThread = at;
1421         Context context = at.getSystemContext();
1422         context.setTheme(android.R.style.Theme_Holo);
1423         m.mContext = context;
1424         m.mFactoryTest = factoryTest;
1425         m.mMainStack = new ActivityStack(m, context, true);
1426 
1427         m.mBatteryStatsService.publish(context);
1428         m.mUsageStatsService.publish(context);
1429 
1430         synchronized (thr) {
1431             thr.mReady = true;
1432             thr.notifyAll();
1433         }
1434 
1435         m.startRunning(null, null, null, null);
1436 
1437         return context;
1438     }
1439 
self()1440     public static ActivityManagerService self() {
1441         return mSelf;
1442     }
1443 
1444     static class AThread extends Thread {
1445         ActivityManagerService mService;
1446         boolean mReady = false;
1447 
AThread()1448         public AThread() {
1449             super("ActivityManager");
1450         }
1451 
run()1452         public void run() {
1453             Looper.prepare();
1454 
1455             android.os.Process.setThreadPriority(
1456                     android.os.Process.THREAD_PRIORITY_FOREGROUND);
1457             android.os.Process.setCanSelfBackground(false);
1458 
1459             ActivityManagerService m = new ActivityManagerService();
1460 
1461             synchronized (this) {
1462                 mService = m;
1463                 notifyAll();
1464             }
1465 
1466             synchronized (this) {
1467                 while (!mReady) {
1468                     try {
1469                         wait();
1470                     } catch (InterruptedException e) {
1471                     }
1472                 }
1473             }
1474 
1475             // For debug builds, log event loop stalls to dropbox for analysis.
1476             if (StrictMode.conditionallyEnableDebugLogging()) {
1477                 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1478             }
1479 
1480             Looper.loop();
1481         }
1482     }
1483 
1484     static class MemBinder extends Binder {
1485         ActivityManagerService mActivityManagerService;
MemBinder(ActivityManagerService activityManagerService)1486         MemBinder(ActivityManagerService activityManagerService) {
1487             mActivityManagerService = activityManagerService;
1488         }
1489 
1490         @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)1491         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1492             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1493                     != PackageManager.PERMISSION_GRANTED) {
1494                 pw.println("Permission Denial: can't dump meminfo from from pid="
1495                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1496                         + " without permission " + android.Manifest.permission.DUMP);
1497                 return;
1498             }
1499 
1500             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1501                     false, null, null, null);
1502         }
1503     }
1504 
1505     static class GraphicsBinder extends Binder {
1506         ActivityManagerService mActivityManagerService;
GraphicsBinder(ActivityManagerService activityManagerService)1507         GraphicsBinder(ActivityManagerService activityManagerService) {
1508             mActivityManagerService = activityManagerService;
1509         }
1510 
1511         @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)1512         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1513             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1514                     != PackageManager.PERMISSION_GRANTED) {
1515                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1516                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1517                         + " without permission " + android.Manifest.permission.DUMP);
1518                 return;
1519             }
1520 
1521             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1522         }
1523     }
1524 
1525     static class DbBinder extends Binder {
1526         ActivityManagerService mActivityManagerService;
DbBinder(ActivityManagerService activityManagerService)1527         DbBinder(ActivityManagerService activityManagerService) {
1528             mActivityManagerService = activityManagerService;
1529         }
1530 
1531         @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)1532         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1533             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1534                     != PackageManager.PERMISSION_GRANTED) {
1535                 pw.println("Permission Denial: can't dump dbinfo from from pid="
1536                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1537                         + " without permission " + android.Manifest.permission.DUMP);
1538                 return;
1539             }
1540 
1541             mActivityManagerService.dumpDbInfo(fd, pw, args);
1542         }
1543     }
1544 
1545     static class CpuBinder extends Binder {
1546         ActivityManagerService mActivityManagerService;
CpuBinder(ActivityManagerService activityManagerService)1547         CpuBinder(ActivityManagerService activityManagerService) {
1548             mActivityManagerService = activityManagerService;
1549         }
1550 
1551         @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)1552         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1553             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1554                     != PackageManager.PERMISSION_GRANTED) {
1555                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
1556                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1557                         + " without permission " + android.Manifest.permission.DUMP);
1558                 return;
1559             }
1560 
1561             synchronized (mActivityManagerService.mProcessStatsThread) {
1562                 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1563                 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1564                         SystemClock.uptimeMillis()));
1565             }
1566         }
1567     }
1568 
ActivityManagerService()1569     private ActivityManagerService() {
1570         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1571 
1572         mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1573         mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1574         mBroadcastQueues[0] = mFgBroadcastQueue;
1575         mBroadcastQueues[1] = mBgBroadcastQueue;
1576 
1577         mServices = new ActiveServices(this);
1578         mProviderMap = new ProviderMap(this);
1579 
1580         File dataDir = Environment.getDataDirectory();
1581         File systemDir = new File(dataDir, "system");
1582         systemDir.mkdirs();
1583         mBatteryStatsService = new BatteryStatsService(new File(
1584                 systemDir, "batterystats.bin").toString());
1585         mBatteryStatsService.getActiveStatistics().readLocked();
1586         mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1587         mOnBattery = DEBUG_POWER ? true
1588                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1589         mBatteryStatsService.getActiveStatistics().setCallback(this);
1590 
1591         mUsageStatsService = new UsageStatsService(new File(
1592                 systemDir, "usagestats").toString());
1593         mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1594 
1595         // User 0 is the first and only user that runs at boot.
1596         mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1597         mUserLru.add(Integer.valueOf(0));
1598         updateStartedUserArrayLocked();
1599 
1600         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1601             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1602 
1603         mConfiguration.setToDefaults();
1604         mConfiguration.setLocale(Locale.getDefault());
1605 
1606         mConfigurationSeq = mConfiguration.seq = 1;
1607         mProcessStats.init();
1608 
1609         mCompatModePackages = new CompatModePackages(this, systemDir);
1610 
1611         // Add ourself to the Watchdog monitors.
1612         Watchdog.getInstance().addMonitor(this);
1613 
1614         mProcessStatsThread = new Thread("ProcessStats") {
1615             public void run() {
1616                 while (true) {
1617                     try {
1618                         try {
1619                             synchronized(this) {
1620                                 final long now = SystemClock.uptimeMillis();
1621                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1622                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1623                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1624                                 //        + ", write delay=" + nextWriteDelay);
1625                                 if (nextWriteDelay < nextCpuDelay) {
1626                                     nextCpuDelay = nextWriteDelay;
1627                                 }
1628                                 if (nextCpuDelay > 0) {
1629                                     mProcessStatsMutexFree.set(true);
1630                                     this.wait(nextCpuDelay);
1631                                 }
1632                             }
1633                         } catch (InterruptedException e) {
1634                         }
1635                         updateCpuStatsNow();
1636                     } catch (Exception e) {
1637                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
1638                     }
1639                 }
1640             }
1641         };
1642         mProcessStatsThread.start();
1643     }
1644 
1645     @Override
onTransact(int code, Parcel data, Parcel reply, int flags)1646     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1647             throws RemoteException {
1648         if (code == SYSPROPS_TRANSACTION) {
1649             // We need to tell all apps about the system property change.
1650             ArrayList<IBinder> procs = new ArrayList<IBinder>();
1651             synchronized(this) {
1652                 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1653                     final int NA = apps.size();
1654                     for (int ia=0; ia<NA; ia++) {
1655                         ProcessRecord app = apps.valueAt(ia);
1656                         if (app.thread != null) {
1657                             procs.add(app.thread.asBinder());
1658                         }
1659                     }
1660                 }
1661             }
1662 
1663             int N = procs.size();
1664             for (int i=0; i<N; i++) {
1665                 Parcel data2 = Parcel.obtain();
1666                 try {
1667                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1668                 } catch (RemoteException e) {
1669                 }
1670                 data2.recycle();
1671             }
1672         }
1673         try {
1674             return super.onTransact(code, data, reply, flags);
1675         } catch (RuntimeException e) {
1676             // The activity manager only throws security exceptions, so let's
1677             // log all others.
1678             if (!(e instanceof SecurityException)) {
1679                 Slog.e(TAG, "Activity Manager Crash", e);
1680             }
1681             throw e;
1682         }
1683     }
1684 
updateCpuStats()1685     void updateCpuStats() {
1686         final long now = SystemClock.uptimeMillis();
1687         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1688             return;
1689         }
1690         if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1691             synchronized (mProcessStatsThread) {
1692                 mProcessStatsThread.notify();
1693             }
1694         }
1695     }
1696 
updateCpuStatsNow()1697     void updateCpuStatsNow() {
1698         synchronized (mProcessStatsThread) {
1699             mProcessStatsMutexFree.set(false);
1700             final long now = SystemClock.uptimeMillis();
1701             boolean haveNewCpuStats = false;
1702 
1703             if (MONITOR_CPU_USAGE &&
1704                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1705                 mLastCpuTime.set(now);
1706                 haveNewCpuStats = true;
1707                 mProcessStats.update();
1708                 //Slog.i(TAG, mProcessStats.printCurrentState());
1709                 //Slog.i(TAG, "Total CPU usage: "
1710                 //        + mProcessStats.getTotalCpuPercent() + "%");
1711 
1712                 // Slog the cpu usage if the property is set.
1713                 if ("true".equals(SystemProperties.get("events.cpu"))) {
1714                     int user = mProcessStats.getLastUserTime();
1715                     int system = mProcessStats.getLastSystemTime();
1716                     int iowait = mProcessStats.getLastIoWaitTime();
1717                     int irq = mProcessStats.getLastIrqTime();
1718                     int softIrq = mProcessStats.getLastSoftIrqTime();
1719                     int idle = mProcessStats.getLastIdleTime();
1720 
1721                     int total = user + system + iowait + irq + softIrq + idle;
1722                     if (total == 0) total = 1;
1723 
1724                     EventLog.writeEvent(EventLogTags.CPU,
1725                             ((user+system+iowait+irq+softIrq) * 100) / total,
1726                             (user * 100) / total,
1727                             (system * 100) / total,
1728                             (iowait * 100) / total,
1729                             (irq * 100) / total,
1730                             (softIrq * 100) / total);
1731                 }
1732             }
1733 
1734             long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1735             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1736             synchronized(bstats) {
1737                 synchronized(mPidsSelfLocked) {
1738                     if (haveNewCpuStats) {
1739                         if (mOnBattery) {
1740                             int perc = bstats.startAddingCpuLocked();
1741                             int totalUTime = 0;
1742                             int totalSTime = 0;
1743                             final int N = mProcessStats.countStats();
1744                             for (int i=0; i<N; i++) {
1745                                 ProcessStats.Stats st = mProcessStats.getStats(i);
1746                                 if (!st.working) {
1747                                     continue;
1748                                 }
1749                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1750                                 int otherUTime = (st.rel_utime*perc)/100;
1751                                 int otherSTime = (st.rel_stime*perc)/100;
1752                                 totalUTime += otherUTime;
1753                                 totalSTime += otherSTime;
1754                                 if (pr != null) {
1755                                     BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1756                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1757                                             st.rel_stime-otherSTime);
1758                                     ps.addSpeedStepTimes(cpuSpeedTimes);
1759                                     pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1760                                 } else {
1761                                     BatteryStatsImpl.Uid.Proc ps =
1762                                             bstats.getProcessStatsLocked(st.name, st.pid);
1763                                     if (ps != null) {
1764                                         ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1765                                                 st.rel_stime-otherSTime);
1766                                         ps.addSpeedStepTimes(cpuSpeedTimes);
1767                                     }
1768                                 }
1769                             }
1770                             bstats.finishAddingCpuLocked(perc, totalUTime,
1771                                     totalSTime, cpuSpeedTimes);
1772                         }
1773                     }
1774                 }
1775 
1776                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1777                     mLastWriteTime = now;
1778                     mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1779                 }
1780             }
1781         }
1782     }
1783 
1784     @Override
batteryNeedsCpuUpdate()1785     public void batteryNeedsCpuUpdate() {
1786         updateCpuStatsNow();
1787     }
1788 
1789     @Override
batteryPowerChanged(boolean onBattery)1790     public void batteryPowerChanged(boolean onBattery) {
1791         // When plugging in, update the CPU stats first before changing
1792         // the plug state.
1793         updateCpuStatsNow();
1794         synchronized (this) {
1795             synchronized(mPidsSelfLocked) {
1796                 mOnBattery = DEBUG_POWER ? true : onBattery;
1797             }
1798         }
1799     }
1800 
1801     /**
1802      * Initialize the application bind args. These are passed to each
1803      * process when the bindApplication() IPC is sent to the process. They're
1804      * lazily setup to make sure the services are running when they're asked for.
1805      */
getCommonServicesLocked()1806     private HashMap<String, IBinder> getCommonServicesLocked() {
1807         if (mAppBindArgs == null) {
1808             mAppBindArgs = new HashMap<String, IBinder>();
1809 
1810             // Setup the application init args
1811             mAppBindArgs.put("package", ServiceManager.getService("package"));
1812             mAppBindArgs.put("window", ServiceManager.getService("window"));
1813             mAppBindArgs.put(Context.ALARM_SERVICE,
1814                     ServiceManager.getService(Context.ALARM_SERVICE));
1815         }
1816         return mAppBindArgs;
1817     }
1818 
setFocusedActivityLocked(ActivityRecord r)1819     final void setFocusedActivityLocked(ActivityRecord r) {
1820         if (mFocusedActivity != r) {
1821             mFocusedActivity = r;
1822             if (r != null) {
1823                 mWindowManager.setFocusedApp(r.appToken, true);
1824             }
1825         }
1826     }
1827 
updateLruProcessInternalLocked(ProcessRecord app, int bestPos)1828     private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) {
1829         // put it on the LRU to keep track of when it should be exited.
1830         int lrui = mLruProcesses.indexOf(app);
1831         if (lrui >= 0) mLruProcesses.remove(lrui);
1832 
1833         int i = mLruProcesses.size()-1;
1834         int skipTop = 0;
1835 
1836         app.lruSeq = mLruSeq;
1837 
1838         // compute the new weight for this process.
1839         app.lastActivityTime = SystemClock.uptimeMillis();
1840         if (app.activities.size() > 0) {
1841             // If this process has activities, we more strongly want to keep
1842             // it around.
1843             app.lruWeight = app.lastActivityTime;
1844         } else if (app.pubProviders.size() > 0) {
1845             // If this process contains content providers, we want to keep
1846             // it a little more strongly.
1847             app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1848             // Also don't let it kick out the first few "real" hidden processes.
1849             skipTop = ProcessList.MIN_HIDDEN_APPS;
1850         } else {
1851             // If this process doesn't have activities, we less strongly
1852             // want to keep it around, and generally want to avoid getting
1853             // in front of any very recently used activities.
1854             app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1855             // Also don't let it kick out the first few "real" hidden processes.
1856             skipTop = ProcessList.MIN_HIDDEN_APPS;
1857         }
1858 
1859         while (i >= 0) {
1860             ProcessRecord p = mLruProcesses.get(i);
1861             // If this app shouldn't be in front of the first N background
1862             // apps, then skip over that many that are currently hidden.
1863             if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1864                 skipTop--;
1865             }
1866             if (p.lruWeight <= app.lruWeight || i < bestPos) {
1867                 mLruProcesses.add(i+1, app);
1868                 break;
1869             }
1870             i--;
1871         }
1872         if (i < 0) {
1873             mLruProcesses.add(0, app);
1874         }
1875 
1876         // If the app is currently using a content provider or service,
1877         // bump those processes as well.
1878         if (app.connections.size() > 0) {
1879             for (ConnectionRecord cr : app.connections) {
1880                 if (cr.binding != null && cr.binding.service != null
1881                         && cr.binding.service.app != null
1882                         && cr.binding.service.app.lruSeq != mLruSeq) {
1883                     updateLruProcessInternalLocked(cr.binding.service.app, i+1);
1884                 }
1885             }
1886         }
1887         for (int j=app.conProviders.size()-1; j>=0; j--) {
1888             ContentProviderRecord cpr = app.conProviders.get(j).provider;
1889             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1890                 updateLruProcessInternalLocked(cpr.proc, i+1);
1891             }
1892         }
1893     }
1894 
updateLruProcessLocked(ProcessRecord app, boolean oomAdj)1895     final void updateLruProcessLocked(ProcessRecord app,
1896             boolean oomAdj) {
1897         mLruSeq++;
1898         updateLruProcessInternalLocked(app, 0);
1899 
1900         //Slog.i(TAG, "Putting proc to front: " + app.processName);
1901         if (oomAdj) {
1902             updateOomAdjLocked();
1903         }
1904     }
1905 
getProcessRecordLocked( String processName, int uid)1906     final ProcessRecord getProcessRecordLocked(
1907             String processName, int uid) {
1908         if (uid == Process.SYSTEM_UID) {
1909             // The system gets to run in any process.  If there are multiple
1910             // processes with the same uid, just pick the first (this
1911             // should never happen).
1912             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1913                     processName);
1914             if (procs == null) return null;
1915             final int N = procs.size();
1916             for (int i = 0; i < N; i++) {
1917                 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1918             }
1919         }
1920         ProcessRecord proc = mProcessNames.get(processName, uid);
1921         return proc;
1922     }
1923 
ensurePackageDexOpt(String packageName)1924     void ensurePackageDexOpt(String packageName) {
1925         IPackageManager pm = AppGlobals.getPackageManager();
1926         try {
1927             if (pm.performDexOpt(packageName)) {
1928                 mDidDexOpt = true;
1929             }
1930         } catch (RemoteException e) {
1931         }
1932     }
1933 
isNextTransitionForward()1934     boolean isNextTransitionForward() {
1935         int transit = mWindowManager.getPendingAppTransition();
1936         return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1937                 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1938                 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1939     }
1940 
startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, boolean allowWhileBooting, boolean isolated)1941     final ProcessRecord startProcessLocked(String processName,
1942             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1943             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1944             boolean isolated) {
1945         ProcessRecord app;
1946         if (!isolated) {
1947             app = getProcessRecordLocked(processName, info.uid);
1948         } else {
1949             // If this is an isolated process, it can't re-use an existing process.
1950             app = null;
1951         }
1952         // We don't have to do anything more if:
1953         // (1) There is an existing application record; and
1954         // (2) The caller doesn't think it is dead, OR there is no thread
1955         //     object attached to it so we know it couldn't have crashed; and
1956         // (3) There is a pid assigned to it, so it is either starting or
1957         //     already running.
1958         if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1959                 + " app=" + app + " knownToBeDead=" + knownToBeDead
1960                 + " thread=" + (app != null ? app.thread : null)
1961                 + " pid=" + (app != null ? app.pid : -1));
1962         if (app != null && app.pid > 0) {
1963             if (!knownToBeDead || app.thread == null) {
1964                 // We already have the app running, or are waiting for it to
1965                 // come up (we have a pid but not yet its thread), so keep it.
1966                 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1967                 // If this is a new package in the process, add the package to the list
1968                 app.addPackage(info.packageName);
1969                 return app;
1970             } else {
1971                 // An application record is attached to a previous process,
1972                 // clean it up now.
1973                 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
1974                 handleAppDiedLocked(app, true, true);
1975             }
1976         }
1977 
1978         String hostingNameStr = hostingName != null
1979                 ? hostingName.flattenToShortString() : null;
1980 
1981         if (!isolated) {
1982             if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1983                 // If we are in the background, then check to see if this process
1984                 // is bad.  If so, we will just silently fail.
1985                 if (mBadProcesses.get(info.processName, info.uid) != null) {
1986                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1987                             + "/" + info.processName);
1988                     return null;
1989                 }
1990             } else {
1991                 // When the user is explicitly starting a process, then clear its
1992                 // crash count so that we won't make it bad until they see at
1993                 // least one crash dialog again, and make the process good again
1994                 // if it had been bad.
1995                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1996                         + "/" + info.processName);
1997                 mProcessCrashTimes.remove(info.processName, info.uid);
1998                 if (mBadProcesses.get(info.processName, info.uid) != null) {
1999                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2000                             UserHandle.getUserId(info.uid), info.uid,
2001                             info.processName);
2002                     mBadProcesses.remove(info.processName, info.uid);
2003                     if (app != null) {
2004                         app.bad = false;
2005                     }
2006                 }
2007             }
2008         }
2009 
2010         if (app == null) {
2011             app = newProcessRecordLocked(null, info, processName, isolated);
2012             if (app == null) {
2013                 Slog.w(TAG, "Failed making new process record for "
2014                         + processName + "/" + info.uid + " isolated=" + isolated);
2015                 return null;
2016             }
2017             mProcessNames.put(processName, app.uid, app);
2018             if (isolated) {
2019                 mIsolatedProcesses.put(app.uid, app);
2020             }
2021         } else {
2022             // If this is a new package in the process, add the package to the list
2023             app.addPackage(info.packageName);
2024         }
2025 
2026         // If the system is not ready yet, then hold off on starting this
2027         // process until it is.
2028         if (!mProcessesReady
2029                 && !isAllowedWhileBooting(info)
2030                 && !allowWhileBooting) {
2031             if (!mProcessesOnHold.contains(app)) {
2032                 mProcessesOnHold.add(app);
2033             }
2034             if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2035             return app;
2036         }
2037 
2038         startProcessLocked(app, hostingType, hostingNameStr);
2039         return (app.pid != 0) ? app : null;
2040     }
2041 
isAllowedWhileBooting(ApplicationInfo ai)2042     boolean isAllowedWhileBooting(ApplicationInfo ai) {
2043         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2044     }
2045 
startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr)2046     private final void startProcessLocked(ProcessRecord app,
2047             String hostingType, String hostingNameStr) {
2048         if (app.pid > 0 && app.pid != MY_PID) {
2049             synchronized (mPidsSelfLocked) {
2050                 mPidsSelfLocked.remove(app.pid);
2051                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2052             }
2053             app.setPid(0);
2054         }
2055 
2056         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2057                 "startProcessLocked removing on hold: " + app);
2058         mProcessesOnHold.remove(app);
2059 
2060         updateCpuStats();
2061 
2062         System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2063         mProcDeaths[0] = 0;
2064 
2065         try {
2066             int uid = app.uid;
2067 
2068             int[] gids = null;
2069             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2070             if (!app.isolated) {
2071                 int[] permGids = null;
2072                 try {
2073                     final PackageManager pm = mContext.getPackageManager();
2074                     permGids = pm.getPackageGids(app.info.packageName);
2075 
2076                     if (Environment.isExternalStorageEmulated()) {
2077                         if (pm.checkPermission(
2078                                 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2079                                 app.info.packageName) == PERMISSION_GRANTED) {
2080                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2081                         } else {
2082                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2083                         }
2084                     }
2085                 } catch (PackageManager.NameNotFoundException e) {
2086                     Slog.w(TAG, "Unable to retrieve gids", e);
2087                 }
2088 
2089                 /*
2090                  * Add shared application GID so applications can share some
2091                  * resources like shared libraries
2092                  */
2093                 if (permGids == null) {
2094                     gids = new int[1];
2095                 } else {
2096                     gids = new int[permGids.length + 1];
2097                     System.arraycopy(permGids, 0, gids, 1, permGids.length);
2098                 }
2099                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2100             }
2101             if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2102                 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2103                         && mTopComponent != null
2104                         && app.processName.equals(mTopComponent.getPackageName())) {
2105                     uid = 0;
2106                 }
2107                 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2108                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2109                     uid = 0;
2110                 }
2111             }
2112             int debugFlags = 0;
2113             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2114                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2115                 // Also turn on CheckJNI for debuggable apps. It's quite
2116                 // awkward to turn on otherwise.
2117                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2118             }
2119             // Run the app in safe mode if its manifest requests so or the
2120             // system is booted in safe mode.
2121             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2122                 Zygote.systemInSafeMode == true) {
2123                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2124             }
2125             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2126                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2127             }
2128             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2129                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2130             }
2131             if ("1".equals(SystemProperties.get("debug.assert"))) {
2132                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2133             }
2134 
2135             // Start the process.  It will either succeed and return a result containing
2136             // the PID of the new process, or else throw a RuntimeException.
2137             Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2138                     app.processName, uid, uid, gids, debugFlags, mountExternal,
2139                     app.info.targetSdkVersion, null, null);
2140 
2141             BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2142             synchronized (bs) {
2143                 if (bs.isOnBattery()) {
2144                     app.batteryStats.incStartsLocked();
2145                 }
2146             }
2147 
2148             EventLog.writeEvent(EventLogTags.AM_PROC_START,
2149                     UserHandle.getUserId(uid), startResult.pid, uid,
2150                     app.processName, hostingType,
2151                     hostingNameStr != null ? hostingNameStr : "");
2152 
2153             if (app.persistent) {
2154                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2155             }
2156 
2157             StringBuilder buf = mStringBuilder;
2158             buf.setLength(0);
2159             buf.append("Start proc ");
2160             buf.append(app.processName);
2161             buf.append(" for ");
2162             buf.append(hostingType);
2163             if (hostingNameStr != null) {
2164                 buf.append(" ");
2165                 buf.append(hostingNameStr);
2166             }
2167             buf.append(": pid=");
2168             buf.append(startResult.pid);
2169             buf.append(" uid=");
2170             buf.append(uid);
2171             buf.append(" gids={");
2172             if (gids != null) {
2173                 for (int gi=0; gi<gids.length; gi++) {
2174                     if (gi != 0) buf.append(", ");
2175                     buf.append(gids[gi]);
2176 
2177                 }
2178             }
2179             buf.append("}");
2180             Slog.i(TAG, buf.toString());
2181             app.setPid(startResult.pid);
2182             app.usingWrapper = startResult.usingWrapper;
2183             app.removed = false;
2184             synchronized (mPidsSelfLocked) {
2185                 this.mPidsSelfLocked.put(startResult.pid, app);
2186                 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2187                 msg.obj = app;
2188                 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2189                         ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2190             }
2191         } catch (RuntimeException e) {
2192             // XXX do better error recovery.
2193             app.setPid(0);
2194             Slog.e(TAG, "Failure starting process " + app.processName, e);
2195         }
2196     }
2197 
updateUsageStats(ActivityRecord resumedComponent, boolean resumed)2198     void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2199         if (resumed) {
2200             mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2201         } else {
2202             mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2203         }
2204     }
2205 
startHomeActivityLocked(int userId)2206     boolean startHomeActivityLocked(int userId) {
2207         if (mHeadless) {
2208             // Added because none of the other calls to ensureBootCompleted seem to fire
2209             // when running headless.
2210             ensureBootCompleted();
2211             return false;
2212         }
2213 
2214         if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2215                 && mTopAction == null) {
2216             // We are running in factory test mode, but unable to find
2217             // the factory test app, so just sit around displaying the
2218             // error message and don't try to start anything.
2219             return false;
2220         }
2221         Intent intent = new Intent(
2222             mTopAction,
2223             mTopData != null ? Uri.parse(mTopData) : null);
2224         intent.setComponent(mTopComponent);
2225         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2226             intent.addCategory(Intent.CATEGORY_HOME);
2227         }
2228         ActivityInfo aInfo =
2229             resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2230         if (aInfo != null) {
2231             intent.setComponent(new ComponentName(
2232                     aInfo.applicationInfo.packageName, aInfo.name));
2233             // Don't do this if the home app is currently being
2234             // instrumented.
2235             aInfo = new ActivityInfo(aInfo);
2236             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2237             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2238                     aInfo.applicationInfo.uid);
2239             if (app == null || app.instrumentationClass == null) {
2240                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2241                 mMainStack.startActivityLocked(null, intent, null, aInfo,
2242                         null, null, 0, 0, 0, 0, null, false, null);
2243             }
2244         }
2245 
2246         return true;
2247     }
2248 
resolveActivityInfo(Intent intent, int flags, int userId)2249     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2250         ActivityInfo ai = null;
2251         ComponentName comp = intent.getComponent();
2252         try {
2253             if (comp != null) {
2254                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2255             } else {
2256                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2257                         intent,
2258                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2259                             flags, userId);
2260 
2261                 if (info != null) {
2262                     ai = info.activityInfo;
2263                 }
2264             }
2265         } catch (RemoteException e) {
2266             // ignore
2267         }
2268 
2269         return ai;
2270     }
2271 
2272     /**
2273      * Starts the "new version setup screen" if appropriate.
2274      */
startSetupActivityLocked()2275     void startSetupActivityLocked() {
2276         // Only do this once per boot.
2277         if (mCheckedForSetup) {
2278             return;
2279         }
2280 
2281         // We will show this screen if the current one is a different
2282         // version than the last one shown, and we are not running in
2283         // low-level factory test mode.
2284         final ContentResolver resolver = mContext.getContentResolver();
2285         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2286                 Settings.Global.getInt(resolver,
2287                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2288             mCheckedForSetup = true;
2289 
2290             // See if we should be showing the platform update setup UI.
2291             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2292             List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2293                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2294 
2295             // We don't allow third party apps to replace this.
2296             ResolveInfo ri = null;
2297             for (int i=0; ris != null && i<ris.size(); i++) {
2298                 if ((ris.get(i).activityInfo.applicationInfo.flags
2299                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
2300                     ri = ris.get(i);
2301                     break;
2302                 }
2303             }
2304 
2305             if (ri != null) {
2306                 String vers = ri.activityInfo.metaData != null
2307                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2308                         : null;
2309                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2310                     vers = ri.activityInfo.applicationInfo.metaData.getString(
2311                             Intent.METADATA_SETUP_VERSION);
2312                 }
2313                 String lastVers = Settings.Secure.getString(
2314                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
2315                 if (vers != null && !vers.equals(lastVers)) {
2316                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2317                     intent.setComponent(new ComponentName(
2318                             ri.activityInfo.packageName, ri.activityInfo.name));
2319                     mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2320                             null, null, 0, 0, 0, 0, null, false, null);
2321                 }
2322             }
2323         }
2324     }
2325 
compatibilityInfoForPackageLocked(ApplicationInfo ai)2326     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2327         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2328     }
2329 
enforceNotIsolatedCaller(String caller)2330     void enforceNotIsolatedCaller(String caller) {
2331         if (UserHandle.isIsolated(Binder.getCallingUid())) {
2332             throw new SecurityException("Isolated process not allowed to call " + caller);
2333         }
2334     }
2335 
getFrontActivityScreenCompatMode()2336     public int getFrontActivityScreenCompatMode() {
2337         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2338         synchronized (this) {
2339             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2340         }
2341     }
2342 
setFrontActivityScreenCompatMode(int mode)2343     public void setFrontActivityScreenCompatMode(int mode) {
2344         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2345                 "setFrontActivityScreenCompatMode");
2346         synchronized (this) {
2347             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2348         }
2349     }
2350 
getPackageScreenCompatMode(String packageName)2351     public int getPackageScreenCompatMode(String packageName) {
2352         enforceNotIsolatedCaller("getPackageScreenCompatMode");
2353         synchronized (this) {
2354             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2355         }
2356     }
2357 
setPackageScreenCompatMode(String packageName, int mode)2358     public void setPackageScreenCompatMode(String packageName, int mode) {
2359         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2360                 "setPackageScreenCompatMode");
2361         synchronized (this) {
2362             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2363         }
2364     }
2365 
getPackageAskScreenCompat(String packageName)2366     public boolean getPackageAskScreenCompat(String packageName) {
2367         enforceNotIsolatedCaller("getPackageAskScreenCompat");
2368         synchronized (this) {
2369             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2370         }
2371     }
2372 
setPackageAskScreenCompat(String packageName, boolean ask)2373     public void setPackageAskScreenCompat(String packageName, boolean ask) {
2374         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2375                 "setPackageAskScreenCompat");
2376         synchronized (this) {
2377             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2378         }
2379     }
2380 
reportResumedActivityLocked(ActivityRecord r)2381     void reportResumedActivityLocked(ActivityRecord r) {
2382         //Slog.i(TAG, "**** REPORT RESUME: " + r);
2383         updateUsageStats(r, true);
2384     }
2385 
dispatchProcessesChanged()2386     private void dispatchProcessesChanged() {
2387         int N;
2388         synchronized (this) {
2389             N = mPendingProcessChanges.size();
2390             if (mActiveProcessChanges.length < N) {
2391                 mActiveProcessChanges = new ProcessChangeItem[N];
2392             }
2393             mPendingProcessChanges.toArray(mActiveProcessChanges);
2394             mAvailProcessChanges.addAll(mPendingProcessChanges);
2395             mPendingProcessChanges.clear();
2396             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2397         }
2398         int i = mProcessObservers.beginBroadcast();
2399         while (i > 0) {
2400             i--;
2401             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2402             if (observer != null) {
2403                 try {
2404                     for (int j=0; j<N; j++) {
2405                         ProcessChangeItem item = mActiveProcessChanges[j];
2406                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2407                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2408                                     + item.pid + " uid=" + item.uid + ": "
2409                                     + item.foregroundActivities);
2410                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
2411                                     item.foregroundActivities);
2412                         }
2413                         if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2414                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2415                                     + item.pid + " uid=" + item.uid + ": " + item.importance);
2416                             observer.onImportanceChanged(item.pid, item.uid,
2417                                     item.importance);
2418                         }
2419                     }
2420                 } catch (RemoteException e) {
2421                 }
2422             }
2423         }
2424         mProcessObservers.finishBroadcast();
2425     }
2426 
dispatchProcessDied(int pid, int uid)2427     private void dispatchProcessDied(int pid, int uid) {
2428         int i = mProcessObservers.beginBroadcast();
2429         while (i > 0) {
2430             i--;
2431             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2432             if (observer != null) {
2433                 try {
2434                     observer.onProcessDied(pid, uid);
2435                 } catch (RemoteException e) {
2436                 }
2437             }
2438         }
2439         mProcessObservers.finishBroadcast();
2440     }
2441 
doPendingActivityLaunchesLocked(boolean doResume)2442     final void doPendingActivityLaunchesLocked(boolean doResume) {
2443         final int N = mPendingActivityLaunches.size();
2444         if (N <= 0) {
2445             return;
2446         }
2447         for (int i=0; i<N; i++) {
2448             PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2449             mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2450                     pal.startFlags, doResume && i == (N-1), null);
2451         }
2452         mPendingActivityLaunches.clear();
2453     }
2454 
startActivity(IApplicationThread caller, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, String profileFile, ParcelFileDescriptor profileFd, Bundle options)2455     public final int startActivity(IApplicationThread caller,
2456             Intent intent, String resolvedType, IBinder resultTo,
2457             String resultWho, int requestCode, int startFlags,
2458             String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2459         return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2460                 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2461     }
2462 
startActivityAsUser(IApplicationThread caller, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId)2463     public final int startActivityAsUser(IApplicationThread caller,
2464             Intent intent, String resolvedType, IBinder resultTo,
2465             String resultWho, int requestCode, int startFlags,
2466             String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2467         enforceNotIsolatedCaller("startActivity");
2468         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2469                 false, true, "startActivity", null);
2470         return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2471                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2472                 null, null, options, userId);
2473     }
2474 
startActivityAndWait(IApplicationThread caller, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId)2475     public final WaitResult startActivityAndWait(IApplicationThread caller,
2476             Intent intent, String resolvedType, IBinder resultTo,
2477             String resultWho, int requestCode, int startFlags, String profileFile,
2478             ParcelFileDescriptor profileFd, Bundle options, int userId) {
2479         enforceNotIsolatedCaller("startActivityAndWait");
2480         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2481                 false, true, "startActivityAndWait", null);
2482         WaitResult res = new WaitResult();
2483         mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2484                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2485                 res, null, options, UserHandle.getCallingUserId());
2486         return res;
2487     }
2488 
startActivityWithConfig(IApplicationThread caller, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, Configuration config, Bundle options, int userId)2489     public final int startActivityWithConfig(IApplicationThread caller,
2490             Intent intent, String resolvedType, IBinder resultTo,
2491             String resultWho, int requestCode, int startFlags, Configuration config,
2492             Bundle options, int userId) {
2493         enforceNotIsolatedCaller("startActivityWithConfig");
2494         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2495                 false, true, "startActivityWithConfig", null);
2496         int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2497                 resultTo, resultWho, requestCode, startFlags,
2498                 null, null, null, config, options, userId);
2499         return ret;
2500     }
2501 
startActivityIntentSender(IApplicationThread caller, IntentSender intent, Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle options)2502     public int startActivityIntentSender(IApplicationThread caller,
2503             IntentSender intent, Intent fillInIntent, String resolvedType,
2504             IBinder resultTo, String resultWho, int requestCode,
2505             int flagsMask, int flagsValues, Bundle options) {
2506         enforceNotIsolatedCaller("startActivityIntentSender");
2507         // Refuse possible leaked file descriptors
2508         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2509             throw new IllegalArgumentException("File descriptors passed in Intent");
2510         }
2511 
2512         IIntentSender sender = intent.getTarget();
2513         if (!(sender instanceof PendingIntentRecord)) {
2514             throw new IllegalArgumentException("Bad PendingIntent object");
2515         }
2516 
2517         PendingIntentRecord pir = (PendingIntentRecord)sender;
2518 
2519         synchronized (this) {
2520             // If this is coming from the currently resumed activity, it is
2521             // effectively saying that app switches are allowed at this point.
2522             if (mMainStack.mResumedActivity != null
2523                     && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2524                             Binder.getCallingUid()) {
2525                 mAppSwitchesAllowedTime = 0;
2526             }
2527         }
2528         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2529                 resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2530         return ret;
2531     }
2532 
startNextMatchingActivity(IBinder callingActivity, Intent intent, Bundle options)2533     public boolean startNextMatchingActivity(IBinder callingActivity,
2534             Intent intent, Bundle options) {
2535         // Refuse possible leaked file descriptors
2536         if (intent != null && intent.hasFileDescriptors() == true) {
2537             throw new IllegalArgumentException("File descriptors passed in Intent");
2538         }
2539 
2540         synchronized (this) {
2541             ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2542             if (r == null) {
2543                 ActivityOptions.abort(options);
2544                 return false;
2545             }
2546             if (r.app == null || r.app.thread == null) {
2547                 // The caller is not running...  d'oh!
2548                 ActivityOptions.abort(options);
2549                 return false;
2550             }
2551             intent = new Intent(intent);
2552             // The caller is not allowed to change the data.
2553             intent.setDataAndType(r.intent.getData(), r.intent.getType());
2554             // And we are resetting to find the next component...
2555             intent.setComponent(null);
2556 
2557             ActivityInfo aInfo = null;
2558             try {
2559                 List<ResolveInfo> resolves =
2560                     AppGlobals.getPackageManager().queryIntentActivities(
2561                             intent, r.resolvedType,
2562                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2563                             UserHandle.getCallingUserId());
2564 
2565                 // Look for the original activity in the list...
2566                 final int N = resolves != null ? resolves.size() : 0;
2567                 for (int i=0; i<N; i++) {
2568                     ResolveInfo rInfo = resolves.get(i);
2569                     if (rInfo.activityInfo.packageName.equals(r.packageName)
2570                             && rInfo.activityInfo.name.equals(r.info.name)) {
2571                         // We found the current one...  the next matching is
2572                         // after it.
2573                         i++;
2574                         if (i<N) {
2575                             aInfo = resolves.get(i).activityInfo;
2576                         }
2577                         break;
2578                     }
2579                 }
2580             } catch (RemoteException e) {
2581             }
2582 
2583             if (aInfo == null) {
2584                 // Nobody who is next!
2585                 ActivityOptions.abort(options);
2586                 return false;
2587             }
2588 
2589             intent.setComponent(new ComponentName(
2590                     aInfo.applicationInfo.packageName, aInfo.name));
2591             intent.setFlags(intent.getFlags()&~(
2592                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2593                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
2594                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2595                     Intent.FLAG_ACTIVITY_NEW_TASK));
2596 
2597             // Okay now we need to start the new activity, replacing the
2598             // currently running activity.  This is a little tricky because
2599             // we want to start the new one as if the current one is finished,
2600             // but not finish the current one first so that there is no flicker.
2601             // And thus...
2602             final boolean wasFinishing = r.finishing;
2603             r.finishing = true;
2604 
2605             // Propagate reply information over to the new activity.
2606             final ActivityRecord resultTo = r.resultTo;
2607             final String resultWho = r.resultWho;
2608             final int requestCode = r.requestCode;
2609             r.resultTo = null;
2610             if (resultTo != null) {
2611                 resultTo.removeResultsLocked(r, resultWho, requestCode);
2612             }
2613 
2614             final long origId = Binder.clearCallingIdentity();
2615             int res = mMainStack.startActivityLocked(r.app.thread, intent,
2616                     r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2617                     resultWho, requestCode, -1, r.launchedFromUid, 0,
2618                     options, false, null);
2619             Binder.restoreCallingIdentity(origId);
2620 
2621             r.finishing = wasFinishing;
2622             if (res != ActivityManager.START_SUCCESS) {
2623                 return false;
2624             }
2625             return true;
2626         }
2627     }
2628 
startActivityInPackage(int uid, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, Bundle options, int userId)2629     final int startActivityInPackage(int uid,
2630             Intent intent, String resolvedType, IBinder resultTo,
2631             String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
2632 
2633         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2634                 false, true, "startActivityInPackage", null);
2635 
2636         int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2637                 resultTo, resultWho, requestCode, startFlags,
2638                 null, null, null, null, options, userId);
2639         return ret;
2640     }
2641 
startActivities(IApplicationThread caller, Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, int userId)2642     public final int startActivities(IApplicationThread caller,
2643             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
2644             int userId) {
2645         enforceNotIsolatedCaller("startActivities");
2646         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2647                 false, true, "startActivity", null);
2648         int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2649                 options, userId);
2650         return ret;
2651     }
2652 
startActivitiesInPackage(int uid, Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, int userId)2653     final int startActivitiesInPackage(int uid,
2654             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2655             Bundle options, int userId) {
2656 
2657         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2658                 false, true, "startActivityInPackage", null);
2659         int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2660                 options, userId);
2661         return ret;
2662     }
2663 
addRecentTaskLocked(TaskRecord task)2664     final void addRecentTaskLocked(TaskRecord task) {
2665         int N = mRecentTasks.size();
2666         // Quick case: check if the top-most recent task is the same.
2667         if (N > 0 && mRecentTasks.get(0) == task) {
2668             return;
2669         }
2670         // Remove any existing entries that are the same kind of task.
2671         for (int i=0; i<N; i++) {
2672             TaskRecord tr = mRecentTasks.get(i);
2673             if (task.userId == tr.userId
2674                     && ((task.affinity != null && task.affinity.equals(tr.affinity))
2675                     || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2676                 mRecentTasks.remove(i);
2677                 i--;
2678                 N--;
2679                 if (task.intent == null) {
2680                     // If the new recent task we are adding is not fully
2681                     // specified, then replace it with the existing recent task.
2682                     task = tr;
2683                 }
2684             }
2685         }
2686         if (N >= MAX_RECENT_TASKS) {
2687             mRecentTasks.remove(N-1);
2688         }
2689         mRecentTasks.add(0, task);
2690     }
2691 
setRequestedOrientation(IBinder token, int requestedOrientation)2692     public void setRequestedOrientation(IBinder token,
2693             int requestedOrientation) {
2694         synchronized (this) {
2695             ActivityRecord r = mMainStack.isInStackLocked(token);
2696             if (r == null) {
2697                 return;
2698             }
2699             final long origId = Binder.clearCallingIdentity();
2700             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2701             Configuration config = mWindowManager.updateOrientationFromAppTokens(
2702                     mConfiguration,
2703                     r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2704             if (config != null) {
2705                 r.frozenBeforeDestroy = true;
2706                 if (!updateConfigurationLocked(config, r, false, false)) {
2707                     mMainStack.resumeTopActivityLocked(null);
2708                 }
2709             }
2710             Binder.restoreCallingIdentity(origId);
2711         }
2712     }
2713 
getRequestedOrientation(IBinder token)2714     public int getRequestedOrientation(IBinder token) {
2715         synchronized (this) {
2716             ActivityRecord r = mMainStack.isInStackLocked(token);
2717             if (r == null) {
2718                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2719             }
2720             return mWindowManager.getAppOrientation(r.appToken);
2721         }
2722     }
2723 
2724     /**
2725      * This is the internal entry point for handling Activity.finish().
2726      *
2727      * @param token The Binder token referencing the Activity we want to finish.
2728      * @param resultCode Result code, if any, from this Activity.
2729      * @param resultData Result data (Intent), if any, from this Activity.
2730      *
2731      * @return Returns true if the activity successfully finished, or false if it is still running.
2732      */
finishActivity(IBinder token, int resultCode, Intent resultData)2733     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2734         // Refuse possible leaked file descriptors
2735         if (resultData != null && resultData.hasFileDescriptors() == true) {
2736             throw new IllegalArgumentException("File descriptors passed in Intent");
2737         }
2738 
2739         synchronized(this) {
2740             if (mController != null) {
2741                 // Find the first activity that is not finishing.
2742                 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2743                 if (next != null) {
2744                     // ask watcher if this is allowed
2745                     boolean resumeOK = true;
2746                     try {
2747                         resumeOK = mController.activityResuming(next.packageName);
2748                     } catch (RemoteException e) {
2749                         mController = null;
2750                     }
2751 
2752                     if (!resumeOK) {
2753                         return false;
2754                     }
2755                 }
2756             }
2757             final long origId = Binder.clearCallingIdentity();
2758             boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2759                     resultData, "app-request", true);
2760             Binder.restoreCallingIdentity(origId);
2761             return res;
2762         }
2763     }
2764 
finishHeavyWeightApp()2765     public final void finishHeavyWeightApp() {
2766         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2767                 != PackageManager.PERMISSION_GRANTED) {
2768             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2769                     + Binder.getCallingPid()
2770                     + ", uid=" + Binder.getCallingUid()
2771                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2772             Slog.w(TAG, msg);
2773             throw new SecurityException(msg);
2774         }
2775 
2776         synchronized(this) {
2777             if (mHeavyWeightProcess == null) {
2778                 return;
2779             }
2780 
2781             ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2782                     mHeavyWeightProcess.activities);
2783             for (int i=0; i<activities.size(); i++) {
2784                 ActivityRecord r = activities.get(i);
2785                 if (!r.finishing) {
2786                     int index = mMainStack.indexOfTokenLocked(r.appToken);
2787                     if (index >= 0) {
2788                         mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2789                                 null, "finish-heavy", true);
2790                     }
2791                 }
2792             }
2793 
2794             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
2795                     mHeavyWeightProcess.userId, 0));
2796             mHeavyWeightProcess = null;
2797         }
2798     }
2799 
crashApplication(int uid, int initialPid, String packageName, String message)2800     public void crashApplication(int uid, int initialPid, String packageName,
2801             String message) {
2802         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2803                 != PackageManager.PERMISSION_GRANTED) {
2804             String msg = "Permission Denial: crashApplication() from pid="
2805                     + Binder.getCallingPid()
2806                     + ", uid=" + Binder.getCallingUid()
2807                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2808             Slog.w(TAG, msg);
2809             throw new SecurityException(msg);
2810         }
2811 
2812         synchronized(this) {
2813             ProcessRecord proc = null;
2814 
2815             // Figure out which process to kill.  We don't trust that initialPid
2816             // still has any relation to current pids, so must scan through the
2817             // list.
2818             synchronized (mPidsSelfLocked) {
2819                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2820                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
2821                     if (p.uid != uid) {
2822                         continue;
2823                     }
2824                     if (p.pid == initialPid) {
2825                         proc = p;
2826                         break;
2827                     }
2828                     for (String str : p.pkgList) {
2829                         if (str.equals(packageName)) {
2830                             proc = p;
2831                         }
2832                     }
2833                 }
2834             }
2835 
2836             if (proc == null) {
2837                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2838                         + " initialPid=" + initialPid
2839                         + " packageName=" + packageName);
2840                 return;
2841             }
2842 
2843             if (proc.thread != null) {
2844                 if (proc.pid == Process.myPid()) {
2845                     Log.w(TAG, "crashApplication: trying to crash self!");
2846                     return;
2847                 }
2848                 long ident = Binder.clearCallingIdentity();
2849                 try {
2850                     proc.thread.scheduleCrash(message);
2851                 } catch (RemoteException e) {
2852                 }
2853                 Binder.restoreCallingIdentity(ident);
2854             }
2855         }
2856     }
2857 
finishSubActivity(IBinder token, String resultWho, int requestCode)2858     public final void finishSubActivity(IBinder token, String resultWho,
2859             int requestCode) {
2860         synchronized(this) {
2861             final long origId = Binder.clearCallingIdentity();
2862             mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2863             Binder.restoreCallingIdentity(origId);
2864         }
2865     }
2866 
finishActivityAffinity(IBinder token)2867     public boolean finishActivityAffinity(IBinder token) {
2868         synchronized(this) {
2869             final long origId = Binder.clearCallingIdentity();
2870             boolean res = mMainStack.finishActivityAffinityLocked(token);
2871             Binder.restoreCallingIdentity(origId);
2872             return res;
2873         }
2874     }
2875 
willActivityBeVisible(IBinder token)2876     public boolean willActivityBeVisible(IBinder token) {
2877         synchronized(this) {
2878             int i;
2879             for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2880                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2881                 if (r.appToken == token) {
2882                     return true;
2883                 }
2884                 if (r.fullscreen && !r.finishing) {
2885                     return false;
2886                 }
2887             }
2888             return true;
2889         }
2890     }
2891 
overridePendingTransition(IBinder token, String packageName, int enterAnim, int exitAnim)2892     public void overridePendingTransition(IBinder token, String packageName,
2893             int enterAnim, int exitAnim) {
2894         synchronized(this) {
2895             ActivityRecord self = mMainStack.isInStackLocked(token);
2896             if (self == null) {
2897                 return;
2898             }
2899 
2900             final long origId = Binder.clearCallingIdentity();
2901 
2902             if (self.state == ActivityState.RESUMED
2903                     || self.state == ActivityState.PAUSING) {
2904                 mWindowManager.overridePendingAppTransition(packageName,
2905                         enterAnim, exitAnim, null);
2906             }
2907 
2908             Binder.restoreCallingIdentity(origId);
2909         }
2910     }
2911 
2912     /**
2913      * Main function for removing an existing process from the activity manager
2914      * as a result of that process going away.  Clears out all connections
2915      * to the process.
2916      */
handleAppDiedLocked(ProcessRecord app, boolean restarting, boolean allowRestart)2917     private final void handleAppDiedLocked(ProcessRecord app,
2918             boolean restarting, boolean allowRestart) {
2919         cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2920         if (!restarting) {
2921             mLruProcesses.remove(app);
2922         }
2923 
2924         if (mProfileProc == app) {
2925             clearProfilerLocked();
2926         }
2927 
2928         // Just in case...
2929         if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2930             if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG,
2931                     "App died while pausing: " + mMainStack.mPausingActivity);
2932             mMainStack.mPausingActivity = null;
2933         }
2934         if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2935             mMainStack.mLastPausedActivity = null;
2936         }
2937 
2938         // Remove this application's activities from active lists.
2939         boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app);
2940 
2941         app.activities.clear();
2942 
2943         if (app.instrumentationClass != null) {
2944             Slog.w(TAG, "Crash of app " + app.processName
2945                   + " running instrumentation " + app.instrumentationClass);
2946             Bundle info = new Bundle();
2947             info.putString("shortMsg", "Process crashed.");
2948             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2949         }
2950 
2951         if (!restarting) {
2952             if (!mMainStack.resumeTopActivityLocked(null)) {
2953                 // If there was nothing to resume, and we are not already
2954                 // restarting this process, but there is a visible activity that
2955                 // is hosted by the process...  then make sure all visible
2956                 // activities are running, taking care of restarting this
2957                 // process.
2958                 if (hasVisibleActivities) {
2959                     mMainStack.ensureActivitiesVisibleLocked(null, 0);
2960                 }
2961             }
2962         }
2963     }
2964 
getLRURecordIndexForAppLocked(IApplicationThread thread)2965     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2966         IBinder threadBinder = thread.asBinder();
2967         // Find the application record.
2968         for (int i=mLruProcesses.size()-1; i>=0; i--) {
2969             ProcessRecord rec = mLruProcesses.get(i);
2970             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2971                 return i;
2972             }
2973         }
2974         return -1;
2975     }
2976 
getRecordForAppLocked( IApplicationThread thread)2977     final ProcessRecord getRecordForAppLocked(
2978             IApplicationThread thread) {
2979         if (thread == null) {
2980             return null;
2981         }
2982 
2983         int appIndex = getLRURecordIndexForAppLocked(thread);
2984         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2985     }
2986 
appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread)2987     final void appDiedLocked(ProcessRecord app, int pid,
2988             IApplicationThread thread) {
2989 
2990         mProcDeaths[0]++;
2991 
2992         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2993         synchronized (stats) {
2994             stats.noteProcessDiedLocked(app.info.uid, pid);
2995         }
2996 
2997         // Clean up already done if the process has been re-started.
2998         if (app.pid == pid && app.thread != null &&
2999                 app.thread.asBinder() == thread.asBinder()) {
3000             if (!app.killedBackground) {
3001                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3002                         + ") has died.");
3003             }
3004             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3005             if (DEBUG_CLEANUP) Slog.v(
3006                 TAG, "Dying app: " + app + ", pid: " + pid
3007                 + ", thread: " + thread.asBinder());
3008             boolean doLowMem = app.instrumentationClass == null;
3009             handleAppDiedLocked(app, false, true);
3010 
3011             if (doLowMem) {
3012                 // If there are no longer any background processes running,
3013                 // and the app that died was not running instrumentation,
3014                 // then tell everyone we are now low on memory.
3015                 boolean haveBg = false;
3016                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3017                     ProcessRecord rec = mLruProcesses.get(i);
3018                     if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3019                         haveBg = true;
3020                         break;
3021                     }
3022                 }
3023 
3024                 if (!haveBg) {
3025                     EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3026                     long now = SystemClock.uptimeMillis();
3027                     for (int i=mLruProcesses.size()-1; i>=0; i--) {
3028                         ProcessRecord rec = mLruProcesses.get(i);
3029                         if (rec != app && rec.thread != null &&
3030                                 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3031                             // The low memory report is overriding any current
3032                             // state for a GC request.  Make sure to do
3033                             // heavy/important/visible/foreground processes first.
3034                             if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3035                                 rec.lastRequestedGc = 0;
3036                             } else {
3037                                 rec.lastRequestedGc = rec.lastLowMemory;
3038                             }
3039                             rec.reportLowMemory = true;
3040                             rec.lastLowMemory = now;
3041                             mProcessesToGc.remove(rec);
3042                             addProcessToGcListLocked(rec);
3043                         }
3044                     }
3045                     mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3046                     scheduleAppGcsLocked();
3047                 }
3048             }
3049         } else if (app.pid != pid) {
3050             // A new process has already been started.
3051             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3052                     + ") has died and restarted (pid " + app.pid + ").");
3053             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3054         } else if (DEBUG_PROCESSES) {
3055             Slog.d(TAG, "Received spurious death notification for thread "
3056                     + thread.asBinder());
3057         }
3058     }
3059 
3060     /**
3061      * If a stack trace dump file is configured, dump process stack traces.
3062      * @param clearTraces causes the dump file to be erased prior to the new
3063      *    traces being written, if true; when false, the new traces will be
3064      *    appended to any existing file content.
3065      * @param firstPids of dalvik VM processes to dump stack traces for first
3066      * @param lastPids of dalvik VM processes to dump stack traces for last
3067      * @param nativeProcs optional list of native process names to dump stack crawls
3068      * @return file containing stack traces, or null if no dump file is configured
3069      */
dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs)3070     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3071             ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3072         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3073         if (tracesPath == null || tracesPath.length() == 0) {
3074             return null;
3075         }
3076 
3077         File tracesFile = new File(tracesPath);
3078         try {
3079             File tracesDir = tracesFile.getParentFile();
3080             if (!tracesDir.exists()) {
3081                 tracesFile.mkdirs();
3082                 if (!SELinux.restorecon(tracesDir)) {
3083                     return null;
3084                 }
3085             }
3086             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3087 
3088             if (clearTraces && tracesFile.exists()) tracesFile.delete();
3089             tracesFile.createNewFile();
3090             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3091         } catch (IOException e) {
3092             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3093             return null;
3094         }
3095 
3096         dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3097         return tracesFile;
3098     }
3099 
dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs)3100     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3101             ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3102         // Use a FileObserver to detect when traces finish writing.
3103         // The order of traces is considered important to maintain for legibility.
3104         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3105             public synchronized void onEvent(int event, String path) { notify(); }
3106         };
3107 
3108         try {
3109             observer.startWatching();
3110 
3111             // First collect all of the stacks of the most important pids.
3112             if (firstPids != null) {
3113                 try {
3114                     int num = firstPids.size();
3115                     for (int i = 0; i < num; i++) {
3116                         synchronized (observer) {
3117                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3118                             observer.wait(200);  // Wait for write-close, give up after 200msec
3119                         }
3120                     }
3121                 } catch (InterruptedException e) {
3122                     Log.wtf(TAG, e);
3123                 }
3124             }
3125 
3126             // Next measure CPU usage.
3127             if (processStats != null) {
3128                 processStats.init();
3129                 System.gc();
3130                 processStats.update();
3131                 try {
3132                     synchronized (processStats) {
3133                         processStats.wait(500); // measure over 1/2 second.
3134                     }
3135                 } catch (InterruptedException e) {
3136                 }
3137                 processStats.update();
3138 
3139                 // We'll take the stack crawls of just the top apps using CPU.
3140                 final int N = processStats.countWorkingStats();
3141                 int numProcs = 0;
3142                 for (int i=0; i<N && numProcs<5; i++) {
3143                     ProcessStats.Stats stats = processStats.getWorkingStats(i);
3144                     if (lastPids.indexOfKey(stats.pid) >= 0) {
3145                         numProcs++;
3146                         try {
3147                             synchronized (observer) {
3148                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3149                                 observer.wait(200);  // Wait for write-close, give up after 200msec
3150                             }
3151                         } catch (InterruptedException e) {
3152                             Log.wtf(TAG, e);
3153                         }
3154 
3155                     }
3156                 }
3157             }
3158 
3159         } finally {
3160             observer.stopWatching();
3161         }
3162 
3163         if (nativeProcs != null) {
3164             int[] pids = Process.getPidsForCommands(nativeProcs);
3165             if (pids != null) {
3166                 for (int pid : pids) {
3167                     Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3168                 }
3169             }
3170         }
3171     }
3172 
logAppTooSlow(ProcessRecord app, long startTime, String msg)3173     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3174         if (true || IS_USER_BUILD) {
3175             return;
3176         }
3177         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3178         if (tracesPath == null || tracesPath.length() == 0) {
3179             return;
3180         }
3181 
3182         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3183         StrictMode.allowThreadDiskWrites();
3184         try {
3185             final File tracesFile = new File(tracesPath);
3186             final File tracesDir = tracesFile.getParentFile();
3187             final File tracesTmp = new File(tracesDir, "__tmp__");
3188             try {
3189                 if (!tracesDir.exists()) {
3190                     tracesFile.mkdirs();
3191                     if (!SELinux.restorecon(tracesDir.getPath())) {
3192                         return;
3193                     }
3194                 }
3195                 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3196 
3197                 if (tracesFile.exists()) {
3198                     tracesTmp.delete();
3199                     tracesFile.renameTo(tracesTmp);
3200                 }
3201                 StringBuilder sb = new StringBuilder();
3202                 Time tobj = new Time();
3203                 tobj.set(System.currentTimeMillis());
3204                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3205                 sb.append(": ");
3206                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3207                 sb.append(" since ");
3208                 sb.append(msg);
3209                 FileOutputStream fos = new FileOutputStream(tracesFile);
3210                 fos.write(sb.toString().getBytes());
3211                 if (app == null) {
3212                     fos.write("\n*** No application process!".getBytes());
3213                 }
3214                 fos.close();
3215                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3216             } catch (IOException e) {
3217                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3218                 return;
3219             }
3220 
3221             if (app != null) {
3222                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
3223                 firstPids.add(app.pid);
3224                 dumpStackTraces(tracesPath, firstPids, null, null, null);
3225             }
3226 
3227             File lastTracesFile = null;
3228             File curTracesFile = null;
3229             for (int i=9; i>=0; i--) {
3230                 String name = String.format("slow%02d.txt", i);
3231                 curTracesFile = new File(tracesDir, name);
3232                 if (curTracesFile.exists()) {
3233                     if (lastTracesFile != null) {
3234                         curTracesFile.renameTo(lastTracesFile);
3235                     } else {
3236                         curTracesFile.delete();
3237                     }
3238                 }
3239                 lastTracesFile = curTracesFile;
3240             }
3241             tracesFile.renameTo(curTracesFile);
3242             if (tracesTmp.exists()) {
3243                 tracesTmp.renameTo(tracesFile);
3244             }
3245         } finally {
3246             StrictMode.setThreadPolicy(oldPolicy);
3247         }
3248     }
3249 
appNotResponding(ProcessRecord app, ActivityRecord activity, ActivityRecord parent, boolean aboveSystem, final String annotation)3250     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3251             ActivityRecord parent, boolean aboveSystem, final String annotation) {
3252         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3253         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3254 
3255         if (mController != null) {
3256             try {
3257                 // 0 == continue, -1 = kill process immediately
3258                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3259                 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3260             } catch (RemoteException e) {
3261                 mController = null;
3262             }
3263         }
3264 
3265         long anrTime = SystemClock.uptimeMillis();
3266         if (MONITOR_CPU_USAGE) {
3267             updateCpuStatsNow();
3268         }
3269 
3270         synchronized (this) {
3271             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3272             if (mShuttingDown) {
3273                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3274                 return;
3275             } else if (app.notResponding) {
3276                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3277                 return;
3278             } else if (app.crashing) {
3279                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3280                 return;
3281             }
3282 
3283             // In case we come through here for the same app before completing
3284             // this one, mark as anring now so we will bail out.
3285             app.notResponding = true;
3286 
3287             // Log the ANR to the event log.
3288             EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3289                     app.processName, app.info.flags, annotation);
3290 
3291             // Dump thread traces as quickly as we can, starting with "interesting" processes.
3292             firstPids.add(app.pid);
3293 
3294             int parentPid = app.pid;
3295             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3296             if (parentPid != app.pid) firstPids.add(parentPid);
3297 
3298             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3299 
3300             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3301                 ProcessRecord r = mLruProcesses.get(i);
3302                 if (r != null && r.thread != null) {
3303                     int pid = r.pid;
3304                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3305                         if (r.persistent) {
3306                             firstPids.add(pid);
3307                         } else {
3308                             lastPids.put(pid, Boolean.TRUE);
3309                         }
3310                     }
3311                 }
3312             }
3313         }
3314 
3315         // Log the ANR to the main log.
3316         StringBuilder info = new StringBuilder();
3317         info.setLength(0);
3318         info.append("ANR in ").append(app.processName);
3319         if (activity != null && activity.shortComponentName != null) {
3320             info.append(" (").append(activity.shortComponentName).append(")");
3321         }
3322         info.append("\n");
3323         if (annotation != null) {
3324             info.append("Reason: ").append(annotation).append("\n");
3325         }
3326         if (parent != null && parent != activity) {
3327             info.append("Parent: ").append(parent.shortComponentName).append("\n");
3328         }
3329 
3330         final ProcessStats processStats = new ProcessStats(true);
3331 
3332         File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3333 
3334         String cpuInfo = null;
3335         if (MONITOR_CPU_USAGE) {
3336             updateCpuStatsNow();
3337             synchronized (mProcessStatsThread) {
3338                 cpuInfo = mProcessStats.printCurrentState(anrTime);
3339             }
3340             info.append(processStats.printCurrentLoad());
3341             info.append(cpuInfo);
3342         }
3343 
3344         info.append(processStats.printCurrentState(anrTime));
3345 
3346         Slog.e(TAG, info.toString());
3347         if (tracesFile == null) {
3348             // There is no trace file, so dump (only) the alleged culprit's threads to the log
3349             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3350         }
3351 
3352         addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3353                 cpuInfo, tracesFile, null);
3354 
3355         if (mController != null) {
3356             try {
3357                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3358                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3359                 if (res != 0) {
3360                     if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3361                     return;
3362                 }
3363             } catch (RemoteException e) {
3364                 mController = null;
3365             }
3366         }
3367 
3368         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3369         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3370                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3371 
3372         synchronized (this) {
3373             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3374                 Slog.w(TAG, "Killing " + app + ": background ANR");
3375                 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
3376                         app.processName, app.setAdj, "background ANR");
3377                 Process.killProcessQuiet(app.pid);
3378                 return;
3379             }
3380 
3381             // Set the app's notResponding state, and look up the errorReportReceiver
3382             makeAppNotRespondingLocked(app,
3383                     activity != null ? activity.shortComponentName : null,
3384                     annotation != null ? "ANR " + annotation : "ANR",
3385                     info.toString());
3386 
3387             // Bring up the infamous App Not Responding dialog
3388             Message msg = Message.obtain();
3389             HashMap map = new HashMap();
3390             msg.what = SHOW_NOT_RESPONDING_MSG;
3391             msg.obj = map;
3392             msg.arg1 = aboveSystem ? 1 : 0;
3393             map.put("app", app);
3394             if (activity != null) {
3395                 map.put("activity", activity);
3396             }
3397 
3398             mHandler.sendMessage(msg);
3399         }
3400     }
3401 
showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next)3402     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3403         if (!mLaunchWarningShown) {
3404             mLaunchWarningShown = true;
3405             mHandler.post(new Runnable() {
3406                 @Override
3407                 public void run() {
3408                     synchronized (ActivityManagerService.this) {
3409                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3410                         d.show();
3411                         mHandler.postDelayed(new Runnable() {
3412                             @Override
3413                             public void run() {
3414                                 synchronized (ActivityManagerService.this) {
3415                                     d.dismiss();
3416                                     mLaunchWarningShown = false;
3417                                 }
3418                             }
3419                         }, 4000);
3420                     }
3421                 }
3422             });
3423         }
3424     }
3425 
clearApplicationUserData(final String packageName, final IPackageDataObserver observer, int userId)3426     public boolean clearApplicationUserData(final String packageName,
3427             final IPackageDataObserver observer, int userId) {
3428         enforceNotIsolatedCaller("clearApplicationUserData");
3429         int uid = Binder.getCallingUid();
3430         int pid = Binder.getCallingPid();
3431         userId = handleIncomingUser(pid, uid,
3432                 userId, false, true, "clearApplicationUserData", null);
3433         long callingId = Binder.clearCallingIdentity();
3434         try {
3435             IPackageManager pm = AppGlobals.getPackageManager();
3436             int pkgUid = -1;
3437             synchronized(this) {
3438                 try {
3439                     pkgUid = pm.getPackageUid(packageName, userId);
3440                 } catch (RemoteException e) {
3441                 }
3442                 if (pkgUid == -1) {
3443                     Slog.w(TAG, "Invalid packageName:" + packageName);
3444                     return false;
3445                 }
3446                 if (uid == pkgUid || checkComponentPermission(
3447                         android.Manifest.permission.CLEAR_APP_USER_DATA,
3448                         pid, uid, -1, true)
3449                         == PackageManager.PERMISSION_GRANTED) {
3450                     forceStopPackageLocked(packageName, pkgUid);
3451                 } else {
3452                     throw new SecurityException(pid+" does not have permission:"+
3453                             android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3454                                     "for process:"+packageName);
3455                 }
3456             }
3457 
3458             try {
3459                 //clear application user data
3460                 pm.clearApplicationUserData(packageName, observer, userId);
3461                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3462                         Uri.fromParts("package", packageName, null));
3463                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
3464                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3465                         null, null, 0, null, null, null, false, false, userId);
3466             } catch (RemoteException e) {
3467             }
3468         } finally {
3469             Binder.restoreCallingIdentity(callingId);
3470         }
3471         return true;
3472     }
3473 
killBackgroundProcesses(final String packageName, int userId)3474     public void killBackgroundProcesses(final String packageName, int userId) {
3475         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3476                 != PackageManager.PERMISSION_GRANTED &&
3477                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3478                         != PackageManager.PERMISSION_GRANTED) {
3479             String msg = "Permission Denial: killBackgroundProcesses() from pid="
3480                     + Binder.getCallingPid()
3481                     + ", uid=" + Binder.getCallingUid()
3482                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3483             Slog.w(TAG, msg);
3484             throw new SecurityException(msg);
3485         }
3486 
3487         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3488                 userId, true, true, "killBackgroundProcesses", null);
3489         long callingId = Binder.clearCallingIdentity();
3490         try {
3491             IPackageManager pm = AppGlobals.getPackageManager();
3492             synchronized(this) {
3493                 int appId = -1;
3494                 try {
3495                     appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
3496                 } catch (RemoteException e) {
3497                 }
3498                 if (appId == -1) {
3499                     Slog.w(TAG, "Invalid packageName: " + packageName);
3500                     return;
3501                 }
3502                 killPackageProcessesLocked(packageName, appId, userId,
3503                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3504             }
3505         } finally {
3506             Binder.restoreCallingIdentity(callingId);
3507         }
3508     }
3509 
killAllBackgroundProcesses()3510     public void killAllBackgroundProcesses() {
3511         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3512                 != PackageManager.PERMISSION_GRANTED) {
3513             String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3514                     + Binder.getCallingPid()
3515                     + ", uid=" + Binder.getCallingUid()
3516                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3517             Slog.w(TAG, msg);
3518             throw new SecurityException(msg);
3519         }
3520 
3521         long callingId = Binder.clearCallingIdentity();
3522         try {
3523             synchronized(this) {
3524                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3525                 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3526                     final int NA = apps.size();
3527                     for (int ia=0; ia<NA; ia++) {
3528                         ProcessRecord app = apps.valueAt(ia);
3529                         if (app.persistent) {
3530                             // we don't kill persistent processes
3531                             continue;
3532                         }
3533                         if (app.removed) {
3534                             procs.add(app);
3535                         } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3536                             app.removed = true;
3537                             procs.add(app);
3538                         }
3539                     }
3540                 }
3541 
3542                 int N = procs.size();
3543                 for (int i=0; i<N; i++) {
3544                     removeProcessLocked(procs.get(i), false, true, "kill all background");
3545                 }
3546             }
3547         } finally {
3548             Binder.restoreCallingIdentity(callingId);
3549         }
3550     }
3551 
forceStopPackage(final String packageName, int userId)3552     public void forceStopPackage(final String packageName, int userId) {
3553         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3554                 != PackageManager.PERMISSION_GRANTED) {
3555             String msg = "Permission Denial: forceStopPackage() from pid="
3556                     + Binder.getCallingPid()
3557                     + ", uid=" + Binder.getCallingUid()
3558                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3559             Slog.w(TAG, msg);
3560             throw new SecurityException(msg);
3561         }
3562         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3563                 userId, true, true, "forceStopPackage", null);
3564         long callingId = Binder.clearCallingIdentity();
3565         try {
3566             IPackageManager pm = AppGlobals.getPackageManager();
3567             synchronized(this) {
3568                 int[] users = userId == UserHandle.USER_ALL
3569                         ? getUsersLocked() : new int[] { userId };
3570                 for (int user : users) {
3571                     int pkgUid = -1;
3572                     try {
3573                         pkgUid = pm.getPackageUid(packageName, user);
3574                     } catch (RemoteException e) {
3575                     }
3576                     if (pkgUid == -1) {
3577                         Slog.w(TAG, "Invalid packageName: " + packageName);
3578                         continue;
3579                     }
3580                     try {
3581                         pm.setPackageStoppedState(packageName, true, user);
3582                     } catch (RemoteException e) {
3583                     } catch (IllegalArgumentException e) {
3584                         Slog.w(TAG, "Failed trying to unstop package "
3585                                 + packageName + ": " + e);
3586                     }
3587                     if (isUserRunningLocked(user, false)) {
3588                         forceStopPackageLocked(packageName, pkgUid);
3589                     }
3590                 }
3591             }
3592         } finally {
3593             Binder.restoreCallingIdentity(callingId);
3594         }
3595     }
3596 
3597     /*
3598      * The pkg name and app id have to be specified.
3599      */
killApplicationWithAppId(String pkg, int appid)3600     public void killApplicationWithAppId(String pkg, int appid) {
3601         if (pkg == null) {
3602             return;
3603         }
3604         // Make sure the uid is valid.
3605         if (appid < 0) {
3606             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
3607             return;
3608         }
3609         int callerUid = Binder.getCallingUid();
3610         // Only the system server can kill an application
3611         if (callerUid == Process.SYSTEM_UID) {
3612             // Post an aysnc message to kill the application
3613             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3614             msg.arg1 = appid;
3615             msg.arg2 = 0;
3616             msg.obj = pkg;
3617             mHandler.sendMessage(msg);
3618         } else {
3619             throw new SecurityException(callerUid + " cannot kill pkg: " +
3620                     pkg);
3621         }
3622     }
3623 
closeSystemDialogs(String reason)3624     public void closeSystemDialogs(String reason) {
3625         enforceNotIsolatedCaller("closeSystemDialogs");
3626 
3627         final int pid = Binder.getCallingPid();
3628         final int uid = Binder.getCallingUid();
3629         final long origId = Binder.clearCallingIdentity();
3630         try {
3631             synchronized (this) {
3632                 // Only allow this from foreground processes, so that background
3633                 // applications can't abuse it to prevent system UI from being shown.
3634                 if (uid >= Process.FIRST_APPLICATION_UID) {
3635                     ProcessRecord proc;
3636                     synchronized (mPidsSelfLocked) {
3637                         proc = mPidsSelfLocked.get(pid);
3638                     }
3639                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
3640                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
3641                                 + " from background process " + proc);
3642                         return;
3643                     }
3644                 }
3645                 closeSystemDialogsLocked(reason);
3646             }
3647         } finally {
3648             Binder.restoreCallingIdentity(origId);
3649         }
3650     }
3651 
closeSystemDialogsLocked(String reason)3652     void closeSystemDialogsLocked(String reason) {
3653         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3654         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3655                 | Intent.FLAG_RECEIVER_FOREGROUND);
3656         if (reason != null) {
3657             intent.putExtra("reason", reason);
3658         }
3659         mWindowManager.closeSystemDialogs(reason);
3660 
3661         for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3662             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3663             if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3664                 r.stack.finishActivityLocked(r, i,
3665                         Activity.RESULT_CANCELED, null, "close-sys", true);
3666             }
3667         }
3668 
3669         broadcastIntentLocked(null, null, intent, null,
3670                 null, 0, null, null, null, false, false, -1,
3671                 Process.SYSTEM_UID, UserHandle.USER_ALL);
3672     }
3673 
getProcessMemoryInfo(int[] pids)3674     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3675             throws RemoteException {
3676         enforceNotIsolatedCaller("getProcessMemoryInfo");
3677         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3678         for (int i=pids.length-1; i>=0; i--) {
3679             infos[i] = new Debug.MemoryInfo();
3680             Debug.getMemoryInfo(pids[i], infos[i]);
3681         }
3682         return infos;
3683     }
3684 
getProcessPss(int[] pids)3685     public long[] getProcessPss(int[] pids) throws RemoteException {
3686         enforceNotIsolatedCaller("getProcessPss");
3687         long[] pss = new long[pids.length];
3688         for (int i=pids.length-1; i>=0; i--) {
3689             pss[i] = Debug.getPss(pids[i]);
3690         }
3691         return pss;
3692     }
3693 
killApplicationProcess(String processName, int uid)3694     public void killApplicationProcess(String processName, int uid) {
3695         if (processName == null) {
3696             return;
3697         }
3698 
3699         int callerUid = Binder.getCallingUid();
3700         // Only the system server can kill an application
3701         if (callerUid == Process.SYSTEM_UID) {
3702             synchronized (this) {
3703                 ProcessRecord app = getProcessRecordLocked(processName, uid);
3704                 if (app != null && app.thread != null) {
3705                     try {
3706                         app.thread.scheduleSuicide();
3707                     } catch (RemoteException e) {
3708                         // If the other end already died, then our work here is done.
3709                     }
3710                 } else {
3711                     Slog.w(TAG, "Process/uid not found attempting kill of "
3712                             + processName + " / " + uid);
3713                 }
3714             }
3715         } else {
3716             throw new SecurityException(callerUid + " cannot kill app process: " +
3717                     processName);
3718         }
3719     }
3720 
forceStopPackageLocked(final String packageName, int uid)3721     private void forceStopPackageLocked(final String packageName, int uid) {
3722         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
3723                 false, true, false, UserHandle.getUserId(uid));
3724         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3725                 Uri.fromParts("package", packageName, null));
3726         if (!mProcessesReady) {
3727             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3728                     | Intent.FLAG_RECEIVER_FOREGROUND);
3729         }
3730         intent.putExtra(Intent.EXTRA_UID, uid);
3731         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
3732         broadcastIntentLocked(null, null, intent,
3733                 null, null, 0, null, null, null,
3734                 false, false,
3735                 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3736     }
3737 
forceStopUserLocked(int userId)3738     private void forceStopUserLocked(int userId) {
3739         forceStopPackageLocked(null, -1, false, false, true, false, userId);
3740         Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3741         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3742                 | Intent.FLAG_RECEIVER_FOREGROUND);
3743         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3744         broadcastIntentLocked(null, null, intent,
3745                 null, null, 0, null, null, null,
3746                 false, false,
3747                 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
3748     }
3749 
killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, boolean evenPersistent, String reason)3750     private final boolean killPackageProcessesLocked(String packageName, int appId,
3751             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3752             boolean doit, boolean evenPersistent, String reason) {
3753         ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3754 
3755         // Remove all processes this package may have touched: all with the
3756         // same UID (except for the system or root user), and all whose name
3757         // matches the package name.
3758         final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3759         for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3760             final int NA = apps.size();
3761             for (int ia=0; ia<NA; ia++) {
3762                 ProcessRecord app = apps.valueAt(ia);
3763                 if (app.persistent && !evenPersistent) {
3764                     // we don't kill persistent processes
3765                     continue;
3766                 }
3767                 if (app.removed) {
3768                     if (doit) {
3769                         procs.add(app);
3770                     }
3771                     continue;
3772                 }
3773 
3774                 // Skip process if it doesn't meet our oom adj requirement.
3775                 if (app.setAdj < minOomAdj) {
3776                     continue;
3777                 }
3778 
3779                 // If no package is specified, we call all processes under the
3780                 // give user id.
3781                 if (packageName == null) {
3782                     if (app.userId != userId) {
3783                         continue;
3784                     }
3785                 // Package has been specified, we want to hit all processes
3786                 // that match it.  We need to qualify this by the processes
3787                 // that are running under the specified app and user ID.
3788                 } else {
3789                     if (UserHandle.getAppId(app.uid) != appId) {
3790                         continue;
3791                     }
3792                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
3793                         continue;
3794                     }
3795                     if (!app.pkgList.contains(packageName)) {
3796                         continue;
3797                     }
3798                 }
3799 
3800                 // Process has passed all conditions, kill it!
3801                 if (!doit) {
3802                     return true;
3803                 }
3804                 app.removed = true;
3805                 procs.add(app);
3806             }
3807         }
3808 
3809         int N = procs.size();
3810         for (int i=0; i<N; i++) {
3811             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3812         }
3813         return N > 0;
3814     }
3815 
forceStopPackageLocked(String name, int appId, boolean callerWillRestart, boolean purgeCache, boolean doit, boolean evenPersistent, int userId)3816     private final boolean forceStopPackageLocked(String name, int appId,
3817             boolean callerWillRestart, boolean purgeCache, boolean doit,
3818             boolean evenPersistent, int userId) {
3819         int i;
3820         int N;
3821 
3822         if (userId == UserHandle.USER_ALL && name == null) {
3823             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
3824         }
3825 
3826         if (appId < 0 && name != null) {
3827             try {
3828                 appId = UserHandle.getAppId(
3829                         AppGlobals.getPackageManager().getPackageUid(name, 0));
3830             } catch (RemoteException e) {
3831             }
3832         }
3833 
3834         if (doit) {
3835             if (name != null) {
3836                 Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
3837                         + " user=" + userId);
3838             } else {
3839                 Slog.i(TAG, "Force stopping user " + userId);
3840             }
3841 
3842             Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3843             while (badApps.hasNext()) {
3844                 SparseArray<Long> ba = badApps.next();
3845                 for (i=ba.size()-1; i>=0; i--) {
3846                     boolean remove = false;
3847                     final int entUid = ba.keyAt(i);
3848                     if (name != null) {
3849                         if (userId == UserHandle.USER_ALL) {
3850                             if (UserHandle.getAppId(entUid) == appId) {
3851                                 remove = true;
3852                             }
3853                         } else {
3854                             if (entUid == UserHandle.getUid(userId, appId)) {
3855                                 remove = true;
3856                             }
3857                         }
3858                     } else if (UserHandle.getUserId(entUid) == userId) {
3859                         remove = true;
3860                     }
3861                     if (remove) {
3862                         ba.removeAt(i);
3863                     }
3864                 }
3865                 if (ba.size() == 0) {
3866                     badApps.remove();
3867                 }
3868             }
3869         }
3870 
3871         boolean didSomething = killPackageProcessesLocked(name, appId, userId,
3872                 -100, callerWillRestart, true, doit, evenPersistent,
3873                 name == null ? ("force stop user " + userId) : ("force stop " + name));
3874 
3875         TaskRecord lastTask = null;
3876         for (i=0; i<mMainStack.mHistory.size(); i++) {
3877             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3878             final boolean samePackage = r.packageName.equals(name)
3879                     || (name == null && r.userId == userId);
3880             if ((userId == UserHandle.USER_ALL || r.userId == userId)
3881                     && (samePackage || r.task == lastTask)
3882                     && (r.app == null || evenPersistent || !r.app.persistent)) {
3883                 if (!doit) {
3884                     if (r.finishing) {
3885                         // If this activity is just finishing, then it is not
3886                         // interesting as far as something to stop.
3887                         continue;
3888                     }
3889                     return true;
3890                 }
3891                 didSomething = true;
3892                 Slog.i(TAG, "  Force finishing activity " + r);
3893                 if (samePackage) {
3894                     if (r.app != null) {
3895                         r.app.removed = true;
3896                     }
3897                     r.app = null;
3898                 }
3899                 lastTask = r.task;
3900                 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3901                         null, "force-stop", true)) {
3902                     i--;
3903                 }
3904             }
3905         }
3906 
3907         if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3908             if (!doit) {
3909                 return true;
3910             }
3911             didSomething = true;
3912         }
3913 
3914         if (name == null) {
3915             // Remove all sticky broadcasts from this user.
3916             mStickyBroadcasts.remove(userId);
3917         }
3918 
3919         ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3920         if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
3921                 userId, providers)) {
3922             if (!doit) {
3923                 return true;
3924             }
3925             didSomething = true;
3926         }
3927         N = providers.size();
3928         for (i=0; i<N; i++) {
3929             removeDyingProviderLocked(null, providers.get(i), true);
3930         }
3931 
3932         if (name == null) {
3933             // Remove pending intents.  For now we only do this when force
3934             // stopping users, because we have some problems when doing this
3935             // for packages -- app widgets are not currently cleaned up for
3936             // such packages, so they can be left with bad pending intents.
3937             if (mIntentSenderRecords.size() > 0) {
3938                 Iterator<WeakReference<PendingIntentRecord>> it
3939                         = mIntentSenderRecords.values().iterator();
3940                 while (it.hasNext()) {
3941                     WeakReference<PendingIntentRecord> wpir = it.next();
3942                     if (wpir == null) {
3943                         it.remove();
3944                         continue;
3945                     }
3946                     PendingIntentRecord pir = wpir.get();
3947                     if (pir == null) {
3948                         it.remove();
3949                         continue;
3950                     }
3951                     if (name == null) {
3952                         // Stopping user, remove all objects for the user.
3953                         if (pir.key.userId != userId) {
3954                             // Not the same user, skip it.
3955                             continue;
3956                         }
3957                     } else {
3958                         if (UserHandle.getAppId(pir.uid) != appId) {
3959                             // Different app id, skip it.
3960                             continue;
3961                         }
3962                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
3963                             // Different user, skip it.
3964                             continue;
3965                         }
3966                         if (!pir.key.packageName.equals(name)) {
3967                             // Different package, skip it.
3968                             continue;
3969                         }
3970                     }
3971                     if (!doit) {
3972                         return true;
3973                     }
3974                     didSomething = true;
3975                     it.remove();
3976                     pir.canceled = true;
3977                     if (pir.key.activity != null) {
3978                         pir.key.activity.pendingResults.remove(pir.ref);
3979                     }
3980                 }
3981             }
3982         }
3983 
3984         if (doit) {
3985             if (purgeCache && name != null) {
3986                 AttributeCache ac = AttributeCache.instance();
3987                 if (ac != null) {
3988                     ac.removePackage(name);
3989                 }
3990             }
3991             if (mBooted) {
3992                 mMainStack.resumeTopActivityLocked(null);
3993                 mMainStack.scheduleIdleLocked();
3994             }
3995         }
3996 
3997         return didSomething;
3998     }
3999 
removeProcessLocked(ProcessRecord app, boolean callerWillRestart, boolean allowRestart, String reason)4000     private final boolean removeProcessLocked(ProcessRecord app,
4001             boolean callerWillRestart, boolean allowRestart, String reason) {
4002         final String name = app.processName;
4003         final int uid = app.uid;
4004         if (DEBUG_PROCESSES) Slog.d(
4005             TAG, "Force removing proc " + app.toShortString() + " (" + name
4006             + "/" + uid + ")");
4007 
4008         mProcessNames.remove(name, uid);
4009         mIsolatedProcesses.remove(app.uid);
4010         if (mHeavyWeightProcess == app) {
4011             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4012                     mHeavyWeightProcess.userId, 0));
4013             mHeavyWeightProcess = null;
4014         }
4015         boolean needRestart = false;
4016         if (app.pid > 0 && app.pid != MY_PID) {
4017             int pid = app.pid;
4018             synchronized (mPidsSelfLocked) {
4019                 mPidsSelfLocked.remove(pid);
4020                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4021             }
4022             Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
4023             handleAppDiedLocked(app, true, allowRestart);
4024             mLruProcesses.remove(app);
4025             Process.killProcessQuiet(pid);
4026 
4027             if (app.persistent && !app.isolated) {
4028                 if (!callerWillRestart) {
4029                     addAppLocked(app.info, false);
4030                 } else {
4031                     needRestart = true;
4032                 }
4033             }
4034         } else {
4035             mRemovedProcesses.add(app);
4036         }
4037 
4038         return needRestart;
4039     }
4040 
processStartTimedOutLocked(ProcessRecord app)4041     private final void processStartTimedOutLocked(ProcessRecord app) {
4042         final int pid = app.pid;
4043         boolean gone = false;
4044         synchronized (mPidsSelfLocked) {
4045             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4046             if (knownApp != null && knownApp.thread == null) {
4047                 mPidsSelfLocked.remove(pid);
4048                 gone = true;
4049             }
4050         }
4051 
4052         if (gone) {
4053             Slog.w(TAG, "Process " + app + " failed to attach");
4054             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4055                     pid, app.uid, app.processName);
4056             mProcessNames.remove(app.processName, app.uid);
4057             mIsolatedProcesses.remove(app.uid);
4058             if (mHeavyWeightProcess == app) {
4059                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4060                         mHeavyWeightProcess.userId, 0));
4061                 mHeavyWeightProcess = null;
4062             }
4063             // Take care of any launching providers waiting for this process.
4064             checkAppInLaunchingProvidersLocked(app, true);
4065             // Take care of any services that are waiting for the process.
4066             mServices.processStartTimedOutLocked(app);
4067             EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid,
4068                     app.processName, app.setAdj, "start timeout");
4069             Process.killProcessQuiet(pid);
4070             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4071                 Slog.w(TAG, "Unattached app died before backup, skipping");
4072                 try {
4073                     IBackupManager bm = IBackupManager.Stub.asInterface(
4074                             ServiceManager.getService(Context.BACKUP_SERVICE));
4075                     bm.agentDisconnected(app.info.packageName);
4076                 } catch (RemoteException e) {
4077                     // Can't happen; the backup manager is local
4078                 }
4079             }
4080             if (isPendingBroadcastProcessLocked(pid)) {
4081                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4082                 skipPendingBroadcastLocked(pid);
4083             }
4084         } else {
4085             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4086         }
4087     }
4088 
attachApplicationLocked(IApplicationThread thread, int pid)4089     private final boolean attachApplicationLocked(IApplicationThread thread,
4090             int pid) {
4091 
4092         // Find the application record that is being attached...  either via
4093         // the pid if we are running in multiple processes, or just pull the
4094         // next app record if we are emulating process with anonymous threads.
4095         ProcessRecord app;
4096         if (pid != MY_PID && pid >= 0) {
4097             synchronized (mPidsSelfLocked) {
4098                 app = mPidsSelfLocked.get(pid);
4099             }
4100         } else {
4101             app = null;
4102         }
4103 
4104         if (app == null) {
4105             Slog.w(TAG, "No pending application record for pid " + pid
4106                     + " (IApplicationThread " + thread + "); dropping process");
4107             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4108             if (pid > 0 && pid != MY_PID) {
4109                 Process.killProcessQuiet(pid);
4110             } else {
4111                 try {
4112                     thread.scheduleExit();
4113                 } catch (Exception e) {
4114                     // Ignore exceptions.
4115                 }
4116             }
4117             return false;
4118         }
4119 
4120         // If this application record is still attached to a previous
4121         // process, clean it up now.
4122         if (app.thread != null) {
4123             handleAppDiedLocked(app, true, true);
4124         }
4125 
4126         // Tell the process all about itself.
4127 
4128         if (localLOGV) Slog.v(
4129                 TAG, "Binding process pid " + pid + " to record " + app);
4130 
4131         String processName = app.processName;
4132         try {
4133             AppDeathRecipient adr = new AppDeathRecipient(
4134                     app, pid, thread);
4135             thread.asBinder().linkToDeath(adr, 0);
4136             app.deathRecipient = adr;
4137         } catch (RemoteException e) {
4138             app.resetPackageList();
4139             startProcessLocked(app, "link fail", processName);
4140             return false;
4141         }
4142 
4143         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4144 
4145         app.thread = thread;
4146         app.curAdj = app.setAdj = -100;
4147         app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4148         app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4149         app.forcingToForeground = null;
4150         app.foregroundServices = false;
4151         app.hasShownUi = false;
4152         app.debugging = false;
4153 
4154         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4155 
4156         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4157         List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4158 
4159         if (!normalMode) {
4160             Slog.i(TAG, "Launching preboot mode app: " + app);
4161         }
4162 
4163         if (localLOGV) Slog.v(
4164             TAG, "New app record " + app
4165             + " thread=" + thread.asBinder() + " pid=" + pid);
4166         try {
4167             int testMode = IApplicationThread.DEBUG_OFF;
4168             if (mDebugApp != null && mDebugApp.equals(processName)) {
4169                 testMode = mWaitForDebugger
4170                     ? IApplicationThread.DEBUG_WAIT
4171                     : IApplicationThread.DEBUG_ON;
4172                 app.debugging = true;
4173                 if (mDebugTransient) {
4174                     mDebugApp = mOrigDebugApp;
4175                     mWaitForDebugger = mOrigWaitForDebugger;
4176                 }
4177             }
4178             String profileFile = app.instrumentationProfileFile;
4179             ParcelFileDescriptor profileFd = null;
4180             boolean profileAutoStop = false;
4181             if (mProfileApp != null && mProfileApp.equals(processName)) {
4182                 mProfileProc = app;
4183                 profileFile = mProfileFile;
4184                 profileFd = mProfileFd;
4185                 profileAutoStop = mAutoStopProfiler;
4186             }
4187             boolean enableOpenGlTrace = false;
4188             if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4189                 enableOpenGlTrace = true;
4190                 mOpenGlTraceApp = null;
4191             }
4192 
4193             // If the app is being launched for restore or full backup, set it up specially
4194             boolean isRestrictedBackupMode = false;
4195             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4196                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4197                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4198                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4199             }
4200 
4201             ensurePackageDexOpt(app.instrumentationInfo != null
4202                     ? app.instrumentationInfo.packageName
4203                     : app.info.packageName);
4204             if (app.instrumentationClass != null) {
4205                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4206             }
4207             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4208                     + processName + " with config " + mConfiguration);
4209             ApplicationInfo appInfo = app.instrumentationInfo != null
4210                     ? app.instrumentationInfo : app.info;
4211             app.compat = compatibilityInfoForPackageLocked(appInfo);
4212             if (profileFd != null) {
4213                 profileFd = profileFd.dup();
4214             }
4215             thread.bindApplication(processName, appInfo, providers,
4216                     app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4217                     app.instrumentationArguments, app.instrumentationWatcher, testMode,
4218                     enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4219                     new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4220                     mCoreSettingsObserver.getCoreSettingsLocked());
4221             updateLruProcessLocked(app, false);
4222             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4223         } catch (Exception e) {
4224             // todo: Yikes!  What should we do?  For now we will try to
4225             // start another process, but that could easily get us in
4226             // an infinite loop of restarting processes...
4227             Slog.w(TAG, "Exception thrown during bind!", e);
4228 
4229             app.resetPackageList();
4230             app.unlinkDeathRecipient();
4231             startProcessLocked(app, "bind fail", processName);
4232             return false;
4233         }
4234 
4235         // Remove this record from the list of starting applications.
4236         mPersistentStartingProcesses.remove(app);
4237         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4238                 "Attach application locked removing on hold: " + app);
4239         mProcessesOnHold.remove(app);
4240 
4241         boolean badApp = false;
4242         boolean didSomething = false;
4243 
4244         // See if the top visible activity is waiting to run in this process...
4245         ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4246         if (hr != null && normalMode) {
4247             if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4248                     && processName.equals(hr.processName)) {
4249                 try {
4250                     if (mHeadless) {
4251                         Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4252                     } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4253                         didSomething = true;
4254                     }
4255                 } catch (Exception e) {
4256                     Slog.w(TAG, "Exception in new application when starting activity "
4257                           + hr.intent.getComponent().flattenToShortString(), e);
4258                     badApp = true;
4259                 }
4260             } else {
4261                 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4262             }
4263         }
4264 
4265         // Find any services that should be running in this process...
4266         if (!badApp) {
4267             try {
4268                 didSomething |= mServices.attachApplicationLocked(app, processName);
4269             } catch (Exception e) {
4270                 badApp = true;
4271             }
4272         }
4273 
4274         // Check if a next-broadcast receiver is in this process...
4275         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4276             try {
4277                 didSomething = sendPendingBroadcastsLocked(app);
4278             } catch (Exception e) {
4279                 // If the app died trying to launch the receiver we declare it 'bad'
4280                 badApp = true;
4281             }
4282         }
4283 
4284         // Check whether the next backup agent is in this process...
4285         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4286             if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4287             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4288             try {
4289                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4290                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4291                         mBackupTarget.backupMode);
4292             } catch (Exception e) {
4293                 Slog.w(TAG, "Exception scheduling backup agent creation: ");
4294                 e.printStackTrace();
4295             }
4296         }
4297 
4298         if (badApp) {
4299             // todo: Also need to kill application to deal with all
4300             // kinds of exceptions.
4301             handleAppDiedLocked(app, false, true);
4302             return false;
4303         }
4304 
4305         if (!didSomething) {
4306             updateOomAdjLocked();
4307         }
4308 
4309         return true;
4310     }
4311 
attachApplication(IApplicationThread thread)4312     public final void attachApplication(IApplicationThread thread) {
4313         synchronized (this) {
4314             int callingPid = Binder.getCallingPid();
4315             final long origId = Binder.clearCallingIdentity();
4316             attachApplicationLocked(thread, callingPid);
4317             Binder.restoreCallingIdentity(origId);
4318         }
4319     }
4320 
activityIdle(IBinder token, Configuration config, boolean stopProfiling)4321     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4322         final long origId = Binder.clearCallingIdentity();
4323         ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4324         if (stopProfiling) {
4325             synchronized (this) {
4326                 if (mProfileProc == r.app) {
4327                     if (mProfileFd != null) {
4328                         try {
4329                             mProfileFd.close();
4330                         } catch (IOException e) {
4331                         }
4332                         clearProfilerLocked();
4333                     }
4334                 }
4335             }
4336         }
4337         Binder.restoreCallingIdentity(origId);
4338     }
4339 
enableScreenAfterBoot()4340     void enableScreenAfterBoot() {
4341         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4342                 SystemClock.uptimeMillis());
4343         mWindowManager.enableScreenAfterBoot();
4344 
4345         synchronized (this) {
4346             updateEventDispatchingLocked();
4347         }
4348     }
4349 
showBootMessage(final CharSequence msg, final boolean always)4350     public void showBootMessage(final CharSequence msg, final boolean always) {
4351         enforceNotIsolatedCaller("showBootMessage");
4352         mWindowManager.showBootMessage(msg, always);
4353     }
4354 
dismissKeyguardOnNextActivity()4355     public void dismissKeyguardOnNextActivity() {
4356         enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4357         final long token = Binder.clearCallingIdentity();
4358         try {
4359             synchronized (this) {
4360                 if (mLockScreenShown) {
4361                     mLockScreenShown = false;
4362                     comeOutOfSleepIfNeededLocked();
4363                 }
4364                 mMainStack.dismissKeyguardOnNextActivityLocked();
4365             }
4366         } finally {
4367             Binder.restoreCallingIdentity(token);
4368         }
4369     }
4370 
finishBooting()4371     final void finishBooting() {
4372         IntentFilter pkgFilter = new IntentFilter();
4373         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4374         pkgFilter.addDataScheme("package");
4375         mContext.registerReceiver(new BroadcastReceiver() {
4376             @Override
4377             public void onReceive(Context context, Intent intent) {
4378                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4379                 if (pkgs != null) {
4380                     for (String pkg : pkgs) {
4381                         synchronized (ActivityManagerService.this) {
4382                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4383                                 setResultCode(Activity.RESULT_OK);
4384                                 return;
4385                             }
4386                         }
4387                     }
4388                 }
4389             }
4390         }, pkgFilter);
4391 
4392         synchronized (this) {
4393             // Ensure that any processes we had put on hold are now started
4394             // up.
4395             final int NP = mProcessesOnHold.size();
4396             if (NP > 0) {
4397                 ArrayList<ProcessRecord> procs =
4398                     new ArrayList<ProcessRecord>(mProcessesOnHold);
4399                 for (int ip=0; ip<NP; ip++) {
4400                     if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4401                             + procs.get(ip));
4402                     startProcessLocked(procs.get(ip), "on-hold", null);
4403                 }
4404             }
4405 
4406             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4407                 // Start looking for apps that are abusing wake locks.
4408                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4409                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4410                 // Tell anyone interested that we are done booting!
4411                 SystemProperties.set("sys.boot_completed", "1");
4412                 SystemProperties.set("dev.bootcomplete", "1");
4413                 for (int i=0; i<mStartedUsers.size(); i++) {
4414                     UserStartedState uss = mStartedUsers.valueAt(i);
4415                     if (uss.mState == UserStartedState.STATE_BOOTING) {
4416                         uss.mState = UserStartedState.STATE_RUNNING;
4417                         final int userId = mStartedUsers.keyAt(i);
4418                         Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4419                         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4420                         broadcastIntentLocked(null, null, intent,
4421                                 null, null, 0, null, null,
4422                                 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4423                                 false, false, MY_PID, Process.SYSTEM_UID, userId);
4424                     }
4425                 }
4426             }
4427         }
4428     }
4429 
ensureBootCompleted()4430     final void ensureBootCompleted() {
4431         boolean booting;
4432         boolean enableScreen;
4433         synchronized (this) {
4434             booting = mBooting;
4435             mBooting = false;
4436             enableScreen = !mBooted;
4437             mBooted = true;
4438         }
4439 
4440         if (booting) {
4441             finishBooting();
4442         }
4443 
4444         if (enableScreen) {
4445             enableScreenAfterBoot();
4446         }
4447     }
4448 
activityResumed(IBinder token)4449     public final void activityResumed(IBinder token) {
4450         final long origId = Binder.clearCallingIdentity();
4451         mMainStack.activityResumed(token);
4452         Binder.restoreCallingIdentity(origId);
4453     }
4454 
activityPaused(IBinder token)4455     public final void activityPaused(IBinder token) {
4456         final long origId = Binder.clearCallingIdentity();
4457         mMainStack.activityPaused(token, false);
4458         Binder.restoreCallingIdentity(origId);
4459     }
4460 
activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, CharSequence description)4461     public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4462             CharSequence description) {
4463         if (localLOGV) Slog.v(
4464             TAG, "Activity stopped: token=" + token);
4465 
4466         // Refuse possible leaked file descriptors
4467         if (icicle != null && icicle.hasFileDescriptors()) {
4468             throw new IllegalArgumentException("File descriptors passed in Bundle");
4469         }
4470 
4471         ActivityRecord r = null;
4472 
4473         final long origId = Binder.clearCallingIdentity();
4474 
4475         synchronized (this) {
4476             r = mMainStack.isInStackLocked(token);
4477             if (r != null) {
4478                 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4479             }
4480         }
4481 
4482         if (r != null) {
4483             sendPendingThumbnail(r, null, null, null, false);
4484         }
4485 
4486         trimApplications();
4487 
4488         Binder.restoreCallingIdentity(origId);
4489     }
4490 
activityDestroyed(IBinder token)4491     public final void activityDestroyed(IBinder token) {
4492         if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4493         mMainStack.activityDestroyed(token);
4494     }
4495 
getCallingPackage(IBinder token)4496     public String getCallingPackage(IBinder token) {
4497         synchronized (this) {
4498             ActivityRecord r = getCallingRecordLocked(token);
4499             return r != null && r.app != null ? r.info.packageName : null;
4500         }
4501     }
4502 
getCallingActivity(IBinder token)4503     public ComponentName getCallingActivity(IBinder token) {
4504         synchronized (this) {
4505             ActivityRecord r = getCallingRecordLocked(token);
4506             return r != null ? r.intent.getComponent() : null;
4507         }
4508     }
4509 
getCallingRecordLocked(IBinder token)4510     private ActivityRecord getCallingRecordLocked(IBinder token) {
4511         ActivityRecord r = mMainStack.isInStackLocked(token);
4512         if (r == null) {
4513             return null;
4514         }
4515         return r.resultTo;
4516     }
4517 
getActivityClassForToken(IBinder token)4518     public ComponentName getActivityClassForToken(IBinder token) {
4519         synchronized(this) {
4520             ActivityRecord r = mMainStack.isInStackLocked(token);
4521             if (r == null) {
4522                 return null;
4523             }
4524             return r.intent.getComponent();
4525         }
4526     }
4527 
getPackageForToken(IBinder token)4528     public String getPackageForToken(IBinder token) {
4529         synchronized(this) {
4530             ActivityRecord r = mMainStack.isInStackLocked(token);
4531             if (r == null) {
4532                 return null;
4533             }
4534             return r.packageName;
4535         }
4536     }
4537 
getIntentSender(int type, String packageName, IBinder token, String resultWho, int requestCode, Intent[] intents, String[] resolvedTypes, int flags, Bundle options, int userId)4538     public IIntentSender getIntentSender(int type,
4539             String packageName, IBinder token, String resultWho,
4540             int requestCode, Intent[] intents, String[] resolvedTypes,
4541             int flags, Bundle options, int userId) {
4542         enforceNotIsolatedCaller("getIntentSender");
4543         // Refuse possible leaked file descriptors
4544         if (intents != null) {
4545             if (intents.length < 1) {
4546                 throw new IllegalArgumentException("Intents array length must be >= 1");
4547             }
4548             for (int i=0; i<intents.length; i++) {
4549                 Intent intent = intents[i];
4550                 if (intent != null) {
4551                     if (intent.hasFileDescriptors()) {
4552                         throw new IllegalArgumentException("File descriptors passed in Intent");
4553                     }
4554                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4555                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4556                         throw new IllegalArgumentException(
4557                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4558                     }
4559                     intents[i] = new Intent(intent);
4560                 }
4561             }
4562             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4563                 throw new IllegalArgumentException(
4564                         "Intent array length does not match resolvedTypes length");
4565             }
4566         }
4567         if (options != null) {
4568             if (options.hasFileDescriptors()) {
4569                 throw new IllegalArgumentException("File descriptors passed in options");
4570             }
4571         }
4572 
4573         synchronized(this) {
4574             int callingUid = Binder.getCallingUid();
4575             int origUserId = userId;
4576             userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
4577                     type == ActivityManager.INTENT_SENDER_BROADCAST, false,
4578                     "getIntentSender", null);
4579             if (origUserId == UserHandle.USER_CURRENT) {
4580                 // We don't want to evaluate this until the pending intent is
4581                 // actually executed.  However, we do want to always do the
4582                 // security checking for it above.
4583                 userId = UserHandle.USER_CURRENT;
4584             }
4585             try {
4586                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4587                     int uid = AppGlobals.getPackageManager()
4588                             .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4589                     if (!UserHandle.isSameApp(callingUid, uid)) {
4590                         String msg = "Permission Denial: getIntentSender() from pid="
4591                             + Binder.getCallingPid()
4592                             + ", uid=" + Binder.getCallingUid()
4593                             + ", (need uid=" + uid + ")"
4594                             + " is not allowed to send as package " + packageName;
4595                         Slog.w(TAG, msg);
4596                         throw new SecurityException(msg);
4597                     }
4598                 }
4599 
4600                 return getIntentSenderLocked(type, packageName, callingUid, userId,
4601                         token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4602 
4603             } catch (RemoteException e) {
4604                 throw new SecurityException(e);
4605             }
4606         }
4607     }
4608 
getIntentSenderLocked(int type, String packageName, int callingUid, int userId, IBinder token, String resultWho, int requestCode, Intent[] intents, String[] resolvedTypes, int flags, Bundle options)4609     IIntentSender getIntentSenderLocked(int type, String packageName,
4610             int callingUid, int userId, IBinder token, String resultWho,
4611             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4612             Bundle options) {
4613         if (DEBUG_MU)
4614             Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4615         ActivityRecord activity = null;
4616         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4617             activity = mMainStack.isInStackLocked(token);
4618             if (activity == null) {
4619                 return null;
4620             }
4621             if (activity.finishing) {
4622                 return null;
4623             }
4624         }
4625 
4626         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4627         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4628         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4629         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4630                 |PendingIntent.FLAG_UPDATE_CURRENT);
4631 
4632         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4633                 type, packageName, activity, resultWho,
4634                 requestCode, intents, resolvedTypes, flags, options, userId);
4635         WeakReference<PendingIntentRecord> ref;
4636         ref = mIntentSenderRecords.get(key);
4637         PendingIntentRecord rec = ref != null ? ref.get() : null;
4638         if (rec != null) {
4639             if (!cancelCurrent) {
4640                 if (updateCurrent) {
4641                     if (rec.key.requestIntent != null) {
4642                         rec.key.requestIntent.replaceExtras(intents != null ?
4643                                 intents[intents.length - 1] : null);
4644                     }
4645                     if (intents != null) {
4646                         intents[intents.length-1] = rec.key.requestIntent;
4647                         rec.key.allIntents = intents;
4648                         rec.key.allResolvedTypes = resolvedTypes;
4649                     } else {
4650                         rec.key.allIntents = null;
4651                         rec.key.allResolvedTypes = null;
4652                     }
4653                 }
4654                 return rec;
4655             }
4656             rec.canceled = true;
4657             mIntentSenderRecords.remove(key);
4658         }
4659         if (noCreate) {
4660             return rec;
4661         }
4662         rec = new PendingIntentRecord(this, key, callingUid);
4663         mIntentSenderRecords.put(key, rec.ref);
4664         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4665             if (activity.pendingResults == null) {
4666                 activity.pendingResults
4667                         = new HashSet<WeakReference<PendingIntentRecord>>();
4668             }
4669             activity.pendingResults.add(rec.ref);
4670         }
4671         return rec;
4672     }
4673 
cancelIntentSender(IIntentSender sender)4674     public void cancelIntentSender(IIntentSender sender) {
4675         if (!(sender instanceof PendingIntentRecord)) {
4676             return;
4677         }
4678         synchronized(this) {
4679             PendingIntentRecord rec = (PendingIntentRecord)sender;
4680             try {
4681                 int uid = AppGlobals.getPackageManager()
4682                         .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4683                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4684                     String msg = "Permission Denial: cancelIntentSender() from pid="
4685                         + Binder.getCallingPid()
4686                         + ", uid=" + Binder.getCallingUid()
4687                         + " is not allowed to cancel packges "
4688                         + rec.key.packageName;
4689                     Slog.w(TAG, msg);
4690                     throw new SecurityException(msg);
4691                 }
4692             } catch (RemoteException e) {
4693                 throw new SecurityException(e);
4694             }
4695             cancelIntentSenderLocked(rec, true);
4696         }
4697     }
4698 
cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity)4699     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4700         rec.canceled = true;
4701         mIntentSenderRecords.remove(rec.key);
4702         if (cleanActivity && rec.key.activity != null) {
4703             rec.key.activity.pendingResults.remove(rec.ref);
4704         }
4705     }
4706 
getPackageForIntentSender(IIntentSender pendingResult)4707     public String getPackageForIntentSender(IIntentSender pendingResult) {
4708         if (!(pendingResult instanceof PendingIntentRecord)) {
4709             return null;
4710         }
4711         try {
4712             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4713             return res.key.packageName;
4714         } catch (ClassCastException e) {
4715         }
4716         return null;
4717     }
4718 
getUidForIntentSender(IIntentSender sender)4719     public int getUidForIntentSender(IIntentSender sender) {
4720         if (sender instanceof PendingIntentRecord) {
4721             try {
4722                 PendingIntentRecord res = (PendingIntentRecord)sender;
4723                 return res.uid;
4724             } catch (ClassCastException e) {
4725             }
4726         }
4727         return -1;
4728     }
4729 
isIntentSenderTargetedToPackage(IIntentSender pendingResult)4730     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4731         if (!(pendingResult instanceof PendingIntentRecord)) {
4732             return false;
4733         }
4734         try {
4735             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4736             if (res.key.allIntents == null) {
4737                 return false;
4738             }
4739             for (int i=0; i<res.key.allIntents.length; i++) {
4740                 Intent intent = res.key.allIntents[i];
4741                 if (intent.getPackage() != null && intent.getComponent() != null) {
4742                     return false;
4743                 }
4744             }
4745             return true;
4746         } catch (ClassCastException e) {
4747         }
4748         return false;
4749     }
4750 
isIntentSenderAnActivity(IIntentSender pendingResult)4751     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4752         if (!(pendingResult instanceof PendingIntentRecord)) {
4753             return false;
4754         }
4755         try {
4756             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4757             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4758                 return true;
4759             }
4760             return false;
4761         } catch (ClassCastException e) {
4762         }
4763         return false;
4764     }
4765 
getIntentForIntentSender(IIntentSender pendingResult)4766     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
4767         if (!(pendingResult instanceof PendingIntentRecord)) {
4768             return null;
4769         }
4770         try {
4771             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4772             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
4773         } catch (ClassCastException e) {
4774         }
4775         return null;
4776     }
4777 
setProcessLimit(int max)4778     public void setProcessLimit(int max) {
4779         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4780                 "setProcessLimit()");
4781         synchronized (this) {
4782             mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4783             mProcessLimitOverride = max;
4784         }
4785         trimApplications();
4786     }
4787 
4788     public int getProcessLimit() {
4789         synchronized (this) {
4790             return mProcessLimitOverride;
4791         }
4792     }
4793 
4794     void foregroundTokenDied(ForegroundToken token) {
4795         synchronized (ActivityManagerService.this) {
4796             synchronized (mPidsSelfLocked) {
4797                 ForegroundToken cur
4798                     = mForegroundProcesses.get(token.pid);
4799                 if (cur != token) {
4800                     return;
4801                 }
4802                 mForegroundProcesses.remove(token.pid);
4803                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4804                 if (pr == null) {
4805                     return;
4806                 }
4807                 pr.forcingToForeground = null;
4808                 pr.foregroundServices = false;
4809             }
4810             updateOomAdjLocked();
4811         }
4812     }
4813 
4814     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4815         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4816                 "setProcessForeground()");
4817         synchronized(this) {
4818             boolean changed = false;
4819 
4820             synchronized (mPidsSelfLocked) {
4821                 ProcessRecord pr = mPidsSelfLocked.get(pid);
4822                 if (pr == null && isForeground) {
4823                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4824                     return;
4825                 }
4826                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4827                 if (oldToken != null) {
4828                     oldToken.token.unlinkToDeath(oldToken, 0);
4829                     mForegroundProcesses.remove(pid);
4830                     if (pr != null) {
4831                         pr.forcingToForeground = null;
4832                     }
4833                     changed = true;
4834                 }
4835                 if (isForeground && token != null) {
4836                     ForegroundToken newToken = new ForegroundToken() {
4837                         public void binderDied() {
4838                             foregroundTokenDied(this);
4839                         }
4840                     };
4841                     newToken.pid = pid;
4842                     newToken.token = token;
4843                     try {
4844                         token.linkToDeath(newToken, 0);
4845                         mForegroundProcesses.put(pid, newToken);
4846                         pr.forcingToForeground = token;
4847                         changed = true;
4848                     } catch (RemoteException e) {
4849                         // If the process died while doing this, we will later
4850                         // do the cleanup with the process death link.
4851                     }
4852                 }
4853             }
4854 
4855             if (changed) {
4856                 updateOomAdjLocked();
4857             }
4858         }
4859     }
4860 
4861     // =========================================================
4862     // PERMISSIONS
4863     // =========================================================
4864 
4865     static class PermissionController extends IPermissionController.Stub {
4866         ActivityManagerService mActivityManagerService;
4867         PermissionController(ActivityManagerService activityManagerService) {
4868             mActivityManagerService = activityManagerService;
4869         }
4870 
4871         public boolean checkPermission(String permission, int pid, int uid) {
4872             return mActivityManagerService.checkPermission(permission, pid,
4873                     uid) == PackageManager.PERMISSION_GRANTED;
4874         }
4875     }
4876 
4877     /**
4878      * This can be called with or without the global lock held.
4879      */
4880     int checkComponentPermission(String permission, int pid, int uid,
4881             int owningUid, boolean exported) {
4882         // We might be performing an operation on behalf of an indirect binder
4883         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4884         // client identity accordingly before proceeding.
4885         Identity tlsIdentity = sCallerIdentity.get();
4886         if (tlsIdentity != null) {
4887             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4888                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4889             uid = tlsIdentity.uid;
4890             pid = tlsIdentity.pid;
4891         }
4892 
4893         if (pid == MY_PID) {
4894             return PackageManager.PERMISSION_GRANTED;
4895         }
4896 
4897         return ActivityManager.checkComponentPermission(permission, uid,
4898                 owningUid, exported);
4899     }
4900 
4901     /**
4902      * As the only public entry point for permissions checking, this method
4903      * can enforce the semantic that requesting a check on a null global
4904      * permission is automatically denied.  (Internally a null permission
4905      * string is used when calling {@link #checkComponentPermission} in cases
4906      * when only uid-based security is needed.)
4907      *
4908      * This can be called with or without the global lock held.
4909      */
4910     public int checkPermission(String permission, int pid, int uid) {
4911         if (permission == null) {
4912             return PackageManager.PERMISSION_DENIED;
4913         }
4914         return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4915     }
4916 
4917     /**
4918      * Binder IPC calls go through the public entry point.
4919      * This can be called with or without the global lock held.
4920      */
4921     int checkCallingPermission(String permission) {
4922         return checkPermission(permission,
4923                 Binder.getCallingPid(),
4924                 UserHandle.getAppId(Binder.getCallingUid()));
4925     }
4926 
4927     /**
4928      * This can be called with or without the global lock held.
4929      */
4930     void enforceCallingPermission(String permission, String func) {
4931         if (checkCallingPermission(permission)
4932                 == PackageManager.PERMISSION_GRANTED) {
4933             return;
4934         }
4935 
4936         String msg = "Permission Denial: " + func + " from pid="
4937                 + Binder.getCallingPid()
4938                 + ", uid=" + Binder.getCallingUid()
4939                 + " requires " + permission;
4940         Slog.w(TAG, msg);
4941         throw new SecurityException(msg);
4942     }
4943 
4944     /**
4945      * Determine if UID is holding permissions required to access {@link Uri} in
4946      * the given {@link ProviderInfo}. Final permission checking is always done
4947      * in {@link ContentProvider}.
4948      */
4949     private final boolean checkHoldingPermissionsLocked(
4950             IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4951         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4952                 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4953 
4954         if (pi.applicationInfo.uid == uid) {
4955             return true;
4956         } else if (!pi.exported) {
4957             return false;
4958         }
4959 
4960         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4961         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4962         try {
4963             // check if target holds top-level <provider> permissions
4964             if (!readMet && pi.readPermission != null
4965                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4966                 readMet = true;
4967             }
4968             if (!writeMet && pi.writePermission != null
4969                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4970                 writeMet = true;
4971             }
4972 
4973             // track if unprotected read/write is allowed; any denied
4974             // <path-permission> below removes this ability
4975             boolean allowDefaultRead = pi.readPermission == null;
4976             boolean allowDefaultWrite = pi.writePermission == null;
4977 
4978             // check if target holds any <path-permission> that match uri
4979             final PathPermission[] pps = pi.pathPermissions;
4980             if (pps != null) {
4981                 final String path = uri.getPath();
4982                 int i = pps.length;
4983                 while (i > 0 && (!readMet || !writeMet)) {
4984                     i--;
4985                     PathPermission pp = pps[i];
4986                     if (pp.match(path)) {
4987                         if (!readMet) {
4988                             final String pprperm = pp.getReadPermission();
4989                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4990                                     + pprperm + " for " + pp.getPath()
4991                                     + ": match=" + pp.match(path)
4992                                     + " check=" + pm.checkUidPermission(pprperm, uid));
4993                             if (pprperm != null) {
4994                                 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4995                                     readMet = true;
4996                                 } else {
4997                                     allowDefaultRead = false;
4998                                 }
4999                             }
5000                         }
5001                         if (!writeMet) {
5002                             final String ppwperm = pp.getWritePermission();
5003                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5004                                     + ppwperm + " for " + pp.getPath()
5005                                     + ": match=" + pp.match(path)
5006                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
5007                             if (ppwperm != null) {
5008                                 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5009                                     writeMet = true;
5010                                 } else {
5011                                     allowDefaultWrite = false;
5012                                 }
5013                             }
5014                         }
5015                     }
5016                 }
5017             }
5018 
5019             // grant unprotected <provider> read/write, if not blocked by
5020             // <path-permission> above
5021             if (allowDefaultRead) readMet = true;
5022             if (allowDefaultWrite) writeMet = true;
5023 
5024         } catch (RemoteException e) {
5025             return false;
5026         }
5027 
5028         return readMet && writeMet;
5029     }
5030 
checkUriPermissionLocked(Uri uri, int uid, int modeFlags)5031     private final boolean checkUriPermissionLocked(Uri uri, int uid,
5032             int modeFlags) {
5033         // Root gets to do everything.
5034         if (uid == 0) {
5035             return true;
5036         }
5037         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5038         if (perms == null) return false;
5039         UriPermission perm = perms.get(uri);
5040         if (perm == null) return false;
5041         return (modeFlags&perm.modeFlags) == modeFlags;
5042     }
5043 
checkUriPermission(Uri uri, int pid, int uid, int modeFlags)5044     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5045         enforceNotIsolatedCaller("checkUriPermission");
5046 
5047         // Another redirected-binder-call permissions check as in
5048         // {@link checkComponentPermission}.
5049         Identity tlsIdentity = sCallerIdentity.get();
5050         if (tlsIdentity != null) {
5051             uid = tlsIdentity.uid;
5052             pid = tlsIdentity.pid;
5053         }
5054 
5055         // Our own process gets to do everything.
5056         if (pid == MY_PID) {
5057             return PackageManager.PERMISSION_GRANTED;
5058         }
5059         synchronized(this) {
5060             return checkUriPermissionLocked(uri, uid, modeFlags)
5061                     ? PackageManager.PERMISSION_GRANTED
5062                     : PackageManager.PERMISSION_DENIED;
5063         }
5064     }
5065 
5066     /**
5067      * Check if the targetPkg can be granted permission to access uri by
5068      * the callingUid using the given modeFlags.  Throws a security exception
5069      * if callingUid is not allowed to do this.  Returns the uid of the target
5070      * if the URI permission grant should be performed; returns -1 if it is not
5071      * needed (for example targetPkg already has permission to access the URI).
5072      * If you already know the uid of the target, you can supply it in
5073      * lastTargetUid else set that to -1.
5074      */
checkGrantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, int modeFlags, int lastTargetUid)5075     int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5076             Uri uri, int modeFlags, int lastTargetUid) {
5077         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5078                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5079         if (modeFlags == 0) {
5080             return -1;
5081         }
5082 
5083         if (targetPkg != null) {
5084             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5085                     "Checking grant " + targetPkg + " permission to " + uri);
5086         }
5087 
5088         final IPackageManager pm = AppGlobals.getPackageManager();
5089 
5090         // If this is not a content: uri, we can't do anything with it.
5091         if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5092             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5093                     "Can't grant URI permission for non-content URI: " + uri);
5094             return -1;
5095         }
5096 
5097         String name = uri.getAuthority();
5098         ProviderInfo pi = null;
5099         ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5100                 UserHandle.getUserId(callingUid));
5101         if (cpr != null) {
5102             pi = cpr.info;
5103         } else {
5104             try {
5105                 pi = pm.resolveContentProvider(name,
5106                         PackageManager.GET_URI_PERMISSION_PATTERNS,
5107                         UserHandle.getUserId(callingUid));
5108             } catch (RemoteException ex) {
5109             }
5110         }
5111         if (pi == null) {
5112             Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5113             return -1;
5114         }
5115 
5116         int targetUid = lastTargetUid;
5117         if (targetUid < 0 && targetPkg != null) {
5118             try {
5119                 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5120                 if (targetUid < 0) {
5121                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5122                             "Can't grant URI permission no uid for: " + targetPkg);
5123                     return -1;
5124                 }
5125             } catch (RemoteException ex) {
5126                 return -1;
5127             }
5128         }
5129 
5130         if (targetUid >= 0) {
5131             // First...  does the target actually need this permission?
5132             if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5133                 // No need to grant the target this permission.
5134                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5135                         "Target " + targetPkg + " already has full permission to " + uri);
5136                 return -1;
5137             }
5138         } else {
5139             // First...  there is no target package, so can anyone access it?
5140             boolean allowed = pi.exported;
5141             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5142                 if (pi.readPermission != null) {
5143                     allowed = false;
5144                 }
5145             }
5146             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5147                 if (pi.writePermission != null) {
5148                     allowed = false;
5149                 }
5150             }
5151             if (allowed) {
5152                 return -1;
5153             }
5154         }
5155 
5156         // Second...  is the provider allowing granting of URI permissions?
5157         if (!pi.grantUriPermissions) {
5158             throw new SecurityException("Provider " + pi.packageName
5159                     + "/" + pi.name
5160                     + " does not allow granting of Uri permissions (uri "
5161                     + uri + ")");
5162         }
5163         if (pi.uriPermissionPatterns != null) {
5164             final int N = pi.uriPermissionPatterns.length;
5165             boolean allowed = false;
5166             for (int i=0; i<N; i++) {
5167                 if (pi.uriPermissionPatterns[i] != null
5168                         && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5169                     allowed = true;
5170                     break;
5171                 }
5172             }
5173             if (!allowed) {
5174                 throw new SecurityException("Provider " + pi.packageName
5175                         + "/" + pi.name
5176                         + " does not allow granting of permission to path of Uri "
5177                         + uri);
5178             }
5179         }
5180 
5181         // Third...  does the caller itself have permission to access
5182         // this uri?
5183         if (callingUid != Process.myUid()) {
5184             if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5185                 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5186                     throw new SecurityException("Uid " + callingUid
5187                             + " does not have permission to uri " + uri);
5188                 }
5189             }
5190         }
5191 
5192         return targetUid;
5193     }
5194 
checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, int modeFlags)5195     public int checkGrantUriPermission(int callingUid, String targetPkg,
5196             Uri uri, int modeFlags) {
5197         enforceNotIsolatedCaller("checkGrantUriPermission");
5198         synchronized(this) {
5199             return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5200         }
5201     }
5202 
grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner)5203     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5204             Uri uri, int modeFlags, UriPermissionOwner owner) {
5205         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5206                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5207         if (modeFlags == 0) {
5208             return;
5209         }
5210 
5211         // So here we are: the caller has the assumed permission
5212         // to the uri, and the target doesn't.  Let's now give this to
5213         // the target.
5214 
5215         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5216                 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5217 
5218         HashMap<Uri, UriPermission> targetUris
5219                 = mGrantedUriPermissions.get(targetUid);
5220         if (targetUris == null) {
5221             targetUris = new HashMap<Uri, UriPermission>();
5222             mGrantedUriPermissions.put(targetUid, targetUris);
5223         }
5224 
5225         UriPermission perm = targetUris.get(uri);
5226         if (perm == null) {
5227             perm = new UriPermission(targetUid, uri);
5228             targetUris.put(uri, perm);
5229         }
5230 
5231         perm.modeFlags |= modeFlags;
5232         if (owner == null) {
5233             perm.globalModeFlags |= modeFlags;
5234         } else {
5235             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5236                  perm.readOwners.add(owner);
5237                  owner.addReadPermission(perm);
5238             }
5239             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5240                  perm.writeOwners.add(owner);
5241                  owner.addWritePermission(perm);
5242             }
5243         }
5244     }
5245 
grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner)5246     void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5247             int modeFlags, UriPermissionOwner owner) {
5248         if (targetPkg == null) {
5249             throw new NullPointerException("targetPkg");
5250         }
5251 
5252         int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5253         if (targetUid < 0) {
5254             return;
5255         }
5256 
5257         grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5258     }
5259 
5260     static class NeededUriGrants extends ArrayList<Uri> {
5261         final String targetPkg;
5262         final int targetUid;
5263         final int flags;
5264 
NeededUriGrants(String _targetPkg, int _targetUid, int _flags)5265         NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5266             targetPkg = _targetPkg;
5267             targetUid = _targetUid;
5268             flags = _flags;
5269         }
5270     }
5271 
5272     /**
5273      * Like checkGrantUriPermissionLocked, but takes an Intent.
5274      */
checkGrantUriPermissionFromIntentLocked(int callingUid, String targetPkg, Intent intent, int mode, NeededUriGrants needed)5275     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5276             String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5277         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5278                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5279                 + " clip=" + (intent != null ? intent.getClipData() : null)
5280                 + " from " + intent + "; flags=0x"
5281                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5282 
5283         if (targetPkg == null) {
5284             throw new NullPointerException("targetPkg");
5285         }
5286 
5287         if (intent == null) {
5288             return null;
5289         }
5290         Uri data = intent.getData();
5291         ClipData clip = intent.getClipData();
5292         if (data == null && clip == null) {
5293             return null;
5294         }
5295         if (data != null) {
5296             int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5297                 mode, needed != null ? needed.targetUid : -1);
5298             if (target > 0) {
5299                 if (needed == null) {
5300                     needed = new NeededUriGrants(targetPkg, target, mode);
5301                 }
5302                 needed.add(data);
5303             }
5304         }
5305         if (clip != null) {
5306             for (int i=0; i<clip.getItemCount(); i++) {
5307                 Uri uri = clip.getItemAt(i).getUri();
5308                 if (uri != null) {
5309                     int target = -1;
5310                     target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5311                             mode, needed != null ? needed.targetUid : -1);
5312                     if (target > 0) {
5313                         if (needed == null) {
5314                             needed = new NeededUriGrants(targetPkg, target, mode);
5315                         }
5316                         needed.add(uri);
5317                     }
5318                 } else {
5319                     Intent clipIntent = clip.getItemAt(i).getIntent();
5320                     if (clipIntent != null) {
5321                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5322                                 callingUid, targetPkg, clipIntent, mode, needed);
5323                         if (newNeeded != null) {
5324                             needed = newNeeded;
5325                         }
5326                     }
5327                 }
5328             }
5329         }
5330 
5331         return needed;
5332     }
5333 
5334     /**
5335      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5336      */
grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, UriPermissionOwner owner)5337     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5338             UriPermissionOwner owner) {
5339         if (needed != null) {
5340             for (int i=0; i<needed.size(); i++) {
5341                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5342                         needed.get(i), needed.flags, owner);
5343             }
5344         }
5345     }
5346 
grantUriPermissionFromIntentLocked(int callingUid, String targetPkg, Intent intent, UriPermissionOwner owner)5347     void grantUriPermissionFromIntentLocked(int callingUid,
5348             String targetPkg, Intent intent, UriPermissionOwner owner) {
5349         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5350                 intent, intent != null ? intent.getFlags() : 0, null);
5351         if (needed == null) {
5352             return;
5353         }
5354 
5355         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5356     }
5357 
grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, int modeFlags)5358     public void grantUriPermission(IApplicationThread caller, String targetPkg,
5359             Uri uri, int modeFlags) {
5360         enforceNotIsolatedCaller("grantUriPermission");
5361         synchronized(this) {
5362             final ProcessRecord r = getRecordForAppLocked(caller);
5363             if (r == null) {
5364                 throw new SecurityException("Unable to find app for caller "
5365                         + caller
5366                         + " when granting permission to uri " + uri);
5367             }
5368             if (targetPkg == null) {
5369                 throw new IllegalArgumentException("null target");
5370             }
5371             if (uri == null) {
5372                 throw new IllegalArgumentException("null uri");
5373             }
5374 
5375             grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5376                     null);
5377         }
5378     }
5379 
removeUriPermissionIfNeededLocked(UriPermission perm)5380     void removeUriPermissionIfNeededLocked(UriPermission perm) {
5381         if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5382                 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5383             HashMap<Uri, UriPermission> perms
5384                     = mGrantedUriPermissions.get(perm.uid);
5385             if (perms != null) {
5386                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5387                         "Removing " + perm.uid + " permission to " + perm.uri);
5388                 perms.remove(perm.uri);
5389                 if (perms.size() == 0) {
5390                     mGrantedUriPermissions.remove(perm.uid);
5391                 }
5392             }
5393         }
5394     }
5395 
revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags)5396     private void revokeUriPermissionLocked(int callingUid, Uri uri,
5397             int modeFlags) {
5398         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5399                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5400         if (modeFlags == 0) {
5401             return;
5402         }
5403 
5404         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5405                 "Revoking all granted permissions to " + uri);
5406 
5407         final IPackageManager pm = AppGlobals.getPackageManager();
5408 
5409         final String authority = uri.getAuthority();
5410         ProviderInfo pi = null;
5411         int userId = UserHandle.getUserId(callingUid);
5412         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5413         if (cpr != null) {
5414             pi = cpr.info;
5415         } else {
5416             try {
5417                 pi = pm.resolveContentProvider(authority,
5418                         PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5419             } catch (RemoteException ex) {
5420             }
5421         }
5422         if (pi == null) {
5423             Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5424             return;
5425         }
5426 
5427         // Does the caller have this permission on the URI?
5428         if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5429             // Right now, if you are not the original owner of the permission,
5430             // you are not allowed to revoke it.
5431             //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5432                 throw new SecurityException("Uid " + callingUid
5433                         + " does not have permission to uri " + uri);
5434             //}
5435         }
5436 
5437         // Go through all of the permissions and remove any that match.
5438         final List<String> SEGMENTS = uri.getPathSegments();
5439         if (SEGMENTS != null) {
5440             final int NS = SEGMENTS.size();
5441             int N = mGrantedUriPermissions.size();
5442             for (int i=0; i<N; i++) {
5443                 HashMap<Uri, UriPermission> perms
5444                         = mGrantedUriPermissions.valueAt(i);
5445                 Iterator<UriPermission> it = perms.values().iterator();
5446             toploop:
5447                 while (it.hasNext()) {
5448                     UriPermission perm = it.next();
5449                     Uri targetUri = perm.uri;
5450                     if (!authority.equals(targetUri.getAuthority())) {
5451                         continue;
5452                     }
5453                     List<String> targetSegments = targetUri.getPathSegments();
5454                     if (targetSegments == null) {
5455                         continue;
5456                     }
5457                     if (targetSegments.size() < NS) {
5458                         continue;
5459                     }
5460                     for (int j=0; j<NS; j++) {
5461                         if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5462                             continue toploop;
5463                         }
5464                     }
5465                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5466                             "Revoking " + perm.uid + " permission to " + perm.uri);
5467                     perm.clearModes(modeFlags);
5468                     if (perm.modeFlags == 0) {
5469                         it.remove();
5470                     }
5471                 }
5472                 if (perms.size() == 0) {
5473                     mGrantedUriPermissions.remove(
5474                             mGrantedUriPermissions.keyAt(i));
5475                     N--;
5476                     i--;
5477                 }
5478             }
5479         }
5480     }
5481 
revokeUriPermission(IApplicationThread caller, Uri uri, int modeFlags)5482     public void revokeUriPermission(IApplicationThread caller, Uri uri,
5483             int modeFlags) {
5484         enforceNotIsolatedCaller("revokeUriPermission");
5485         synchronized(this) {
5486             final ProcessRecord r = getRecordForAppLocked(caller);
5487             if (r == null) {
5488                 throw new SecurityException("Unable to find app for caller "
5489                         + caller
5490                         + " when revoking permission to uri " + uri);
5491             }
5492             if (uri == null) {
5493                 Slog.w(TAG, "revokeUriPermission: null uri");
5494                 return;
5495             }
5496 
5497             modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5498                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5499             if (modeFlags == 0) {
5500                 return;
5501             }
5502 
5503             final IPackageManager pm = AppGlobals.getPackageManager();
5504 
5505             final String authority = uri.getAuthority();
5506             ProviderInfo pi = null;
5507             ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5508             if (cpr != null) {
5509                 pi = cpr.info;
5510             } else {
5511                 try {
5512                     pi = pm.resolveContentProvider(authority,
5513                             PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5514                 } catch (RemoteException ex) {
5515                 }
5516             }
5517             if (pi == null) {
5518                 Slog.w(TAG, "No content provider found for permission revoke: "
5519                         + uri.toSafeString());
5520                 return;
5521             }
5522 
5523             revokeUriPermissionLocked(r.uid, uri, modeFlags);
5524         }
5525     }
5526 
5527     @Override
newUriPermissionOwner(String name)5528     public IBinder newUriPermissionOwner(String name) {
5529         enforceNotIsolatedCaller("newUriPermissionOwner");
5530         synchronized(this) {
5531             UriPermissionOwner owner = new UriPermissionOwner(this, name);
5532             return owner.getExternalTokenLocked();
5533         }
5534     }
5535 
5536     @Override
grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, int modeFlags)5537     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5538             Uri uri, int modeFlags) {
5539         synchronized(this) {
5540             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5541             if (owner == null) {
5542                 throw new IllegalArgumentException("Unknown owner: " + token);
5543             }
5544             if (fromUid != Binder.getCallingUid()) {
5545                 if (Binder.getCallingUid() != Process.myUid()) {
5546                     // Only system code can grant URI permissions on behalf
5547                     // of other users.
5548                     throw new SecurityException("nice try");
5549                 }
5550             }
5551             if (targetPkg == null) {
5552                 throw new IllegalArgumentException("null target");
5553             }
5554             if (uri == null) {
5555                 throw new IllegalArgumentException("null uri");
5556             }
5557 
5558             grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5559         }
5560     }
5561 
5562     @Override
revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode)5563     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5564         synchronized(this) {
5565             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5566             if (owner == null) {
5567                 throw new IllegalArgumentException("Unknown owner: " + token);
5568             }
5569 
5570             if (uri == null) {
5571                 owner.removeUriPermissionsLocked(mode);
5572             } else {
5573                 owner.removeUriPermissionLocked(uri, mode);
5574             }
5575         }
5576     }
5577 
showWaitingForDebugger(IApplicationThread who, boolean waiting)5578     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5579         synchronized (this) {
5580             ProcessRecord app =
5581                 who != null ? getRecordForAppLocked(who) : null;
5582             if (app == null) return;
5583 
5584             Message msg = Message.obtain();
5585             msg.what = WAIT_FOR_DEBUGGER_MSG;
5586             msg.obj = app;
5587             msg.arg1 = waiting ? 1 : 0;
5588             mHandler.sendMessage(msg);
5589         }
5590     }
5591 
getMemoryInfo(ActivityManager.MemoryInfo outInfo)5592     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5593         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5594         final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5595         outInfo.availMem = Process.getFreeMemory();
5596         outInfo.totalMem = Process.getTotalMemory();
5597         outInfo.threshold = homeAppMem;
5598         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5599         outInfo.hiddenAppThreshold = hiddenAppMem;
5600         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5601                 ProcessList.SERVICE_ADJ);
5602         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5603                 ProcessList.VISIBLE_APP_ADJ);
5604         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5605                 ProcessList.FOREGROUND_APP_ADJ);
5606     }
5607 
5608     // =========================================================
5609     // TASK MANAGEMENT
5610     // =========================================================
5611 
5612     public List getTasks(int maxNum, int flags,
5613                          IThumbnailReceiver receiver) {
5614         ArrayList list = new ArrayList();
5615 
5616         PendingThumbnailsRecord pending = null;
5617         IApplicationThread topThumbnail = null;
5618         ActivityRecord topRecord = null;
5619 
5620         synchronized(this) {
5621             if (localLOGV) Slog.v(
5622                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5623                 + ", receiver=" + receiver);
5624 
5625             if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5626                     != PackageManager.PERMISSION_GRANTED) {
5627                 if (receiver != null) {
5628                     // If the caller wants to wait for pending thumbnails,
5629                     // it ain't gonna get them.
5630                     try {
5631                         receiver.finished();
5632                     } catch (RemoteException ex) {
5633                     }
5634                 }
5635                 String msg = "Permission Denial: getTasks() from pid="
5636                         + Binder.getCallingPid()
5637                         + ", uid=" + Binder.getCallingUid()
5638                         + " requires " + android.Manifest.permission.GET_TASKS;
5639                 Slog.w(TAG, msg);
5640                 throw new SecurityException(msg);
5641             }
5642 
5643             int pos = mMainStack.mHistory.size()-1;
5644             ActivityRecord next =
5645                 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5646             ActivityRecord top = null;
5647             TaskRecord curTask = null;
5648             int numActivities = 0;
5649             int numRunning = 0;
5650             while (pos >= 0 && maxNum > 0) {
5651                 final ActivityRecord r = next;
5652                 pos--;
5653                 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5654 
5655                 // Initialize state for next task if needed.
5656                 if (top == null ||
5657                         (top.state == ActivityState.INITIALIZING
5658                             && top.task == r.task)) {
5659                     top = r;
5660                     curTask = r.task;
5661                     numActivities = numRunning = 0;
5662                 }
5663 
5664                 // Add 'r' into the current task.
5665                 numActivities++;
5666                 if (r.app != null && r.app.thread != null) {
5667                     numRunning++;
5668                 }
5669 
5670                 if (localLOGV) Slog.v(
5671                     TAG, r.intent.getComponent().flattenToShortString()
5672                     + ": task=" + r.task);
5673 
5674                 // If the next one is a different task, generate a new
5675                 // TaskInfo entry for what we have.
5676                 if (next == null || next.task != curTask) {
5677                     ActivityManager.RunningTaskInfo ci
5678                             = new ActivityManager.RunningTaskInfo();
5679                     ci.id = curTask.taskId;
5680                     ci.baseActivity = r.intent.getComponent();
5681                     ci.topActivity = top.intent.getComponent();
5682                     if (top.thumbHolder != null) {
5683                         ci.description = top.thumbHolder.lastDescription;
5684                     }
5685                     ci.numActivities = numActivities;
5686                     ci.numRunning = numRunning;
5687                     //System.out.println(
5688                     //    "#" + maxNum + ": " + " descr=" + ci.description);
5689                     if (ci.thumbnail == null && receiver != null) {
5690                         if (localLOGV) Slog.v(
5691                             TAG, "State=" + top.state + "Idle=" + top.idle
5692                             + " app=" + top.app
5693                             + " thr=" + (top.app != null ? top.app.thread : null));
5694                         if (top.state == ActivityState.RESUMED
5695                                 || top.state == ActivityState.PAUSING) {
5696                             if (top.idle && top.app != null
5697                                 && top.app.thread != null) {
5698                                 topRecord = top;
5699                                 topThumbnail = top.app.thread;
5700                             } else {
5701                                 top.thumbnailNeeded = true;
5702                             }
5703                         }
5704                         if (pending == null) {
5705                             pending = new PendingThumbnailsRecord(receiver);
5706                         }
5707                         pending.pendingRecords.add(top);
5708                     }
5709                     list.add(ci);
5710                     maxNum--;
5711                     top = null;
5712                 }
5713             }
5714 
5715             if (pending != null) {
5716                 mPendingThumbnails.add(pending);
5717             }
5718         }
5719 
Slog.v(TAG, "We have pending thumbnails: " + pending)5720         if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5721 
5722         if (topThumbnail != null) {
Slog.v(TAG, "Requesting top thumbnail")5723             if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5724             try {
5725                 topThumbnail.requestThumbnail(topRecord.appToken);
5726             } catch (Exception e) {
5727                 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5728                 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5729             }
5730         }
5731 
5732         if (pending == null && receiver != null) {
5733             // In this case all thumbnails were available and the client
5734             // is being asked to be told when the remaining ones come in...
5735             // which is unusually, since the top-most currently running
5736             // activity should never have a canned thumbnail!  Oh well.
5737             try {
receiver.finished()5738                 receiver.finished();
5739             } catch (RemoteException ex) {
5740             }
5741         }
5742 
5743         return list;
5744     }
5745 
getRecentTasks(int maxNum, int flags, int userId)5746     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5747             int flags, int userId) {
5748         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
5749                 false, true, "getRecentTasks", null);
5750 
5751         synchronized (this) {
5752             enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5753                     "getRecentTasks()");
5754             final boolean detailed = checkCallingPermission(
5755                     android.Manifest.permission.GET_DETAILED_TASKS)
5756                     == PackageManager.PERMISSION_GRANTED;
5757 
5758             IPackageManager pm = AppGlobals.getPackageManager();
5759 
5760             final int N = mRecentTasks.size();
5761             ArrayList<ActivityManager.RecentTaskInfo> res
5762                     = new ArrayList<ActivityManager.RecentTaskInfo>(
5763                             maxNum < N ? maxNum : N);
5764             for (int i=0; i<N && maxNum > 0; i++) {
5765                 TaskRecord tr = mRecentTasks.get(i);
5766                 // Only add calling user's recent tasks
5767                 if (tr.userId != userId) continue;
5768                 // Return the entry if desired by the caller.  We always return
5769                 // the first entry, because callers always expect this to be the
5770                 // foreground app.  We may filter others if the caller has
5771                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5772                 // we should exclude the entry.
5773 
5774                 if (i == 0
5775                         || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5776                         || (tr.intent == null)
5777                         || ((tr.intent.getFlags()
5778                                 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5779                     ActivityManager.RecentTaskInfo rti
5780                             = new ActivityManager.RecentTaskInfo();
5781                     rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5782                     rti.persistentId = tr.taskId;
5783                     rti.baseIntent = new Intent(
5784                             tr.intent != null ? tr.intent : tr.affinityIntent);
5785                     if (!detailed) {
5786                         rti.baseIntent.replaceExtras((Bundle)null);
5787                     }
5788                     rti.origActivity = tr.origActivity;
5789                     rti.description = tr.lastDescription;
5790 
5791                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5792                         // Check whether this activity is currently available.
5793                         try {
5794                             if (rti.origActivity != null) {
5795                                 if (pm.getActivityInfo(rti.origActivity, 0, userId)
5796                                         == null) {
5797                                     continue;
5798                                 }
5799                             } else if (rti.baseIntent != null) {
5800                                 if (pm.queryIntentActivities(rti.baseIntent,
5801                                         null, 0, userId) == null) {
5802                                     continue;
5803                                 }
5804                             }
5805                         } catch (RemoteException e) {
5806                             // Will never happen.
5807                         }
5808                     }
5809 
5810                     res.add(rti);
5811                     maxNum--;
5812                 }
5813             }
5814             return res;
5815         }
5816     }
5817 
taskForIdLocked(int id)5818     private TaskRecord taskForIdLocked(int id) {
5819         final int N = mRecentTasks.size();
5820         for (int i=0; i<N; i++) {
5821             TaskRecord tr = mRecentTasks.get(i);
5822             if (tr.taskId == id) {
5823                 return tr;
5824             }
5825         }
5826         return null;
5827     }
5828 
getTaskThumbnails(int id)5829     public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5830         synchronized (this) {
5831             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5832                     "getTaskThumbnails()");
5833             TaskRecord tr = taskForIdLocked(id);
5834             if (tr != null) {
5835                 return mMainStack.getTaskThumbnailsLocked(tr);
5836             }
5837         }
5838         return null;
5839     }
5840 
getTaskTopThumbnail(int id)5841     public Bitmap getTaskTopThumbnail(int id) {
5842         synchronized (this) {
5843             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5844                     "getTaskTopThumbnail()");
5845             TaskRecord tr = taskForIdLocked(id);
5846             if (tr != null) {
5847                 return mMainStack.getTaskTopThumbnailLocked(tr);
5848             }
5849         }
5850         return null;
5851     }
5852 
removeSubTask(int taskId, int subTaskIndex)5853     public boolean removeSubTask(int taskId, int subTaskIndex) {
5854         synchronized (this) {
5855             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5856                     "removeSubTask()");
5857             long ident = Binder.clearCallingIdentity();
5858             try {
5859                 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5860                         true) != null;
5861             } finally {
5862                 Binder.restoreCallingIdentity(ident);
5863             }
5864         }
5865     }
5866 
cleanUpRemovedTaskLocked(TaskRecord tr, int flags)5867     private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5868         final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5869         Intent baseIntent = new Intent(
5870                 tr.intent != null ? tr.intent : tr.affinityIntent);
5871         ComponentName component = baseIntent.getComponent();
5872         if (component == null) {
5873             Slog.w(TAG, "Now component for base intent of task: " + tr);
5874             return;
5875         }
5876 
5877         // Find any running services associated with this app.
5878         mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5879 
5880         if (killProcesses) {
5881             // Find any running processes associated with this app.
5882             final String pkg = component.getPackageName();
5883             ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5884             HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5885             for (SparseArray<ProcessRecord> uids : pmap.values()) {
5886                 for (int i=0; i<uids.size(); i++) {
5887                     ProcessRecord proc = uids.valueAt(i);
5888                     if (proc.userId != tr.userId) {
5889                         continue;
5890                     }
5891                     if (!proc.pkgList.contains(pkg)) {
5892                         continue;
5893                     }
5894                     procs.add(proc);
5895                 }
5896             }
5897 
5898             // Kill the running processes.
5899             for (int i=0; i<procs.size(); i++) {
5900                 ProcessRecord pr = procs.get(i);
5901                 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5902                     Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5903                     EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
5904                             pr.processName, pr.setAdj, "remove task");
5905                     pr.killedBackground = true;
5906                     Process.killProcessQuiet(pr.pid);
5907                 } else {
5908                     pr.waitingToKill = "remove task";
5909                 }
5910             }
5911         }
5912     }
5913 
removeTask(int taskId, int flags)5914     public boolean removeTask(int taskId, int flags) {
5915         synchronized (this) {
5916             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5917                     "removeTask()");
5918             long ident = Binder.clearCallingIdentity();
5919             try {
5920                 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5921                         false);
5922                 if (r != null) {
5923                     mRecentTasks.remove(r.task);
5924                     cleanUpRemovedTaskLocked(r.task, flags);
5925                     return true;
5926                 } else {
5927                     TaskRecord tr = null;
5928                     int i=0;
5929                     while (i < mRecentTasks.size()) {
5930                         TaskRecord t = mRecentTasks.get(i);
5931                         if (t.taskId == taskId) {
5932                             tr = t;
5933                             break;
5934                         }
5935                         i++;
5936                     }
5937                     if (tr != null) {
5938                         if (tr.numActivities <= 0) {
5939                             // Caller is just removing a recent task that is
5940                             // not actively running.  That is easy!
5941                             mRecentTasks.remove(i);
5942                             cleanUpRemovedTaskLocked(tr, flags);
5943                             return true;
5944                         } else {
5945                             Slog.w(TAG, "removeTask: task " + taskId
5946                                     + " does not have activities to remove, "
5947                                     + " but numActivities=" + tr.numActivities
5948                                     + ": " + tr);
5949                         }
5950                     }
5951                 }
5952             } finally {
5953                 Binder.restoreCallingIdentity(ident);
5954             }
5955         }
5956         return false;
5957     }
5958 
findAffinityTaskTopLocked(int startIndex, String affinity)5959     private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5960         int j;
5961         TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5962         TaskRecord jt = startTask;
5963 
5964         // First look backwards
5965         for (j=startIndex-1; j>=0; j--) {
5966             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5967             if (r.task != jt) {
5968                 jt = r.task;
5969                 if (affinity.equals(jt.affinity)) {
5970                     return j;
5971                 }
5972             }
5973         }
5974 
5975         // Now look forwards
5976         final int N = mMainStack.mHistory.size();
5977         jt = startTask;
5978         for (j=startIndex+1; j<N; j++) {
5979             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5980             if (r.task != jt) {
5981                 if (affinity.equals(jt.affinity)) {
5982                     return j;
5983                 }
5984                 jt = r.task;
5985             }
5986         }
5987 
5988         // Might it be at the top?
5989         if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5990             return N-1;
5991         }
5992 
5993         return -1;
5994     }
5995 
5996     /**
5997      * TODO: Add mController hook
5998      */
moveTaskToFront(int task, int flags, Bundle options)5999     public void moveTaskToFront(int task, int flags, Bundle options) {
6000         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6001                 "moveTaskToFront()");
6002 
6003         synchronized(this) {
6004             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6005                     Binder.getCallingUid(), "Task to front")) {
6006                 ActivityOptions.abort(options);
6007                 return;
6008             }
6009             final long origId = Binder.clearCallingIdentity();
6010             try {
6011                 TaskRecord tr = taskForIdLocked(task);
6012                 if (tr != null) {
6013                     if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6014                         mMainStack.mUserLeaving = true;
6015                     }
6016                     if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6017                         // Caller wants the home activity moved with it.  To accomplish this,
6018                         // we'll just move the home task to the top first.
6019                         mMainStack.moveHomeToFrontLocked();
6020                     }
6021                     mMainStack.moveTaskToFrontLocked(tr, null, options);
6022                     return;
6023                 }
6024                 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6025                     ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
6026                     if (hr.task.taskId == task) {
6027                         if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6028                             mMainStack.mUserLeaving = true;
6029                         }
6030                         if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6031                             // Caller wants the home activity moved with it.  To accomplish this,
6032                             // we'll just move the home task to the top first.
6033                             mMainStack.moveHomeToFrontLocked();
6034                         }
6035                         mMainStack.moveTaskToFrontLocked(hr.task, null, options);
6036                         return;
6037                     }
6038                 }
6039             } finally {
6040                 Binder.restoreCallingIdentity(origId);
6041             }
6042             ActivityOptions.abort(options);
6043         }
6044     }
6045 
moveTaskToBack(int task)6046     public void moveTaskToBack(int task) {
6047         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6048                 "moveTaskToBack()");
6049 
6050         synchronized(this) {
6051             if (mMainStack.mResumedActivity != null
6052                     && mMainStack.mResumedActivity.task.taskId == task) {
6053                 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6054                         Binder.getCallingUid(), "Task to back")) {
6055                     return;
6056                 }
6057             }
6058             final long origId = Binder.clearCallingIdentity();
6059             mMainStack.moveTaskToBackLocked(task, null);
6060             Binder.restoreCallingIdentity(origId);
6061         }
6062     }
6063 
6064     /**
6065      * Moves an activity, and all of the other activities within the same task, to the bottom
6066      * of the history stack.  The activity's order within the task is unchanged.
6067      *
6068      * @param token A reference to the activity we wish to move
6069      * @param nonRoot If false then this only works if the activity is the root
6070      *                of a task; if true it will work for any activity in a task.
6071      * @return Returns true if the move completed, false if not.
6072      */
moveActivityTaskToBack(IBinder token, boolean nonRoot)6073     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6074         enforceNotIsolatedCaller("moveActivityTaskToBack");
6075         synchronized(this) {
6076             final long origId = Binder.clearCallingIdentity();
6077             int taskId = getTaskForActivityLocked(token, !nonRoot);
6078             if (taskId >= 0) {
6079                 return mMainStack.moveTaskToBackLocked(taskId, null);
6080             }
6081             Binder.restoreCallingIdentity(origId);
6082         }
6083         return false;
6084     }
6085 
moveTaskBackwards(int task)6086     public void moveTaskBackwards(int task) {
6087         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6088                 "moveTaskBackwards()");
6089 
6090         synchronized(this) {
6091             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6092                     Binder.getCallingUid(), "Task backwards")) {
6093                 return;
6094             }
6095             final long origId = Binder.clearCallingIdentity();
6096             moveTaskBackwardsLocked(task);
6097             Binder.restoreCallingIdentity(origId);
6098         }
6099     }
6100 
moveTaskBackwardsLocked(int task)6101     private final void moveTaskBackwardsLocked(int task) {
6102         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
6103     }
6104 
getTaskForActivity(IBinder token, boolean onlyRoot)6105     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6106         synchronized(this) {
6107             return getTaskForActivityLocked(token, onlyRoot);
6108         }
6109     }
6110 
getTaskForActivityLocked(IBinder token, boolean onlyRoot)6111     int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
6112         final int N = mMainStack.mHistory.size();
6113         TaskRecord lastTask = null;
6114         for (int i=0; i<N; i++) {
6115             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6116             if (r.appToken == token) {
6117                 if (!onlyRoot || lastTask != r.task) {
6118                     return r.task.taskId;
6119                 }
6120                 return -1;
6121             }
6122             lastTask = r.task;
6123         }
6124 
6125         return -1;
6126     }
6127 
6128     // =========================================================
6129     // THUMBNAILS
6130     // =========================================================
6131 
reportThumbnail(IBinder token, Bitmap thumbnail, CharSequence description)6132     public void reportThumbnail(IBinder token,
6133             Bitmap thumbnail, CharSequence description) {
6134         //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6135         final long origId = Binder.clearCallingIdentity();
6136         sendPendingThumbnail(null, token, thumbnail, description, true);
6137         Binder.restoreCallingIdentity(origId);
6138     }
6139 
sendPendingThumbnail(ActivityRecord r, IBinder token, Bitmap thumbnail, CharSequence description, boolean always)6140     final void sendPendingThumbnail(ActivityRecord r, IBinder token,
6141             Bitmap thumbnail, CharSequence description, boolean always) {
6142         TaskRecord task = null;
6143         ArrayList receivers = null;
6144 
6145         //System.out.println("Send pending thumbnail: " + r);
6146 
6147         synchronized(this) {
6148             if (r == null) {
6149                 r = mMainStack.isInStackLocked(token);
6150                 if (r == null) {
6151                     return;
6152                 }
6153             }
6154             if (thumbnail == null && r.thumbHolder != null) {
6155                 thumbnail = r.thumbHolder.lastThumbnail;
6156                 description = r.thumbHolder.lastDescription;
6157             }
6158             if (thumbnail == null && !always) {
6159                 // If there is no thumbnail, and this entry is not actually
6160                 // going away, then abort for now and pick up the next
6161                 // thumbnail we get.
6162                 return;
6163             }
6164             task = r.task;
6165 
6166             int N = mPendingThumbnails.size();
6167             int i=0;
6168             while (i<N) {
6169                 PendingThumbnailsRecord pr =
6170                     (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6171                 //System.out.println("Looking in " + pr.pendingRecords);
6172                 if (pr.pendingRecords.remove(r)) {
6173                     if (receivers == null) {
6174                         receivers = new ArrayList();
6175                     }
6176                     receivers.add(pr);
6177                     if (pr.pendingRecords.size() == 0) {
6178                         pr.finished = true;
6179                         mPendingThumbnails.remove(i);
6180                         N--;
6181                         continue;
6182                     }
6183                 }
6184                 i++;
6185             }
6186         }
6187 
6188         if (receivers != null) {
6189             final int N = receivers.size();
6190             for (int i=0; i<N; i++) {
6191                 try {
6192                     PendingThumbnailsRecord pr =
6193                         (PendingThumbnailsRecord)receivers.get(i);
6194                     pr.receiver.newThumbnail(
6195                         task != null ? task.taskId : -1, thumbnail, description);
6196                     if (pr.finished) {
6197                         pr.receiver.finished();
6198                     }
6199                 } catch (Exception e) {
6200                     Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6201                 }
6202             }
6203         }
6204     }
6205 
6206     // =========================================================
6207     // CONTENT PROVIDERS
6208     // =========================================================
6209 
generateApplicationProvidersLocked(ProcessRecord app)6210     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6211         List<ProviderInfo> providers = null;
6212         try {
6213             providers = AppGlobals.getPackageManager().
6214                 queryContentProviders(app.processName, app.uid,
6215                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6216         } catch (RemoteException ex) {
6217         }
6218         if (DEBUG_MU)
6219             Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6220         int userId = app.userId;
6221         if (providers != null) {
6222             int N = providers.size();
6223             for (int i=0; i<N; i++) {
6224                 ProviderInfo cpi =
6225                     (ProviderInfo)providers.get(i);
6226                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6227                         cpi.name, cpi.flags);
6228                 if (singleton && UserHandle.getUserId(app.uid) != 0) {
6229                     // This is a singleton provider, but a user besides the
6230                     // default user is asking to initialize a process it runs
6231                     // in...  well, no, it doesn't actually run in this process,
6232                     // it runs in the process of the default user.  Get rid of it.
6233                     providers.remove(i);
6234                     N--;
6235                     continue;
6236                 }
6237 
6238                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6239                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6240                 if (cpr == null) {
6241                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6242                     mProviderMap.putProviderByClass(comp, cpr);
6243                 }
6244                 if (DEBUG_MU)
6245                     Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6246                 app.pubProviders.put(cpi.name, cpr);
6247                 app.addPackage(cpi.applicationInfo.packageName);
6248                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
6249             }
6250         }
6251         return providers;
6252     }
6253 
6254     /**
6255      * Check if {@link ProcessRecord} has a possible chance at accessing the
6256      * given {@link ProviderInfo}. Final permission checking is always done
6257      * in {@link ContentProvider}.
6258      */
checkContentProviderPermissionLocked( ProviderInfo cpi, ProcessRecord r)6259     private final String checkContentProviderPermissionLocked(
6260             ProviderInfo cpi, ProcessRecord r) {
6261         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6262         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6263         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6264                 cpi.applicationInfo.uid, cpi.exported)
6265                 == PackageManager.PERMISSION_GRANTED) {
6266             return null;
6267         }
6268         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6269                 cpi.applicationInfo.uid, cpi.exported)
6270                 == PackageManager.PERMISSION_GRANTED) {
6271             return null;
6272         }
6273 
6274         PathPermission[] pps = cpi.pathPermissions;
6275         if (pps != null) {
6276             int i = pps.length;
6277             while (i > 0) {
6278                 i--;
6279                 PathPermission pp = pps[i];
6280                 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6281                         cpi.applicationInfo.uid, cpi.exported)
6282                         == PackageManager.PERMISSION_GRANTED) {
6283                     return null;
6284                 }
6285                 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6286                         cpi.applicationInfo.uid, cpi.exported)
6287                         == PackageManager.PERMISSION_GRANTED) {
6288                     return null;
6289                 }
6290             }
6291         }
6292 
6293         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6294         if (perms != null) {
6295             for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6296                 if (uri.getKey().getAuthority().equals(cpi.authority)) {
6297                     return null;
6298                 }
6299             }
6300         }
6301 
6302         String msg;
6303         if (!cpi.exported) {
6304             msg = "Permission Denial: opening provider " + cpi.name
6305                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6306                     + ", uid=" + callingUid + ") that is not exported from uid "
6307                     + cpi.applicationInfo.uid;
6308         } else {
6309             msg = "Permission Denial: opening provider " + cpi.name
6310                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6311                     + ", uid=" + callingUid + ") requires "
6312                     + cpi.readPermission + " or " + cpi.writePermission;
6313         }
6314         Slog.w(TAG, msg);
6315         return msg;
6316     }
6317 
incProviderCountLocked(ProcessRecord r, final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable)6318     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6319             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6320         if (r != null) {
6321             for (int i=0; i<r.conProviders.size(); i++) {
6322                 ContentProviderConnection conn = r.conProviders.get(i);
6323                 if (conn.provider == cpr) {
6324                     if (DEBUG_PROVIDER) Slog.v(TAG,
6325                             "Adding provider requested by "
6326                             + r.processName + " from process "
6327                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6328                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6329                     if (stable) {
6330                         conn.stableCount++;
6331                         conn.numStableIncs++;
6332                     } else {
6333                         conn.unstableCount++;
6334                         conn.numUnstableIncs++;
6335                     }
6336                     return conn;
6337                 }
6338             }
6339             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6340             if (stable) {
6341                 conn.stableCount = 1;
6342                 conn.numStableIncs = 1;
6343             } else {
6344                 conn.unstableCount = 1;
6345                 conn.numUnstableIncs = 1;
6346             }
6347             cpr.connections.add(conn);
6348             r.conProviders.add(conn);
6349             return conn;
6350         }
6351         cpr.addExternalProcessHandleLocked(externalProcessToken);
6352         return null;
6353     }
6354 
decProviderCountLocked(ContentProviderConnection conn, ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable)6355     boolean decProviderCountLocked(ContentProviderConnection conn,
6356             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6357         if (conn != null) {
6358             cpr = conn.provider;
6359             if (DEBUG_PROVIDER) Slog.v(TAG,
6360                     "Removing provider requested by "
6361                     + conn.client.processName + " from process "
6362                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6363                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6364             if (stable) {
6365                 conn.stableCount--;
6366             } else {
6367                 conn.unstableCount--;
6368             }
6369             if (conn.stableCount == 0 && conn.unstableCount == 0) {
6370                 cpr.connections.remove(conn);
6371                 conn.client.conProviders.remove(conn);
6372                 return true;
6373             }
6374             return false;
6375         }
6376         cpr.removeExternalProcessHandleLocked(externalProcessToken);
6377         return false;
6378     }
6379 
getContentProviderImpl(IApplicationThread caller, String name, IBinder token, boolean stable, int userId)6380     private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6381             String name, IBinder token, boolean stable, int userId) {
6382         ContentProviderRecord cpr;
6383         ContentProviderConnection conn = null;
6384         ProviderInfo cpi = null;
6385 
6386         synchronized(this) {
6387             ProcessRecord r = null;
6388             if (caller != null) {
6389                 r = getRecordForAppLocked(caller);
6390                 if (r == null) {
6391                     throw new SecurityException(
6392                             "Unable to find app for caller " + caller
6393                           + " (pid=" + Binder.getCallingPid()
6394                           + ") when getting content provider " + name);
6395                 }
6396             }
6397 
6398             // First check if this content provider has been published...
6399             cpr = mProviderMap.getProviderByName(name, userId);
6400             boolean providerRunning = cpr != null;
6401             if (providerRunning) {
6402                 cpi = cpr.info;
6403                 String msg;
6404                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6405                     throw new SecurityException(msg);
6406                 }
6407 
6408                 if (r != null && cpr.canRunHere(r)) {
6409                     // This provider has been published or is in the process
6410                     // of being published...  but it is also allowed to run
6411                     // in the caller's process, so don't make a connection
6412                     // and just let the caller instantiate its own instance.
6413                     ContentProviderHolder holder = cpr.newHolder(null);
6414                     // don't give caller the provider object, it needs
6415                     // to make its own.
6416                     holder.provider = null;
6417                     return holder;
6418                 }
6419 
6420                 final long origId = Binder.clearCallingIdentity();
6421 
6422                 // In this case the provider instance already exists, so we can
6423                 // return it right away.
6424                 conn = incProviderCountLocked(r, cpr, token, stable);
6425                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6426                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6427                         // If this is a perceptible app accessing the provider,
6428                         // make sure to count it as being accessed and thus
6429                         // back up on the LRU list.  This is good because
6430                         // content providers are often expensive to start.
6431                         updateLruProcessLocked(cpr.proc, false);
6432                     }
6433                 }
6434 
6435                 if (cpr.proc != null) {
6436                     if (false) {
6437                         if (cpr.name.flattenToShortString().equals(
6438                                 "com.android.providers.calendar/.CalendarProvider2")) {
6439                             Slog.v(TAG, "****************** KILLING "
6440                                 + cpr.name.flattenToShortString());
6441                             Process.killProcess(cpr.proc.pid);
6442                         }
6443                     }
6444                     boolean success = updateOomAdjLocked(cpr.proc);
6445                     if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6446                     // NOTE: there is still a race here where a signal could be
6447                     // pending on the process even though we managed to update its
6448                     // adj level.  Not sure what to do about this, but at least
6449                     // the race is now smaller.
6450                     if (!success) {
6451                         // Uh oh...  it looks like the provider's process
6452                         // has been killed on us.  We need to wait for a new
6453                         // process to be started, and make sure its death
6454                         // doesn't kill our process.
6455                         Slog.i(TAG,
6456                                 "Existing provider " + cpr.name.flattenToShortString()
6457                                 + " is crashing; detaching " + r);
6458                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6459                         appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6460                         if (!lastRef) {
6461                             // This wasn't the last ref our process had on
6462                             // the provider...  we have now been killed, bail.
6463                             return null;
6464                         }
6465                         providerRunning = false;
6466                         conn = null;
6467                     }
6468                 }
6469 
6470                 Binder.restoreCallingIdentity(origId);
6471             }
6472 
6473             boolean singleton;
6474             if (!providerRunning) {
6475                 try {
6476                     cpi = AppGlobals.getPackageManager().
6477                         resolveContentProvider(name,
6478                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6479                 } catch (RemoteException ex) {
6480                 }
6481                 if (cpi == null) {
6482                     return null;
6483                 }
6484                 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6485                         cpi.name, cpi.flags);
6486                 if (singleton) {
6487                     userId = 0;
6488                 }
6489                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6490 
6491                 String msg;
6492                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6493                     throw new SecurityException(msg);
6494                 }
6495 
6496                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6497                         && !cpi.processName.equals("system")) {
6498                     // If this content provider does not run in the system
6499                     // process, and the system is not yet ready to run other
6500                     // processes, then fail fast instead of hanging.
6501                     throw new IllegalArgumentException(
6502                             "Attempt to launch content provider before system ready");
6503                 }
6504 
6505                 // Make sure that the user who owns this provider is started.  If not,
6506                 // we don't want to allow it to run.
6507                 if (mStartedUsers.get(userId) == null) {
6508                     Slog.w(TAG, "Unable to launch app "
6509                             + cpi.applicationInfo.packageName + "/"
6510                             + cpi.applicationInfo.uid + " for provider "
6511                             + name + ": user " + userId + " is stopped");
6512                     return null;
6513                 }
6514 
6515                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6516                 cpr = mProviderMap.getProviderByClass(comp, userId);
6517                 final boolean firstClass = cpr == null;
6518                 if (firstClass) {
6519                     try {
6520                         ApplicationInfo ai =
6521                             AppGlobals.getPackageManager().
6522                                 getApplicationInfo(
6523                                         cpi.applicationInfo.packageName,
6524                                         STOCK_PM_FLAGS, userId);
6525                         if (ai == null) {
6526                             Slog.w(TAG, "No package info for content provider "
6527                                     + cpi.name);
6528                             return null;
6529                         }
6530                         ai = getAppInfoForUser(ai, userId);
6531                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6532                     } catch (RemoteException ex) {
6533                         // pm is in same process, this will never happen.
6534                     }
6535                 }
6536 
6537                 if (r != null && cpr.canRunHere(r)) {
6538                     // If this is a multiprocess provider, then just return its
6539                     // info and allow the caller to instantiate it.  Only do
6540                     // this if the provider is the same user as the caller's
6541                     // process, or can run as root (so can be in any process).
6542                     return cpr.newHolder(null);
6543                 }
6544 
6545                 if (DEBUG_PROVIDER) {
6546                     RuntimeException e = new RuntimeException("here");
6547                     Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6548                           + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6549                 }
6550 
6551                 // This is single process, and our app is now connecting to it.
6552                 // See if we are already in the process of launching this
6553                 // provider.
6554                 final int N = mLaunchingProviders.size();
6555                 int i;
6556                 for (i=0; i<N; i++) {
6557                     if (mLaunchingProviders.get(i) == cpr) {
6558                         break;
6559                     }
6560                 }
6561 
6562                 // If the provider is not already being launched, then get it
6563                 // started.
6564                 if (i >= N) {
6565                     final long origId = Binder.clearCallingIdentity();
6566 
6567                     try {
6568                         // Content provider is now in use, its package can't be stopped.
6569                         try {
6570                             AppGlobals.getPackageManager().setPackageStoppedState(
6571                                     cpr.appInfo.packageName, false, userId);
6572                         } catch (RemoteException e) {
6573                         } catch (IllegalArgumentException e) {
6574                             Slog.w(TAG, "Failed trying to unstop package "
6575                                     + cpr.appInfo.packageName + ": " + e);
6576                         }
6577 
6578                         ProcessRecord proc = startProcessLocked(cpi.processName,
6579                                 cpr.appInfo, false, 0, "content provider",
6580                                 new ComponentName(cpi.applicationInfo.packageName,
6581                                         cpi.name), false, false);
6582                         if (proc == null) {
6583                             Slog.w(TAG, "Unable to launch app "
6584                                     + cpi.applicationInfo.packageName + "/"
6585                                     + cpi.applicationInfo.uid + " for provider "
6586                                     + name + ": process is bad");
6587                             return null;
6588                         }
6589                         cpr.launchingApp = proc;
6590                         mLaunchingProviders.add(cpr);
6591                     } finally {
6592                         Binder.restoreCallingIdentity(origId);
6593                     }
6594                 }
6595 
6596                 // Make sure the provider is published (the same provider class
6597                 // may be published under multiple names).
6598                 if (firstClass) {
6599                     mProviderMap.putProviderByClass(comp, cpr);
6600                 }
6601 
6602                 mProviderMap.putProviderByName(name, cpr);
6603                 conn = incProviderCountLocked(r, cpr, token, stable);
6604                 if (conn != null) {
6605                     conn.waiting = true;
6606                 }
6607             }
6608         }
6609 
6610         // Wait for the provider to be published...
6611         synchronized (cpr) {
6612             while (cpr.provider == null) {
6613                 if (cpr.launchingApp == null) {
6614                     Slog.w(TAG, "Unable to launch app "
6615                             + cpi.applicationInfo.packageName + "/"
6616                             + cpi.applicationInfo.uid + " for provider "
6617                             + name + ": launching app became null");
6618                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6619                             UserHandle.getUserId(cpi.applicationInfo.uid),
6620                             cpi.applicationInfo.packageName,
6621                             cpi.applicationInfo.uid, name);
6622                     return null;
6623                 }
6624                 try {
6625                     if (DEBUG_MU) {
6626                         Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6627                                 + cpr.launchingApp);
6628                     }
6629                     if (conn != null) {
6630                         conn.waiting = true;
6631                     }
6632                     cpr.wait();
6633                 } catch (InterruptedException ex) {
6634                 } finally {
6635                     if (conn != null) {
6636                         conn.waiting = false;
6637                     }
6638                 }
6639             }
6640         }
6641         return cpr != null ? cpr.newHolder(conn) : null;
6642     }
6643 
getContentProvider( IApplicationThread caller, String name, int userId, boolean stable)6644     public final ContentProviderHolder getContentProvider(
6645             IApplicationThread caller, String name, int userId, boolean stable) {
6646         enforceNotIsolatedCaller("getContentProvider");
6647         if (caller == null) {
6648             String msg = "null IApplicationThread when getting content provider "
6649                     + name;
6650             Slog.w(TAG, msg);
6651             throw new SecurityException(msg);
6652         }
6653 
6654         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6655                 false, true, "getContentProvider", null);
6656         return getContentProviderImpl(caller, name, null, stable, userId);
6657     }
6658 
getContentProviderExternal( String name, int userId, IBinder token)6659     public ContentProviderHolder getContentProviderExternal(
6660             String name, int userId, IBinder token) {
6661         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6662             "Do not have permission in call getContentProviderExternal()");
6663         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6664                 false, true, "getContentProvider", null);
6665         return getContentProviderExternalUnchecked(name, token, userId);
6666     }
6667 
getContentProviderExternalUnchecked(String name, IBinder token, int userId)6668     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6669             IBinder token, int userId) {
6670         return getContentProviderImpl(null, name, token, true, userId);
6671     }
6672 
6673     /**
6674      * Drop a content provider from a ProcessRecord's bookkeeping
6675      * @param cpr
6676      */
removeContentProvider(IBinder connection, boolean stable)6677     public void removeContentProvider(IBinder connection, boolean stable) {
6678         enforceNotIsolatedCaller("removeContentProvider");
6679         synchronized (this) {
6680             ContentProviderConnection conn;
6681             try {
6682                 conn = (ContentProviderConnection)connection;
6683             } catch (ClassCastException e) {
6684                 String msg ="removeContentProvider: " + connection
6685                         + " not a ContentProviderConnection";
6686                 Slog.w(TAG, msg);
6687                 throw new IllegalArgumentException(msg);
6688             }
6689             if (conn == null) {
6690                 throw new NullPointerException("connection is null");
6691             }
6692             if (decProviderCountLocked(conn, null, null, stable)) {
6693                 updateOomAdjLocked();
6694             }
6695         }
6696     }
6697 
removeContentProviderExternal(String name, IBinder token)6698     public void removeContentProviderExternal(String name, IBinder token) {
6699         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6700             "Do not have permission in call removeContentProviderExternal()");
6701         removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6702     }
6703 
removeContentProviderExternalUnchecked(String name, IBinder token, int userId)6704     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
6705         synchronized (this) {
6706             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6707             if(cpr == null) {
6708                 //remove from mProvidersByClass
6709                 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6710                 return;
6711             }
6712 
6713             //update content provider record entry info
6714             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6715             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6716             if (localCpr.hasExternalProcessHandles()) {
6717                 if (localCpr.removeExternalProcessHandleLocked(token)) {
6718                     updateOomAdjLocked();
6719                 } else {
6720                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6721                             + " with no external reference for token: "
6722                             + token + ".");
6723                 }
6724             } else {
6725                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6726                         + " with no external references.");
6727             }
6728         }
6729     }
6730 
publishContentProviders(IApplicationThread caller, List<ContentProviderHolder> providers)6731     public final void publishContentProviders(IApplicationThread caller,
6732             List<ContentProviderHolder> providers) {
6733         if (providers == null) {
6734             return;
6735         }
6736 
6737         enforceNotIsolatedCaller("publishContentProviders");
6738         synchronized (this) {
6739             final ProcessRecord r = getRecordForAppLocked(caller);
6740             if (DEBUG_MU)
6741                 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6742             if (r == null) {
6743                 throw new SecurityException(
6744                         "Unable to find app for caller " + caller
6745                       + " (pid=" + Binder.getCallingPid()
6746                       + ") when publishing content providers");
6747             }
6748 
6749             final long origId = Binder.clearCallingIdentity();
6750 
6751             final int N = providers.size();
6752             for (int i=0; i<N; i++) {
6753                 ContentProviderHolder src = providers.get(i);
6754                 if (src == null || src.info == null || src.provider == null) {
6755                     continue;
6756                 }
6757                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6758                 if (DEBUG_MU)
6759                     Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6760                 if (dst != null) {
6761                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6762                     mProviderMap.putProviderByClass(comp, dst);
6763                     String names[] = dst.info.authority.split(";");
6764                     for (int j = 0; j < names.length; j++) {
6765                         mProviderMap.putProviderByName(names[j], dst);
6766                     }
6767 
6768                     int NL = mLaunchingProviders.size();
6769                     int j;
6770                     for (j=0; j<NL; j++) {
6771                         if (mLaunchingProviders.get(j) == dst) {
6772                             mLaunchingProviders.remove(j);
6773                             j--;
6774                             NL--;
6775                         }
6776                     }
6777                     synchronized (dst) {
6778                         dst.provider = src.provider;
6779                         dst.proc = r;
6780                         dst.notifyAll();
6781                     }
6782                     updateOomAdjLocked(r);
6783                 }
6784             }
6785 
6786             Binder.restoreCallingIdentity(origId);
6787         }
6788     }
6789 
refContentProvider(IBinder connection, int stable, int unstable)6790     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6791         ContentProviderConnection conn;
6792         try {
6793             conn = (ContentProviderConnection)connection;
6794         } catch (ClassCastException e) {
6795             String msg ="refContentProvider: " + connection
6796                     + " not a ContentProviderConnection";
6797             Slog.w(TAG, msg);
6798             throw new IllegalArgumentException(msg);
6799         }
6800         if (conn == null) {
6801             throw new NullPointerException("connection is null");
6802         }
6803 
6804         synchronized (this) {
6805             if (stable > 0) {
6806                 conn.numStableIncs += stable;
6807             }
6808             stable = conn.stableCount + stable;
6809             if (stable < 0) {
6810                 throw new IllegalStateException("stableCount < 0: " + stable);
6811             }
6812 
6813             if (unstable > 0) {
6814                 conn.numUnstableIncs += unstable;
6815             }
6816             unstable = conn.unstableCount + unstable;
6817             if (unstable < 0) {
6818                 throw new IllegalStateException("unstableCount < 0: " + unstable);
6819             }
6820 
6821             if ((stable+unstable) <= 0) {
6822                 throw new IllegalStateException("ref counts can't go to zero here: stable="
6823                         + stable + " unstable=" + unstable);
6824             }
6825             conn.stableCount = stable;
6826             conn.unstableCount = unstable;
6827             return !conn.dead;
6828         }
6829     }
6830 
unstableProviderDied(IBinder connection)6831     public void unstableProviderDied(IBinder connection) {
6832         ContentProviderConnection conn;
6833         try {
6834             conn = (ContentProviderConnection)connection;
6835         } catch (ClassCastException e) {
6836             String msg ="refContentProvider: " + connection
6837                     + " not a ContentProviderConnection";
6838             Slog.w(TAG, msg);
6839             throw new IllegalArgumentException(msg);
6840         }
6841         if (conn == null) {
6842             throw new NullPointerException("connection is null");
6843         }
6844 
6845         // Safely retrieve the content provider associated with the connection.
6846         IContentProvider provider;
6847         synchronized (this) {
6848             provider = conn.provider.provider;
6849         }
6850 
6851         if (provider == null) {
6852             // Um, yeah, we're way ahead of you.
6853             return;
6854         }
6855 
6856         // Make sure the caller is being honest with us.
6857         if (provider.asBinder().pingBinder()) {
6858             // Er, no, still looks good to us.
6859             synchronized (this) {
6860                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6861                         + " says " + conn + " died, but we don't agree");
6862                 return;
6863             }
6864         }
6865 
6866         // Well look at that!  It's dead!
6867         synchronized (this) {
6868             if (conn.provider.provider != provider) {
6869                 // But something changed...  good enough.
6870                 return;
6871             }
6872 
6873             ProcessRecord proc = conn.provider.proc;
6874             if (proc == null || proc.thread == null) {
6875                 // Seems like the process is already cleaned up.
6876                 return;
6877             }
6878 
6879             // As far as we're concerned, this is just like receiving a
6880             // death notification...  just a bit prematurely.
6881             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6882                     + ") early provider death");
6883             final long ident = Binder.clearCallingIdentity();
6884             try {
6885                 appDiedLocked(proc, proc.pid, proc.thread);
6886             } finally {
6887                 Binder.restoreCallingIdentity(ident);
6888             }
6889         }
6890     }
6891 
installSystemProviders()6892     public static final void installSystemProviders() {
6893         List<ProviderInfo> providers;
6894         synchronized (mSelf) {
6895             ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6896             providers = mSelf.generateApplicationProvidersLocked(app);
6897             if (providers != null) {
6898                 for (int i=providers.size()-1; i>=0; i--) {
6899                     ProviderInfo pi = (ProviderInfo)providers.get(i);
6900                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6901                         Slog.w(TAG, "Not installing system proc provider " + pi.name
6902                                 + ": not system .apk");
6903                         providers.remove(i);
6904                     }
6905                 }
6906             }
6907         }
6908         if (providers != null) {
6909             mSystemThread.installSystemProviders(providers);
6910         }
6911 
6912         mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6913 
6914         mSelf.mUsageStatsService.monitorPackages();
6915     }
6916 
6917     /**
6918      * Allows app to retrieve the MIME type of a URI without having permission
6919      * to access its content provider.
6920      *
6921      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6922      *
6923      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6924      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6925      */
getProviderMimeType(Uri uri, int userId)6926     public String getProviderMimeType(Uri uri, int userId) {
6927         enforceNotIsolatedCaller("getProviderMimeType");
6928         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6929                 userId, false, true, "getProviderMimeType", null);
6930         final String name = uri.getAuthority();
6931         final long ident = Binder.clearCallingIdentity();
6932         ContentProviderHolder holder = null;
6933 
6934         try {
6935             holder = getContentProviderExternalUnchecked(name, null, userId);
6936             if (holder != null) {
6937                 return holder.provider.getType(uri);
6938             }
6939         } catch (RemoteException e) {
6940             Log.w(TAG, "Content provider dead retrieving " + uri, e);
6941             return null;
6942         } finally {
6943             if (holder != null) {
6944                 removeContentProviderExternalUnchecked(name, null, userId);
6945             }
6946             Binder.restoreCallingIdentity(ident);
6947         }
6948 
6949         return null;
6950     }
6951 
6952     // =========================================================
6953     // GLOBAL MANAGEMENT
6954     // =========================================================
6955 
newProcessRecordLocked(IApplicationThread thread, ApplicationInfo info, String customProcess, boolean isolated)6956     final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6957             ApplicationInfo info, String customProcess, boolean isolated) {
6958         String proc = customProcess != null ? customProcess : info.processName;
6959         BatteryStatsImpl.Uid.Proc ps = null;
6960         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6961         int uid = info.uid;
6962         if (isolated) {
6963             int userId = UserHandle.getUserId(uid);
6964             int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6965             uid = 0;
6966             while (true) {
6967                 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6968                         || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6969                     mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6970                 }
6971                 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6972                 mNextIsolatedProcessUid++;
6973                 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6974                     // No process for this uid, use it.
6975                     break;
6976                 }
6977                 stepsLeft--;
6978                 if (stepsLeft <= 0) {
6979                     return null;
6980                 }
6981             }
6982         }
6983         synchronized (stats) {
6984             ps = stats.getProcessStatsLocked(info.uid, proc);
6985         }
6986         return new ProcessRecord(ps, thread, info, proc, uid);
6987     }
6988 
addAppLocked(ApplicationInfo info, boolean isolated)6989     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6990         ProcessRecord app;
6991         if (!isolated) {
6992             app = getProcessRecordLocked(info.processName, info.uid);
6993         } else {
6994             app = null;
6995         }
6996 
6997         if (app == null) {
6998             app = newProcessRecordLocked(null, info, null, isolated);
6999             mProcessNames.put(info.processName, app.uid, app);
7000             if (isolated) {
7001                 mIsolatedProcesses.put(app.uid, app);
7002             }
7003             updateLruProcessLocked(app, true);
7004         }
7005 
7006         // This package really, really can not be stopped.
7007         try {
7008             AppGlobals.getPackageManager().setPackageStoppedState(
7009                     info.packageName, false, UserHandle.getUserId(app.uid));
7010         } catch (RemoteException e) {
7011         } catch (IllegalArgumentException e) {
7012             Slog.w(TAG, "Failed trying to unstop package "
7013                     + info.packageName + ": " + e);
7014         }
7015 
7016         if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7017                 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7018             app.persistent = true;
7019             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
7020         }
7021         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7022             mPersistentStartingProcesses.add(app);
7023             startProcessLocked(app, "added application", app.processName);
7024         }
7025 
7026         return app;
7027     }
7028 
unhandledBack()7029     public void unhandledBack() {
7030         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7031                 "unhandledBack()");
7032 
7033         synchronized(this) {
7034             int count = mMainStack.mHistory.size();
7035             if (DEBUG_SWITCH) Slog.d(
7036                 TAG, "Performing unhandledBack(): stack size = " + count);
7037             if (count > 1) {
7038                 final long origId = Binder.clearCallingIdentity();
7039                 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
7040                         count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
7041                 Binder.restoreCallingIdentity(origId);
7042             }
7043         }
7044     }
7045 
openContentUri(Uri uri)7046     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7047         enforceNotIsolatedCaller("openContentUri");
7048         final int userId = UserHandle.getCallingUserId();
7049         String name = uri.getAuthority();
7050         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
7051         ParcelFileDescriptor pfd = null;
7052         if (cph != null) {
7053             // We record the binder invoker's uid in thread-local storage before
7054             // going to the content provider to open the file.  Later, in the code
7055             // that handles all permissions checks, we look for this uid and use
7056             // that rather than the Activity Manager's own uid.  The effect is that
7057             // we do the check against the caller's permissions even though it looks
7058             // to the content provider like the Activity Manager itself is making
7059             // the request.
7060             sCallerIdentity.set(new Identity(
7061                     Binder.getCallingPid(), Binder.getCallingUid()));
7062             try {
7063                 pfd = cph.provider.openFile(uri, "r");
7064             } catch (FileNotFoundException e) {
7065                 // do nothing; pfd will be returned null
7066             } finally {
7067                 // Ensure that whatever happens, we clean up the identity state
7068                 sCallerIdentity.remove();
7069             }
7070 
7071             // We've got the fd now, so we're done with the provider.
7072             removeContentProviderExternalUnchecked(name, null, userId);
7073         } else {
7074             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
7075         }
7076         return pfd;
7077     }
7078 
7079     // Actually is sleeping or shutting down or whatever else in the future
7080     // is an inactive state.
isSleeping()7081     public boolean isSleeping() {
7082         return mSleeping || mShuttingDown;
7083     }
7084 
goingToSleep()7085     public void goingToSleep() {
7086         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7087                 != PackageManager.PERMISSION_GRANTED) {
7088             throw new SecurityException("Requires permission "
7089                     + android.Manifest.permission.DEVICE_POWER);
7090         }
7091 
7092         synchronized(this) {
7093             mWentToSleep = true;
7094             updateEventDispatchingLocked();
7095 
7096             if (!mSleeping) {
7097                 mSleeping = true;
7098                 mMainStack.stopIfSleepingLocked();
7099 
7100                 // Initialize the wake times of all processes.
7101                 checkExcessivePowerUsageLocked(false);
7102                 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7103                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7104                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7105             }
7106         }
7107     }
7108 
shutdown(int timeout)7109     public boolean shutdown(int timeout) {
7110         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7111                 != PackageManager.PERMISSION_GRANTED) {
7112             throw new SecurityException("Requires permission "
7113                     + android.Manifest.permission.SHUTDOWN);
7114         }
7115 
7116         boolean timedout = false;
7117 
7118         synchronized(this) {
7119             mShuttingDown = true;
7120             updateEventDispatchingLocked();
7121 
7122             if (mMainStack.mResumedActivity != null) {
7123                 mMainStack.stopIfSleepingLocked();
7124                 final long endTime = System.currentTimeMillis() + timeout;
7125                 while (mMainStack.mResumedActivity != null
7126                         || mMainStack.mPausingActivity != null) {
7127                     long delay = endTime - System.currentTimeMillis();
7128                     if (delay <= 0) {
7129                         Slog.w(TAG, "Activity manager shutdown timed out");
7130                         timedout = true;
7131                         break;
7132                     }
7133                     try {
7134                         this.wait();
7135                     } catch (InterruptedException e) {
7136                     }
7137                 }
7138             }
7139         }
7140 
7141         mUsageStatsService.shutdown();
7142         mBatteryStatsService.shutdown();
7143 
7144         return timedout;
7145     }
7146 
activitySlept(IBinder token)7147     public final void activitySlept(IBinder token) {
7148         if (localLOGV) Slog.v(
7149             TAG, "Activity slept: token=" + token);
7150 
7151         ActivityRecord r = null;
7152 
7153         final long origId = Binder.clearCallingIdentity();
7154 
7155         synchronized (this) {
7156             r = mMainStack.isInStackLocked(token);
7157             if (r != null) {
7158                 mMainStack.activitySleptLocked(r);
7159             }
7160         }
7161 
7162         Binder.restoreCallingIdentity(origId);
7163     }
7164 
comeOutOfSleepIfNeededLocked()7165     private void comeOutOfSleepIfNeededLocked() {
7166         if (!mWentToSleep && !mLockScreenShown) {
7167             if (mSleeping) {
7168                 mSleeping = false;
7169                 mMainStack.awakeFromSleepingLocked();
7170                 mMainStack.resumeTopActivityLocked(null);
7171             }
7172         }
7173     }
7174 
wakingUp()7175     public void wakingUp() {
7176         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7177                 != PackageManager.PERMISSION_GRANTED) {
7178             throw new SecurityException("Requires permission "
7179                     + android.Manifest.permission.DEVICE_POWER);
7180         }
7181 
7182         synchronized(this) {
7183             mWentToSleep = false;
7184             updateEventDispatchingLocked();
7185             comeOutOfSleepIfNeededLocked();
7186         }
7187     }
7188 
updateEventDispatchingLocked()7189     private void updateEventDispatchingLocked() {
7190         mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7191     }
7192 
setLockScreenShown(boolean shown)7193     public void setLockScreenShown(boolean shown) {
7194         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7195                 != PackageManager.PERMISSION_GRANTED) {
7196             throw new SecurityException("Requires permission "
7197                     + android.Manifest.permission.DEVICE_POWER);
7198         }
7199 
7200         synchronized(this) {
7201             mLockScreenShown = shown;
7202             comeOutOfSleepIfNeededLocked();
7203         }
7204     }
7205 
stopAppSwitches()7206     public void stopAppSwitches() {
7207         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7208                 != PackageManager.PERMISSION_GRANTED) {
7209             throw new SecurityException("Requires permission "
7210                     + android.Manifest.permission.STOP_APP_SWITCHES);
7211         }
7212 
7213         synchronized(this) {
7214             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7215                     + APP_SWITCH_DELAY_TIME;
7216             mDidAppSwitch = false;
7217             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7218             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7219             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7220         }
7221     }
7222 
resumeAppSwitches()7223     public void resumeAppSwitches() {
7224         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7225                 != PackageManager.PERMISSION_GRANTED) {
7226             throw new SecurityException("Requires permission "
7227                     + android.Manifest.permission.STOP_APP_SWITCHES);
7228         }
7229 
7230         synchronized(this) {
7231             // Note that we don't execute any pending app switches... we will
7232             // let those wait until either the timeout, or the next start
7233             // activity request.
7234             mAppSwitchesAllowedTime = 0;
7235         }
7236     }
7237 
checkAppSwitchAllowedLocked(int callingPid, int callingUid, String name)7238     boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7239             String name) {
7240         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7241             return true;
7242         }
7243 
7244         final int perm = checkComponentPermission(
7245                 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7246                 callingUid, -1, true);
7247         if (perm == PackageManager.PERMISSION_GRANTED) {
7248             return true;
7249         }
7250 
7251         Slog.w(TAG, name + " request from " + callingUid + " stopped");
7252         return false;
7253     }
7254 
setDebugApp(String packageName, boolean waitForDebugger, boolean persistent)7255     public void setDebugApp(String packageName, boolean waitForDebugger,
7256             boolean persistent) {
7257         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7258                 "setDebugApp()");
7259 
7260         // Note that this is not really thread safe if there are multiple
7261         // callers into it at the same time, but that's not a situation we
7262         // care about.
7263         if (persistent) {
7264             final ContentResolver resolver = mContext.getContentResolver();
7265             Settings.Global.putString(
7266                 resolver, Settings.Global.DEBUG_APP,
7267                 packageName);
7268             Settings.Global.putInt(
7269                 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
7270                 waitForDebugger ? 1 : 0);
7271         }
7272 
7273         synchronized (this) {
7274             if (!persistent) {
7275                 mOrigDebugApp = mDebugApp;
7276                 mOrigWaitForDebugger = mWaitForDebugger;
7277             }
7278             mDebugApp = packageName;
7279             mWaitForDebugger = waitForDebugger;
7280             mDebugTransient = !persistent;
7281             if (packageName != null) {
7282                 final long origId = Binder.clearCallingIdentity();
7283                 forceStopPackageLocked(packageName, -1, false, false, true, true,
7284                         UserHandle.USER_ALL);
7285                 Binder.restoreCallingIdentity(origId);
7286             }
7287         }
7288     }
7289 
setOpenGlTraceApp(ApplicationInfo app, String processName)7290     void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7291         synchronized (this) {
7292             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7293             if (!isDebuggable) {
7294                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7295                     throw new SecurityException("Process not debuggable: " + app.packageName);
7296                 }
7297             }
7298 
7299             mOpenGlTraceApp = processName;
7300         }
7301     }
7302 
setProfileApp(ApplicationInfo app, String processName, String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler)7303     void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7304             ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7305         synchronized (this) {
7306             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7307             if (!isDebuggable) {
7308                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7309                     throw new SecurityException("Process not debuggable: " + app.packageName);
7310                 }
7311             }
7312             mProfileApp = processName;
7313             mProfileFile = profileFile;
7314             if (mProfileFd != null) {
7315                 try {
7316                     mProfileFd.close();
7317                 } catch (IOException e) {
7318                 }
7319                 mProfileFd = null;
7320             }
7321             mProfileFd = profileFd;
7322             mProfileType = 0;
7323             mAutoStopProfiler = autoStopProfiler;
7324         }
7325     }
7326 
setAlwaysFinish(boolean enabled)7327     public void setAlwaysFinish(boolean enabled) {
7328         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7329                 "setAlwaysFinish()");
7330 
7331         Settings.Global.putInt(
7332                 mContext.getContentResolver(),
7333                 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7334 
7335         synchronized (this) {
7336             mAlwaysFinishActivities = enabled;
7337         }
7338     }
7339 
setActivityController(IActivityController controller)7340     public void setActivityController(IActivityController controller) {
7341         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7342                 "setActivityController()");
7343         synchronized (this) {
7344             mController = controller;
7345         }
7346     }
7347 
isUserAMonkey()7348     public boolean isUserAMonkey() {
7349         // For now the fact that there is a controller implies
7350         // we have a monkey.
7351         synchronized (this) {
7352             return mController != null;
7353         }
7354     }
7355 
requestBugReport()7356     public void requestBugReport() {
7357         // No permission check because this can't do anything harmful --
7358         // it will just eventually cause the user to be presented with
7359         // a UI to select where the bug report goes.
7360         SystemProperties.set("ctl.start", "bugreport");
7361     }
7362 
inputDispatchingTimedOut(int pid, boolean aboveSystem)7363     public long inputDispatchingTimedOut(int pid, boolean aboveSystem) {
7364         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
7365                 != PackageManager.PERMISSION_GRANTED) {
7366             throw new SecurityException("Requires permission "
7367                     + android.Manifest.permission.FILTER_EVENTS);
7368         }
7369 
7370         ProcessRecord proc;
7371 
7372         // TODO: Unify this code with ActivityRecord.keyDispatchingTimedOut().
7373         synchronized (this) {
7374             synchronized (mPidsSelfLocked) {
7375                 proc = mPidsSelfLocked.get(pid);
7376             }
7377             if (proc != null) {
7378                 if (proc.debugging) {
7379                     return -1;
7380                 }
7381 
7382                 if (mDidDexOpt) {
7383                     // Give more time since we were dexopting.
7384                     mDidDexOpt = false;
7385                     return -1;
7386                 }
7387 
7388                 if (proc.instrumentationClass != null) {
7389                     Bundle info = new Bundle();
7390                     info.putString("shortMsg", "keyDispatchingTimedOut");
7391                     info.putString("longMsg", "Timed out while dispatching key event");
7392                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
7393                     proc = null;
7394                 }
7395             }
7396         }
7397 
7398         if (proc != null) {
7399             appNotResponding(proc, null, null, aboveSystem, "keyDispatchingTimedOut");
7400             if (proc.instrumentationClass != null || proc.usingWrapper) {
7401                 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
7402             }
7403         }
7404 
7405         return KEY_DISPATCHING_TIMEOUT;
7406     }
7407 
registerProcessObserver(IProcessObserver observer)7408     public void registerProcessObserver(IProcessObserver observer) {
7409         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7410                 "registerProcessObserver()");
7411         synchronized (this) {
7412             mProcessObservers.register(observer);
7413         }
7414     }
7415 
unregisterProcessObserver(IProcessObserver observer)7416     public void unregisterProcessObserver(IProcessObserver observer) {
7417         synchronized (this) {
7418             mProcessObservers.unregister(observer);
7419         }
7420     }
7421 
setImmersive(IBinder token, boolean immersive)7422     public void setImmersive(IBinder token, boolean immersive) {
7423         synchronized(this) {
7424             ActivityRecord r = mMainStack.isInStackLocked(token);
7425             if (r == null) {
7426                 throw new IllegalArgumentException();
7427             }
7428             r.immersive = immersive;
7429         }
7430     }
7431 
isImmersive(IBinder token)7432     public boolean isImmersive(IBinder token) {
7433         synchronized (this) {
7434             ActivityRecord r = mMainStack.isInStackLocked(token);
7435             if (r == null) {
7436                 throw new IllegalArgumentException();
7437             }
7438             return r.immersive;
7439         }
7440     }
7441 
isTopActivityImmersive()7442     public boolean isTopActivityImmersive() {
7443         enforceNotIsolatedCaller("startActivity");
7444         synchronized (this) {
7445             ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7446             return (r != null) ? r.immersive : false;
7447         }
7448     }
7449 
enterSafeMode()7450     public final void enterSafeMode() {
7451         synchronized(this) {
7452             // It only makes sense to do this before the system is ready
7453             // and started launching other packages.
7454             if (!mSystemReady) {
7455                 try {
7456                     AppGlobals.getPackageManager().enterSafeMode();
7457                 } catch (RemoteException e) {
7458                 }
7459             }
7460         }
7461     }
7462 
showSafeModeOverlay()7463     public final void showSafeModeOverlay() {
7464         View v = LayoutInflater.from(mContext).inflate(
7465                 com.android.internal.R.layout.safe_mode, null);
7466         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7467         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7468         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7469         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7470         lp.gravity = Gravity.BOTTOM | Gravity.START;
7471         lp.format = v.getBackground().getOpacity();
7472         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7473                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7474         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
7475         ((WindowManager)mContext.getSystemService(
7476                 Context.WINDOW_SERVICE)).addView(v, lp);
7477     }
7478 
noteWakeupAlarm(IIntentSender sender)7479     public void noteWakeupAlarm(IIntentSender sender) {
7480         if (!(sender instanceof PendingIntentRecord)) {
7481             return;
7482         }
7483         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7484         synchronized (stats) {
7485             if (mBatteryStatsService.isOnBattery()) {
7486                 mBatteryStatsService.enforceCallingPermission();
7487                 PendingIntentRecord rec = (PendingIntentRecord)sender;
7488                 int MY_UID = Binder.getCallingUid();
7489                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7490                 BatteryStatsImpl.Uid.Pkg pkg =
7491                     stats.getPackageStatsLocked(uid, rec.key.packageName);
7492                 pkg.incWakeupsLocked();
7493             }
7494         }
7495     }
7496 
killPids(int[] pids, String pReason, boolean secure)7497     public boolean killPids(int[] pids, String pReason, boolean secure) {
7498         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7499             throw new SecurityException("killPids only available to the system");
7500         }
7501         String reason = (pReason == null) ? "Unknown" : pReason;
7502         // XXX Note: don't acquire main activity lock here, because the window
7503         // manager calls in with its locks held.
7504 
7505         boolean killed = false;
7506         synchronized (mPidsSelfLocked) {
7507             int[] types = new int[pids.length];
7508             int worstType = 0;
7509             for (int i=0; i<pids.length; i++) {
7510                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7511                 if (proc != null) {
7512                     int type = proc.setAdj;
7513                     types[i] = type;
7514                     if (type > worstType) {
7515                         worstType = type;
7516                     }
7517                 }
7518             }
7519 
7520             // If the worst oom_adj is somewhere in the hidden proc LRU range,
7521             // then constrain it so we will kill all hidden procs.
7522             if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7523                     && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7524                 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7525             }
7526 
7527             // If this is not a secure call, don't let it kill processes that
7528             // are important.
7529             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7530                 worstType = ProcessList.SERVICE_ADJ;
7531             }
7532 
7533             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7534             for (int i=0; i<pids.length; i++) {
7535                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7536                 if (proc == null) {
7537                     continue;
7538                 }
7539                 int adj = proc.setAdj;
7540                 if (adj >= worstType && !proc.killedBackground) {
7541                     Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7542                     EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid,
7543                             proc.processName, adj, reason);
7544                     killed = true;
7545                     proc.killedBackground = true;
7546                     Process.killProcessQuiet(pids[i]);
7547                 }
7548             }
7549         }
7550         return killed;
7551     }
7552 
7553     @Override
killProcessesBelowForeground(String reason)7554     public boolean killProcessesBelowForeground(String reason) {
7555         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7556             throw new SecurityException("killProcessesBelowForeground() only available to system");
7557         }
7558 
7559         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7560     }
7561 
killProcessesBelowAdj(int belowAdj, String reason)7562     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7563         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7564             throw new SecurityException("killProcessesBelowAdj() only available to system");
7565         }
7566 
7567         boolean killed = false;
7568         synchronized (mPidsSelfLocked) {
7569             final int size = mPidsSelfLocked.size();
7570             for (int i = 0; i < size; i++) {
7571                 final int pid = mPidsSelfLocked.keyAt(i);
7572                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7573                 if (proc == null) continue;
7574 
7575                 final int adj = proc.setAdj;
7576                 if (adj > belowAdj && !proc.killedBackground) {
7577                     Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7578                     EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId,
7579                             proc.pid, proc.processName, adj, reason);
7580                     killed = true;
7581                     proc.killedBackground = true;
7582                     Process.killProcessQuiet(pid);
7583                 }
7584             }
7585         }
7586         return killed;
7587     }
7588 
startRunning(String pkg, String cls, String action, String data)7589     public final void startRunning(String pkg, String cls, String action,
7590             String data) {
7591         synchronized(this) {
7592             if (mStartRunning) {
7593                 return;
7594             }
7595             mStartRunning = true;
7596             mTopComponent = pkg != null && cls != null
7597                     ? new ComponentName(pkg, cls) : null;
7598             mTopAction = action != null ? action : Intent.ACTION_MAIN;
7599             mTopData = data;
7600             if (!mSystemReady) {
7601                 return;
7602             }
7603         }
7604 
7605         systemReady(null);
7606     }
7607 
retrieveSettings()7608     private void retrieveSettings() {
7609         final ContentResolver resolver = mContext.getContentResolver();
7610         String debugApp = Settings.Global.getString(
7611             resolver, Settings.Global.DEBUG_APP);
7612         boolean waitForDebugger = Settings.Global.getInt(
7613             resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
7614         boolean alwaysFinishActivities = Settings.Global.getInt(
7615             resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7616 
7617         Configuration configuration = new Configuration();
7618         Settings.System.getConfiguration(resolver, configuration);
7619 
7620         synchronized (this) {
7621             mDebugApp = mOrigDebugApp = debugApp;
7622             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7623             mAlwaysFinishActivities = alwaysFinishActivities;
7624             // This happens before any activities are started, so we can
7625             // change mConfiguration in-place.
7626             updateConfigurationLocked(configuration, null, false, true);
7627             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7628         }
7629     }
7630 
testIsSystemReady()7631     public boolean testIsSystemReady() {
7632         // no need to synchronize(this) just to read & return the value
7633         return mSystemReady;
7634     }
7635 
getCalledPreBootReceiversFile()7636     private static File getCalledPreBootReceiversFile() {
7637         File dataDir = Environment.getDataDirectory();
7638         File systemDir = new File(dataDir, "system");
7639         File fname = new File(systemDir, "called_pre_boots.dat");
7640         return fname;
7641     }
7642 
7643     static final int LAST_DONE_VERSION = 10000;
7644 
readLastDonePreBootReceivers()7645     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7646         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7647         File file = getCalledPreBootReceiversFile();
7648         FileInputStream fis = null;
7649         try {
7650             fis = new FileInputStream(file);
7651             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7652             int fvers = dis.readInt();
7653             if (fvers == LAST_DONE_VERSION) {
7654                 String vers = dis.readUTF();
7655                 String codename = dis.readUTF();
7656                 String build = dis.readUTF();
7657                 if (android.os.Build.VERSION.RELEASE.equals(vers)
7658                         && android.os.Build.VERSION.CODENAME.equals(codename)
7659                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7660                     int num = dis.readInt();
7661                     while (num > 0) {
7662                         num--;
7663                         String pkg = dis.readUTF();
7664                         String cls = dis.readUTF();
7665                         lastDoneReceivers.add(new ComponentName(pkg, cls));
7666                     }
7667                 }
7668             }
7669         } catch (FileNotFoundException e) {
7670         } catch (IOException e) {
7671             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7672         } finally {
7673             if (fis != null) {
7674                 try {
7675                     fis.close();
7676                 } catch (IOException e) {
7677                 }
7678             }
7679         }
7680         return lastDoneReceivers;
7681     }
7682 
writeLastDonePreBootReceivers(ArrayList<ComponentName> list)7683     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7684         File file = getCalledPreBootReceiversFile();
7685         FileOutputStream fos = null;
7686         DataOutputStream dos = null;
7687         try {
7688             Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7689             fos = new FileOutputStream(file);
7690             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7691             dos.writeInt(LAST_DONE_VERSION);
7692             dos.writeUTF(android.os.Build.VERSION.RELEASE);
7693             dos.writeUTF(android.os.Build.VERSION.CODENAME);
7694             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7695             dos.writeInt(list.size());
7696             for (int i=0; i<list.size(); i++) {
7697                 dos.writeUTF(list.get(i).getPackageName());
7698                 dos.writeUTF(list.get(i).getClassName());
7699             }
7700         } catch (IOException e) {
7701             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7702             file.delete();
7703         } finally {
7704             FileUtils.sync(fos);
7705             if (dos != null) {
7706                 try {
7707                     dos.close();
7708                 } catch (IOException e) {
7709                     // TODO Auto-generated catch block
7710                     e.printStackTrace();
7711                 }
7712             }
7713         }
7714     }
7715 
systemReady(final Runnable goingCallback)7716     public void systemReady(final Runnable goingCallback) {
7717         synchronized(this) {
7718             if (mSystemReady) {
7719                 if (goingCallback != null) goingCallback.run();
7720                 return;
7721             }
7722 
7723             // Check to see if there are any update receivers to run.
7724             if (!mDidUpdate) {
7725                 if (mWaitingUpdate) {
7726                     return;
7727                 }
7728                 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7729                 List<ResolveInfo> ris = null;
7730                 try {
7731                     ris = AppGlobals.getPackageManager().queryIntentReceivers(
7732                             intent, null, 0, 0);
7733                 } catch (RemoteException e) {
7734                 }
7735                 if (ris != null) {
7736                     for (int i=ris.size()-1; i>=0; i--) {
7737                         if ((ris.get(i).activityInfo.applicationInfo.flags
7738                                 &ApplicationInfo.FLAG_SYSTEM) == 0) {
7739                             ris.remove(i);
7740                         }
7741                     }
7742                     intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7743 
7744                     ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7745 
7746                     final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7747                     for (int i=0; i<ris.size(); i++) {
7748                         ActivityInfo ai = ris.get(i).activityInfo;
7749                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
7750                         if (lastDoneReceivers.contains(comp)) {
7751                             ris.remove(i);
7752                             i--;
7753                         }
7754                     }
7755 
7756                     final int[] users = getUsersLocked();
7757                     for (int i=0; i<ris.size(); i++) {
7758                         ActivityInfo ai = ris.get(i).activityInfo;
7759                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
7760                         doneReceivers.add(comp);
7761                         intent.setComponent(comp);
7762                         for (int j=0; j<users.length; j++) {
7763                             IIntentReceiver finisher = null;
7764                             if (i == ris.size()-1 && j == users.length-1) {
7765                                 finisher = new IIntentReceiver.Stub() {
7766                                     public void performReceive(Intent intent, int resultCode,
7767                                             String data, Bundle extras, boolean ordered,
7768                                             boolean sticky, int sendingUser) {
7769                                         // The raw IIntentReceiver interface is called
7770                                         // with the AM lock held, so redispatch to
7771                                         // execute our code without the lock.
7772                                         mHandler.post(new Runnable() {
7773                                             public void run() {
7774                                                 synchronized (ActivityManagerService.this) {
7775                                                     mDidUpdate = true;
7776                                                 }
7777                                                 writeLastDonePreBootReceivers(doneReceivers);
7778                                                 showBootMessage(mContext.getText(
7779                                                         R.string.android_upgrading_complete),
7780                                                         false);
7781                                                 systemReady(goingCallback);
7782                                             }
7783                                         });
7784                                     }
7785                                 };
7786                             }
7787                             Slog.i(TAG, "Sending system update to " + intent.getComponent()
7788                                     + " for user " + users[j]);
7789                             broadcastIntentLocked(null, null, intent, null, finisher,
7790                                     0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7791                                     users[j]);
7792                             if (finisher != null) {
7793                                 mWaitingUpdate = true;
7794                             }
7795                         }
7796                     }
7797                 }
7798                 if (mWaitingUpdate) {
7799                     return;
7800                 }
7801                 mDidUpdate = true;
7802             }
7803 
7804             mSystemReady = true;
7805             if (!mStartRunning) {
7806                 return;
7807             }
7808         }
7809 
7810         ArrayList<ProcessRecord> procsToKill = null;
7811         synchronized(mPidsSelfLocked) {
7812             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7813                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7814                 if (!isAllowedWhileBooting(proc.info)){
7815                     if (procsToKill == null) {
7816                         procsToKill = new ArrayList<ProcessRecord>();
7817                     }
7818                     procsToKill.add(proc);
7819                 }
7820             }
7821         }
7822 
7823         synchronized(this) {
7824             if (procsToKill != null) {
7825                 for (int i=procsToKill.size()-1; i>=0; i--) {
7826                     ProcessRecord proc = procsToKill.get(i);
7827                     Slog.i(TAG, "Removing system update proc: " + proc);
7828                     removeProcessLocked(proc, true, false, "system update done");
7829                 }
7830             }
7831 
7832             // Now that we have cleaned up any update processes, we
7833             // are ready to start launching real processes and know that
7834             // we won't trample on them any more.
7835             mProcessesReady = true;
7836         }
7837 
7838         Slog.i(TAG, "System now ready");
7839         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7840             SystemClock.uptimeMillis());
7841 
7842         synchronized(this) {
7843             // Make sure we have no pre-ready processes sitting around.
7844 
7845             if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7846                 ResolveInfo ri = mContext.getPackageManager()
7847                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7848                                 STOCK_PM_FLAGS);
7849                 CharSequence errorMsg = null;
7850                 if (ri != null) {
7851                     ActivityInfo ai = ri.activityInfo;
7852                     ApplicationInfo app = ai.applicationInfo;
7853                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7854                         mTopAction = Intent.ACTION_FACTORY_TEST;
7855                         mTopData = null;
7856                         mTopComponent = new ComponentName(app.packageName,
7857                                 ai.name);
7858                     } else {
7859                         errorMsg = mContext.getResources().getText(
7860                                 com.android.internal.R.string.factorytest_not_system);
7861                     }
7862                 } else {
7863                     errorMsg = mContext.getResources().getText(
7864                             com.android.internal.R.string.factorytest_no_action);
7865                 }
7866                 if (errorMsg != null) {
7867                     mTopAction = null;
7868                     mTopData = null;
7869                     mTopComponent = null;
7870                     Message msg = Message.obtain();
7871                     msg.what = SHOW_FACTORY_ERROR_MSG;
7872                     msg.getData().putCharSequence("msg", errorMsg);
7873                     mHandler.sendMessage(msg);
7874                 }
7875             }
7876         }
7877 
7878         retrieveSettings();
7879 
7880         if (goingCallback != null) goingCallback.run();
7881 
7882         synchronized (this) {
7883             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7884                 try {
7885                     List apps = AppGlobals.getPackageManager().
7886                         getPersistentApplications(STOCK_PM_FLAGS);
7887                     if (apps != null) {
7888                         int N = apps.size();
7889                         int i;
7890                         for (i=0; i<N; i++) {
7891                             ApplicationInfo info
7892                                 = (ApplicationInfo)apps.get(i);
7893                             if (info != null &&
7894                                     !info.packageName.equals("android")) {
7895                                 addAppLocked(info, false);
7896                             }
7897                         }
7898                     }
7899                 } catch (RemoteException ex) {
7900                     // pm is in same process, this will never happen.
7901                 }
7902             }
7903 
7904             // Start up initial activity.
7905             mBooting = true;
7906 
7907             try {
7908                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7909                     Message msg = Message.obtain();
7910                     msg.what = SHOW_UID_ERROR_MSG;
7911                     mHandler.sendMessage(msg);
7912                 }
7913             } catch (RemoteException e) {
7914             }
7915 
7916             long ident = Binder.clearCallingIdentity();
7917             try {
7918                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
7919                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
7920                         | Intent.FLAG_RECEIVER_FOREGROUND);
7921                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
7922                 broadcastIntentLocked(null, null, intent,
7923                         null, null, 0, null, null, null,
7924                         false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
7925                 intent = new Intent(Intent.ACTION_USER_STARTING);
7926                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
7927                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
7928                 broadcastIntentLocked(null, null, intent,
7929                         null, new IIntentReceiver.Stub() {
7930                             @Override
7931                             public void performReceive(Intent intent, int resultCode, String data,
7932                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
7933                                     throws RemoteException {
7934                             }
7935                         }, 0, null, null,
7936                         android.Manifest.permission.INTERACT_ACROSS_USERS,
7937                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
7938             } finally {
7939                 Binder.restoreCallingIdentity(ident);
7940             }
7941             mMainStack.resumeTopActivityLocked(null);
7942             sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
7943         }
7944     }
7945 
makeAppCrashingLocked(ProcessRecord app, String shortMsg, String longMsg, String stackTrace)7946     private boolean makeAppCrashingLocked(ProcessRecord app,
7947             String shortMsg, String longMsg, String stackTrace) {
7948         app.crashing = true;
7949         app.crashingReport = generateProcessError(app,
7950                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7951         startAppProblemLocked(app);
7952         app.stopFreezingAllLocked();
7953         return handleAppCrashLocked(app);
7954     }
7955 
makeAppNotRespondingLocked(ProcessRecord app, String activity, String shortMsg, String longMsg)7956     private void makeAppNotRespondingLocked(ProcessRecord app,
7957             String activity, String shortMsg, String longMsg) {
7958         app.notResponding = true;
7959         app.notRespondingReport = generateProcessError(app,
7960                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7961                 activity, shortMsg, longMsg, null);
7962         startAppProblemLocked(app);
7963         app.stopFreezingAllLocked();
7964     }
7965 
7966     /**
7967      * Generate a process error record, suitable for attachment to a ProcessRecord.
7968      *
7969      * @param app The ProcessRecord in which the error occurred.
7970      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7971      *                      ActivityManager.AppErrorStateInfo
7972      * @param activity The activity associated with the crash, if known.
7973      * @param shortMsg Short message describing the crash.
7974      * @param longMsg Long message describing the crash.
7975      * @param stackTrace Full crash stack trace, may be null.
7976      *
7977      * @return Returns a fully-formed AppErrorStateInfo record.
7978      */
generateProcessError(ProcessRecord app, int condition, String activity, String shortMsg, String longMsg, String stackTrace)7979     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7980             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7981         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7982 
7983         report.condition = condition;
7984         report.processName = app.processName;
7985         report.pid = app.pid;
7986         report.uid = app.info.uid;
7987         report.tag = activity;
7988         report.shortMsg = shortMsg;
7989         report.longMsg = longMsg;
7990         report.stackTrace = stackTrace;
7991 
7992         return report;
7993     }
7994 
killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog)7995     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7996         synchronized (this) {
7997             app.crashing = false;
7998             app.crashingReport = null;
7999             app.notResponding = false;
8000             app.notRespondingReport = null;
8001             if (app.anrDialog == fromDialog) {
8002                 app.anrDialog = null;
8003             }
8004             if (app.waitDialog == fromDialog) {
8005                 app.waitDialog = null;
8006             }
8007             if (app.pid > 0 && app.pid != MY_PID) {
8008                 handleAppCrashLocked(app);
8009                 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
8010                 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
8011                         app.processName, app.setAdj, "user's request after error");
8012                 Process.killProcessQuiet(app.pid);
8013             }
8014         }
8015     }
8016 
handleAppCrashLocked(ProcessRecord app)8017     private boolean handleAppCrashLocked(ProcessRecord app) {
8018         if (mHeadless) {
8019             Log.e(TAG, "handleAppCrashLocked: " + app.processName);
8020             return false;
8021         }
8022         long now = SystemClock.uptimeMillis();
8023 
8024         Long crashTime;
8025         if (!app.isolated) {
8026             crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
8027         } else {
8028             crashTime = null;
8029         }
8030         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
8031             // This process loses!
8032             Slog.w(TAG, "Process " + app.info.processName
8033                     + " has crashed too many times: killing!");
8034             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
8035                     app.userId, app.info.processName, app.uid);
8036             for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
8037                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
8038                 if (r.app == app) {
8039                     Slog.w(TAG, "  Force finishing activity "
8040                         + r.intent.getComponent().flattenToShortString());
8041                     r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
8042                             null, "crashed", false);
8043                 }
8044             }
8045             if (!app.persistent) {
8046                 // We don't want to start this process again until the user
8047                 // explicitly does so...  but for persistent process, we really
8048                 // need to keep it running.  If a persistent process is actually
8049                 // repeatedly crashing, then badness for everyone.
8050                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
8051                         app.info.processName);
8052                 if (!app.isolated) {
8053                     // XXX We don't have a way to mark isolated processes
8054                     // as bad, since they don't have a peristent identity.
8055                     mBadProcesses.put(app.info.processName, app.uid, now);
8056                     mProcessCrashTimes.remove(app.info.processName, app.uid);
8057                 }
8058                 app.bad = true;
8059                 app.removed = true;
8060                 // Don't let services in this process be restarted and potentially
8061                 // annoy the user repeatedly.  Unless it is persistent, since those
8062                 // processes run critical code.
8063                 removeProcessLocked(app, false, false, "crash");
8064                 mMainStack.resumeTopActivityLocked(null);
8065                 return false;
8066             }
8067             mMainStack.resumeTopActivityLocked(null);
8068         } else {
8069             ActivityRecord r = mMainStack.topRunningActivityLocked(null);
8070             if (r != null && r.app == app) {
8071                 // If the top running activity is from this crashing
8072                 // process, then terminate it to avoid getting in a loop.
8073                 Slog.w(TAG, "  Force finishing activity "
8074                         + r.intent.getComponent().flattenToShortString());
8075                 int index = mMainStack.indexOfActivityLocked(r);
8076                 r.stack.finishActivityLocked(r, index,
8077                         Activity.RESULT_CANCELED, null, "crashed", false);
8078                 // Also terminate any activities below it that aren't yet
8079                 // stopped, to avoid a situation where one will get
8080                 // re-start our crashing activity once it gets resumed again.
8081                 index--;
8082                 if (index >= 0) {
8083                     r = (ActivityRecord)mMainStack.mHistory.get(index);
8084                     if (r.state == ActivityState.RESUMED
8085                             || r.state == ActivityState.PAUSING
8086                             || r.state == ActivityState.PAUSED) {
8087                         if (!r.isHomeActivity || mHomeProcess != r.app) {
8088                             Slog.w(TAG, "  Force finishing activity "
8089                                     + r.intent.getComponent().flattenToShortString());
8090                             r.stack.finishActivityLocked(r, index,
8091                                     Activity.RESULT_CANCELED, null, "crashed", false);
8092                         }
8093                     }
8094                 }
8095             }
8096         }
8097 
8098         // Bump up the crash count of any services currently running in the proc.
8099         if (app.services.size() != 0) {
8100             // Any services running in the application need to be placed
8101             // back in the pending list.
8102             Iterator<ServiceRecord> it = app.services.iterator();
8103             while (it.hasNext()) {
8104                 ServiceRecord sr = it.next();
8105                 sr.crashCount++;
8106             }
8107         }
8108 
8109         // If the crashing process is what we consider to be the "home process" and it has been
8110         // replaced by a third-party app, clear the package preferred activities from packages
8111         // with a home activity running in the process to prevent a repeatedly crashing app
8112         // from blocking the user to manually clear the list.
8113         if (app == mHomeProcess && mHomeProcess.activities.size() > 0
8114                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
8115             Iterator it = mHomeProcess.activities.iterator();
8116             while (it.hasNext()) {
8117                 ActivityRecord r = (ActivityRecord)it.next();
8118                 if (r.isHomeActivity) {
8119                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
8120                     try {
8121                         ActivityThread.getPackageManager()
8122                                 .clearPackagePreferredActivities(r.packageName);
8123                     } catch (RemoteException c) {
8124                         // pm is in same process, this will never happen.
8125                     }
8126                 }
8127             }
8128         }
8129 
8130         if (!app.isolated) {
8131             // XXX Can't keep track of crash times for isolated processes,
8132             // because they don't have a perisistent identity.
8133             mProcessCrashTimes.put(app.info.processName, app.uid, now);
8134         }
8135 
8136         return true;
8137     }
8138 
startAppProblemLocked(ProcessRecord app)8139     void startAppProblemLocked(ProcessRecord app) {
8140         if (app.userId == mCurrentUserId) {
8141             app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8142                     mContext, app.info.packageName, app.info.flags);
8143         } else {
8144             // If this app is not running under the current user, then we
8145             // can't give it a report button because that would require
8146             // launching the report UI under a different user.
8147             app.errorReportReceiver = null;
8148         }
8149         skipCurrentReceiverLocked(app);
8150     }
8151 
skipCurrentReceiverLocked(ProcessRecord app)8152     void skipCurrentReceiverLocked(ProcessRecord app) {
8153         for (BroadcastQueue queue : mBroadcastQueues) {
8154             queue.skipCurrentReceiverLocked(app);
8155         }
8156     }
8157 
8158     /**
8159      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8160      * The application process will exit immediately after this call returns.
8161      * @param app object of the crashing app, null for the system server
8162      * @param crashInfo describing the exception
8163      */
handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo)8164     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
8165         ProcessRecord r = findAppProcess(app, "Crash");
8166         final String processName = app == null ? "system_server"
8167                 : (r == null ? "unknown" : r.processName);
8168 
8169         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
8170                 UserHandle.getUserId(Binder.getCallingUid()), processName,
8171                 r == null ? -1 : r.info.flags,
8172                 crashInfo.exceptionClassName,
8173                 crashInfo.exceptionMessage,
8174                 crashInfo.throwFileName,
8175                 crashInfo.throwLineNumber);
8176 
8177         addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
8178 
8179         crashApplication(r, crashInfo);
8180     }
8181 
handleApplicationStrictModeViolation( IBinder app, int violationMask, StrictMode.ViolationInfo info)8182     public void handleApplicationStrictModeViolation(
8183             IBinder app,
8184             int violationMask,
8185             StrictMode.ViolationInfo info) {
8186         ProcessRecord r = findAppProcess(app, "StrictMode");
8187         if (r == null) {
8188             return;
8189         }
8190 
8191         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
8192             Integer stackFingerprint = info.hashCode();
8193             boolean logIt = true;
8194             synchronized (mAlreadyLoggedViolatedStacks) {
8195                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8196                     logIt = false;
8197                     // TODO: sub-sample into EventLog for these, with
8198                     // the info.durationMillis?  Then we'd get
8199                     // the relative pain numbers, without logging all
8200                     // the stack traces repeatedly.  We'd want to do
8201                     // likewise in the client code, which also does
8202                     // dup suppression, before the Binder call.
8203                 } else {
8204                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8205                         mAlreadyLoggedViolatedStacks.clear();
8206                     }
8207                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8208                 }
8209             }
8210             if (logIt) {
8211                 logStrictModeViolationToDropBox(r, info);
8212             }
8213         }
8214 
8215         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8216             AppErrorResult result = new AppErrorResult();
8217             synchronized (this) {
8218                 final long origId = Binder.clearCallingIdentity();
8219 
8220                 Message msg = Message.obtain();
8221                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8222                 HashMap<String, Object> data = new HashMap<String, Object>();
8223                 data.put("result", result);
8224                 data.put("app", r);
8225                 data.put("violationMask", violationMask);
8226                 data.put("info", info);
8227                 msg.obj = data;
8228                 mHandler.sendMessage(msg);
8229 
8230                 Binder.restoreCallingIdentity(origId);
8231             }
8232             int res = result.get();
8233             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
8234         }
8235     }
8236 
8237     // Depending on the policy in effect, there could be a bunch of
8238     // these in quick succession so we try to batch these together to
8239     // minimize disk writes, number of dropbox entries, and maximize
8240     // compression, by having more fewer, larger records.
logStrictModeViolationToDropBox( ProcessRecord process, StrictMode.ViolationInfo info)8241     private void logStrictModeViolationToDropBox(
8242             ProcessRecord process,
8243             StrictMode.ViolationInfo info) {
8244         if (info == null) {
8245             return;
8246         }
8247         final boolean isSystemApp = process == null ||
8248                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8249                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8250         final String processName = process == null ? "unknown" : process.processName;
8251         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8252         final DropBoxManager dbox = (DropBoxManager)
8253                 mContext.getSystemService(Context.DROPBOX_SERVICE);
8254 
8255         // Exit early if the dropbox isn't configured to accept this report type.
8256         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8257 
8258         boolean bufferWasEmpty;
8259         boolean needsFlush;
8260         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8261         synchronized (sb) {
8262             bufferWasEmpty = sb.length() == 0;
8263             appendDropBoxProcessHeaders(process, processName, sb);
8264             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8265             sb.append("System-App: ").append(isSystemApp).append("\n");
8266             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8267             if (info.violationNumThisLoop != 0) {
8268                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8269             }
8270             if (info.numAnimationsRunning != 0) {
8271                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8272             }
8273             if (info.broadcastIntentAction != null) {
8274                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8275             }
8276             if (info.durationMillis != -1) {
8277                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8278             }
8279             if (info.numInstances != -1) {
8280                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8281             }
8282             if (info.tags != null) {
8283                 for (String tag : info.tags) {
8284                     sb.append("Span-Tag: ").append(tag).append("\n");
8285                 }
8286             }
8287             sb.append("\n");
8288             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8289                 sb.append(info.crashInfo.stackTrace);
8290             }
8291             sb.append("\n");
8292 
8293             // Only buffer up to ~64k.  Various logging bits truncate
8294             // things at 128k.
8295             needsFlush = (sb.length() > 64 * 1024);
8296         }
8297 
8298         // Flush immediately if the buffer's grown too large, or this
8299         // is a non-system app.  Non-system apps are isolated with a
8300         // different tag & policy and not batched.
8301         //
8302         // Batching is useful during internal testing with
8303         // StrictMode settings turned up high.  Without batching,
8304         // thousands of separate files could be created on boot.
8305         if (!isSystemApp || needsFlush) {
8306             new Thread("Error dump: " + dropboxTag) {
8307                 @Override
8308                 public void run() {
8309                     String report;
8310                     synchronized (sb) {
8311                         report = sb.toString();
8312                         sb.delete(0, sb.length());
8313                         sb.trimToSize();
8314                     }
8315                     if (report.length() != 0) {
8316                         dbox.addText(dropboxTag, report);
8317                     }
8318                 }
8319             }.start();
8320             return;
8321         }
8322 
8323         // System app batching:
8324         if (!bufferWasEmpty) {
8325             // An existing dropbox-writing thread is outstanding, so
8326             // we don't need to start it up.  The existing thread will
8327             // catch the buffer appends we just did.
8328             return;
8329         }
8330 
8331         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8332         // (After this point, we shouldn't access AMS internal data structures.)
8333         new Thread("Error dump: " + dropboxTag) {
8334             @Override
8335             public void run() {
8336                 // 5 second sleep to let stacks arrive and be batched together
8337                 try {
8338                     Thread.sleep(5000);  // 5 seconds
8339                 } catch (InterruptedException e) {}
8340 
8341                 String errorReport;
8342                 synchronized (mStrictModeBuffer) {
8343                     errorReport = mStrictModeBuffer.toString();
8344                     if (errorReport.length() == 0) {
8345                         return;
8346                     }
8347                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8348                     mStrictModeBuffer.trimToSize();
8349                 }
8350                 dbox.addText(dropboxTag, errorReport);
8351             }
8352         }.start();
8353     }
8354 
8355     /**
8356      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8357      * @param app object of the crashing app, null for the system server
8358      * @param tag reported by the caller
8359      * @param crashInfo describing the context of the error
8360      * @return true if the process should exit immediately (WTF is fatal)
8361      */
handleApplicationWtf(IBinder app, String tag, ApplicationErrorReport.CrashInfo crashInfo)8362     public boolean handleApplicationWtf(IBinder app, String tag,
8363             ApplicationErrorReport.CrashInfo crashInfo) {
8364         ProcessRecord r = findAppProcess(app, "WTF");
8365         final String processName = app == null ? "system_server"
8366                 : (r == null ? "unknown" : r.processName);
8367 
8368         EventLog.writeEvent(EventLogTags.AM_WTF,
8369                 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
8370                 processName,
8371                 r == null ? -1 : r.info.flags,
8372                 tag, crashInfo.exceptionMessage);
8373 
8374         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8375 
8376         if (r != null && r.pid != Process.myPid() &&
8377                 Settings.Global.getInt(mContext.getContentResolver(),
8378                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
8379             crashApplication(r, crashInfo);
8380             return true;
8381         } else {
8382             return false;
8383         }
8384     }
8385 
8386     /**
8387      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8388      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8389      */
findAppProcess(IBinder app, String reason)8390     private ProcessRecord findAppProcess(IBinder app, String reason) {
8391         if (app == null) {
8392             return null;
8393         }
8394 
8395         synchronized (this) {
8396             for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8397                 final int NA = apps.size();
8398                 for (int ia=0; ia<NA; ia++) {
8399                     ProcessRecord p = apps.valueAt(ia);
8400                     if (p.thread != null && p.thread.asBinder() == app) {
8401                         return p;
8402                     }
8403                 }
8404             }
8405 
8406             Slog.w(TAG, "Can't find mystery application for " + reason
8407                     + " from pid=" + Binder.getCallingPid()
8408                     + " uid=" + Binder.getCallingUid() + ": " + app);
8409             return null;
8410         }
8411     }
8412 
8413     /**
8414      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8415      * to append various headers to the dropbox log text.
8416      */
appendDropBoxProcessHeaders(ProcessRecord process, String processName, StringBuilder sb)8417     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8418             StringBuilder sb) {
8419         // Watchdog thread ends up invoking this function (with
8420         // a null ProcessRecord) to add the stack file to dropbox.
8421         // Do not acquire a lock on this (am) in such cases, as it
8422         // could cause a potential deadlock, if and when watchdog
8423         // is invoked due to unavailability of lock on am and it
8424         // would prevent watchdog from killing system_server.
8425         if (process == null) {
8426             sb.append("Process: ").append(processName).append("\n");
8427             return;
8428         }
8429         // Note: ProcessRecord 'process' is guarded by the service
8430         // instance.  (notably process.pkgList, which could otherwise change
8431         // concurrently during execution of this method)
8432         synchronized (this) {
8433             sb.append("Process: ").append(processName).append("\n");
8434             int flags = process.info.flags;
8435             IPackageManager pm = AppGlobals.getPackageManager();
8436             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8437             for (String pkg : process.pkgList) {
8438                 sb.append("Package: ").append(pkg);
8439                 try {
8440                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
8441                     if (pi != null) {
8442                         sb.append(" v").append(pi.versionCode);
8443                         if (pi.versionName != null) {
8444                             sb.append(" (").append(pi.versionName).append(")");
8445                         }
8446                     }
8447                 } catch (RemoteException e) {
8448                     Slog.e(TAG, "Error getting package info: " + pkg, e);
8449                 }
8450                 sb.append("\n");
8451             }
8452         }
8453     }
8454 
processClass(ProcessRecord process)8455     private static String processClass(ProcessRecord process) {
8456         if (process == null || process.pid == MY_PID) {
8457             return "system_server";
8458         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8459             return "system_app";
8460         } else {
8461             return "data_app";
8462         }
8463     }
8464 
8465     /**
8466      * Write a description of an error (crash, WTF, ANR) to the drop box.
8467      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8468      * @param process which caused the error, null means the system server
8469      * @param activity which triggered the error, null if unknown
8470      * @param parent activity related to the error, null if unknown
8471      * @param subject line related to the error, null if absent
8472      * @param report in long form describing the error, null if absent
8473      * @param logFile to include in the report, null if none
8474      * @param crashInfo giving an application stack trace, null if absent
8475      */
addErrorToDropBox(String eventType, ProcessRecord process, String processName, ActivityRecord activity, ActivityRecord parent, String subject, final String report, final File logFile, final ApplicationErrorReport.CrashInfo crashInfo)8476     public void addErrorToDropBox(String eventType,
8477             ProcessRecord process, String processName, ActivityRecord activity,
8478             ActivityRecord parent, String subject,
8479             final String report, final File logFile,
8480             final ApplicationErrorReport.CrashInfo crashInfo) {
8481         // NOTE -- this must never acquire the ActivityManagerService lock,
8482         // otherwise the watchdog may be prevented from resetting the system.
8483 
8484         final String dropboxTag = processClass(process) + "_" + eventType;
8485         final DropBoxManager dbox = (DropBoxManager)
8486                 mContext.getSystemService(Context.DROPBOX_SERVICE);
8487 
8488         // Exit early if the dropbox isn't configured to accept this report type.
8489         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8490 
8491         final StringBuilder sb = new StringBuilder(1024);
8492         appendDropBoxProcessHeaders(process, processName, sb);
8493         if (activity != null) {
8494             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8495         }
8496         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8497             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8498         }
8499         if (parent != null && parent != activity) {
8500             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8501         }
8502         if (subject != null) {
8503             sb.append("Subject: ").append(subject).append("\n");
8504         }
8505         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8506         if (Debug.isDebuggerConnected()) {
8507             sb.append("Debugger: Connected\n");
8508         }
8509         sb.append("\n");
8510 
8511         // Do the rest in a worker thread to avoid blocking the caller on I/O
8512         // (After this point, we shouldn't access AMS internal data structures.)
8513         Thread worker = new Thread("Error dump: " + dropboxTag) {
8514             @Override
8515             public void run() {
8516                 if (report != null) {
8517                     sb.append(report);
8518                 }
8519                 if (logFile != null) {
8520                     try {
8521                         sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8522                     } catch (IOException e) {
8523                         Slog.e(TAG, "Error reading " + logFile, e);
8524                     }
8525                 }
8526                 if (crashInfo != null && crashInfo.stackTrace != null) {
8527                     sb.append(crashInfo.stackTrace);
8528                 }
8529 
8530                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
8531                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
8532                 if (lines > 0) {
8533                     sb.append("\n");
8534 
8535                     // Merge several logcat streams, and take the last N lines
8536                     InputStreamReader input = null;
8537                     try {
8538                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8539                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8540                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8541 
8542                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
8543                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
8544                         input = new InputStreamReader(logcat.getInputStream());
8545 
8546                         int num;
8547                         char[] buf = new char[8192];
8548                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8549                     } catch (IOException e) {
8550                         Slog.e(TAG, "Error running logcat", e);
8551                     } finally {
8552                         if (input != null) try { input.close(); } catch (IOException e) {}
8553                     }
8554                 }
8555 
8556                 dbox.addText(dropboxTag, sb.toString());
8557             }
8558         };
8559 
8560         if (process == null) {
8561             // If process is null, we are being called from some internal code
8562             // and may be about to die -- run this synchronously.
8563             worker.run();
8564         } else {
8565             worker.start();
8566         }
8567     }
8568 
8569     /**
8570      * Bring up the "unexpected error" dialog box for a crashing app.
8571      * Deal with edge cases (intercepts from instrumented applications,
8572      * ActivityController, error intent receivers, that sort of thing).
8573      * @param r the application crashing
8574      * @param crashInfo describing the failure
8575      */
crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo)8576     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8577         long timeMillis = System.currentTimeMillis();
8578         String shortMsg = crashInfo.exceptionClassName;
8579         String longMsg = crashInfo.exceptionMessage;
8580         String stackTrace = crashInfo.stackTrace;
8581         if (shortMsg != null && longMsg != null) {
8582             longMsg = shortMsg + ": " + longMsg;
8583         } else if (shortMsg != null) {
8584             longMsg = shortMsg;
8585         }
8586 
8587         AppErrorResult result = new AppErrorResult();
8588         synchronized (this) {
8589             if (mController != null) {
8590                 try {
8591                     String name = r != null ? r.processName : null;
8592                     int pid = r != null ? r.pid : Binder.getCallingPid();
8593                     if (!mController.appCrashed(name, pid,
8594                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8595                         Slog.w(TAG, "Force-killing crashed app " + name
8596                                 + " at watcher's request");
8597                         Process.killProcess(pid);
8598                         return;
8599                     }
8600                 } catch (RemoteException e) {
8601                     mController = null;
8602                 }
8603             }
8604 
8605             final long origId = Binder.clearCallingIdentity();
8606 
8607             // If this process is running instrumentation, finish it.
8608             if (r != null && r.instrumentationClass != null) {
8609                 Slog.w(TAG, "Error in app " + r.processName
8610                       + " running instrumentation " + r.instrumentationClass + ":");
8611                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8612                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8613                 Bundle info = new Bundle();
8614                 info.putString("shortMsg", shortMsg);
8615                 info.putString("longMsg", longMsg);
8616                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8617                 Binder.restoreCallingIdentity(origId);
8618                 return;
8619             }
8620 
8621             // If we can't identify the process or it's already exceeded its crash quota,
8622             // quit right away without showing a crash dialog.
8623             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8624                 Binder.restoreCallingIdentity(origId);
8625                 return;
8626             }
8627 
8628             Message msg = Message.obtain();
8629             msg.what = SHOW_ERROR_MSG;
8630             HashMap data = new HashMap();
8631             data.put("result", result);
8632             data.put("app", r);
8633             msg.obj = data;
8634             mHandler.sendMessage(msg);
8635 
8636             Binder.restoreCallingIdentity(origId);
8637         }
8638 
8639         int res = result.get();
8640 
8641         Intent appErrorIntent = null;
8642         synchronized (this) {
8643             if (r != null && !r.isolated) {
8644                 // XXX Can't keep track of crash time for isolated processes,
8645                 // since they don't have a persistent identity.
8646                 mProcessCrashTimes.put(r.info.processName, r.uid,
8647                         SystemClock.uptimeMillis());
8648             }
8649             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8650                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8651             }
8652         }
8653 
8654         if (appErrorIntent != null) {
8655             try {
8656                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
8657             } catch (ActivityNotFoundException e) {
8658                 Slog.w(TAG, "bug report receiver dissappeared", e);
8659             }
8660         }
8661     }
8662 
createAppErrorIntentLocked(ProcessRecord r, long timeMillis, ApplicationErrorReport.CrashInfo crashInfo)8663     Intent createAppErrorIntentLocked(ProcessRecord r,
8664             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8665         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8666         if (report == null) {
8667             return null;
8668         }
8669         Intent result = new Intent(Intent.ACTION_APP_ERROR);
8670         result.setComponent(r.errorReportReceiver);
8671         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8672         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8673         return result;
8674     }
8675 
createAppErrorReportLocked(ProcessRecord r, long timeMillis, ApplicationErrorReport.CrashInfo crashInfo)8676     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8677             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8678         if (r.errorReportReceiver == null) {
8679             return null;
8680         }
8681 
8682         if (!r.crashing && !r.notResponding) {
8683             return null;
8684         }
8685 
8686         ApplicationErrorReport report = new ApplicationErrorReport();
8687         report.packageName = r.info.packageName;
8688         report.installerPackageName = r.errorReportReceiver.getPackageName();
8689         report.processName = r.processName;
8690         report.time = timeMillis;
8691         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8692 
8693         if (r.crashing) {
8694             report.type = ApplicationErrorReport.TYPE_CRASH;
8695             report.crashInfo = crashInfo;
8696         } else if (r.notResponding) {
8697             report.type = ApplicationErrorReport.TYPE_ANR;
8698             report.anrInfo = new ApplicationErrorReport.AnrInfo();
8699 
8700             report.anrInfo.activity = r.notRespondingReport.tag;
8701             report.anrInfo.cause = r.notRespondingReport.shortMsg;
8702             report.anrInfo.info = r.notRespondingReport.longMsg;
8703         }
8704 
8705         return report;
8706     }
8707 
getProcessesInErrorState()8708     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8709         enforceNotIsolatedCaller("getProcessesInErrorState");
8710         // assume our apps are happy - lazy create the list
8711         List<ActivityManager.ProcessErrorStateInfo> errList = null;
8712 
8713         final boolean allUsers = ActivityManager.checkUidPermission(
8714                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8715                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8716         int userId = UserHandle.getUserId(Binder.getCallingUid());
8717 
8718         synchronized (this) {
8719 
8720             // iterate across all processes
8721             for (int i=mLruProcesses.size()-1; i>=0; i--) {
8722                 ProcessRecord app = mLruProcesses.get(i);
8723                 if (!allUsers && app.userId != userId) {
8724                     continue;
8725                 }
8726                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
8727                     // This one's in trouble, so we'll generate a report for it
8728                     // crashes are higher priority (in case there's a crash *and* an anr)
8729                     ActivityManager.ProcessErrorStateInfo report = null;
8730                     if (app.crashing) {
8731                         report = app.crashingReport;
8732                     } else if (app.notResponding) {
8733                         report = app.notRespondingReport;
8734                     }
8735 
8736                     if (report != null) {
8737                         if (errList == null) {
8738                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8739                         }
8740                         errList.add(report);
8741                     } else {
8742                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
8743                                 " crashing = " + app.crashing +
8744                                 " notResponding = " + app.notResponding);
8745                     }
8746                 }
8747             }
8748         }
8749 
8750         return errList;
8751     }
8752 
oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp)8753     static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8754         if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8755             if (currApp != null) {
8756                 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8757             }
8758             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8759         } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8760             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8761         } else if (adj >= ProcessList.HOME_APP_ADJ) {
8762             if (currApp != null) {
8763                 currApp.lru = 0;
8764             }
8765             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8766         } else if (adj >= ProcessList.SERVICE_ADJ) {
8767             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8768         } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8769             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8770         } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8771             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8772         } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8773             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8774         } else {
8775             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8776         }
8777     }
8778 
fillInProcMemInfo(ProcessRecord app, ActivityManager.RunningAppProcessInfo outInfo)8779     private void fillInProcMemInfo(ProcessRecord app,
8780             ActivityManager.RunningAppProcessInfo outInfo) {
8781         outInfo.pid = app.pid;
8782         outInfo.uid = app.info.uid;
8783         if (mHeavyWeightProcess == app) {
8784             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8785         }
8786         if (app.persistent) {
8787             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8788         }
8789         if (app.hasActivities) {
8790             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8791         }
8792         outInfo.lastTrimLevel = app.trimMemoryLevel;
8793         int adj = app.curAdj;
8794         outInfo.importance = oomAdjToImportance(adj, outInfo);
8795         outInfo.importanceReasonCode = app.adjTypeCode;
8796     }
8797 
getRunningAppProcesses()8798     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8799         enforceNotIsolatedCaller("getRunningAppProcesses");
8800         // Lazy instantiation of list
8801         List<ActivityManager.RunningAppProcessInfo> runList = null;
8802         final boolean allUsers = ActivityManager.checkUidPermission(
8803                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8804                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8805         int userId = UserHandle.getUserId(Binder.getCallingUid());
8806         synchronized (this) {
8807             // Iterate across all processes
8808             for (int i=mLruProcesses.size()-1; i>=0; i--) {
8809                 ProcessRecord app = mLruProcesses.get(i);
8810                 if (!allUsers && app.userId != userId) {
8811                     continue;
8812                 }
8813                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8814                     // Generate process state info for running application
8815                     ActivityManager.RunningAppProcessInfo currApp =
8816                         new ActivityManager.RunningAppProcessInfo(app.processName,
8817                                 app.pid, app.getPackageList());
8818                     fillInProcMemInfo(app, currApp);
8819                     if (app.adjSource instanceof ProcessRecord) {
8820                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8821                         currApp.importanceReasonImportance = oomAdjToImportance(
8822                                 app.adjSourceOom, null);
8823                     } else if (app.adjSource instanceof ActivityRecord) {
8824                         ActivityRecord r = (ActivityRecord)app.adjSource;
8825                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8826                     }
8827                     if (app.adjTarget instanceof ComponentName) {
8828                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8829                     }
8830                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8831                     //        + " lru=" + currApp.lru);
8832                     if (runList == null) {
8833                         runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8834                     }
8835                     runList.add(currApp);
8836                 }
8837             }
8838         }
8839         return runList;
8840     }
8841 
getRunningExternalApplications()8842     public List<ApplicationInfo> getRunningExternalApplications() {
8843         enforceNotIsolatedCaller("getRunningExternalApplications");
8844         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8845         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8846         if (runningApps != null && runningApps.size() > 0) {
8847             Set<String> extList = new HashSet<String>();
8848             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8849                 if (app.pkgList != null) {
8850                     for (String pkg : app.pkgList) {
8851                         extList.add(pkg);
8852                     }
8853                 }
8854             }
8855             IPackageManager pm = AppGlobals.getPackageManager();
8856             for (String pkg : extList) {
8857                 try {
8858                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8859                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8860                         retList.add(info);
8861                     }
8862                 } catch (RemoteException e) {
8863                 }
8864             }
8865         }
8866         return retList;
8867     }
8868 
8869     @Override
getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo)8870     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8871         enforceNotIsolatedCaller("getMyMemoryState");
8872         synchronized (this) {
8873             ProcessRecord proc;
8874             synchronized (mPidsSelfLocked) {
8875                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
8876             }
8877             fillInProcMemInfo(proc, outInfo);
8878         }
8879     }
8880 
8881     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)8882     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8883         if (checkCallingPermission(android.Manifest.permission.DUMP)
8884                 != PackageManager.PERMISSION_GRANTED) {
8885             pw.println("Permission Denial: can't dump ActivityManager from from pid="
8886                     + Binder.getCallingPid()
8887                     + ", uid=" + Binder.getCallingUid()
8888                     + " without permission "
8889                     + android.Manifest.permission.DUMP);
8890             return;
8891         }
8892 
8893         boolean dumpAll = false;
8894         boolean dumpClient = false;
8895         String dumpPackage = null;
8896 
8897         int opti = 0;
8898         while (opti < args.length) {
8899             String opt = args[opti];
8900             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8901                 break;
8902             }
8903             opti++;
8904             if ("-a".equals(opt)) {
8905                 dumpAll = true;
8906             } else if ("-c".equals(opt)) {
8907                 dumpClient = true;
8908             } else if ("-h".equals(opt)) {
8909                 pw.println("Activity manager dump options:");
8910                 pw.println("  [-a] [-c] [-h] [cmd] ...");
8911                 pw.println("  cmd may be one of:");
8912                 pw.println("    a[ctivities]: activity stack state");
8913                 pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
8914                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8915                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8916                 pw.println("    o[om]: out of memory management");
8917                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8918                 pw.println("    provider [COMP_SPEC]: provider client-side state");
8919                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8920                 pw.println("    service [COMP_SPEC]: service client-side state");
8921                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
8922                 pw.println("    all: dump all activities");
8923                 pw.println("    top: dump the top activity");
8924                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8925                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8926                 pw.println("    a partial substring in a component name, a");
8927                 pw.println("    hex object identifier.");
8928                 pw.println("  -a: include all available server state.");
8929                 pw.println("  -c: include client state.");
8930                 return;
8931             } else {
8932                 pw.println("Unknown argument: " + opt + "; use -h for help");
8933             }
8934         }
8935 
8936         long origId = Binder.clearCallingIdentity();
8937         boolean more = false;
8938         // Is the caller requesting to dump a particular piece of data?
8939         if (opti < args.length) {
8940             String cmd = args[opti];
8941             opti++;
8942             if ("activities".equals(cmd) || "a".equals(cmd)) {
8943                 synchronized (this) {
8944                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8945                 }
8946             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8947                 String[] newArgs;
8948                 String name;
8949                 if (opti >= args.length) {
8950                     name = null;
8951                     newArgs = EMPTY_STRING_ARRAY;
8952                 } else {
8953                     name = args[opti];
8954                     opti++;
8955                     newArgs = new String[args.length - opti];
8956                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8957                             args.length - opti);
8958                 }
8959                 synchronized (this) {
8960                     dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8961                 }
8962             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8963                 String[] newArgs;
8964                 String name;
8965                 if (opti >= args.length) {
8966                     name = null;
8967                     newArgs = EMPTY_STRING_ARRAY;
8968                 } else {
8969                     name = args[opti];
8970                     opti++;
8971                     newArgs = new String[args.length - opti];
8972                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8973                             args.length - opti);
8974                 }
8975                 synchronized (this) {
8976                     dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8977                 }
8978             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8979                 String[] newArgs;
8980                 String name;
8981                 if (opti >= args.length) {
8982                     name = null;
8983                     newArgs = EMPTY_STRING_ARRAY;
8984                 } else {
8985                     name = args[opti];
8986                     opti++;
8987                     newArgs = new String[args.length - opti];
8988                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8989                             args.length - opti);
8990                 }
8991                 synchronized (this) {
8992                     dumpProcessesLocked(fd, pw, args, opti, true, name);
8993                 }
8994             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8995                 synchronized (this) {
8996                     dumpOomLocked(fd, pw, args, opti, true);
8997                 }
8998             } else if ("provider".equals(cmd)) {
8999                 String[] newArgs;
9000                 String name;
9001                 if (opti >= args.length) {
9002                     name = null;
9003                     newArgs = EMPTY_STRING_ARRAY;
9004                 } else {
9005                     name = args[opti];
9006                     opti++;
9007                     newArgs = new String[args.length - opti];
9008                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9009                 }
9010                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
9011                     pw.println("No providers match: " + name);
9012                     pw.println("Use -h for help.");
9013                 }
9014             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
9015                 synchronized (this) {
9016                     dumpProvidersLocked(fd, pw, args, opti, true, null);
9017                 }
9018             } else if ("service".equals(cmd)) {
9019                 String[] newArgs;
9020                 String name;
9021                 if (opti >= args.length) {
9022                     name = null;
9023                     newArgs = EMPTY_STRING_ARRAY;
9024                 } else {
9025                     name = args[opti];
9026                     opti++;
9027                     newArgs = new String[args.length - opti];
9028                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9029                             args.length - opti);
9030                 }
9031                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
9032                     pw.println("No services match: " + name);
9033                     pw.println("Use -h for help.");
9034                 }
9035             } else if ("package".equals(cmd)) {
9036                 String[] newArgs;
9037                 if (opti >= args.length) {
9038                     pw.println("package: no package name specified");
9039                     pw.println("Use -h for help.");
9040                 } else {
9041                     dumpPackage = args[opti];
9042                     opti++;
9043                     newArgs = new String[args.length - opti];
9044                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9045                             args.length - opti);
9046                     args = newArgs;
9047                     opti = 0;
9048                     more = true;
9049                 }
9050             } else if ("services".equals(cmd) || "s".equals(cmd)) {
9051                 synchronized (this) {
9052                     mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
9053                 }
9054             } else {
9055                 // Dumping a single activity?
9056                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
9057                     pw.println("Bad activity command, or no activities match: " + cmd);
9058                     pw.println("Use -h for help.");
9059                 }
9060             }
9061             if (!more) {
9062                 Binder.restoreCallingIdentity(origId);
9063                 return;
9064             }
9065         }
9066 
9067         // No piece of data specified, dump everything.
9068         synchronized (this) {
9069             boolean needSep;
9070             needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9071             if (needSep) {
9072                 pw.println(" ");
9073             }
9074             if (dumpAll) {
9075                 pw.println("-------------------------------------------------------------------------------");
9076             }
9077             needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9078             if (needSep) {
9079                 pw.println(" ");
9080             }
9081             if (dumpAll) {
9082                 pw.println("-------------------------------------------------------------------------------");
9083             }
9084             needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9085             if (needSep) {
9086                 pw.println(" ");
9087             }
9088             if (dumpAll) {
9089                 pw.println("-------------------------------------------------------------------------------");
9090             }
9091             needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9092             if (needSep) {
9093                 pw.println(" ");
9094             }
9095             if (dumpAll) {
9096                 pw.println("-------------------------------------------------------------------------------");
9097             }
9098             needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9099             if (needSep) {
9100                 pw.println(" ");
9101             }
9102             if (dumpAll) {
9103                 pw.println("-------------------------------------------------------------------------------");
9104             }
9105             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9106         }
9107         Binder.restoreCallingIdentity(origId);
9108     }
9109 
dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, boolean dumpClient, String dumpPackage)9110     boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9111             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
9112         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
9113         pw.println("  Main stack:");
9114         dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
9115                 dumpPackage);
9116         pw.println(" ");
9117         pw.println("  Running activities (most recent first):");
9118         dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
9119                 dumpPackage);
9120         if (mMainStack.mWaitingVisibleActivities.size() > 0) {
9121             pw.println(" ");
9122             pw.println("  Activities waiting for another to become visible:");
9123             dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
9124                     !dumpAll, false, dumpPackage);
9125         }
9126         if (mMainStack.mStoppingActivities.size() > 0) {
9127             pw.println(" ");
9128             pw.println("  Activities waiting to stop:");
9129             dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
9130                     !dumpAll, false, dumpPackage);
9131         }
9132         if (mMainStack.mGoingToSleepActivities.size() > 0) {
9133             pw.println(" ");
9134             pw.println("  Activities waiting to sleep:");
9135             dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
9136                     !dumpAll, false, dumpPackage);
9137         }
9138         if (mMainStack.mFinishingActivities.size() > 0) {
9139             pw.println(" ");
9140             pw.println("  Activities waiting to finish:");
9141             dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
9142                     !dumpAll, false, dumpPackage);
9143         }
9144 
9145         pw.println(" ");
9146         if (mMainStack.mPausingActivity != null) {
9147             pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
9148         }
9149         pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
9150         pw.println("  mFocusedActivity: " + mFocusedActivity);
9151         if (dumpAll) {
9152             pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9153             pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
9154             pw.println("  mDismissKeyguardOnNextActivity: "
9155                     + mMainStack.mDismissKeyguardOnNextActivity);
9156         }
9157 
9158         if (mRecentTasks.size() > 0) {
9159             pw.println();
9160             pw.println("  Recent tasks:");
9161 
9162             final int N = mRecentTasks.size();
9163             for (int i=0; i<N; i++) {
9164                 TaskRecord tr = mRecentTasks.get(i);
9165                 if (dumpPackage != null) {
9166                     if (tr.realActivity == null ||
9167                             !dumpPackage.equals(tr.realActivity)) {
9168                         continue;
9169                     }
9170                 }
9171                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9172                         pw.println(tr);
9173                 if (dumpAll) {
9174                     mRecentTasks.get(i).dump(pw, "    ");
9175                 }
9176             }
9177         }
9178 
9179         if (dumpAll) {
9180             pw.println(" ");
9181             pw.println("  mCurTask: " + mCurTask);
9182         }
9183 
9184         return true;
9185     }
9186 
dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)9187     boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9188             int opti, boolean dumpAll, String dumpPackage) {
9189         boolean needSep = false;
9190         int numPers = 0;
9191 
9192         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9193 
9194         if (dumpAll) {
9195             for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9196                 final int NA = procs.size();
9197                 for (int ia=0; ia<NA; ia++) {
9198                     ProcessRecord r = procs.valueAt(ia);
9199                     if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9200                         continue;
9201                     }
9202                     if (!needSep) {
9203                         pw.println("  All known processes:");
9204                         needSep = true;
9205                     }
9206                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9207                         pw.print(" UID "); pw.print(procs.keyAt(ia));
9208                         pw.print(" "); pw.println(r);
9209                     r.dump(pw, "    ");
9210                     if (r.persistent) {
9211                         numPers++;
9212                     }
9213                 }
9214             }
9215         }
9216 
9217         if (mIsolatedProcesses.size() > 0) {
9218             if (needSep) pw.println(" ");
9219             needSep = true;
9220             pw.println("  Isolated process list (sorted by uid):");
9221             for (int i=0; i<mIsolatedProcesses.size(); i++) {
9222                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
9223                 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9224                     continue;
9225                 }
9226                 pw.println(String.format("%sIsolated #%2d: %s",
9227                         "    ", i, r.toString()));
9228             }
9229         }
9230 
9231         if (mLruProcesses.size() > 0) {
9232             if (needSep) pw.println(" ");
9233             needSep = true;
9234             pw.println("  Process LRU list (sorted by oom_adj):");
9235             dumpProcessOomList(pw, this, mLruProcesses, "    ",
9236                     "Proc", "PERS", false, dumpPackage);
9237             needSep = true;
9238         }
9239 
9240         if (dumpAll) {
9241             synchronized (mPidsSelfLocked) {
9242                 boolean printed = false;
9243                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
9244                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
9245                     if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9246                         continue;
9247                     }
9248                     if (!printed) {
9249                         if (needSep) pw.println(" ");
9250                         needSep = true;
9251                         pw.println("  PID mappings:");
9252                         printed = true;
9253                     }
9254                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9255                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9256                 }
9257             }
9258         }
9259 
9260         if (mForegroundProcesses.size() > 0) {
9261             synchronized (mPidsSelfLocked) {
9262                 boolean printed = false;
9263                 for (int i=0; i<mForegroundProcesses.size(); i++) {
9264                     ProcessRecord r = mPidsSelfLocked.get(
9265                             mForegroundProcesses.valueAt(i).pid);
9266                     if (dumpPackage != null && (r == null
9267                             || !dumpPackage.equals(r.info.packageName))) {
9268                         continue;
9269                     }
9270                     if (!printed) {
9271                         if (needSep) pw.println(" ");
9272                         needSep = true;
9273                         pw.println("  Foreground Processes:");
9274                         printed = true;
9275                     }
9276                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9277                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9278                 }
9279             }
9280         }
9281 
9282         if (mPersistentStartingProcesses.size() > 0) {
9283             if (needSep) pw.println(" ");
9284             needSep = true;
9285             pw.println("  Persisent processes that are starting:");
9286             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9287                     "Starting Norm", "Restarting PERS", dumpPackage);
9288         }
9289 
9290         if (mRemovedProcesses.size() > 0) {
9291             if (needSep) pw.println(" ");
9292             needSep = true;
9293             pw.println("  Processes that are being removed:");
9294             dumpProcessList(pw, this, mRemovedProcesses, "    ",
9295                     "Removed Norm", "Removed PERS", dumpPackage);
9296         }
9297 
9298         if (mProcessesOnHold.size() > 0) {
9299             if (needSep) pw.println(" ");
9300             needSep = true;
9301             pw.println("  Processes that are on old until the system is ready:");
9302             dumpProcessList(pw, this, mProcessesOnHold, "    ",
9303                     "OnHold Norm", "OnHold PERS", dumpPackage);
9304         }
9305 
9306         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9307 
9308         if (mProcessCrashTimes.getMap().size() > 0) {
9309             boolean printed = false;
9310             long now = SystemClock.uptimeMillis();
9311             for (Map.Entry<String, SparseArray<Long>> procs
9312                     : mProcessCrashTimes.getMap().entrySet()) {
9313                 String pname = procs.getKey();
9314                 SparseArray<Long> uids = procs.getValue();
9315                 final int N = uids.size();
9316                 for (int i=0; i<N; i++) {
9317                     int puid = uids.keyAt(i);
9318                     ProcessRecord r = mProcessNames.get(pname, puid);
9319                     if (dumpPackage != null && (r == null
9320                             || !dumpPackage.equals(r.info.packageName))) {
9321                         continue;
9322                     }
9323                     if (!printed) {
9324                         if (needSep) pw.println(" ");
9325                         needSep = true;
9326                         pw.println("  Time since processes crashed:");
9327                         printed = true;
9328                     }
9329                     pw.print("    Process "); pw.print(pname);
9330                             pw.print(" uid "); pw.print(puid);
9331                             pw.print(": last crashed ");
9332                             TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9333                             pw.println(" ago");
9334                 }
9335             }
9336         }
9337 
9338         if (mBadProcesses.getMap().size() > 0) {
9339             boolean printed = false;
9340             for (Map.Entry<String, SparseArray<Long>> procs
9341                     : mBadProcesses.getMap().entrySet()) {
9342                 String pname = procs.getKey();
9343                 SparseArray<Long> uids = procs.getValue();
9344                 final int N = uids.size();
9345                 for (int i=0; i<N; i++) {
9346                     int puid = uids.keyAt(i);
9347                     ProcessRecord r = mProcessNames.get(pname, puid);
9348                     if (dumpPackage != null && (r == null
9349                             || !dumpPackage.equals(r.info.packageName))) {
9350                         continue;
9351                     }
9352                     if (!printed) {
9353                         if (needSep) pw.println(" ");
9354                         needSep = true;
9355                         pw.println("  Bad processes:");
9356                     }
9357                     pw.print("    Bad process "); pw.print(pname);
9358                             pw.print(" uid "); pw.print(puid);
9359                             pw.print(": crashed at time ");
9360                             pw.println(uids.valueAt(i));
9361                 }
9362             }
9363         }
9364 
9365         pw.println();
9366         pw.println("  mStartedUsers:");
9367         for (int i=0; i<mStartedUsers.size(); i++) {
9368             UserStartedState uss = mStartedUsers.valueAt(i);
9369             pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9370                     pw.print(": "); uss.dump("", pw);
9371         }
9372         pw.print("  mStartedUserArray: [");
9373         for (int i=0; i<mStartedUserArray.length; i++) {
9374             if (i > 0) pw.print(", ");
9375             pw.print(mStartedUserArray[i]);
9376         }
9377         pw.println("]");
9378         pw.print("  mUserLru: [");
9379         for (int i=0; i<mUserLru.size(); i++) {
9380             if (i > 0) pw.print(", ");
9381             pw.print(mUserLru.get(i));
9382         }
9383         pw.println("]");
9384         if (dumpAll) {
9385             pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
9386         }
9387         pw.println("  mHomeProcess: " + mHomeProcess);
9388         pw.println("  mPreviousProcess: " + mPreviousProcess);
9389         if (dumpAll) {
9390             StringBuilder sb = new StringBuilder(128);
9391             sb.append("  mPreviousProcessVisibleTime: ");
9392             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9393             pw.println(sb);
9394         }
9395         if (mHeavyWeightProcess != null) {
9396             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9397         }
9398         pw.println("  mConfiguration: " + mConfiguration);
9399         if (dumpAll) {
9400             pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9401             if (mCompatModePackages.getPackages().size() > 0) {
9402                 boolean printed = false;
9403                 for (Map.Entry<String, Integer> entry
9404                         : mCompatModePackages.getPackages().entrySet()) {
9405                     String pkg = entry.getKey();
9406                     int mode = entry.getValue();
9407                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9408                         continue;
9409                     }
9410                     if (!printed) {
9411                         pw.println("  mScreenCompatPackages:");
9412                         printed = true;
9413                     }
9414                     pw.print("    "); pw.print(pkg); pw.print(": ");
9415                             pw.print(mode); pw.println();
9416                 }
9417             }
9418         }
9419         if (mSleeping || mWentToSleep || mLockScreenShown) {
9420             pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9421                     + " mLockScreenShown " + mLockScreenShown);
9422         }
9423         if (mShuttingDown) {
9424             pw.println("  mShuttingDown=" + mShuttingDown);
9425         }
9426         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9427                 || mOrigWaitForDebugger) {
9428             pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9429                     + " mDebugTransient=" + mDebugTransient
9430                     + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9431         }
9432         if (mOpenGlTraceApp != null) {
9433             pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9434         }
9435         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9436                 || mProfileFd != null) {
9437             pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9438             pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9439             pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9440                     + mAutoStopProfiler);
9441         }
9442         if (mAlwaysFinishActivities || mController != null) {
9443             pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9444                     + " mController=" + mController);
9445         }
9446         if (dumpAll) {
9447             pw.println("  Total persistent processes: " + numPers);
9448             pw.println("  mStartRunning=" + mStartRunning
9449                     + " mProcessesReady=" + mProcessesReady
9450                     + " mSystemReady=" + mSystemReady);
9451             pw.println("  mBooting=" + mBooting
9452                     + " mBooted=" + mBooted
9453                     + " mFactoryTest=" + mFactoryTest);
9454             pw.print("  mLastPowerCheckRealtime=");
9455                     TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9456                     pw.println("");
9457             pw.print("  mLastPowerCheckUptime=");
9458                     TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9459                     pw.println("");
9460             pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9461             pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9462             pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9463             pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9464                     + " mNumHiddenProcs=" + mNumHiddenProcs
9465                     + " mNumServiceProcs=" + mNumServiceProcs
9466                     + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9467         }
9468 
9469         return true;
9470     }
9471 
dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean needSep, boolean dumpAll, String dumpPackage)9472     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9473             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9474         if (mProcessesToGc.size() > 0) {
9475             boolean printed = false;
9476             long now = SystemClock.uptimeMillis();
9477             for (int i=0; i<mProcessesToGc.size(); i++) {
9478                 ProcessRecord proc = mProcessesToGc.get(i);
9479                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9480                     continue;
9481                 }
9482                 if (!printed) {
9483                     if (needSep) pw.println(" ");
9484                     needSep = true;
9485                     pw.println("  Processes that are waiting to GC:");
9486                     printed = true;
9487                 }
9488                 pw.print("    Process "); pw.println(proc);
9489                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9490                         pw.print(", last gced=");
9491                         pw.print(now-proc.lastRequestedGc);
9492                         pw.print(" ms ago, last lowMem=");
9493                         pw.print(now-proc.lastLowMemory);
9494                         pw.println(" ms ago");
9495 
9496             }
9497         }
9498         return needSep;
9499     }
9500 
dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll)9501     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9502             int opti, boolean dumpAll) {
9503         boolean needSep = false;
9504 
9505         if (mLruProcesses.size() > 0) {
9506             if (needSep) pw.println(" ");
9507             needSep = true;
9508             pw.println("  OOM levels:");
9509             pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9510             pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9511             pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9512             pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9513             pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9514             pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9515             pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9516             pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9517             pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9518             pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9519             pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9520             pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9521             pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9522 
9523             if (needSep) pw.println(" ");
9524             needSep = true;
9525             pw.println("  Process OOM control:");
9526             dumpProcessOomList(pw, this, mLruProcesses, "    ",
9527                     "Proc", "PERS", true, null);
9528             needSep = true;
9529         }
9530 
9531         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9532 
9533         pw.println();
9534         pw.println("  mHomeProcess: " + mHomeProcess);
9535         pw.println("  mPreviousProcess: " + mPreviousProcess);
9536         if (mHeavyWeightProcess != null) {
9537             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9538         }
9539 
9540         return true;
9541     }
9542 
9543     /**
9544      * There are three ways to call this:
9545      *  - no provider specified: dump all the providers
9546      *  - a flattened component name that matched an existing provider was specified as the
9547      *    first arg: dump that one provider
9548      *  - the first arg isn't the flattened component name of an existing provider:
9549      *    dump all providers whose component contains the first arg as a substring
9550      */
dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, int opti, boolean dumpAll)9551     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9552             int opti, boolean dumpAll) {
9553         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9554     }
9555 
9556     static class ItemMatcher {
9557         ArrayList<ComponentName> components;
9558         ArrayList<String> strings;
9559         ArrayList<Integer> objects;
9560         boolean all;
9561 
ItemMatcher()9562         ItemMatcher() {
9563             all = true;
9564         }
9565 
build(String name)9566         void build(String name) {
9567             ComponentName componentName = ComponentName.unflattenFromString(name);
9568             if (componentName != null) {
9569                 if (components == null) {
9570                     components = new ArrayList<ComponentName>();
9571                 }
9572                 components.add(componentName);
9573                 all = false;
9574             } else {
9575                 int objectId = 0;
9576                 // Not a '/' separated full component name; maybe an object ID?
9577                 try {
9578                     objectId = Integer.parseInt(name, 16);
9579                     if (objects == null) {
9580                         objects = new ArrayList<Integer>();
9581                     }
9582                     objects.add(objectId);
9583                     all = false;
9584                 } catch (RuntimeException e) {
9585                     // Not an integer; just do string match.
9586                     if (strings == null) {
9587                         strings = new ArrayList<String>();
9588                     }
9589                     strings.add(name);
9590                     all = false;
9591                 }
9592             }
9593         }
9594 
build(String[] args, int opti)9595         int build(String[] args, int opti) {
9596             for (; opti<args.length; opti++) {
9597                 String name = args[opti];
9598                 if ("--".equals(name)) {
9599                     return opti+1;
9600                 }
9601                 build(name);
9602             }
9603             return opti;
9604         }
9605 
match(Object object, ComponentName comp)9606         boolean match(Object object, ComponentName comp) {
9607             if (all) {
9608                 return true;
9609             }
9610             if (components != null) {
9611                 for (int i=0; i<components.size(); i++) {
9612                     if (components.get(i).equals(comp)) {
9613                         return true;
9614                     }
9615                 }
9616             }
9617             if (objects != null) {
9618                 for (int i=0; i<objects.size(); i++) {
9619                     if (System.identityHashCode(object) == objects.get(i)) {
9620                         return true;
9621                     }
9622                 }
9623             }
9624             if (strings != null) {
9625                 String flat = comp.flattenToString();
9626                 for (int i=0; i<strings.size(); i++) {
9627                     if (flat.contains(strings.get(i))) {
9628                         return true;
9629                     }
9630                 }
9631             }
9632             return false;
9633         }
9634     }
9635 
9636     /**
9637      * There are three things that cmd can be:
9638      *  - a flattened component name that matches an existing activity
9639      *  - the cmd arg isn't the flattened component name of an existing activity:
9640      *    dump all activity whose component contains the cmd as a substring
9641      *  - A hex number of the ActivityRecord object instance.
9642      */
dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, int opti, boolean dumpAll)9643     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9644             int opti, boolean dumpAll) {
9645         ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9646 
9647         if ("all".equals(name)) {
9648             synchronized (this) {
9649                 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9650                     activities.add(r1);
9651                 }
9652             }
9653         } else if ("top".equals(name)) {
9654             synchronized (this) {
9655                 final int N = mMainStack.mHistory.size();
9656                 if (N > 0) {
9657                     activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9658                 }
9659             }
9660         } else {
9661             ItemMatcher matcher = new ItemMatcher();
9662             matcher.build(name);
9663 
9664             synchronized (this) {
9665                 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9666                     if (matcher.match(r1, r1.intent.getComponent())) {
9667                         activities.add(r1);
9668                     }
9669                 }
9670             }
9671         }
9672 
9673         if (activities.size() <= 0) {
9674             return false;
9675         }
9676 
9677         String[] newArgs = new String[args.length - opti];
9678         if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9679 
9680         TaskRecord lastTask = null;
9681         boolean needSep = false;
9682         for (int i=activities.size()-1; i>=0; i--) {
9683             ActivityRecord r = (ActivityRecord)activities.get(i);
9684             if (needSep) {
9685                 pw.println();
9686             }
9687             needSep = true;
9688             synchronized (this) {
9689                 if (lastTask != r.task) {
9690                     lastTask = r.task;
9691                     pw.print("TASK "); pw.print(lastTask.affinity);
9692                             pw.print(" id="); pw.println(lastTask.taskId);
9693                     if (dumpAll) {
9694                         lastTask.dump(pw, "  ");
9695                     }
9696                 }
9697             }
9698             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9699         }
9700         return true;
9701     }
9702 
9703     /**
9704      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9705      * there is a thread associated with the activity.
9706      */
dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, final ActivityRecord r, String[] args, boolean dumpAll)9707     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9708             final ActivityRecord r, String[] args, boolean dumpAll) {
9709         String innerPrefix = prefix + "  ";
9710         synchronized (this) {
9711             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9712                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9713                     pw.print(" pid=");
9714                     if (r.app != null) pw.println(r.app.pid);
9715                     else pw.println("(not running)");
9716             if (dumpAll) {
9717                 r.dump(pw, innerPrefix);
9718             }
9719         }
9720         if (r.app != null && r.app.thread != null) {
9721             // flush anything that is already in the PrintWriter since the thread is going
9722             // to write to the file descriptor directly
9723             pw.flush();
9724             try {
9725                 TransferPipe tp = new TransferPipe();
9726                 try {
9727                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9728                             r.appToken, innerPrefix, args);
9729                     tp.go(fd);
9730                 } finally {
9731                     tp.kill();
9732                 }
9733             } catch (IOException e) {
9734                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9735             } catch (RemoteException e) {
9736                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9737             }
9738         }
9739     }
9740 
dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)9741     boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9742             int opti, boolean dumpAll, String dumpPackage) {
9743         boolean needSep = false;
9744         boolean onlyHistory = false;
9745 
9746         if ("history".equals(dumpPackage)) {
9747             if (opti < args.length && "-s".equals(args[opti])) {
9748                 dumpAll = false;
9749             }
9750             onlyHistory = true;
9751             dumpPackage = null;
9752         }
9753 
9754         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9755         if (!onlyHistory && dumpAll) {
9756             if (mRegisteredReceivers.size() > 0) {
9757                 boolean printed = false;
9758                 Iterator it = mRegisteredReceivers.values().iterator();
9759                 while (it.hasNext()) {
9760                     ReceiverList r = (ReceiverList)it.next();
9761                     if (dumpPackage != null && (r.app == null ||
9762                             !dumpPackage.equals(r.app.info.packageName))) {
9763                         continue;
9764                     }
9765                     if (!printed) {
9766                         pw.println("  Registered Receivers:");
9767                         needSep = true;
9768                         printed = true;
9769                     }
9770                     pw.print("  * "); pw.println(r);
9771                     r.dump(pw, "    ");
9772                 }
9773             }
9774 
9775             if (mReceiverResolver.dump(pw, needSep ?
9776                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9777                     "    ", dumpPackage, false)) {
9778                 needSep = true;
9779             }
9780         }
9781 
9782         for (BroadcastQueue q : mBroadcastQueues) {
9783             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9784         }
9785 
9786         needSep = true;
9787 
9788         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9789             for (int user=0; user<mStickyBroadcasts.size(); user++) {
9790                 if (needSep) {
9791                     pw.println();
9792                 }
9793                 needSep = true;
9794                 pw.print("  Sticky broadcasts for user ");
9795                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
9796                 StringBuilder sb = new StringBuilder(128);
9797                 for (Map.Entry<String, ArrayList<Intent>> ent
9798                         : mStickyBroadcasts.valueAt(user).entrySet()) {
9799                     pw.print("  * Sticky action "); pw.print(ent.getKey());
9800                     if (dumpAll) {
9801                         pw.println(":");
9802                         ArrayList<Intent> intents = ent.getValue();
9803                         final int N = intents.size();
9804                         for (int i=0; i<N; i++) {
9805                             sb.setLength(0);
9806                             sb.append("    Intent: ");
9807                             intents.get(i).toShortString(sb, false, true, false, false);
9808                             pw.println(sb.toString());
9809                             Bundle bundle = intents.get(i).getExtras();
9810                             if (bundle != null) {
9811                                 pw.print("      ");
9812                                 pw.println(bundle.toString());
9813                             }
9814                         }
9815                     } else {
9816                         pw.println("");
9817                     }
9818                 }
9819             }
9820         }
9821 
9822         if (!onlyHistory && dumpAll) {
9823             pw.println();
9824             for (BroadcastQueue queue : mBroadcastQueues) {
9825                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9826                         + queue.mBroadcastsScheduled);
9827             }
9828             pw.println("  mHandler:");
9829             mHandler.dump(new PrintWriterPrinter(pw), "    ");
9830             needSep = true;
9831         }
9832 
9833         return needSep;
9834     }
9835 
dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)9836     boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9837             int opti, boolean dumpAll, String dumpPackage) {
9838         boolean needSep = true;
9839 
9840         ItemMatcher matcher = new ItemMatcher();
9841         matcher.build(args, opti);
9842 
9843         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9844 
9845         mProviderMap.dumpProvidersLocked(pw, dumpAll);
9846 
9847         if (mLaunchingProviders.size() > 0) {
9848             boolean printed = false;
9849             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9850                 ContentProviderRecord r = mLaunchingProviders.get(i);
9851                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9852                     continue;
9853                 }
9854                 if (!printed) {
9855                     if (needSep) pw.println(" ");
9856                     needSep = true;
9857                     pw.println("  Launching content providers:");
9858                     printed = true;
9859                 }
9860                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
9861                         pw.println(r);
9862             }
9863         }
9864 
9865         if (mGrantedUriPermissions.size() > 0) {
9866             if (needSep) pw.println();
9867             needSep = true;
9868             pw.println("Granted Uri Permissions:");
9869             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9870                 int uid = mGrantedUriPermissions.keyAt(i);
9871                 HashMap<Uri, UriPermission> perms
9872                         = mGrantedUriPermissions.valueAt(i);
9873                 pw.print("  * UID "); pw.print(uid);
9874                         pw.println(" holds:");
9875                 for (UriPermission perm : perms.values()) {
9876                     pw.print("    "); pw.println(perm);
9877                     if (dumpAll) {
9878                         perm.dump(pw, "      ");
9879                     }
9880                 }
9881             }
9882             needSep = true;
9883         }
9884 
9885         return needSep;
9886     }
9887 
dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)9888     boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9889             int opti, boolean dumpAll, String dumpPackage) {
9890         boolean needSep = false;
9891 
9892         if (mIntentSenderRecords.size() > 0) {
9893             boolean printed = false;
9894             Iterator<WeakReference<PendingIntentRecord>> it
9895                     = mIntentSenderRecords.values().iterator();
9896             while (it.hasNext()) {
9897                 WeakReference<PendingIntentRecord> ref = it.next();
9898                 PendingIntentRecord rec = ref != null ? ref.get(): null;
9899                 if (dumpPackage != null && (rec == null
9900                         || !dumpPackage.equals(rec.key.packageName))) {
9901                     continue;
9902                 }
9903                 if (!printed) {
9904                     pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9905                     printed = true;
9906                 }
9907                 needSep = true;
9908                 if (rec != null) {
9909                     pw.print("  * "); pw.println(rec);
9910                     if (dumpAll) {
9911                         rec.dump(pw, "    ");
9912                     }
9913                 } else {
9914                     pw.print("  * "); pw.println(ref);
9915                 }
9916             }
9917         }
9918 
9919         return needSep;
9920     }
9921 
dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, String prefix, String label, boolean complete, boolean brief, boolean client, String dumpPackage)9922     private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9923             String prefix, String label, boolean complete, boolean brief, boolean client,
9924             String dumpPackage) {
9925         TaskRecord lastTask = null;
9926         boolean needNL = false;
9927         final String innerPrefix = prefix + "      ";
9928         final String[] args = new String[0];
9929         for (int i=list.size()-1; i>=0; i--) {
9930             final ActivityRecord r = (ActivityRecord)list.get(i);
9931             if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9932                 continue;
9933             }
9934             final boolean full = !brief && (complete || !r.isInHistory());
9935             if (needNL) {
9936                 pw.println(" ");
9937                 needNL = false;
9938             }
9939             if (lastTask != r.task) {
9940                 lastTask = r.task;
9941                 pw.print(prefix);
9942                 pw.print(full ? "* " : "  ");
9943                 pw.println(lastTask);
9944                 if (full) {
9945                     lastTask.dump(pw, prefix + "  ");
9946                 } else if (complete) {
9947                     // Complete + brief == give a summary.  Isn't that obvious?!?
9948                     if (lastTask.intent != null) {
9949                         pw.print(prefix); pw.print("  ");
9950                                 pw.println(lastTask.intent.toInsecureStringWithClip());
9951                     }
9952                 }
9953             }
9954             pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9955             pw.print(" #"); pw.print(i); pw.print(": ");
9956             pw.println(r);
9957             if (full) {
9958                 r.dump(pw, innerPrefix);
9959             } else if (complete) {
9960                 // Complete + brief == give a summary.  Isn't that obvious?!?
9961                 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9962                 if (r.app != null) {
9963                     pw.print(innerPrefix); pw.println(r.app);
9964                 }
9965             }
9966             if (client && r.app != null && r.app.thread != null) {
9967                 // flush anything that is already in the PrintWriter since the thread is going
9968                 // to write to the file descriptor directly
9969                 pw.flush();
9970                 try {
9971                     TransferPipe tp = new TransferPipe();
9972                     try {
9973                         r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9974                                 r.appToken, innerPrefix, args);
9975                         // Short timeout, since blocking here can
9976                         // deadlock with the application.
9977                         tp.go(fd, 2000);
9978                     } finally {
9979                         tp.kill();
9980                     }
9981                 } catch (IOException e) {
9982                     pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9983                 } catch (RemoteException e) {
9984                     pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9985                 }
9986                 needNL = true;
9987             }
9988         }
9989     }
9990 
buildOomTag(String prefix, String space, int val, int base)9991     private static String buildOomTag(String prefix, String space, int val, int base) {
9992         if (val == base) {
9993             if (space == null) return prefix;
9994             return prefix + "  ";
9995         }
9996         return prefix + "+" + Integer.toString(val-base);
9997     }
9998 
dumpProcessList(PrintWriter pw, ActivityManagerService service, List list, String prefix, String normalLabel, String persistentLabel, String dumpPackage)9999     private static final int dumpProcessList(PrintWriter pw,
10000             ActivityManagerService service, List list,
10001             String prefix, String normalLabel, String persistentLabel,
10002             String dumpPackage) {
10003         int numPers = 0;
10004         final int N = list.size()-1;
10005         for (int i=N; i>=0; i--) {
10006             ProcessRecord r = (ProcessRecord)list.get(i);
10007             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10008                 continue;
10009             }
10010             pw.println(String.format("%s%s #%2d: %s",
10011                     prefix, (r.persistent ? persistentLabel : normalLabel),
10012                     i, r.toString()));
10013             if (r.persistent) {
10014                 numPers++;
10015             }
10016         }
10017         return numPers;
10018     }
10019 
dumpProcessOomList(PrintWriter pw, ActivityManagerService service, List<ProcessRecord> origList, String prefix, String normalLabel, String persistentLabel, boolean inclDetails, String dumpPackage)10020     private static final boolean dumpProcessOomList(PrintWriter pw,
10021             ActivityManagerService service, List<ProcessRecord> origList,
10022             String prefix, String normalLabel, String persistentLabel,
10023             boolean inclDetails, String dumpPackage) {
10024 
10025         ArrayList<Pair<ProcessRecord, Integer>> list
10026                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
10027         for (int i=0; i<origList.size(); i++) {
10028             ProcessRecord r = origList.get(i);
10029             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10030                 continue;
10031             }
10032             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
10033         }
10034 
10035         if (list.size() <= 0) {
10036             return false;
10037         }
10038 
10039         Comparator<Pair<ProcessRecord, Integer>> comparator
10040                 = new Comparator<Pair<ProcessRecord, Integer>>() {
10041             @Override
10042             public int compare(Pair<ProcessRecord, Integer> object1,
10043                     Pair<ProcessRecord, Integer> object2) {
10044                 if (object1.first.setAdj != object2.first.setAdj) {
10045                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
10046                 }
10047                 if (object1.second.intValue() != object2.second.intValue()) {
10048                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
10049                 }
10050                 return 0;
10051             }
10052         };
10053 
10054         Collections.sort(list, comparator);
10055 
10056         final long curRealtime = SystemClock.elapsedRealtime();
10057         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
10058         final long curUptime = SystemClock.uptimeMillis();
10059         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
10060 
10061         for (int i=list.size()-1; i>=0; i--) {
10062             ProcessRecord r = list.get(i).first;
10063             String oomAdj;
10064             if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
10065                 oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
10066             } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
10067                 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
10068             } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
10069                 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
10070             } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
10071                 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
10072             } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10073                 oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
10074             } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
10075                 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
10076             } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10077                 oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10078             } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10079                 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10080             } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10081                 oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10082             } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10083                 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
10084             } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10085                 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
10086             } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10087                 oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
10088             } else {
10089                 oomAdj = Integer.toString(r.setAdj);
10090             }
10091             String schedGroup;
10092             switch (r.setSchedGroup) {
10093                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10094                     schedGroup = "B";
10095                     break;
10096                 case Process.THREAD_GROUP_DEFAULT:
10097                     schedGroup = "F";
10098                     break;
10099                 default:
10100                     schedGroup = Integer.toString(r.setSchedGroup);
10101                     break;
10102             }
10103             String foreground;
10104             if (r.foregroundActivities) {
10105                 foreground = "A";
10106             } else if (r.foregroundServices) {
10107                 foreground = "S";
10108             } else {
10109                 foreground = " ";
10110             }
10111             pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
10112                     prefix, (r.persistent ? persistentLabel : normalLabel),
10113                     (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10114                     foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
10115             if (r.adjSource != null || r.adjTarget != null) {
10116                 pw.print(prefix);
10117                 pw.print("    ");
10118                 if (r.adjTarget instanceof ComponentName) {
10119                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10120                 } else if (r.adjTarget != null) {
10121                     pw.print(r.adjTarget.toString());
10122                 } else {
10123                     pw.print("{null}");
10124                 }
10125                 pw.print("<=");
10126                 if (r.adjSource instanceof ProcessRecord) {
10127                     pw.print("Proc{");
10128                     pw.print(((ProcessRecord)r.adjSource).toShortString());
10129                     pw.println("}");
10130                 } else if (r.adjSource != null) {
10131                     pw.println(r.adjSource.toString());
10132                 } else {
10133                     pw.println("{null}");
10134                 }
10135             }
10136             if (inclDetails) {
10137                 pw.print(prefix);
10138                 pw.print("    ");
10139                 pw.print("oom: max="); pw.print(r.maxAdj);
10140                 pw.print(" hidden="); pw.print(r.hiddenAdj);
10141                 pw.print(" client="); pw.print(r.clientHiddenAdj);
10142                 pw.print(" empty="); pw.print(r.emptyAdj);
10143                 pw.print(" curRaw="); pw.print(r.curRawAdj);
10144                 pw.print(" setRaw="); pw.print(r.setRawAdj);
10145                 pw.print(" cur="); pw.print(r.curAdj);
10146                 pw.print(" set="); pw.println(r.setAdj);
10147                 pw.print(prefix);
10148                 pw.print("    ");
10149                 pw.print("keeping="); pw.print(r.keeping);
10150                 pw.print(" hidden="); pw.print(r.hidden);
10151                 pw.print(" empty="); pw.print(r.empty);
10152                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
10153 
10154                 if (!r.keeping) {
10155                     if (r.lastWakeTime != 0) {
10156                         long wtime;
10157                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10158                         synchronized (stats) {
10159                             wtime = stats.getProcessWakeTime(r.info.uid,
10160                                     r.pid, curRealtime);
10161                         }
10162                         long timeUsed = wtime - r.lastWakeTime;
10163                         pw.print(prefix);
10164                         pw.print("    ");
10165                         pw.print("keep awake over ");
10166                         TimeUtils.formatDuration(realtimeSince, pw);
10167                         pw.print(" used ");
10168                         TimeUtils.formatDuration(timeUsed, pw);
10169                         pw.print(" (");
10170                         pw.print((timeUsed*100)/realtimeSince);
10171                         pw.println("%)");
10172                     }
10173                     if (r.lastCpuTime != 0) {
10174                         long timeUsed = r.curCpuTime - r.lastCpuTime;
10175                         pw.print(prefix);
10176                         pw.print("    ");
10177                         pw.print("run cpu over ");
10178                         TimeUtils.formatDuration(uptimeSince, pw);
10179                         pw.print(" used ");
10180                         TimeUtils.formatDuration(timeUsed, pw);
10181                         pw.print(" (");
10182                         pw.print((timeUsed*100)/uptimeSince);
10183                         pw.println("%)");
10184                     }
10185                 }
10186             }
10187         }
10188         return true;
10189     }
10190 
collectProcesses(PrintWriter pw, int start, String[] args)10191     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10192         ArrayList<ProcessRecord> procs;
10193         synchronized (this) {
10194             if (args != null && args.length > start
10195                     && args[start].charAt(0) != '-') {
10196                 procs = new ArrayList<ProcessRecord>();
10197                 int pid = -1;
10198                 try {
10199                     pid = Integer.parseInt(args[start]);
10200                 } catch (NumberFormatException e) {
10201 
10202                 }
10203                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
10204                     ProcessRecord proc = mLruProcesses.get(i);
10205                     if (proc.pid == pid) {
10206                         procs.add(proc);
10207                     } else if (proc.processName.equals(args[start])) {
10208                         procs.add(proc);
10209                     }
10210                 }
10211                 if (procs.size() <= 0) {
10212                     pw.println("No process found for: " + args[start]);
10213                     return null;
10214                 }
10215             } else {
10216                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
10217             }
10218         }
10219         return procs;
10220     }
10221 
dumpGraphicsHardwareUsage(FileDescriptor fd, PrintWriter pw, String[] args)10222     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10223             PrintWriter pw, String[] args) {
10224         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10225         if (procs == null) {
10226             return;
10227         }
10228 
10229         long uptime = SystemClock.uptimeMillis();
10230         long realtime = SystemClock.elapsedRealtime();
10231         pw.println("Applications Graphics Acceleration Info:");
10232         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10233 
10234         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10235             ProcessRecord r = procs.get(i);
10236             if (r.thread != null) {
10237                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10238                 pw.flush();
10239                 try {
10240                     TransferPipe tp = new TransferPipe();
10241                     try {
10242                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10243                         tp.go(fd);
10244                     } finally {
10245                         tp.kill();
10246                     }
10247                 } catch (IOException e) {
10248                     pw.println("Failure while dumping the app: " + r);
10249                     pw.flush();
10250                 } catch (RemoteException e) {
10251                     pw.println("Got a RemoteException while dumping the app " + r);
10252                     pw.flush();
10253                 }
10254             }
10255         }
10256     }
10257 
dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args)10258     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10259         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10260         if (procs == null) {
10261             return;
10262         }
10263 
10264         pw.println("Applications Database Info:");
10265 
10266         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10267             ProcessRecord r = procs.get(i);
10268             if (r.thread != null) {
10269                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10270                 pw.flush();
10271                 try {
10272                     TransferPipe tp = new TransferPipe();
10273                     try {
10274                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10275                         tp.go(fd);
10276                     } finally {
10277                         tp.kill();
10278                     }
10279                 } catch (IOException e) {
10280                     pw.println("Failure while dumping the app: " + r);
10281                     pw.flush();
10282                 } catch (RemoteException e) {
10283                     pw.println("Got a RemoteException while dumping the app " + r);
10284                     pw.flush();
10285                 }
10286             }
10287         }
10288     }
10289 
10290     final static class MemItem {
10291         final String label;
10292         final String shortLabel;
10293         final long pss;
10294         final int id;
10295         ArrayList<MemItem> subitems;
10296 
MemItem(String _label, String _shortLabel, long _pss, int _id)10297         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10298             label = _label;
10299             shortLabel = _shortLabel;
10300             pss = _pss;
10301             id = _id;
10302         }
10303     }
10304 
dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, boolean sort)10305     static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10306             boolean sort) {
10307         if (sort) {
10308             Collections.sort(items, new Comparator<MemItem>() {
10309                 @Override
10310                 public int compare(MemItem lhs, MemItem rhs) {
10311                     if (lhs.pss < rhs.pss) {
10312                         return 1;
10313                     } else if (lhs.pss > rhs.pss) {
10314                         return -1;
10315                     }
10316                     return 0;
10317                 }
10318             });
10319         }
10320 
10321         for (int i=0; i<items.size(); i++) {
10322             MemItem mi = items.get(i);
10323             pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10324             if (mi.subitems != null) {
10325                 dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10326             }
10327         }
10328     }
10329 
10330     // These are in KB.
10331     static final long[] DUMP_MEM_BUCKETS = new long[] {
10332         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10333         120*1024, 160*1024, 200*1024,
10334         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10335         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10336     };
10337 
appendMemBucket(StringBuilder out, long memKB, String label, boolean stackLike)10338     static final void appendMemBucket(StringBuilder out, long memKB, String label,
10339             boolean stackLike) {
10340         int start = label.lastIndexOf('.');
10341         if (start >= 0) start++;
10342         else start = 0;
10343         int end = label.length();
10344         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10345             if (DUMP_MEM_BUCKETS[i] >= memKB) {
10346                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
10347                 out.append(bucket);
10348                 out.append(stackLike ? "MB." : "MB ");
10349                 out.append(label, start, end);
10350                 return;
10351             }
10352         }
10353         out.append(memKB/1024);
10354         out.append(stackLike ? "MB." : "MB ");
10355         out.append(label, start, end);
10356     }
10357 
10358     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10359             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10360             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10361             ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10362             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10363     };
10364     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10365             "System", "Persistent", "Foreground",
10366             "Visible", "Perceptible", "Heavy Weight",
10367             "Backup", "A Services", "Home", "Previous",
10368             "B Services", "Background"
10369     };
10370 
dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack)10371     final void dumpApplicationMemoryUsage(FileDescriptor fd,
10372             PrintWriter pw, String prefix, String[] args, boolean brief,
10373             PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10374         boolean dumpAll = false;
10375         boolean oomOnly = false;
10376 
10377         int opti = 0;
10378         while (opti < args.length) {
10379             String opt = args[opti];
10380             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10381                 break;
10382             }
10383             opti++;
10384             if ("-a".equals(opt)) {
10385                 dumpAll = true;
10386             } else if ("--oom".equals(opt)) {
10387                 oomOnly = true;
10388             } else if ("-h".equals(opt)) {
10389                 pw.println("meminfo dump options: [-a] [--oom] [process]");
10390                 pw.println("  -a: include all available information for each process.");
10391                 pw.println("  --oom: only show processes organized by oom adj.");
10392                 pw.println("If [process] is specified it can be the name or ");
10393                 pw.println("pid of a specific process to dump.");
10394                 return;
10395             } else {
10396                 pw.println("Unknown argument: " + opt + "; use -h for help");
10397             }
10398         }
10399 
10400         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10401         if (procs == null) {
10402             return;
10403         }
10404 
10405         final boolean isCheckinRequest = scanArgs(args, "--checkin");
10406         long uptime = SystemClock.uptimeMillis();
10407         long realtime = SystemClock.elapsedRealtime();
10408 
10409         if (procs.size() == 1 || isCheckinRequest) {
10410             dumpAll = true;
10411         }
10412 
10413         if (isCheckinRequest) {
10414             // short checkin version
10415             pw.println(uptime + "," + realtime);
10416             pw.flush();
10417         } else {
10418             pw.println("Applications Memory Usage (kB):");
10419             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10420         }
10421 
10422         String[] innerArgs = new String[args.length-opti];
10423         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10424 
10425         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10426         long nativePss=0, dalvikPss=0, otherPss=0;
10427         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10428 
10429         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10430         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10431                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
10432 
10433         long totalPss = 0;
10434 
10435         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10436             ProcessRecord r = procs.get(i);
10437             if (r.thread != null) {
10438                 if (!isCheckinRequest && dumpAll) {
10439                     pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10440                     pw.flush();
10441                 }
10442                 Debug.MemoryInfo mi = null;
10443                 if (dumpAll) {
10444                     try {
10445                         mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10446                     } catch (RemoteException e) {
10447                         if (!isCheckinRequest) {
10448                             pw.println("Got RemoteException!");
10449                             pw.flush();
10450                         }
10451                     }
10452                 } else {
10453                     mi = new Debug.MemoryInfo();
10454                     Debug.getMemoryInfo(r.pid, mi);
10455                 }
10456 
10457                 if (!isCheckinRequest && mi != null) {
10458                     long myTotalPss = mi.getTotalPss();
10459                     totalPss += myTotalPss;
10460                     MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10461                             r.processName, myTotalPss, 0);
10462                     procMems.add(pssItem);
10463 
10464                     nativePss += mi.nativePss;
10465                     dalvikPss += mi.dalvikPss;
10466                     otherPss += mi.otherPss;
10467                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10468                         long mem = mi.getOtherPss(j);
10469                         miscPss[j] += mem;
10470                         otherPss -= mem;
10471                     }
10472 
10473                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10474                         if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10475                                 || oomIndex == (oomPss.length-1)) {
10476                             oomPss[oomIndex] += myTotalPss;
10477                             if (oomProcs[oomIndex] == null) {
10478                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
10479                             }
10480                             oomProcs[oomIndex].add(pssItem);
10481                             break;
10482                         }
10483                     }
10484                 }
10485             }
10486         }
10487 
10488         if (!isCheckinRequest && procs.size() > 1) {
10489             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10490 
10491             catMems.add(new MemItem("Native", "Native", nativePss, -1));
10492             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10493             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10494             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10495                 String label = Debug.MemoryInfo.getOtherLabel(j);
10496                 catMems.add(new MemItem(label, label, miscPss[j], j));
10497             }
10498 
10499             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10500             for (int j=0; j<oomPss.length; j++) {
10501                 if (oomPss[j] != 0) {
10502                     String label = DUMP_MEM_OOM_LABEL[j];
10503                     MemItem item = new MemItem(label, label, oomPss[j],
10504                             DUMP_MEM_OOM_ADJ[j]);
10505                     item.subitems = oomProcs[j];
10506                     oomMems.add(item);
10507                 }
10508             }
10509 
10510             if (outTag != null || outStack != null) {
10511                 if (outTag != null) {
10512                     appendMemBucket(outTag, totalPss, "total", false);
10513                 }
10514                 if (outStack != null) {
10515                     appendMemBucket(outStack, totalPss, "total", true);
10516                 }
10517                 boolean firstLine = true;
10518                 for (int i=0; i<oomMems.size(); i++) {
10519                     MemItem miCat = oomMems.get(i);
10520                     if (miCat.subitems == null || miCat.subitems.size() < 1) {
10521                         continue;
10522                     }
10523                     if (miCat.id < ProcessList.SERVICE_ADJ
10524                             || miCat.id == ProcessList.HOME_APP_ADJ
10525                             || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10526                         if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10527                             outTag.append(" / ");
10528                         }
10529                         if (outStack != null) {
10530                             if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10531                                 if (firstLine) {
10532                                     outStack.append(":");
10533                                     firstLine = false;
10534                                 }
10535                                 outStack.append("\n\t at ");
10536                             } else {
10537                                 outStack.append("$");
10538                             }
10539                         }
10540                         for (int j=0; j<miCat.subitems.size(); j++) {
10541                             MemItem mi = miCat.subitems.get(j);
10542                             if (j > 0) {
10543                                 if (outTag != null) {
10544                                     outTag.append(" ");
10545                                 }
10546                                 if (outStack != null) {
10547                                     outStack.append("$");
10548                                 }
10549                             }
10550                             if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10551                                 appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10552                             }
10553                             if (outStack != null) {
10554                                 appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10555                             }
10556                         }
10557                         if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10558                             outStack.append("(");
10559                             for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10560                                 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10561                                     outStack.append(DUMP_MEM_OOM_LABEL[k]);
10562                                     outStack.append(":");
10563                                     outStack.append(DUMP_MEM_OOM_ADJ[k]);
10564                                 }
10565                             }
10566                             outStack.append(")");
10567                         }
10568                     }
10569                 }
10570             }
10571 
10572             if (!brief && !oomOnly) {
10573                 pw.println();
10574                 pw.println("Total PSS by process:");
10575                 dumpMemItems(pw, "  ", procMems, true);
10576                 pw.println();
10577             }
10578             pw.println("Total PSS by OOM adjustment:");
10579             dumpMemItems(pw, "  ", oomMems, false);
10580             if (!oomOnly) {
10581                 PrintWriter out = categoryPw != null ? categoryPw : pw;
10582                 out.println();
10583                 out.println("Total PSS by category:");
10584                 dumpMemItems(out, "  ", catMems, true);
10585             }
10586             pw.println();
10587             pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10588             final int[] SINGLE_LONG_FORMAT = new int[] {
10589                 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10590             };
10591             long[] longOut = new long[1];
10592             Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10593                     SINGLE_LONG_FORMAT, null, longOut, null);
10594             long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10595             longOut[0] = 0;
10596             Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10597                     SINGLE_LONG_FORMAT, null, longOut, null);
10598             long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10599             longOut[0] = 0;
10600             Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10601                     SINGLE_LONG_FORMAT, null, longOut, null);
10602             long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10603             longOut[0] = 0;
10604             Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10605                     SINGLE_LONG_FORMAT, null, longOut, null);
10606             long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10607             pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10608                     pw.print(shared); pw.println(" kB");
10609             pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10610                     pw.print(voltile); pw.println(" kB volatile");
10611         }
10612     }
10613 
10614     /**
10615      * Searches array of arguments for the specified string
10616      * @param args array of argument strings
10617      * @param value value to search for
10618      * @return true if the value is contained in the array
10619      */
scanArgs(String[] args, String value)10620     private static boolean scanArgs(String[] args, String value) {
10621         if (args != null) {
10622             for (String arg : args) {
10623                 if (value.equals(arg)) {
10624                     return true;
10625                 }
10626             }
10627         }
10628         return false;
10629     }
10630 
removeDyingProviderLocked(ProcessRecord proc, ContentProviderRecord cpr, boolean always)10631     private final boolean removeDyingProviderLocked(ProcessRecord proc,
10632             ContentProviderRecord cpr, boolean always) {
10633         final boolean inLaunching = mLaunchingProviders.contains(cpr);
10634 
10635         if (!inLaunching || always) {
10636             synchronized (cpr) {
10637                 cpr.launchingApp = null;
10638                 cpr.notifyAll();
10639             }
10640             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10641             String names[] = cpr.info.authority.split(";");
10642             for (int j = 0; j < names.length; j++) {
10643                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10644             }
10645         }
10646 
10647         for (int i=0; i<cpr.connections.size(); i++) {
10648             ContentProviderConnection conn = cpr.connections.get(i);
10649             if (conn.waiting) {
10650                 // If this connection is waiting for the provider, then we don't
10651                 // need to mess with its process unless we are always removing
10652                 // or for some reason the provider is not currently launching.
10653                 if (inLaunching && !always) {
10654                     continue;
10655                 }
10656             }
10657             ProcessRecord capp = conn.client;
10658             conn.dead = true;
10659             if (conn.stableCount > 0) {
10660                 if (!capp.persistent && capp.thread != null
10661                         && capp.pid != 0
10662                         && capp.pid != MY_PID) {
10663                     Slog.i(TAG, "Kill " + capp.processName
10664                             + " (pid " + capp.pid + "): provider " + cpr.info.name
10665                             + " in dying process " + (proc != null ? proc.processName : "??"));
10666                     EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid,
10667                             capp.processName, capp.setAdj, "dying provider "
10668                                     + cpr.name.toShortString());
10669                     Process.killProcessQuiet(capp.pid);
10670                 }
10671             } else if (capp.thread != null && conn.provider.provider != null) {
10672                 try {
10673                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10674                 } catch (RemoteException e) {
10675                 }
10676                 // In the protocol here, we don't expect the client to correctly
10677                 // clean up this connection, we'll just remove it.
10678                 cpr.connections.remove(i);
10679                 conn.client.conProviders.remove(conn);
10680             }
10681         }
10682 
10683         if (inLaunching && always) {
10684             mLaunchingProviders.remove(cpr);
10685         }
10686         return inLaunching;
10687     }
10688 
10689     /**
10690      * Main code for cleaning up a process when it has gone away.  This is
10691      * called both as a result of the process dying, or directly when stopping
10692      * a process when running in single process mode.
10693      */
cleanUpApplicationRecordLocked(ProcessRecord app, boolean restarting, boolean allowRestart, int index)10694     private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10695             boolean restarting, boolean allowRestart, int index) {
10696         if (index >= 0) {
10697             mLruProcesses.remove(index);
10698         }
10699 
10700         mProcessesToGc.remove(app);
10701 
10702         // Dismiss any open dialogs.
10703         if (app.crashDialog != null) {
10704             app.crashDialog.dismiss();
10705             app.crashDialog = null;
10706         }
10707         if (app.anrDialog != null) {
10708             app.anrDialog.dismiss();
10709             app.anrDialog = null;
10710         }
10711         if (app.waitDialog != null) {
10712             app.waitDialog.dismiss();
10713             app.waitDialog = null;
10714         }
10715 
10716         app.crashing = false;
10717         app.notResponding = false;
10718 
10719         app.resetPackageList();
10720         app.unlinkDeathRecipient();
10721         app.thread = null;
10722         app.forcingToForeground = null;
10723         app.foregroundServices = false;
10724         app.foregroundActivities = false;
10725         app.hasShownUi = false;
10726         app.hasAboveClient = false;
10727 
10728         mServices.killServicesLocked(app, allowRestart);
10729 
10730         boolean restart = false;
10731 
10732         // Remove published content providers.
10733         if (!app.pubProviders.isEmpty()) {
10734             Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10735             while (it.hasNext()) {
10736                 ContentProviderRecord cpr = it.next();
10737 
10738                 final boolean always = app.bad || !allowRestart;
10739                 if (removeDyingProviderLocked(app, cpr, always) || always) {
10740                     // We left the provider in the launching list, need to
10741                     // restart it.
10742                     restart = true;
10743                 }
10744 
10745                 cpr.provider = null;
10746                 cpr.proc = null;
10747             }
10748             app.pubProviders.clear();
10749         }
10750 
10751         // Take care of any launching providers waiting for this process.
10752         if (checkAppInLaunchingProvidersLocked(app, false)) {
10753             restart = true;
10754         }
10755 
10756         // Unregister from connected content providers.
10757         if (!app.conProviders.isEmpty()) {
10758             for (int i=0; i<app.conProviders.size(); i++) {
10759                 ContentProviderConnection conn = app.conProviders.get(i);
10760                 conn.provider.connections.remove(conn);
10761             }
10762             app.conProviders.clear();
10763         }
10764 
10765         // At this point there may be remaining entries in mLaunchingProviders
10766         // where we were the only one waiting, so they are no longer of use.
10767         // Look for these and clean up if found.
10768         // XXX Commented out for now.  Trying to figure out a way to reproduce
10769         // the actual situation to identify what is actually going on.
10770         if (false) {
10771             for (int i=0; i<mLaunchingProviders.size(); i++) {
10772                 ContentProviderRecord cpr = (ContentProviderRecord)
10773                         mLaunchingProviders.get(i);
10774                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10775                     synchronized (cpr) {
10776                         cpr.launchingApp = null;
10777                         cpr.notifyAll();
10778                     }
10779                 }
10780             }
10781         }
10782 
10783         skipCurrentReceiverLocked(app);
10784 
10785         // Unregister any receivers.
10786         if (app.receivers.size() > 0) {
10787             Iterator<ReceiverList> it = app.receivers.iterator();
10788             while (it.hasNext()) {
10789                 removeReceiverLocked(it.next());
10790             }
10791             app.receivers.clear();
10792         }
10793 
10794         // If the app is undergoing backup, tell the backup manager about it
10795         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10796             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
10797                     + mBackupTarget.appInfo + " died during backup");
10798             try {
10799                 IBackupManager bm = IBackupManager.Stub.asInterface(
10800                         ServiceManager.getService(Context.BACKUP_SERVICE));
10801                 bm.agentDisconnected(app.info.packageName);
10802             } catch (RemoteException e) {
10803                 // can't happen; backup manager is local
10804             }
10805         }
10806 
10807         for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10808             ProcessChangeItem item = mPendingProcessChanges.get(i);
10809             if (item.pid == app.pid) {
10810                 mPendingProcessChanges.remove(i);
10811                 mAvailProcessChanges.add(item);
10812             }
10813         }
10814         mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10815 
10816         // If the caller is restarting this app, then leave it in its
10817         // current lists and let the caller take care of it.
10818         if (restarting) {
10819             return;
10820         }
10821 
10822         if (!app.persistent || app.isolated) {
10823             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
10824                     "Removing non-persistent process during cleanup: " + app);
10825             mProcessNames.remove(app.processName, app.uid);
10826             mIsolatedProcesses.remove(app.uid);
10827             if (mHeavyWeightProcess == app) {
10828                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
10829                         mHeavyWeightProcess.userId, 0));
10830                 mHeavyWeightProcess = null;
10831             }
10832         } else if (!app.removed) {
10833             // This app is persistent, so we need to keep its record around.
10834             // If it is not already on the pending app list, add it there
10835             // and start a new process for it.
10836             if (mPersistentStartingProcesses.indexOf(app) < 0) {
10837                 mPersistentStartingProcesses.add(app);
10838                 restart = true;
10839             }
10840         }
10841         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
10842                 "Clean-up removing on hold: " + app);
10843         mProcessesOnHold.remove(app);
10844 
10845         if (app == mHomeProcess) {
10846             mHomeProcess = null;
10847         }
10848         if (app == mPreviousProcess) {
10849             mPreviousProcess = null;
10850         }
10851 
10852         if (restart && !app.isolated) {
10853             // We have components that still need to be running in the
10854             // process, so re-launch it.
10855             mProcessNames.put(app.processName, app.uid, app);
10856             startProcessLocked(app, "restart", app.processName);
10857         } else if (app.pid > 0 && app.pid != MY_PID) {
10858             // Goodbye!
10859             synchronized (mPidsSelfLocked) {
10860                 mPidsSelfLocked.remove(app.pid);
10861                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10862             }
10863             app.setPid(0);
10864         }
10865     }
10866 
checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad)10867     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10868         // Look through the content providers we are waiting to have launched,
10869         // and if any run in this process then either schedule a restart of
10870         // the process or kill the client waiting for it if this process has
10871         // gone bad.
10872         int NL = mLaunchingProviders.size();
10873         boolean restart = false;
10874         for (int i=0; i<NL; i++) {
10875             ContentProviderRecord cpr = mLaunchingProviders.get(i);
10876             if (cpr.launchingApp == app) {
10877                 if (!alwaysBad && !app.bad) {
10878                     restart = true;
10879                 } else {
10880                     removeDyingProviderLocked(app, cpr, true);
10881                     // cpr should have been removed from mLaunchingProviders
10882                     NL = mLaunchingProviders.size();
10883                     i--;
10884                 }
10885             }
10886         }
10887         return restart;
10888     }
10889 
10890     // =========================================================
10891     // SERVICES
10892     // =========================================================
10893 
getServices(int maxNum, int flags)10894     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10895             int flags) {
10896         enforceNotIsolatedCaller("getServices");
10897         synchronized (this) {
10898             return mServices.getRunningServiceInfoLocked(maxNum, flags);
10899         }
10900     }
10901 
getRunningServiceControlPanel(ComponentName name)10902     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10903         enforceNotIsolatedCaller("getRunningServiceControlPanel");
10904         synchronized (this) {
10905             return mServices.getRunningServiceControlPanelLocked(name);
10906         }
10907     }
10908 
startService(IApplicationThread caller, Intent service, String resolvedType, int userId)10909     public ComponentName startService(IApplicationThread caller, Intent service,
10910             String resolvedType, int userId) {
10911         enforceNotIsolatedCaller("startService");
10912         // Refuse possible leaked file descriptors
10913         if (service != null && service.hasFileDescriptors() == true) {
10914             throw new IllegalArgumentException("File descriptors passed in Intent");
10915         }
10916 
10917         if (DEBUG_SERVICE)
10918             Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10919         synchronized(this) {
10920             final int callingPid = Binder.getCallingPid();
10921             final int callingUid = Binder.getCallingUid();
10922             checkValidCaller(callingUid, userId);
10923             final long origId = Binder.clearCallingIdentity();
10924             ComponentName res = mServices.startServiceLocked(caller, service,
10925                     resolvedType, callingPid, callingUid, userId);
10926             Binder.restoreCallingIdentity(origId);
10927             return res;
10928         }
10929     }
10930 
startServiceInPackage(int uid, Intent service, String resolvedType, int userId)10931     ComponentName startServiceInPackage(int uid,
10932             Intent service, String resolvedType, int userId) {
10933         synchronized(this) {
10934             if (DEBUG_SERVICE)
10935                 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10936             final long origId = Binder.clearCallingIdentity();
10937             ComponentName res = mServices.startServiceLocked(null, service,
10938                     resolvedType, -1, uid, userId);
10939             Binder.restoreCallingIdentity(origId);
10940             return res;
10941         }
10942     }
10943 
stopService(IApplicationThread caller, Intent service, String resolvedType, int userId)10944     public int stopService(IApplicationThread caller, Intent service,
10945             String resolvedType, int userId) {
10946         enforceNotIsolatedCaller("stopService");
10947         // Refuse possible leaked file descriptors
10948         if (service != null && service.hasFileDescriptors() == true) {
10949             throw new IllegalArgumentException("File descriptors passed in Intent");
10950         }
10951 
10952         checkValidCaller(Binder.getCallingUid(), userId);
10953 
10954         synchronized(this) {
10955             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10956         }
10957     }
10958 
peekService(Intent service, String resolvedType)10959     public IBinder peekService(Intent service, String resolvedType) {
10960         enforceNotIsolatedCaller("peekService");
10961         // Refuse possible leaked file descriptors
10962         if (service != null && service.hasFileDescriptors() == true) {
10963             throw new IllegalArgumentException("File descriptors passed in Intent");
10964         }
10965         synchronized(this) {
10966             return mServices.peekServiceLocked(service, resolvedType);
10967         }
10968     }
10969 
stopServiceToken(ComponentName className, IBinder token, int startId)10970     public boolean stopServiceToken(ComponentName className, IBinder token,
10971             int startId) {
10972         synchronized(this) {
10973             return mServices.stopServiceTokenLocked(className, token, startId);
10974         }
10975     }
10976 
setServiceForeground(ComponentName className, IBinder token, int id, Notification notification, boolean removeNotification)10977     public void setServiceForeground(ComponentName className, IBinder token,
10978             int id, Notification notification, boolean removeNotification) {
10979         synchronized(this) {
10980             mServices.setServiceForegroundLocked(className, token, id, notification,
10981                     removeNotification);
10982         }
10983     }
10984 
handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, boolean requireFull, String name, String callerPackage)10985     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
10986             boolean requireFull, String name, String callerPackage) {
10987         final int callingUserId = UserHandle.getUserId(callingUid);
10988         if (callingUserId != userId) {
10989             if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10990                 if ((requireFull || checkComponentPermission(
10991                         android.Manifest.permission.INTERACT_ACROSS_USERS,
10992                         callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
10993                         && checkComponentPermission(
10994                                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10995                                 callingPid, callingUid, -1, true)
10996                                 != PackageManager.PERMISSION_GRANTED) {
10997                     if (userId == UserHandle.USER_CURRENT_OR_SELF) {
10998                         // In this case, they would like to just execute as their
10999                         // owner user instead of failing.
11000                         userId = callingUserId;
11001                     } else {
11002                         StringBuilder builder = new StringBuilder(128);
11003                         builder.append("Permission Denial: ");
11004                         builder.append(name);
11005                         if (callerPackage != null) {
11006                             builder.append(" from ");
11007                             builder.append(callerPackage);
11008                         }
11009                         builder.append(" asks to run as user ");
11010                         builder.append(userId);
11011                         builder.append(" but is calling from user ");
11012                         builder.append(UserHandle.getUserId(callingUid));
11013                         builder.append("; this requires ");
11014                         builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
11015                         if (!requireFull) {
11016                             builder.append(" or ");
11017                             builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
11018                         }
11019                         String msg = builder.toString();
11020                         Slog.w(TAG, msg);
11021                         throw new SecurityException(msg);
11022                     }
11023                 }
11024             }
11025             if (userId == UserHandle.USER_CURRENT
11026                     || userId == UserHandle.USER_CURRENT_OR_SELF) {
11027                 // Note that we may be accessing this outside of a lock...
11028                 // shouldn't be a big deal, if this is being called outside
11029                 // of a locked context there is intrinsically a race with
11030                 // the value the caller will receive and someone else changing it.
11031                 userId = mCurrentUserId;
11032             }
11033             if (!allowAll && userId < 0) {
11034                 throw new IllegalArgumentException(
11035                         "Call does not support special user #" + userId);
11036             }
11037         }
11038         return userId;
11039     }
11040 
isSingleton(String componentProcessName, ApplicationInfo aInfo, String className, int flags)11041     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
11042             String className, int flags) {
11043         boolean result = false;
11044         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
11045             if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
11046                 if (ActivityManager.checkUidPermission(
11047                         android.Manifest.permission.INTERACT_ACROSS_USERS,
11048                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
11049                     ComponentName comp = new ComponentName(aInfo.packageName, className);
11050                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
11051                             + " requests FLAG_SINGLE_USER, but app does not hold "
11052                             + android.Manifest.permission.INTERACT_ACROSS_USERS;
11053                     Slog.w(TAG, msg);
11054                     throw new SecurityException(msg);
11055                 }
11056                 result = true;
11057             }
11058         } else if (componentProcessName == aInfo.packageName) {
11059             result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
11060         } else if ("system".equals(componentProcessName)) {
11061             result = true;
11062         }
11063         if (DEBUG_MU) {
11064             Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
11065                     + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
11066         }
11067         return result;
11068     }
11069 
bindService(IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags, int userId)11070     public int bindService(IApplicationThread caller, IBinder token,
11071             Intent service, String resolvedType,
11072             IServiceConnection connection, int flags, int userId) {
11073         enforceNotIsolatedCaller("bindService");
11074         // Refuse possible leaked file descriptors
11075         if (service != null && service.hasFileDescriptors() == true) {
11076             throw new IllegalArgumentException("File descriptors passed in Intent");
11077         }
11078 
11079         synchronized(this) {
11080             return mServices.bindServiceLocked(caller, token, service, resolvedType,
11081                     connection, flags, userId);
11082         }
11083     }
11084 
unbindService(IServiceConnection connection)11085     public boolean unbindService(IServiceConnection connection) {
11086         synchronized (this) {
11087             return mServices.unbindServiceLocked(connection);
11088         }
11089     }
11090 
publishService(IBinder token, Intent intent, IBinder service)11091     public void publishService(IBinder token, Intent intent, IBinder service) {
11092         // Refuse possible leaked file descriptors
11093         if (intent != null && intent.hasFileDescriptors() == true) {
11094             throw new IllegalArgumentException("File descriptors passed in Intent");
11095         }
11096 
11097         synchronized(this) {
11098             if (!(token instanceof ServiceRecord)) {
11099                 throw new IllegalArgumentException("Invalid service token");
11100             }
11101             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
11102         }
11103     }
11104 
unbindFinished(IBinder token, Intent intent, boolean doRebind)11105     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11106         // Refuse possible leaked file descriptors
11107         if (intent != null && intent.hasFileDescriptors() == true) {
11108             throw new IllegalArgumentException("File descriptors passed in Intent");
11109         }
11110 
11111         synchronized(this) {
11112             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
11113         }
11114     }
11115 
serviceDoneExecuting(IBinder token, int type, int startId, int res)11116     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11117         synchronized(this) {
11118             if (!(token instanceof ServiceRecord)) {
11119                 throw new IllegalArgumentException("Invalid service token");
11120             }
11121             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
11122         }
11123     }
11124 
11125     // =========================================================
11126     // BACKUP AND RESTORE
11127     // =========================================================
11128 
11129     // Cause the target app to be launched if necessary and its backup agent
11130     // instantiated.  The backup agent will invoke backupAgentCreated() on the
11131     // activity manager to announce its creation.
bindBackupAgent(ApplicationInfo app, int backupMode)11132     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11133         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
11134         enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
11135 
11136         synchronized(this) {
11137             // !!! TODO: currently no check here that we're already bound
11138             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11139             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11140             synchronized (stats) {
11141                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11142             }
11143 
11144             // Backup agent is now in use, its package can't be stopped.
11145             try {
11146                 AppGlobals.getPackageManager().setPackageStoppedState(
11147                         app.packageName, false, UserHandle.getUserId(app.uid));
11148             } catch (RemoteException e) {
11149             } catch (IllegalArgumentException e) {
11150                 Slog.w(TAG, "Failed trying to unstop package "
11151                         + app.packageName + ": " + e);
11152             }
11153 
11154             BackupRecord r = new BackupRecord(ss, app, backupMode);
11155             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11156                     ? new ComponentName(app.packageName, app.backupAgentName)
11157                     : new ComponentName("android", "FullBackupAgent");
11158             // startProcessLocked() returns existing proc's record if it's already running
11159             ProcessRecord proc = startProcessLocked(app.processName, app,
11160                     false, 0, "backup", hostingName, false, false);
11161             if (proc == null) {
11162                 Slog.e(TAG, "Unable to start backup agent process " + r);
11163                 return false;
11164             }
11165 
11166             r.app = proc;
11167             mBackupTarget = r;
11168             mBackupAppName = app.packageName;
11169 
11170             // Try not to kill the process during backup
11171             updateOomAdjLocked(proc);
11172 
11173             // If the process is already attached, schedule the creation of the backup agent now.
11174             // If it is not yet live, this will be done when it attaches to the framework.
11175             if (proc.thread != null) {
11176                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
11177                 try {
11178                     proc.thread.scheduleCreateBackupAgent(app,
11179                             compatibilityInfoForPackageLocked(app), backupMode);
11180                 } catch (RemoteException e) {
11181                     // Will time out on the backup manager side
11182                 }
11183             } else {
11184                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
11185             }
11186             // Invariants: at this point, the target app process exists and the application
11187             // is either already running or in the process of coming up.  mBackupTarget and
11188             // mBackupAppName describe the app, so that when it binds back to the AM we
11189             // know that it's scheduled for a backup-agent operation.
11190         }
11191 
11192         return true;
11193     }
11194 
11195     @Override
clearPendingBackup()11196     public void clearPendingBackup() {
11197         if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
11198         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
11199 
11200         synchronized (this) {
11201             mBackupTarget = null;
11202             mBackupAppName = null;
11203         }
11204     }
11205 
11206     // A backup agent has just come up
backupAgentCreated(String agentPackageName, IBinder agent)11207     public void backupAgentCreated(String agentPackageName, IBinder agent) {
11208         if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
11209                 + " = " + agent);
11210 
11211         synchronized(this) {
11212             if (!agentPackageName.equals(mBackupAppName)) {
11213                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11214                 return;
11215             }
11216         }
11217 
11218         long oldIdent = Binder.clearCallingIdentity();
11219         try {
11220             IBackupManager bm = IBackupManager.Stub.asInterface(
11221                     ServiceManager.getService(Context.BACKUP_SERVICE));
11222             bm.agentConnected(agentPackageName, agent);
11223         } catch (RemoteException e) {
11224             // can't happen; the backup manager service is local
11225         } catch (Exception e) {
11226             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11227             e.printStackTrace();
11228         } finally {
11229             Binder.restoreCallingIdentity(oldIdent);
11230         }
11231     }
11232 
11233     // done with this agent
unbindBackupAgent(ApplicationInfo appInfo)11234     public void unbindBackupAgent(ApplicationInfo appInfo) {
11235         if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
11236         if (appInfo == null) {
11237             Slog.w(TAG, "unbind backup agent for null app");
11238             return;
11239         }
11240 
11241         synchronized(this) {
11242             try {
11243                 if (mBackupAppName == null) {
11244                     Slog.w(TAG, "Unbinding backup agent with no active backup");
11245                     return;
11246                 }
11247 
11248                 if (!mBackupAppName.equals(appInfo.packageName)) {
11249                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11250                     return;
11251                 }
11252 
11253                 // Not backing this app up any more; reset its OOM adjustment
11254                 final ProcessRecord proc = mBackupTarget.app;
11255                 updateOomAdjLocked(proc);
11256 
11257                 // If the app crashed during backup, 'thread' will be null here
11258                 if (proc.thread != null) {
11259                     try {
11260                         proc.thread.scheduleDestroyBackupAgent(appInfo,
11261                                 compatibilityInfoForPackageLocked(appInfo));
11262                     } catch (Exception e) {
11263                         Slog.e(TAG, "Exception when unbinding backup agent:");
11264                         e.printStackTrace();
11265                     }
11266                 }
11267             } finally {
11268                 mBackupTarget = null;
11269                 mBackupAppName = null;
11270             }
11271         }
11272     }
11273     // =========================================================
11274     // BROADCASTS
11275     // =========================================================
11276 
getStickiesLocked(String action, IntentFilter filter, List cur, int userId)11277     private final List getStickiesLocked(String action, IntentFilter filter,
11278             List cur, int userId) {
11279         final ContentResolver resolver = mContext.getContentResolver();
11280         HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11281         if (stickies == null) {
11282             return cur;
11283         }
11284         final ArrayList<Intent> list = stickies.get(action);
11285         if (list == null) {
11286             return cur;
11287         }
11288         int N = list.size();
11289         for (int i=0; i<N; i++) {
11290             Intent intent = list.get(i);
11291             if (filter.match(resolver, intent, true, TAG) >= 0) {
11292                 if (cur == null) {
11293                     cur = new ArrayList<Intent>();
11294                 }
11295                 cur.add(intent);
11296             }
11297         }
11298         return cur;
11299     }
11300 
isPendingBroadcastProcessLocked(int pid)11301     boolean isPendingBroadcastProcessLocked(int pid) {
11302         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11303                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11304     }
11305 
skipPendingBroadcastLocked(int pid)11306     void skipPendingBroadcastLocked(int pid) {
11307             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11308             for (BroadcastQueue queue : mBroadcastQueues) {
11309                 queue.skipPendingBroadcastLocked(pid);
11310             }
11311     }
11312 
11313     // The app just attached; send any pending broadcasts that it should receive
sendPendingBroadcastsLocked(ProcessRecord app)11314     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11315         boolean didSomething = false;
11316         for (BroadcastQueue queue : mBroadcastQueues) {
11317             didSomething |= queue.sendPendingBroadcastsLocked(app);
11318         }
11319         return didSomething;
11320     }
11321 
registerReceiver(IApplicationThread caller, String callerPackage, IIntentReceiver receiver, IntentFilter filter, String permission, int userId)11322     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11323             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
11324         enforceNotIsolatedCaller("registerReceiver");
11325         int callingUid;
11326         int callingPid;
11327         synchronized(this) {
11328             ProcessRecord callerApp = null;
11329             if (caller != null) {
11330                 callerApp = getRecordForAppLocked(caller);
11331                 if (callerApp == null) {
11332                     throw new SecurityException(
11333                             "Unable to find app for caller " + caller
11334                             + " (pid=" + Binder.getCallingPid()
11335                             + ") when registering receiver " + receiver);
11336                 }
11337                 if (callerApp.info.uid != Process.SYSTEM_UID &&
11338                         !callerApp.pkgList.contains(callerPackage)) {
11339                     throw new SecurityException("Given caller package " + callerPackage
11340                             + " is not running in process " + callerApp);
11341                 }
11342                 callingUid = callerApp.info.uid;
11343                 callingPid = callerApp.pid;
11344             } else {
11345                 callerPackage = null;
11346                 callingUid = Binder.getCallingUid();
11347                 callingPid = Binder.getCallingPid();
11348             }
11349 
11350             userId = this.handleIncomingUser(callingPid, callingUid, userId,
11351                     true, true, "registerReceiver", callerPackage);
11352 
11353             List allSticky = null;
11354 
11355             // Look for any matching sticky broadcasts...
11356             Iterator actions = filter.actionsIterator();
11357             if (actions != null) {
11358                 while (actions.hasNext()) {
11359                     String action = (String)actions.next();
11360                     allSticky = getStickiesLocked(action, filter, allSticky,
11361                             UserHandle.USER_ALL);
11362                     allSticky = getStickiesLocked(action, filter, allSticky,
11363                             UserHandle.getUserId(callingUid));
11364                 }
11365             } else {
11366                 allSticky = getStickiesLocked(null, filter, allSticky,
11367                         UserHandle.USER_ALL);
11368                 allSticky = getStickiesLocked(null, filter, allSticky,
11369                         UserHandle.getUserId(callingUid));
11370             }
11371 
11372             // The first sticky in the list is returned directly back to
11373             // the client.
11374             Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11375 
11376             if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11377                     + ": " + sticky);
11378 
11379             if (receiver == null) {
11380                 return sticky;
11381             }
11382 
11383             ReceiverList rl
11384                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11385             if (rl == null) {
11386                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11387                         userId, receiver);
11388                 if (rl.app != null) {
11389                     rl.app.receivers.add(rl);
11390                 } else {
11391                     try {
11392                         receiver.asBinder().linkToDeath(rl, 0);
11393                     } catch (RemoteException e) {
11394                         return sticky;
11395                     }
11396                     rl.linkedToDeath = true;
11397                 }
11398                 mRegisteredReceivers.put(receiver.asBinder(), rl);
11399             } else if (rl.uid != callingUid) {
11400                 throw new IllegalArgumentException(
11401                         "Receiver requested to register for uid " + callingUid
11402                         + " was previously registered for uid " + rl.uid);
11403             } else if (rl.pid != callingPid) {
11404                 throw new IllegalArgumentException(
11405                         "Receiver requested to register for pid " + callingPid
11406                         + " was previously registered for pid " + rl.pid);
11407             } else if (rl.userId != userId) {
11408                 throw new IllegalArgumentException(
11409                         "Receiver requested to register for user " + userId
11410                         + " was previously registered for user " + rl.userId);
11411             }
11412             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11413                     permission, callingUid, userId);
11414             rl.add(bf);
11415             if (!bf.debugCheck()) {
11416                 Slog.w(TAG, "==> For Dynamic broadast");
11417             }
11418             mReceiverResolver.addFilter(bf);
11419 
11420             // Enqueue broadcasts for all existing stickies that match
11421             // this filter.
11422             if (allSticky != null) {
11423                 ArrayList receivers = new ArrayList();
11424                 receivers.add(bf);
11425 
11426                 int N = allSticky.size();
11427                 for (int i=0; i<N; i++) {
11428                     Intent intent = (Intent)allSticky.get(i);
11429                     BroadcastQueue queue = broadcastQueueForIntent(intent);
11430                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11431                             null, -1, -1, null, receivers, null, 0, null, null,
11432                             false, true, true, -1);
11433                     queue.enqueueParallelBroadcastLocked(r);
11434                     queue.scheduleBroadcastsLocked();
11435                 }
11436             }
11437 
11438             return sticky;
11439         }
11440     }
11441 
unregisterReceiver(IIntentReceiver receiver)11442     public void unregisterReceiver(IIntentReceiver receiver) {
11443         if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11444 
11445         final long origId = Binder.clearCallingIdentity();
11446         try {
11447             boolean doTrim = false;
11448 
11449             synchronized(this) {
11450                 ReceiverList rl
11451                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11452                 if (rl != null) {
11453                     if (rl.curBroadcast != null) {
11454                         BroadcastRecord r = rl.curBroadcast;
11455                         final boolean doNext = finishReceiverLocked(
11456                                 receiver.asBinder(), r.resultCode, r.resultData,
11457                                 r.resultExtras, r.resultAbort, true);
11458                         if (doNext) {
11459                             doTrim = true;
11460                             r.queue.processNextBroadcast(false);
11461                         }
11462                     }
11463 
11464                     if (rl.app != null) {
11465                         rl.app.receivers.remove(rl);
11466                     }
11467                     removeReceiverLocked(rl);
11468                     if (rl.linkedToDeath) {
11469                         rl.linkedToDeath = false;
11470                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
11471                     }
11472                 }
11473             }
11474 
11475             // If we actually concluded any broadcasts, we might now be able
11476             // to trim the recipients' apps from our working set
11477             if (doTrim) {
11478                 trimApplications();
11479                 return;
11480             }
11481 
11482         } finally {
11483             Binder.restoreCallingIdentity(origId);
11484         }
11485     }
11486 
removeReceiverLocked(ReceiverList rl)11487     void removeReceiverLocked(ReceiverList rl) {
11488         mRegisteredReceivers.remove(rl.receiver.asBinder());
11489         int N = rl.size();
11490         for (int i=0; i<N; i++) {
11491             mReceiverResolver.removeFilter(rl.get(i));
11492         }
11493     }
11494 
sendPackageBroadcastLocked(int cmd, String[] packages, int userId)11495     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
11496         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11497             ProcessRecord r = mLruProcesses.get(i);
11498             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
11499                 try {
11500                     r.thread.dispatchPackageBroadcast(cmd, packages);
11501                 } catch (RemoteException ex) {
11502                 }
11503             }
11504         }
11505     }
11506 
collectReceiverComponents(Intent intent, String resolvedType, int[] users)11507     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11508             int[] users) {
11509         List<ResolveInfo> receivers = null;
11510         try {
11511             HashSet<ComponentName> singleUserReceivers = null;
11512             boolean scannedFirstReceivers = false;
11513             for (int user : users) {
11514                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11515                         .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11516                 if (user != 0 && newReceivers != null) {
11517                     // If this is not the primary user, we need to check for
11518                     // any receivers that should be filtered out.
11519                     for (int i=0; i<newReceivers.size(); i++) {
11520                         ResolveInfo ri = newReceivers.get(i);
11521                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
11522                             newReceivers.remove(i);
11523                             i--;
11524                         }
11525                     }
11526                 }
11527                 if (newReceivers != null && newReceivers.size() == 0) {
11528                     newReceivers = null;
11529                 }
11530                 if (receivers == null) {
11531                     receivers = newReceivers;
11532                 } else if (newReceivers != null) {
11533                     // We need to concatenate the additional receivers
11534                     // found with what we have do far.  This would be easy,
11535                     // but we also need to de-dup any receivers that are
11536                     // singleUser.
11537                     if (!scannedFirstReceivers) {
11538                         // Collect any single user receivers we had already retrieved.
11539                         scannedFirstReceivers = true;
11540                         for (int i=0; i<receivers.size(); i++) {
11541                             ResolveInfo ri = receivers.get(i);
11542                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11543                                 ComponentName cn = new ComponentName(
11544                                         ri.activityInfo.packageName, ri.activityInfo.name);
11545                                 if (singleUserReceivers == null) {
11546                                     singleUserReceivers = new HashSet<ComponentName>();
11547                                 }
11548                                 singleUserReceivers.add(cn);
11549                             }
11550                         }
11551                     }
11552                     // Add the new results to the existing results, tracking
11553                     // and de-dupping single user receivers.
11554                     for (int i=0; i<newReceivers.size(); i++) {
11555                         ResolveInfo ri = newReceivers.get(i);
11556                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11557                             ComponentName cn = new ComponentName(
11558                                     ri.activityInfo.packageName, ri.activityInfo.name);
11559                             if (singleUserReceivers == null) {
11560                                 singleUserReceivers = new HashSet<ComponentName>();
11561                             }
11562                             if (!singleUserReceivers.contains(cn)) {
11563                                 singleUserReceivers.add(cn);
11564                                 receivers.add(ri);
11565                             }
11566                         } else {
11567                             receivers.add(ri);
11568                         }
11569                     }
11570                 }
11571             }
11572         } catch (RemoteException ex) {
11573             // pm is in same process, this will never happen.
11574         }
11575         return receivers;
11576     }
11577 
broadcastIntentLocked(ProcessRecord callerApp, String callerPackage, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String requiredPermission, boolean ordered, boolean sticky, int callingPid, int callingUid, int userId)11578     private final int broadcastIntentLocked(ProcessRecord callerApp,
11579             String callerPackage, Intent intent, String resolvedType,
11580             IIntentReceiver resultTo, int resultCode, String resultData,
11581             Bundle map, String requiredPermission,
11582             boolean ordered, boolean sticky, int callingPid, int callingUid,
11583             int userId) {
11584         intent = new Intent(intent);
11585 
11586         // By default broadcasts do not go to stopped apps.
11587         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11588 
11589         if (DEBUG_BROADCAST_LIGHT) Slog.v(
11590             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11591             + " ordered=" + ordered + " userid=" + userId);
11592         if ((resultTo != null) && !ordered) {
11593             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11594         }
11595 
11596         userId = handleIncomingUser(callingPid, callingUid, userId,
11597                 true, false, "broadcast", callerPackage);
11598 
11599         // Make sure that the user who is receiving this broadcast is started.
11600         // If not, we will just skip it.
11601         if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
11602             if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
11603                     & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
11604                 Slog.w(TAG, "Skipping broadcast of " + intent
11605                         + ": user " + userId + " is stopped");
11606                 return ActivityManager.BROADCAST_SUCCESS;
11607             }
11608         }
11609 
11610         /*
11611          * Prevent non-system code (defined here to be non-persistent
11612          * processes) from sending protected broadcasts.
11613          */
11614         int callingAppId = UserHandle.getAppId(callingUid);
11615         if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
11616             || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
11617             callingUid == 0) {
11618             // Always okay.
11619         } else if (callerApp == null || !callerApp.persistent) {
11620             try {
11621                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
11622                         intent.getAction())) {
11623                     String msg = "Permission Denial: not allowed to send broadcast "
11624                             + intent.getAction() + " from pid="
11625                             + callingPid + ", uid=" + callingUid;
11626                     Slog.w(TAG, msg);
11627                     throw new SecurityException(msg);
11628                 }
11629             } catch (RemoteException e) {
11630                 Slog.w(TAG, "Remote exception", e);
11631                 return ActivityManager.BROADCAST_SUCCESS;
11632             }
11633         }
11634 
11635         // Handle special intents: if this broadcast is from the package
11636         // manager about a package being removed, we need to remove all of
11637         // its activities from the history stack.
11638         final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11639                 intent.getAction());
11640         if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11641                 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11642                 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11643                 || uidRemoved) {
11644             if (checkComponentPermission(
11645                     android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11646                     callingPid, callingUid, -1, true)
11647                     == PackageManager.PERMISSION_GRANTED) {
11648                 if (uidRemoved) {
11649                     final Bundle intentExtras = intent.getExtras();
11650                     final int uid = intentExtras != null
11651                             ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11652                     if (uid >= 0) {
11653                         BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11654                         synchronized (bs) {
11655                             bs.removeUidStatsLocked(uid);
11656                         }
11657                     }
11658                 } else {
11659                     // If resources are unavailable just force stop all
11660                     // those packages and flush the attribute cache as well.
11661                     if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11662                         String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11663                         if (list != null && (list.length > 0)) {
11664                             for (String pkg : list) {
11665                                 forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11666                             }
11667                             sendPackageBroadcastLocked(
11668                                     IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
11669                         }
11670                     } else {
11671                         Uri data = intent.getData();
11672                         String ssp;
11673                         if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11674                             if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11675                                 forceStopPackageLocked(ssp,
11676                                         intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11677                                         false, userId);
11678                             }
11679                             if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11680                                 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11681                                         new String[] {ssp}, userId);
11682                             }
11683                         }
11684                     }
11685                 }
11686             } else {
11687                 String msg = "Permission Denial: " + intent.getAction()
11688                         + " broadcast from " + callerPackage + " (pid=" + callingPid
11689                         + ", uid=" + callingUid + ")"
11690                         + " requires "
11691                         + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11692                 Slog.w(TAG, msg);
11693                 throw new SecurityException(msg);
11694             }
11695 
11696         // Special case for adding a package: by default turn on compatibility
11697         // mode.
11698         } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11699             Uri data = intent.getData();
11700             String ssp;
11701             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11702                 mCompatModePackages.handlePackageAddedLocked(ssp,
11703                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11704             }
11705         }
11706 
11707         /*
11708          * If this is the time zone changed action, queue up a message that will reset the timezone
11709          * of all currently running processes. This message will get queued up before the broadcast
11710          * happens.
11711          */
11712         if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11713             mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11714         }
11715 
11716         if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11717             mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11718         }
11719 
11720         if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11721             ProxyProperties proxy = intent.getParcelableExtra("proxy");
11722             mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11723         }
11724 
11725         // Add to the sticky list if requested.
11726         if (sticky) {
11727             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11728                     callingPid, callingUid)
11729                     != PackageManager.PERMISSION_GRANTED) {
11730                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11731                         + callingPid + ", uid=" + callingUid
11732                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11733                 Slog.w(TAG, msg);
11734                 throw new SecurityException(msg);
11735             }
11736             if (requiredPermission != null) {
11737                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
11738                         + " and enforce permission " + requiredPermission);
11739                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11740             }
11741             if (intent.getComponent() != null) {
11742                 throw new SecurityException(
11743                         "Sticky broadcasts can't target a specific component");
11744             }
11745             // We use userId directly here, since the "all" target is maintained
11746             // as a separate set of sticky broadcasts.
11747             if (userId != UserHandle.USER_ALL) {
11748                 // But first, if this is not a broadcast to all users, then
11749                 // make sure it doesn't conflict with an existing broadcast to
11750                 // all users.
11751                 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
11752                         UserHandle.USER_ALL);
11753                 if (stickies != null) {
11754                     ArrayList<Intent> list = stickies.get(intent.getAction());
11755                     if (list != null) {
11756                         int N = list.size();
11757                         int i;
11758                         for (i=0; i<N; i++) {
11759                             if (intent.filterEquals(list.get(i))) {
11760                                 throw new IllegalArgumentException(
11761                                         "Sticky broadcast " + intent + " for user "
11762                                         + userId + " conflicts with existing global broadcast");
11763                             }
11764                         }
11765                     }
11766                 }
11767             }
11768             HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11769             if (stickies == null) {
11770                 stickies = new HashMap<String, ArrayList<Intent>>();
11771                 mStickyBroadcasts.put(userId, stickies);
11772             }
11773             ArrayList<Intent> list = stickies.get(intent.getAction());
11774             if (list == null) {
11775                 list = new ArrayList<Intent>();
11776                 stickies.put(intent.getAction(), list);
11777             }
11778             int N = list.size();
11779             int i;
11780             for (i=0; i<N; i++) {
11781                 if (intent.filterEquals(list.get(i))) {
11782                     // This sticky already exists, replace it.
11783                     list.set(i, new Intent(intent));
11784                     break;
11785                 }
11786             }
11787             if (i >= N) {
11788                 list.add(new Intent(intent));
11789             }
11790         }
11791 
11792         int[] users;
11793         if (userId == UserHandle.USER_ALL) {
11794             // Caller wants broadcast to go to all started users.
11795             users = mStartedUserArray;
11796         } else {
11797             // Caller wants broadcast to go to one specific user.
11798             users = new int[] {userId};
11799         }
11800 
11801         // Figure out who all will receive this broadcast.
11802         List receivers = null;
11803         List<BroadcastFilter> registeredReceivers = null;
11804         // Need to resolve the intent to interested receivers...
11805         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11806                  == 0) {
11807             receivers = collectReceiverComponents(intent, resolvedType, users);
11808         }
11809         if (intent.getComponent() == null) {
11810             registeredReceivers = mReceiverResolver.queryIntent(intent,
11811                     resolvedType, false, userId);
11812         }
11813 
11814         final boolean replacePending =
11815                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11816 
11817         if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11818                 + " replacePending=" + replacePending);
11819 
11820         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11821         if (!ordered && NR > 0) {
11822             // If we are not serializing this broadcast, then send the
11823             // registered receivers separately so they don't wait for the
11824             // components to be launched.
11825             final BroadcastQueue queue = broadcastQueueForIntent(intent);
11826             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11827                     callerPackage, callingPid, callingUid, requiredPermission,
11828                     registeredReceivers, resultTo, resultCode, resultData, map,
11829                     ordered, sticky, false, userId);
11830             if (DEBUG_BROADCAST) Slog.v(
11831                     TAG, "Enqueueing parallel broadcast " + r);
11832             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11833             if (!replaced) {
11834                 queue.enqueueParallelBroadcastLocked(r);
11835                 queue.scheduleBroadcastsLocked();
11836             }
11837             registeredReceivers = null;
11838             NR = 0;
11839         }
11840 
11841         // Merge into one list.
11842         int ir = 0;
11843         if (receivers != null) {
11844             // A special case for PACKAGE_ADDED: do not allow the package
11845             // being added to see this broadcast.  This prevents them from
11846             // using this as a back door to get run as soon as they are
11847             // installed.  Maybe in the future we want to have a special install
11848             // broadcast or such for apps, but we'd like to deliberately make
11849             // this decision.
11850             String skipPackages[] = null;
11851             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11852                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11853                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11854                 Uri data = intent.getData();
11855                 if (data != null) {
11856                     String pkgName = data.getSchemeSpecificPart();
11857                     if (pkgName != null) {
11858                         skipPackages = new String[] { pkgName };
11859                     }
11860                 }
11861             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11862                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11863             }
11864             if (skipPackages != null && (skipPackages.length > 0)) {
11865                 for (String skipPackage : skipPackages) {
11866                     if (skipPackage != null) {
11867                         int NT = receivers.size();
11868                         for (int it=0; it<NT; it++) {
11869                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
11870                             if (curt.activityInfo.packageName.equals(skipPackage)) {
11871                                 receivers.remove(it);
11872                                 it--;
11873                                 NT--;
11874                             }
11875                         }
11876                     }
11877                 }
11878             }
11879 
11880             int NT = receivers != null ? receivers.size() : 0;
11881             int it = 0;
11882             ResolveInfo curt = null;
11883             BroadcastFilter curr = null;
11884             while (it < NT && ir < NR) {
11885                 if (curt == null) {
11886                     curt = (ResolveInfo)receivers.get(it);
11887                 }
11888                 if (curr == null) {
11889                     curr = registeredReceivers.get(ir);
11890                 }
11891                 if (curr.getPriority() >= curt.priority) {
11892                     // Insert this broadcast record into the final list.
11893                     receivers.add(it, curr);
11894                     ir++;
11895                     curr = null;
11896                     it++;
11897                     NT++;
11898                 } else {
11899                     // Skip to the next ResolveInfo in the final list.
11900                     it++;
11901                     curt = null;
11902                 }
11903             }
11904         }
11905         while (ir < NR) {
11906             if (receivers == null) {
11907                 receivers = new ArrayList();
11908             }
11909             receivers.add(registeredReceivers.get(ir));
11910             ir++;
11911         }
11912 
11913         if ((receivers != null && receivers.size() > 0)
11914                 || resultTo != null) {
11915             BroadcastQueue queue = broadcastQueueForIntent(intent);
11916             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11917                     callerPackage, callingPid, callingUid, requiredPermission,
11918                     receivers, resultTo, resultCode, resultData, map, ordered,
11919                     sticky, false, userId);
11920             if (DEBUG_BROADCAST) Slog.v(
11921                     TAG, "Enqueueing ordered broadcast " + r
11922                     + ": prev had " + queue.mOrderedBroadcasts.size());
11923             if (DEBUG_BROADCAST) {
11924                 int seq = r.intent.getIntExtra("seq", -1);
11925                 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11926             }
11927             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11928             if (!replaced) {
11929                 queue.enqueueOrderedBroadcastLocked(r);
11930                 queue.scheduleBroadcastsLocked();
11931             }
11932         }
11933 
11934         return ActivityManager.BROADCAST_SUCCESS;
11935     }
11936 
verifyBroadcastLocked(Intent intent)11937     final Intent verifyBroadcastLocked(Intent intent) {
11938         // Refuse possible leaked file descriptors
11939         if (intent != null && intent.hasFileDescriptors() == true) {
11940             throw new IllegalArgumentException("File descriptors passed in Intent");
11941         }
11942 
11943         int flags = intent.getFlags();
11944 
11945         if (!mProcessesReady) {
11946             // if the caller really truly claims to know what they're doing, go
11947             // ahead and allow the broadcast without launching any receivers
11948             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11949                 intent = new Intent(intent);
11950                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11951             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11952                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11953                         + " before boot completion");
11954                 throw new IllegalStateException("Cannot broadcast before boot completed");
11955             }
11956         }
11957 
11958         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11959             throw new IllegalArgumentException(
11960                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11961         }
11962 
11963         return intent;
11964     }
11965 
broadcastIntent(IApplicationThread caller, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String requiredPermission, boolean serialized, boolean sticky, int userId)11966     public final int broadcastIntent(IApplicationThread caller,
11967             Intent intent, String resolvedType, IIntentReceiver resultTo,
11968             int resultCode, String resultData, Bundle map,
11969             String requiredPermission, boolean serialized, boolean sticky, int userId) {
11970         enforceNotIsolatedCaller("broadcastIntent");
11971         synchronized(this) {
11972             intent = verifyBroadcastLocked(intent);
11973 
11974             final ProcessRecord callerApp = getRecordForAppLocked(caller);
11975             final int callingPid = Binder.getCallingPid();
11976             final int callingUid = Binder.getCallingUid();
11977             final long origId = Binder.clearCallingIdentity();
11978             int res = broadcastIntentLocked(callerApp,
11979                     callerApp != null ? callerApp.info.packageName : null,
11980                     intent, resolvedType, resultTo,
11981                     resultCode, resultData, map, requiredPermission, serialized, sticky,
11982                     callingPid, callingUid, userId);
11983             Binder.restoreCallingIdentity(origId);
11984             return res;
11985         }
11986     }
11987 
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)11988     int broadcastIntentInPackage(String packageName, int uid,
11989             Intent intent, String resolvedType, IIntentReceiver resultTo,
11990             int resultCode, String resultData, Bundle map,
11991             String requiredPermission, boolean serialized, boolean sticky, int userId) {
11992         synchronized(this) {
11993             intent = verifyBroadcastLocked(intent);
11994 
11995             final long origId = Binder.clearCallingIdentity();
11996             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11997                     resultTo, resultCode, resultData, map, requiredPermission,
11998                     serialized, sticky, -1, uid, userId);
11999             Binder.restoreCallingIdentity(origId);
12000             return res;
12001         }
12002     }
12003 
unbroadcastIntent(IApplicationThread caller, Intent intent, int userId)12004     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
12005         // Refuse possible leaked file descriptors
12006         if (intent != null && intent.hasFileDescriptors() == true) {
12007             throw new IllegalArgumentException("File descriptors passed in Intent");
12008         }
12009 
12010         userId = handleIncomingUser(Binder.getCallingPid(),
12011                 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
12012 
12013         synchronized(this) {
12014             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
12015                     != PackageManager.PERMISSION_GRANTED) {
12016                 String msg = "Permission Denial: unbroadcastIntent() from pid="
12017                         + Binder.getCallingPid()
12018                         + ", uid=" + Binder.getCallingUid()
12019                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
12020                 Slog.w(TAG, msg);
12021                 throw new SecurityException(msg);
12022             }
12023             HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12024             if (stickies != null) {
12025                 ArrayList<Intent> list = stickies.get(intent.getAction());
12026                 if (list != null) {
12027                     int N = list.size();
12028                     int i;
12029                     for (i=0; i<N; i++) {
12030                         if (intent.filterEquals(list.get(i))) {
12031                             list.remove(i);
12032                             break;
12033                         }
12034                     }
12035                     if (list.size() <= 0) {
12036                         stickies.remove(intent.getAction());
12037                     }
12038                 }
12039                 if (stickies.size() <= 0) {
12040                     mStickyBroadcasts.remove(userId);
12041                 }
12042             }
12043         }
12044     }
12045 
finishReceiverLocked(IBinder receiver, int resultCode, String resultData, Bundle resultExtras, boolean resultAbort, boolean explicit)12046     private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12047             String resultData, Bundle resultExtras, boolean resultAbort,
12048             boolean explicit) {
12049         final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
12050         if (r == null) {
12051             Slog.w(TAG, "finishReceiver called but not found on queue");
12052             return false;
12053         }
12054 
12055         return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
12056                 explicit);
12057     }
12058 
finishReceiver(IBinder who, int resultCode, String resultData, Bundle resultExtras, boolean resultAbort)12059     public void finishReceiver(IBinder who, int resultCode, String resultData,
12060             Bundle resultExtras, boolean resultAbort) {
12061         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
12062 
12063         // Refuse possible leaked file descriptors
12064         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12065             throw new IllegalArgumentException("File descriptors passed in Bundle");
12066         }
12067 
12068         final long origId = Binder.clearCallingIdentity();
12069         try {
12070             boolean doNext = false;
12071             BroadcastRecord r = null;
12072 
12073             synchronized(this) {
12074                 r = broadcastRecordForReceiverLocked(who);
12075                 if (r != null) {
12076                     doNext = r.queue.finishReceiverLocked(r, resultCode,
12077                         resultData, resultExtras, resultAbort, true);
12078                 }
12079             }
12080 
12081             if (doNext) {
12082                 r.queue.processNextBroadcast(false);
12083             }
12084             trimApplications();
12085         } finally {
12086             Binder.restoreCallingIdentity(origId);
12087         }
12088     }
12089 
12090     // =========================================================
12091     // INSTRUMENTATION
12092     // =========================================================
12093 
startInstrumentation(ComponentName className, String profileFile, int flags, Bundle arguments, IInstrumentationWatcher watcher, int userId)12094     public boolean startInstrumentation(ComponentName className,
12095             String profileFile, int flags, Bundle arguments,
12096             IInstrumentationWatcher watcher, int userId) {
12097         enforceNotIsolatedCaller("startInstrumentation");
12098         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12099                 userId, false, true, "startInstrumentation", null);
12100         // Refuse possible leaked file descriptors
12101         if (arguments != null && arguments.hasFileDescriptors()) {
12102             throw new IllegalArgumentException("File descriptors passed in Bundle");
12103         }
12104 
12105         synchronized(this) {
12106             InstrumentationInfo ii = null;
12107             ApplicationInfo ai = null;
12108             try {
12109                 ii = mContext.getPackageManager().getInstrumentationInfo(
12110                     className, STOCK_PM_FLAGS);
12111                 ai = AppGlobals.getPackageManager().getApplicationInfo(
12112                         ii.targetPackage, STOCK_PM_FLAGS, userId);
12113             } catch (PackageManager.NameNotFoundException e) {
12114             } catch (RemoteException e) {
12115             }
12116             if (ii == null) {
12117                 reportStartInstrumentationFailure(watcher, className,
12118                         "Unable to find instrumentation info for: " + className);
12119                 return false;
12120             }
12121             if (ai == null) {
12122                 reportStartInstrumentationFailure(watcher, className,
12123                         "Unable to find instrumentation target package: " + ii.targetPackage);
12124                 return false;
12125             }
12126 
12127             int match = mContext.getPackageManager().checkSignatures(
12128                     ii.targetPackage, ii.packageName);
12129             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12130                 String msg = "Permission Denial: starting instrumentation "
12131                         + className + " from pid="
12132                         + Binder.getCallingPid()
12133                         + ", uid=" + Binder.getCallingPid()
12134                         + " not allowed because package " + ii.packageName
12135                         + " does not have a signature matching the target "
12136                         + ii.targetPackage;
12137                 reportStartInstrumentationFailure(watcher, className, msg);
12138                 throw new SecurityException(msg);
12139             }
12140 
12141             final long origId = Binder.clearCallingIdentity();
12142             // Instrumentation can kill and relaunch even persistent processes
12143             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
12144             ProcessRecord app = addAppLocked(ai, false);
12145             app.instrumentationClass = className;
12146             app.instrumentationInfo = ai;
12147             app.instrumentationProfileFile = profileFile;
12148             app.instrumentationArguments = arguments;
12149             app.instrumentationWatcher = watcher;
12150             app.instrumentationResultClass = className;
12151             Binder.restoreCallingIdentity(origId);
12152         }
12153 
12154         return true;
12155     }
12156 
12157     /**
12158      * Report errors that occur while attempting to start Instrumentation.  Always writes the
12159      * error to the logs, but if somebody is watching, send the report there too.  This enables
12160      * the "am" command to report errors with more information.
12161      *
12162      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12163      * @param cn The component name of the instrumentation.
12164      * @param report The error report.
12165      */
reportStartInstrumentationFailure(IInstrumentationWatcher watcher, ComponentName cn, String report)12166     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12167             ComponentName cn, String report) {
12168         Slog.w(TAG, report);
12169         try {
12170             if (watcher != null) {
12171                 Bundle results = new Bundle();
12172                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12173                 results.putString("Error", report);
12174                 watcher.instrumentationStatus(cn, -1, results);
12175             }
12176         } catch (RemoteException e) {
12177             Slog.w(TAG, e);
12178         }
12179     }
12180 
finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results)12181     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12182         if (app.instrumentationWatcher != null) {
12183             try {
12184                 // NOTE:  IInstrumentationWatcher *must* be oneway here
12185                 app.instrumentationWatcher.instrumentationFinished(
12186                     app.instrumentationClass,
12187                     resultCode,
12188                     results);
12189             } catch (RemoteException e) {
12190             }
12191         }
12192         app.instrumentationWatcher = null;
12193         app.instrumentationClass = null;
12194         app.instrumentationInfo = null;
12195         app.instrumentationProfileFile = null;
12196         app.instrumentationArguments = null;
12197 
12198         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
12199     }
12200 
finishInstrumentation(IApplicationThread target, int resultCode, Bundle results)12201     public void finishInstrumentation(IApplicationThread target,
12202             int resultCode, Bundle results) {
12203         int userId = UserHandle.getCallingUserId();
12204         // Refuse possible leaked file descriptors
12205         if (results != null && results.hasFileDescriptors()) {
12206             throw new IllegalArgumentException("File descriptors passed in Intent");
12207         }
12208 
12209         synchronized(this) {
12210             ProcessRecord app = getRecordForAppLocked(target);
12211             if (app == null) {
12212                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
12213                 return;
12214             }
12215             final long origId = Binder.clearCallingIdentity();
12216             finishInstrumentationLocked(app, resultCode, results);
12217             Binder.restoreCallingIdentity(origId);
12218         }
12219     }
12220 
12221     // =========================================================
12222     // CONFIGURATION
12223     // =========================================================
12224 
getDeviceConfigurationInfo()12225     public ConfigurationInfo getDeviceConfigurationInfo() {
12226         ConfigurationInfo config = new ConfigurationInfo();
12227         synchronized (this) {
12228             config.reqTouchScreen = mConfiguration.touchscreen;
12229             config.reqKeyboardType = mConfiguration.keyboard;
12230             config.reqNavigation = mConfiguration.navigation;
12231             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12232                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12233                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12234             }
12235             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12236                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12237                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12238             }
12239             config.reqGlEsVersion = GL_ES_VERSION;
12240         }
12241         return config;
12242     }
12243 
getConfiguration()12244     public Configuration getConfiguration() {
12245         Configuration ci;
12246         synchronized(this) {
12247             ci = new Configuration(mConfiguration);
12248         }
12249         return ci;
12250     }
12251 
updatePersistentConfiguration(Configuration values)12252     public void updatePersistentConfiguration(Configuration values) {
12253         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12254                 "updateConfiguration()");
12255         enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12256                 "updateConfiguration()");
12257         if (values == null) {
12258             throw new NullPointerException("Configuration must not be null");
12259         }
12260 
12261         synchronized(this) {
12262             final long origId = Binder.clearCallingIdentity();
12263             updateConfigurationLocked(values, null, true, false);
12264             Binder.restoreCallingIdentity(origId);
12265         }
12266     }
12267 
updateConfiguration(Configuration values)12268     public void updateConfiguration(Configuration values) {
12269         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12270                 "updateConfiguration()");
12271 
12272         synchronized(this) {
12273             if (values == null && mWindowManager != null) {
12274                 // sentinel: fetch the current configuration from the window manager
12275                 values = mWindowManager.computeNewConfiguration();
12276             }
12277 
12278             if (mWindowManager != null) {
12279                 mProcessList.applyDisplaySize(mWindowManager);
12280             }
12281 
12282             final long origId = Binder.clearCallingIdentity();
12283             if (values != null) {
12284                 Settings.System.clearConfiguration(values);
12285             }
12286             updateConfigurationLocked(values, null, false, false);
12287             Binder.restoreCallingIdentity(origId);
12288         }
12289     }
12290 
12291     /**
12292      * Do either or both things: (1) change the current configuration, and (2)
12293      * make sure the given activity is running with the (now) current
12294      * configuration.  Returns true if the activity has been left running, or
12295      * false if <var>starting</var> is being destroyed to match the new
12296      * configuration.
12297      * @param persistent TODO
12298      */
updateConfigurationLocked(Configuration values, ActivityRecord starting, boolean persistent, boolean initLocale)12299     boolean updateConfigurationLocked(Configuration values,
12300             ActivityRecord starting, boolean persistent, boolean initLocale) {
12301         // do nothing if we are headless
12302         if (mHeadless) return true;
12303 
12304         int changes = 0;
12305 
12306         boolean kept = true;
12307 
12308         if (values != null) {
12309             Configuration newConfig = new Configuration(mConfiguration);
12310             changes = newConfig.updateFrom(values);
12311             if (changes != 0) {
12312                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12313                     Slog.i(TAG, "Updating configuration to: " + values);
12314                 }
12315 
12316                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12317 
12318                 if (values.locale != null && !initLocale) {
12319                     saveLocaleLocked(values.locale,
12320                                      !values.locale.equals(mConfiguration.locale),
12321                                      values.userSetLocale);
12322                 }
12323 
12324                 mConfigurationSeq++;
12325                 if (mConfigurationSeq <= 0) {
12326                     mConfigurationSeq = 1;
12327                 }
12328                 newConfig.seq = mConfigurationSeq;
12329                 mConfiguration = newConfig;
12330                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
12331 
12332                 final Configuration configCopy = new Configuration(mConfiguration);
12333 
12334                 // TODO: If our config changes, should we auto dismiss any currently
12335                 // showing dialogs?
12336                 mShowDialogs = shouldShowDialogs(newConfig);
12337 
12338                 AttributeCache ac = AttributeCache.instance();
12339                 if (ac != null) {
12340                     ac.updateConfiguration(configCopy);
12341                 }
12342 
12343                 // Make sure all resources in our process are updated
12344                 // right now, so that anyone who is going to retrieve
12345                 // resource values after we return will be sure to get
12346                 // the new ones.  This is especially important during
12347                 // boot, where the first config change needs to guarantee
12348                 // all resources have that config before following boot
12349                 // code is executed.
12350                 mSystemThread.applyConfigurationToResources(configCopy);
12351 
12352                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
12353                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12354                     msg.obj = new Configuration(configCopy);
12355                     mHandler.sendMessage(msg);
12356                 }
12357 
12358                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12359                     ProcessRecord app = mLruProcesses.get(i);
12360                     try {
12361                         if (app.thread != null) {
12362                             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12363                                     + app.processName + " new config " + mConfiguration);
12364                             app.thread.scheduleConfigurationChanged(configCopy);
12365                         }
12366                     } catch (Exception e) {
12367                     }
12368                 }
12369                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12370                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12371                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
12372                         | Intent.FLAG_RECEIVER_FOREGROUND);
12373                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12374                         null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12375                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12376                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
12377                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12378                     broadcastIntentLocked(null, null, intent,
12379                             null, null, 0, null, null,
12380                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12381                 }
12382             }
12383         }
12384 
12385         if (changes != 0 && starting == null) {
12386             // If the configuration changed, and the caller is not already
12387             // in the process of starting an activity, then find the top
12388             // activity to check if its configuration needs to change.
12389             starting = mMainStack.topRunningActivityLocked(null);
12390         }
12391 
12392         if (starting != null) {
12393             kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12394             // And we need to make sure at this point that all other activities
12395             // are made visible with the correct configuration.
12396             mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12397         }
12398 
12399         if (values != null && mWindowManager != null) {
12400             mWindowManager.setNewConfiguration(mConfiguration);
12401         }
12402 
12403         return kept;
12404     }
12405 
12406     /**
12407      * Decide based on the configuration whether we should shouw the ANR,
12408      * crash, etc dialogs.  The idea is that if there is no affordnace to
12409      * press the on-screen buttons, we shouldn't show the dialog.
12410      *
12411      * A thought: SystemUI might also want to get told about this, the Power
12412      * dialog / global actions also might want different behaviors.
12413      */
shouldShowDialogs(Configuration config)12414     private static final boolean shouldShowDialogs(Configuration config) {
12415         return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12416                 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12417     }
12418 
12419     /**
12420      * Save the locale.  You must be inside a synchronized (this) block.
12421      */
saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist)12422     private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12423         if(isDiff) {
12424             SystemProperties.set("user.language", l.getLanguage());
12425             SystemProperties.set("user.region", l.getCountry());
12426         }
12427 
12428         if(isPersist) {
12429             SystemProperties.set("persist.sys.language", l.getLanguage());
12430             SystemProperties.set("persist.sys.country", l.getCountry());
12431             SystemProperties.set("persist.sys.localevar", l.getVariant());
12432         }
12433     }
12434 
12435     @Override
targetTaskAffinityMatchesActivity(IBinder token, String destAffinity)12436     public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12437         ActivityRecord srec = ActivityRecord.forToken(token);
12438         return srec != null && srec.task.affinity != null &&
12439                 srec.task.affinity.equals(destAffinity);
12440     }
12441 
navigateUpTo(IBinder token, Intent destIntent, int resultCode, Intent resultData)12442     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12443             Intent resultData) {
12444         ComponentName dest = destIntent.getComponent();
12445 
12446         synchronized (this) {
12447             ActivityRecord srec = ActivityRecord.forToken(token);
12448             if (srec == null) {
12449                 return false;
12450             }
12451             ArrayList<ActivityRecord> history = srec.stack.mHistory;
12452             final int start = history.indexOf(srec);
12453             if (start < 0) {
12454                 // Current activity is not in history stack; do nothing.
12455                 return false;
12456             }
12457             int finishTo = start - 1;
12458             ActivityRecord parent = null;
12459             boolean foundParentInTask = false;
12460             if (dest != null) {
12461                 TaskRecord tr = srec.task;
12462                 for (int i = start - 1; i >= 0; i--) {
12463                     ActivityRecord r = history.get(i);
12464                     if (tr != r.task) {
12465                         // Couldn't find parent in the same task; stop at the one above this.
12466                         // (Root of current task; in-app "home" behavior)
12467                         // Always at least finish the current activity.
12468                         finishTo = Math.min(start - 1, i + 1);
12469                         parent = history.get(finishTo);
12470                         break;
12471                     } else if (r.info.packageName.equals(dest.getPackageName()) &&
12472                             r.info.name.equals(dest.getClassName())) {
12473                         finishTo = i;
12474                         parent = r;
12475                         foundParentInTask = true;
12476                         break;
12477                     }
12478                 }
12479             }
12480 
12481             if (mController != null) {
12482                 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12483                 if (next != null) {
12484                     // ask watcher if this is allowed
12485                     boolean resumeOK = true;
12486                     try {
12487                         resumeOK = mController.activityResuming(next.packageName);
12488                     } catch (RemoteException e) {
12489                         mController = null;
12490                     }
12491 
12492                     if (!resumeOK) {
12493                         return false;
12494                     }
12495                 }
12496             }
12497             final long origId = Binder.clearCallingIdentity();
12498             for (int i = start; i > finishTo; i--) {
12499                 ActivityRecord r = history.get(i);
12500                 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12501                         "navigate-up", true);
12502                 // Only return the supplied result for the first activity finished
12503                 resultCode = Activity.RESULT_CANCELED;
12504                 resultData = null;
12505             }
12506 
12507             if (parent != null && foundParentInTask) {
12508                 final int parentLaunchMode = parent.info.launchMode;
12509                 final int destIntentFlags = destIntent.getFlags();
12510                 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12511                         parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12512                         parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12513                         (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12514                     parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12515                 } else {
12516                     try {
12517                         ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12518                                 destIntent.getComponent(), 0, srec.userId);
12519                         int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12520                                 null, aInfo, parent.appToken, null,
12521                                 0, -1, parent.launchedFromUid, 0, null, true, null);
12522                         foundParentInTask = res == ActivityManager.START_SUCCESS;
12523                     } catch (RemoteException e) {
12524                         foundParentInTask = false;
12525                     }
12526                     mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12527                             resultData, "navigate-up", true);
12528                 }
12529             }
12530             Binder.restoreCallingIdentity(origId);
12531             return foundParentInTask;
12532         }
12533     }
12534 
getLaunchedFromUid(IBinder activityToken)12535     public int getLaunchedFromUid(IBinder activityToken) {
12536         ActivityRecord srec = ActivityRecord.forToken(activityToken);
12537         if (srec == null) {
12538             return -1;
12539         }
12540         return srec.launchedFromUid;
12541     }
12542 
12543     // =========================================================
12544     // LIFETIME MANAGEMENT
12545     // =========================================================
12546 
12547     // Returns which broadcast queue the app is the current [or imminent] receiver
12548     // on, or 'null' if the app is not an active broadcast recipient.
isReceivingBroadcast(ProcessRecord app)12549     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12550         BroadcastRecord r = app.curReceiver;
12551         if (r != null) {
12552             return r.queue;
12553         }
12554 
12555         // It's not the current receiver, but it might be starting up to become one
12556         synchronized (this) {
12557             for (BroadcastQueue queue : mBroadcastQueues) {
12558                 r = queue.mPendingBroadcast;
12559                 if (r != null && r.curApp == app) {
12560                     // found it; report which queue it's in
12561                     return queue;
12562                 }
12563             }
12564         }
12565 
12566         return null;
12567     }
12568 
computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll)12569     private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj,
12570             int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12571         if (mAdjSeq == app.adjSeq) {
12572             // This adjustment has already been computed.  If we are calling
12573             // from the top, we may have already computed our adjustment with
12574             // an earlier hidden adjustment that isn't really for us... if
12575             // so, use the new hidden adjustment.
12576             if (!recursed && app.hidden) {
12577                 if (app.hasActivities) {
12578                     app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
12579                 } else if (app.hasClientActivities) {
12580                     app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj;
12581                 } else {
12582                     app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj;
12583                 }
12584             }
12585             return app.curRawAdj;
12586         }
12587 
12588         if (app.thread == null) {
12589             app.adjSeq = mAdjSeq;
12590             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12591             return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12592         }
12593 
12594         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12595         app.adjSource = null;
12596         app.adjTarget = null;
12597         app.empty = false;
12598         app.hidden = false;
12599         app.hasClientActivities = false;
12600 
12601         final int activitiesSize = app.activities.size();
12602 
12603         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12604             // The max adjustment doesn't allow this app to be anything
12605             // below foreground, so it is not worth doing work for it.
12606             app.adjType = "fixed";
12607             app.adjSeq = mAdjSeq;
12608             app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12609             app.hasActivities = false;
12610             app.foregroundActivities = false;
12611             app.keeping = true;
12612             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12613             // System process can do UI, and when they do we want to have
12614             // them trim their memory after the user leaves the UI.  To
12615             // facilitate this, here we need to determine whether or not it
12616             // is currently showing UI.
12617             app.systemNoUi = true;
12618             if (app == TOP_APP) {
12619                 app.systemNoUi = false;
12620                 app.hasActivities = true;
12621             } else if (activitiesSize > 0) {
12622                 for (int j = 0; j < activitiesSize; j++) {
12623                     final ActivityRecord r = app.activities.get(j);
12624                     if (r.visible) {
12625                         app.systemNoUi = false;
12626                     }
12627                     if (r.app == app) {
12628                         app.hasActivities = true;
12629                     }
12630                 }
12631             }
12632             return (app.curAdj=app.maxAdj);
12633         }
12634 
12635         app.keeping = false;
12636         app.systemNoUi = false;
12637         app.hasActivities = false;
12638 
12639         // Determine the importance of the process, starting with most
12640         // important to least, and assign an appropriate OOM adjustment.
12641         int adj;
12642         int schedGroup;
12643         boolean foregroundActivities = false;
12644         boolean interesting = false;
12645         BroadcastQueue queue;
12646         if (app == TOP_APP) {
12647             // The last app on the list is the foreground app.
12648             adj = ProcessList.FOREGROUND_APP_ADJ;
12649             schedGroup = Process.THREAD_GROUP_DEFAULT;
12650             app.adjType = "top-activity";
12651             foregroundActivities = true;
12652             interesting = true;
12653             app.hasActivities = true;
12654         } else if (app.instrumentationClass != null) {
12655             // Don't want to kill running instrumentation.
12656             adj = ProcessList.FOREGROUND_APP_ADJ;
12657             schedGroup = Process.THREAD_GROUP_DEFAULT;
12658             app.adjType = "instrumentation";
12659             interesting = true;
12660         } else if ((queue = isReceivingBroadcast(app)) != null) {
12661             // An app that is currently receiving a broadcast also
12662             // counts as being in the foreground for OOM killer purposes.
12663             // It's placed in a sched group based on the nature of the
12664             // broadcast as reflected by which queue it's active in.
12665             adj = ProcessList.FOREGROUND_APP_ADJ;
12666             schedGroup = (queue == mFgBroadcastQueue)
12667                     ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12668             app.adjType = "broadcast";
12669         } else if (app.executingServices.size() > 0) {
12670             // An app that is currently executing a service callback also
12671             // counts as being in the foreground.
12672             adj = ProcessList.FOREGROUND_APP_ADJ;
12673             schedGroup = Process.THREAD_GROUP_DEFAULT;
12674             app.adjType = "exec-service";
12675         } else {
12676             // Assume process is hidden (has activities); we will correct
12677             // later if this is not the case.
12678             adj = hiddenAdj;
12679             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12680             app.hidden = true;
12681             app.adjType = "bg-act";
12682         }
12683 
12684         boolean hasStoppingActivities = false;
12685 
12686         // Examine all activities if not already foreground.
12687         if (!foregroundActivities && activitiesSize > 0) {
12688             for (int j = 0; j < activitiesSize; j++) {
12689                 final ActivityRecord r = app.activities.get(j);
12690                 if (r.visible) {
12691                     // App has a visible activity; only upgrade adjustment.
12692                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
12693                         adj = ProcessList.VISIBLE_APP_ADJ;
12694                         app.adjType = "visible";
12695                     }
12696                     schedGroup = Process.THREAD_GROUP_DEFAULT;
12697                     app.hidden = false;
12698                     app.hasActivities = true;
12699                     foregroundActivities = true;
12700                     break;
12701                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12702                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12703                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12704                         app.adjType = "pausing";
12705                     }
12706                     app.hidden = false;
12707                     foregroundActivities = true;
12708                 } else if (r.state == ActivityState.STOPPING) {
12709                     // We will apply the actual adjustment later, because
12710                     // we want to allow this process to immediately go through
12711                     // any memory trimming that is in effect.
12712                     app.hidden = false;
12713                     foregroundActivities = true;
12714                     hasStoppingActivities = true;
12715                 }
12716                 if (r.app == app) {
12717                     app.hasActivities = true;
12718                 }
12719             }
12720         }
12721 
12722         if (adj == hiddenAdj && !app.hasActivities) {
12723             if (app.hasClientActivities) {
12724                 adj = clientHiddenAdj;
12725                 app.adjType = "bg-client-act";
12726             } else {
12727                 // Whoops, this process is completely empty as far as we know
12728                 // at this point.
12729                 adj = emptyAdj;
12730                 app.empty = true;
12731                 app.adjType = "bg-empty";
12732             }
12733         }
12734 
12735         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12736             if (app.foregroundServices) {
12737                 // The user is aware of this app, so make it visible.
12738                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12739                 app.hidden = false;
12740                 app.adjType = "fg-service";
12741                 schedGroup = Process.THREAD_GROUP_DEFAULT;
12742             } else if (app.forcingToForeground != null) {
12743                 // The user is aware of this app, so make it visible.
12744                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12745                 app.hidden = false;
12746                 app.adjType = "force-fg";
12747                 app.adjSource = app.forcingToForeground;
12748                 schedGroup = Process.THREAD_GROUP_DEFAULT;
12749             }
12750         }
12751 
12752         if (app.foregroundServices) {
12753             interesting = true;
12754         }
12755 
12756         if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12757             // We don't want to kill the current heavy-weight process.
12758             adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12759             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12760             app.hidden = false;
12761             app.adjType = "heavy";
12762         }
12763 
12764         if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12765             // This process is hosting what we currently consider to be the
12766             // home app, so we don't want to let it go into the background.
12767             adj = ProcessList.HOME_APP_ADJ;
12768             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12769             app.hidden = false;
12770             app.adjType = "home";
12771         }
12772 
12773         if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12774                 && app.activities.size() > 0) {
12775             // This was the previous process that showed UI to the user.
12776             // We want to try to keep it around more aggressively, to give
12777             // a good experience around switching between two apps.
12778             adj = ProcessList.PREVIOUS_APP_ADJ;
12779             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12780             app.hidden = false;
12781             app.adjType = "previous";
12782         }
12783 
12784         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12785                 + " reason=" + app.adjType);
12786 
12787         // By default, we use the computed adjustment.  It may be changed if
12788         // there are applications dependent on our services or providers, but
12789         // this gives us a baseline and makes sure we don't get into an
12790         // infinite recursion.
12791         app.adjSeq = mAdjSeq;
12792         app.curRawAdj = app.nonStoppingAdj = adj;
12793 
12794         if (mBackupTarget != null && app == mBackupTarget.app) {
12795             // If possible we want to avoid killing apps while they're being backed up
12796             if (adj > ProcessList.BACKUP_APP_ADJ) {
12797                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12798                 adj = ProcessList.BACKUP_APP_ADJ;
12799                 app.adjType = "backup";
12800                 app.hidden = false;
12801             }
12802         }
12803 
12804         if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12805                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12806             final long now = SystemClock.uptimeMillis();
12807             // This process is more important if the top activity is
12808             // bound to the service.
12809             Iterator<ServiceRecord> jt = app.services.iterator();
12810             while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12811                 ServiceRecord s = jt.next();
12812                 if (s.startRequested) {
12813                     if (app.hasShownUi && app != mHomeProcess) {
12814                         // If this process has shown some UI, let it immediately
12815                         // go to the LRU list because it may be pretty heavy with
12816                         // UI stuff.  We'll tag it with a label just to help
12817                         // debug and understand what is going on.
12818                         if (adj > ProcessList.SERVICE_ADJ) {
12819                             app.adjType = "started-bg-ui-services";
12820                         }
12821                     } else {
12822                         if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12823                             // This service has seen some activity within
12824                             // recent memory, so we will keep its process ahead
12825                             // of the background processes.
12826                             if (adj > ProcessList.SERVICE_ADJ) {
12827                                 adj = ProcessList.SERVICE_ADJ;
12828                                 app.adjType = "started-services";
12829                                 app.hidden = false;
12830                             }
12831                         }
12832                         // If we have let the service slide into the background
12833                         // state, still have some text describing what it is doing
12834                         // even though the service no longer has an impact.
12835                         if (adj > ProcessList.SERVICE_ADJ) {
12836                             app.adjType = "started-bg-services";
12837                         }
12838                     }
12839                     // Don't kill this process because it is doing work; it
12840                     // has said it is doing work.
12841                     app.keeping = true;
12842                 }
12843                 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12844                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12845                     Iterator<ArrayList<ConnectionRecord>> kt
12846                             = s.connections.values().iterator();
12847                     while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12848                         ArrayList<ConnectionRecord> clist = kt.next();
12849                         for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12850                             // XXX should compute this based on the max of
12851                             // all connected clients.
12852                             ConnectionRecord cr = clist.get(i);
12853                             if (cr.binding.client == app) {
12854                                 // Binding to ourself is not interesting.
12855                                 continue;
12856                             }
12857                             if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12858                                 ProcessRecord client = cr.binding.client;
12859                                 int clientAdj = adj;
12860                                 int myHiddenAdj = hiddenAdj;
12861                                 if (myHiddenAdj > client.hiddenAdj) {
12862                                     if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12863                                         myHiddenAdj = client.hiddenAdj;
12864                                     } else {
12865                                         myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12866                                     }
12867                                 }
12868                                 int myClientHiddenAdj = clientHiddenAdj;
12869                                 if (myClientHiddenAdj > client.clientHiddenAdj) {
12870                                     if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12871                                         myClientHiddenAdj = client.clientHiddenAdj;
12872                                     } else {
12873                                         myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12874                                     }
12875                                 }
12876                                 int myEmptyAdj = emptyAdj;
12877                                 if (myEmptyAdj > client.emptyAdj) {
12878                                     if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12879                                         myEmptyAdj = client.emptyAdj;
12880                                     } else {
12881                                         myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12882                                     }
12883                                 }
12884                                 clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12885                                         myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
12886                                 String adjType = null;
12887                                 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12888                                     // Not doing bind OOM management, so treat
12889                                     // this guy more like a started service.
12890                                     if (app.hasShownUi && app != mHomeProcess) {
12891                                         // If this process has shown some UI, let it immediately
12892                                         // go to the LRU list because it may be pretty heavy with
12893                                         // UI stuff.  We'll tag it with a label just to help
12894                                         // debug and understand what is going on.
12895                                         if (adj > clientAdj) {
12896                                             adjType = "bound-bg-ui-services";
12897                                         }
12898                                         app.hidden = false;
12899                                         clientAdj = adj;
12900                                     } else {
12901                                         if (now >= (s.lastActivity
12902                                                 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12903                                             // This service has not seen activity within
12904                                             // recent memory, so allow it to drop to the
12905                                             // LRU list if there is no other reason to keep
12906                                             // it around.  We'll also tag it with a label just
12907                                             // to help debug and undertand what is going on.
12908                                             if (adj > clientAdj) {
12909                                                 adjType = "bound-bg-services";
12910                                             }
12911                                             clientAdj = adj;
12912                                         }
12913                                     }
12914                                 } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12915                                     if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
12916                                         // If this connection is keeping the service
12917                                         // created, then we want to try to better follow
12918                                         // its memory management semantics for activities.
12919                                         // That is, if it is sitting in the background
12920                                         // LRU list as a hidden process (with activities),
12921                                         // we don't want the service it is connected to
12922                                         // to go into the empty LRU and quickly get killed,
12923                                         // because I'll we'll do is just end up restarting
12924                                         // the service.
12925                                         app.hasClientActivities |= client.hasActivities;
12926                                     }
12927                                 }
12928                                 if (adj > clientAdj) {
12929                                     // If this process has recently shown UI, and
12930                                     // the process that is binding to it is less
12931                                     // important than being visible, then we don't
12932                                     // care about the binding as much as we care
12933                                     // about letting this process get into the LRU
12934                                     // list to be killed and restarted if needed for
12935                                     // memory.
12936                                     if (app.hasShownUi && app != mHomeProcess
12937                                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12938                                         adjType = "bound-bg-ui-services";
12939                                     } else {
12940                                         if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12941                                                 |Context.BIND_IMPORTANT)) != 0) {
12942                                             adj = clientAdj;
12943                                         } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12944                                                 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12945                                                 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12946                                             adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12947                                         } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12948                                             adj = clientAdj;
12949                                         } else {
12950                                             app.pendingUiClean = true;
12951                                             if (adj > ProcessList.VISIBLE_APP_ADJ) {
12952                                                 adj = ProcessList.VISIBLE_APP_ADJ;
12953                                             }
12954                                         }
12955                                         if (!client.hidden) {
12956                                             app.hidden = false;
12957                                         }
12958                                         if (client.keeping) {
12959                                             app.keeping = true;
12960                                         }
12961                                         adjType = "service";
12962                                     }
12963                                 }
12964                                 if (adjType != null) {
12965                                     app.adjType = adjType;
12966                                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12967                                             .REASON_SERVICE_IN_USE;
12968                                     app.adjSource = cr.binding.client;
12969                                     app.adjSourceOom = clientAdj;
12970                                     app.adjTarget = s.name;
12971                                 }
12972                                 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12973                                     if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12974                                         schedGroup = Process.THREAD_GROUP_DEFAULT;
12975                                     }
12976                                 }
12977                             }
12978                             final ActivityRecord a = cr.activity;
12979                             if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12980                                 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12981                                         (a.visible || a.state == ActivityState.RESUMED
12982                                          || a.state == ActivityState.PAUSING)) {
12983                                     adj = ProcessList.FOREGROUND_APP_ADJ;
12984                                     if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12985                                         schedGroup = Process.THREAD_GROUP_DEFAULT;
12986                                     }
12987                                     app.hidden = false;
12988                                     app.adjType = "service";
12989                                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12990                                             .REASON_SERVICE_IN_USE;
12991                                     app.adjSource = a;
12992                                     app.adjSourceOom = adj;
12993                                     app.adjTarget = s.name;
12994                                 }
12995                             }
12996                         }
12997                     }
12998                 }
12999             }
13000 
13001             // Finally, if this process has active services running in it, we
13002             // would like to avoid killing it unless it would prevent the current
13003             // application from running.  By default we put the process in
13004             // with the rest of the background processes; as we scan through
13005             // its services we may bump it up from there.
13006             if (adj > hiddenAdj) {
13007                 adj = hiddenAdj;
13008                 app.hidden = false;
13009                 app.adjType = "bg-services";
13010             }
13011         }
13012 
13013         if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13014                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13015             Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
13016             while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
13017                     || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13018                 ContentProviderRecord cpr = jt.next();
13019                 for (int i = cpr.connections.size()-1;
13020                         i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13021                                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
13022                         i--) {
13023                     ContentProviderConnection conn = cpr.connections.get(i);
13024                     ProcessRecord client = conn.client;
13025                     if (client == app) {
13026                         // Being our own client is not interesting.
13027                         continue;
13028                     }
13029                     int myHiddenAdj = hiddenAdj;
13030                     if (myHiddenAdj > client.hiddenAdj) {
13031                         if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
13032                             myHiddenAdj = client.hiddenAdj;
13033                         } else {
13034                             myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
13035                         }
13036                     }
13037                     int myClientHiddenAdj = clientHiddenAdj;
13038                     if (myClientHiddenAdj > client.clientHiddenAdj) {
13039                         if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) {
13040                             myClientHiddenAdj = client.clientHiddenAdj;
13041                         } else {
13042                             myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
13043                         }
13044                     }
13045                     int myEmptyAdj = emptyAdj;
13046                     if (myEmptyAdj > client.emptyAdj) {
13047                         if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
13048                             myEmptyAdj = client.emptyAdj;
13049                         } else {
13050                             myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
13051                         }
13052                     }
13053                     int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
13054                             myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
13055                     if (adj > clientAdj) {
13056                         if (app.hasShownUi && app != mHomeProcess
13057                                 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13058                             app.adjType = "bg-ui-provider";
13059                         } else {
13060                             adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13061                                     ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
13062                             app.adjType = "provider";
13063                         }
13064                         if (!client.hidden) {
13065                             app.hidden = false;
13066                         }
13067                         if (client.keeping) {
13068                             app.keeping = true;
13069                         }
13070                         app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13071                                 .REASON_PROVIDER_IN_USE;
13072                         app.adjSource = client;
13073                         app.adjSourceOom = clientAdj;
13074                         app.adjTarget = cpr.name;
13075                     }
13076                     if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13077                         schedGroup = Process.THREAD_GROUP_DEFAULT;
13078                     }
13079                 }
13080                 // If the provider has external (non-framework) process
13081                 // dependencies, ensure that its adjustment is at least
13082                 // FOREGROUND_APP_ADJ.
13083                 if (cpr.hasExternalProcessHandles()) {
13084                     if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13085                         adj = ProcessList.FOREGROUND_APP_ADJ;
13086                         schedGroup = Process.THREAD_GROUP_DEFAULT;
13087                         app.hidden = false;
13088                         app.keeping = true;
13089                         app.adjType = "provider";
13090                         app.adjTarget = cpr.name;
13091                     }
13092                 }
13093             }
13094         }
13095 
13096         if (adj == ProcessList.SERVICE_ADJ) {
13097             if (doingAll) {
13098                 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
13099                 mNewNumServiceProcs++;
13100             }
13101             if (app.serviceb) {
13102                 adj = ProcessList.SERVICE_B_ADJ;
13103             }
13104         } else {
13105             app.serviceb = false;
13106         }
13107 
13108         app.nonStoppingAdj = adj;
13109 
13110         if (hasStoppingActivities) {
13111             // Only upgrade adjustment.
13112             if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13113                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13114                 app.adjType = "stopping";
13115             }
13116         }
13117 
13118         app.curRawAdj = adj;
13119 
13120         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
13121         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13122         if (adj > app.maxAdj) {
13123             adj = app.maxAdj;
13124             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
13125                 schedGroup = Process.THREAD_GROUP_DEFAULT;
13126             }
13127         }
13128         if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13129             app.keeping = true;
13130         }
13131 
13132         if (app.hasAboveClient) {
13133             // If this process has bound to any services with BIND_ABOVE_CLIENT,
13134             // then we need to drop its adjustment to be lower than the service's
13135             // in order to honor the request.  We want to drop it by one adjustment
13136             // level...  but there is special meaning applied to various levels so
13137             // we will skip some of them.
13138             if (adj < ProcessList.FOREGROUND_APP_ADJ) {
13139                 // System process will not get dropped, ever
13140             } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13141                 adj = ProcessList.VISIBLE_APP_ADJ;
13142             } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13143                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13144             } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13145                 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13146             } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
13147                 adj++;
13148             }
13149         }
13150 
13151         int importance = app.memImportance;
13152         if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
13153             app.curAdj = adj;
13154             app.curSchedGroup = schedGroup;
13155             if (!interesting) {
13156                 // For this reporting, if there is not something explicitly
13157                 // interesting in this process then we will push it to the
13158                 // background importance.
13159                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13160             } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13161                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13162             } else if (adj >= ProcessList.SERVICE_B_ADJ) {
13163                 importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13164             } else if (adj >= ProcessList.HOME_APP_ADJ) {
13165                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13166             } else if (adj >= ProcessList.SERVICE_ADJ) {
13167                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13168             } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13169                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
13170             } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
13171                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
13172             } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
13173                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
13174             } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
13175                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
13176             } else {
13177                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
13178             }
13179         }
13180 
13181         int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
13182         if (foregroundActivities != app.foregroundActivities) {
13183             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
13184         }
13185         if (changes != 0) {
13186             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
13187             app.memImportance = importance;
13188             app.foregroundActivities = foregroundActivities;
13189             int i = mPendingProcessChanges.size()-1;
13190             ProcessChangeItem item = null;
13191             while (i >= 0) {
13192                 item = mPendingProcessChanges.get(i);
13193                 if (item.pid == app.pid) {
13194                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
13195                     break;
13196                 }
13197                 i--;
13198             }
13199             if (i < 0) {
13200                 // No existing item in pending changes; need a new one.
13201                 final int NA = mAvailProcessChanges.size();
13202                 if (NA > 0) {
13203                     item = mAvailProcessChanges.remove(NA-1);
13204                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
13205                 } else {
13206                     item = new ProcessChangeItem();
13207                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
13208                 }
13209                 item.changes = 0;
13210                 item.pid = app.pid;
13211                 item.uid = app.info.uid;
13212                 if (mPendingProcessChanges.size() == 0) {
13213                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
13214                             "*** Enqueueing dispatch processes changed!");
13215                     mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
13216                 }
13217                 mPendingProcessChanges.add(item);
13218             }
13219             item.changes |= changes;
13220             item.importance = importance;
13221             item.foregroundActivities = foregroundActivities;
13222             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
13223                     + Integer.toHexString(System.identityHashCode(item))
13224                     + " " + app.toShortString() + ": changes=" + item.changes
13225                     + " importance=" + item.importance
13226                     + " foreground=" + item.foregroundActivities
13227                     + " type=" + app.adjType + " source=" + app.adjSource
13228                     + " target=" + app.adjTarget);
13229         }
13230 
13231         return app.curRawAdj;
13232     }
13233 
13234     /**
13235      * Ask a given process to GC right now.
13236      */
performAppGcLocked(ProcessRecord app)13237     final void performAppGcLocked(ProcessRecord app) {
13238         try {
13239             app.lastRequestedGc = SystemClock.uptimeMillis();
13240             if (app.thread != null) {
13241                 if (app.reportLowMemory) {
13242                     app.reportLowMemory = false;
13243                     app.thread.scheduleLowMemory();
13244                 } else {
13245                     app.thread.processInBackground();
13246                 }
13247             }
13248         } catch (Exception e) {
13249             // whatever.
13250         }
13251     }
13252 
13253     /**
13254      * Returns true if things are idle enough to perform GCs.
13255      */
canGcNowLocked()13256     private final boolean canGcNowLocked() {
13257         boolean processingBroadcasts = false;
13258         for (BroadcastQueue q : mBroadcastQueues) {
13259             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
13260                 processingBroadcasts = true;
13261             }
13262         }
13263         return !processingBroadcasts
13264                 && (mSleeping || (mMainStack.mResumedActivity != null &&
13265                         mMainStack.mResumedActivity.idle));
13266     }
13267 
13268     /**
13269      * Perform GCs on all processes that are waiting for it, but only
13270      * if things are idle.
13271      */
performAppGcsLocked()13272     final void performAppGcsLocked() {
13273         final int N = mProcessesToGc.size();
13274         if (N <= 0) {
13275             return;
13276         }
13277         if (canGcNowLocked()) {
13278             while (mProcessesToGc.size() > 0) {
13279                 ProcessRecord proc = mProcessesToGc.remove(0);
13280                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
13281                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13282                             <= SystemClock.uptimeMillis()) {
13283                         // To avoid spamming the system, we will GC processes one
13284                         // at a time, waiting a few seconds between each.
13285                         performAppGcLocked(proc);
13286                         scheduleAppGcsLocked();
13287                         return;
13288                     } else {
13289                         // It hasn't been long enough since we last GCed this
13290                         // process...  put it in the list to wait for its time.
13291                         addProcessToGcListLocked(proc);
13292                         break;
13293                     }
13294                 }
13295             }
13296 
13297             scheduleAppGcsLocked();
13298         }
13299     }
13300 
13301     /**
13302      * If all looks good, perform GCs on all processes waiting for them.
13303      */
performAppGcsIfAppropriateLocked()13304     final void performAppGcsIfAppropriateLocked() {
13305         if (canGcNowLocked()) {
13306             performAppGcsLocked();
13307             return;
13308         }
13309         // Still not idle, wait some more.
13310         scheduleAppGcsLocked();
13311     }
13312 
13313     /**
13314      * Schedule the execution of all pending app GCs.
13315      */
scheduleAppGcsLocked()13316     final void scheduleAppGcsLocked() {
13317         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13318 
13319         if (mProcessesToGc.size() > 0) {
13320             // Schedule a GC for the time to the next process.
13321             ProcessRecord proc = mProcessesToGc.get(0);
13322             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13323 
13324             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
13325             long now = SystemClock.uptimeMillis();
13326             if (when < (now+GC_TIMEOUT)) {
13327                 when = now + GC_TIMEOUT;
13328             }
13329             mHandler.sendMessageAtTime(msg, when);
13330         }
13331     }
13332 
13333     /**
13334      * Add a process to the array of processes waiting to be GCed.  Keeps the
13335      * list in sorted order by the last GC time.  The process can't already be
13336      * on the list.
13337      */
addProcessToGcListLocked(ProcessRecord proc)13338     final void addProcessToGcListLocked(ProcessRecord proc) {
13339         boolean added = false;
13340         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13341             if (mProcessesToGc.get(i).lastRequestedGc <
13342                     proc.lastRequestedGc) {
13343                 added = true;
13344                 mProcessesToGc.add(i+1, proc);
13345                 break;
13346             }
13347         }
13348         if (!added) {
13349             mProcessesToGc.add(0, proc);
13350         }
13351     }
13352 
13353     /**
13354      * Set up to ask a process to GC itself.  This will either do it
13355      * immediately, or put it on the list of processes to gc the next
13356      * time things are idle.
13357      */
scheduleAppGcLocked(ProcessRecord app)13358     final void scheduleAppGcLocked(ProcessRecord app) {
13359         long now = SystemClock.uptimeMillis();
13360         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13361             return;
13362         }
13363         if (!mProcessesToGc.contains(app)) {
13364             addProcessToGcListLocked(app);
13365             scheduleAppGcsLocked();
13366         }
13367     }
13368 
checkExcessivePowerUsageLocked(boolean doKills)13369     final void checkExcessivePowerUsageLocked(boolean doKills) {
13370         updateCpuStatsNow();
13371 
13372         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13373         boolean doWakeKills = doKills;
13374         boolean doCpuKills = doKills;
13375         if (mLastPowerCheckRealtime == 0) {
13376             doWakeKills = false;
13377         }
13378         if (mLastPowerCheckUptime == 0) {
13379             doCpuKills = false;
13380         }
13381         if (stats.isScreenOn()) {
13382             doWakeKills = false;
13383         }
13384         final long curRealtime = SystemClock.elapsedRealtime();
13385         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13386         final long curUptime = SystemClock.uptimeMillis();
13387         final long uptimeSince = curUptime - mLastPowerCheckUptime;
13388         mLastPowerCheckRealtime = curRealtime;
13389         mLastPowerCheckUptime = curUptime;
13390         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13391             doWakeKills = false;
13392         }
13393         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13394             doCpuKills = false;
13395         }
13396         int i = mLruProcesses.size();
13397         while (i > 0) {
13398             i--;
13399             ProcessRecord app = mLruProcesses.get(i);
13400             if (!app.keeping) {
13401                 long wtime;
13402                 synchronized (stats) {
13403                     wtime = stats.getProcessWakeTime(app.info.uid,
13404                             app.pid, curRealtime);
13405                 }
13406                 long wtimeUsed = wtime - app.lastWakeTime;
13407                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13408                 if (DEBUG_POWER) {
13409                     StringBuilder sb = new StringBuilder(128);
13410                     sb.append("Wake for ");
13411                     app.toShortString(sb);
13412                     sb.append(": over ");
13413                     TimeUtils.formatDuration(realtimeSince, sb);
13414                     sb.append(" used ");
13415                     TimeUtils.formatDuration(wtimeUsed, sb);
13416                     sb.append(" (");
13417                     sb.append((wtimeUsed*100)/realtimeSince);
13418                     sb.append("%)");
13419                     Slog.i(TAG, sb.toString());
13420                     sb.setLength(0);
13421                     sb.append("CPU for ");
13422                     app.toShortString(sb);
13423                     sb.append(": over ");
13424                     TimeUtils.formatDuration(uptimeSince, sb);
13425                     sb.append(" used ");
13426                     TimeUtils.formatDuration(cputimeUsed, sb);
13427                     sb.append(" (");
13428                     sb.append((cputimeUsed*100)/uptimeSince);
13429                     sb.append("%)");
13430                     Slog.i(TAG, sb.toString());
13431                 }
13432                 // If a process has held a wake lock for more
13433                 // than 50% of the time during this period,
13434                 // that sounds bad.  Kill!
13435                 if (doWakeKills && realtimeSince > 0
13436                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
13437                     synchronized (stats) {
13438                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13439                                 realtimeSince, wtimeUsed);
13440                     }
13441                     Slog.w(TAG, "Excessive wake lock in " + app.processName
13442                             + " (pid " + app.pid + "): held " + wtimeUsed
13443                             + " during " + realtimeSince);
13444                     EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13445                             app.processName, app.setAdj, "excessive wake lock");
13446                     Process.killProcessQuiet(app.pid);
13447                 } else if (doCpuKills && uptimeSince > 0
13448                         && ((cputimeUsed*100)/uptimeSince) >= 50) {
13449                     synchronized (stats) {
13450                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13451                                 uptimeSince, cputimeUsed);
13452                     }
13453                     Slog.w(TAG, "Excessive CPU in " + app.processName
13454                             + " (pid " + app.pid + "): used " + cputimeUsed
13455                             + " during " + uptimeSince);
13456                     EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13457                             app.processName, app.setAdj, "excessive cpu");
13458                     Process.killProcessQuiet(app.pid);
13459                 } else {
13460                     app.lastWakeTime = wtime;
13461                     app.lastCpuTime = app.curCpuTime;
13462                 }
13463             }
13464         }
13465     }
13466 
updateOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll)13467     private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13468             int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
13469         app.hiddenAdj = hiddenAdj;
13470         app.clientHiddenAdj = clientHiddenAdj;
13471         app.emptyAdj = emptyAdj;
13472 
13473         if (app.thread == null) {
13474             return false;
13475         }
13476 
13477         final boolean wasKeeping = app.keeping;
13478 
13479         boolean success = true;
13480 
13481         computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll);
13482 
13483         if (app.curRawAdj != app.setRawAdj) {
13484             if (wasKeeping && !app.keeping) {
13485                 // This app is no longer something we want to keep.  Note
13486                 // its current wake lock time to later know to kill it if
13487                 // it is not behaving well.
13488                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13489                 synchronized (stats) {
13490                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13491                             app.pid, SystemClock.elapsedRealtime());
13492                 }
13493                 app.lastCpuTime = app.curCpuTime;
13494             }
13495 
13496             app.setRawAdj = app.curRawAdj;
13497         }
13498 
13499         if (app.curAdj != app.setAdj) {
13500             if (Process.setOomAdj(app.pid, app.curAdj)) {
13501                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13502                     TAG, "Set " + app.pid + " " + app.processName +
13503                     " adj " + app.curAdj + ": " + app.adjType);
13504                 app.setAdj = app.curAdj;
13505             } else {
13506                 success = false;
13507                 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13508             }
13509         }
13510         if (app.setSchedGroup != app.curSchedGroup) {
13511             app.setSchedGroup = app.curSchedGroup;
13512             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13513                     "Setting process group of " + app.processName
13514                     + " to " + app.curSchedGroup);
13515             if (app.waitingToKill != null &&
13516                     app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13517                 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13518                 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13519                         app.processName, app.setAdj, app.waitingToKill);
13520                 app.killedBackground = true;
13521                 Process.killProcessQuiet(app.pid);
13522                 success = false;
13523             } else {
13524                 if (true) {
13525                     long oldId = Binder.clearCallingIdentity();
13526                     try {
13527                         Process.setProcessGroup(app.pid, app.curSchedGroup);
13528                     } catch (Exception e) {
13529                         Slog.w(TAG, "Failed setting process group of " + app.pid
13530                                 + " to " + app.curSchedGroup);
13531                         e.printStackTrace();
13532                     } finally {
13533                         Binder.restoreCallingIdentity(oldId);
13534                     }
13535                 } else {
13536                     if (app.thread != null) {
13537                         try {
13538                             app.thread.setSchedulingGroup(app.curSchedGroup);
13539                         } catch (RemoteException e) {
13540                         }
13541                     }
13542                 }
13543             }
13544         }
13545         return success;
13546     }
13547 
resumedAppLocked()13548     private final ActivityRecord resumedAppLocked() {
13549         ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13550         if (resumedActivity == null || resumedActivity.app == null) {
13551             resumedActivity = mMainStack.mPausingActivity;
13552             if (resumedActivity == null || resumedActivity.app == null) {
13553                 resumedActivity = mMainStack.topRunningActivityLocked(null);
13554             }
13555         }
13556         return resumedActivity;
13557     }
13558 
updateOomAdjLocked(ProcessRecord app)13559     final boolean updateOomAdjLocked(ProcessRecord app) {
13560         final ActivityRecord TOP_ACT = resumedAppLocked();
13561         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13562         int curAdj = app.curAdj;
13563         final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13564             && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13565 
13566         mAdjSeq++;
13567 
13568         boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj,
13569                 app.emptyAdj, TOP_APP, false);
13570         final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13571             && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13572         if (nowHidden != wasHidden) {
13573             // Changed to/from hidden state, so apps after it in the LRU
13574             // list may also be changed.
13575             updateOomAdjLocked();
13576         }
13577         return success;
13578     }
13579 
updateOomAdjLocked()13580     final void updateOomAdjLocked() {
13581         final ActivityRecord TOP_ACT = resumedAppLocked();
13582         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13583         final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME;
13584 
13585         if (false) {
13586             RuntimeException e = new RuntimeException();
13587             e.fillInStackTrace();
13588             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13589         }
13590 
13591         mAdjSeq++;
13592         mNewNumServiceProcs = 0;
13593 
13594         final int emptyProcessLimit;
13595         final int hiddenProcessLimit;
13596         if (mProcessLimit <= 0) {
13597             emptyProcessLimit = hiddenProcessLimit = 0;
13598         } else if (mProcessLimit == 1) {
13599             emptyProcessLimit = 1;
13600             hiddenProcessLimit = 0;
13601         } else {
13602             emptyProcessLimit = (mProcessLimit*2)/3;
13603             hiddenProcessLimit = mProcessLimit - emptyProcessLimit;
13604         }
13605 
13606         // Let's determine how many processes we have running vs.
13607         // how many slots we have for background processes; we may want
13608         // to put multiple processes in a slot of there are enough of
13609         // them.
13610         int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13611                 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13612         int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs;
13613         if (numEmptyProcs > hiddenProcessLimit) {
13614             // If there are more empty processes than our limit on hidden
13615             // processes, then use the hidden process limit for the factor.
13616             // This ensures that the really old empty processes get pushed
13617             // down to the bottom, so if we are running low on memory we will
13618             // have a better chance at keeping around more hidden processes
13619             // instead of a gazillion empty processes.
13620             numEmptyProcs = hiddenProcessLimit;
13621         }
13622         int emptyFactor = numEmptyProcs/numSlots;
13623         if (emptyFactor < 1) emptyFactor = 1;
13624         int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13625         if (hiddenFactor < 1) hiddenFactor = 1;
13626         int stepHidden = 0;
13627         int stepEmpty = 0;
13628         int numHidden = 0;
13629         int numEmpty = 0;
13630         int numTrimming = 0;
13631 
13632         mNumNonHiddenProcs = 0;
13633         mNumHiddenProcs = 0;
13634 
13635         // First update the OOM adjustment for each of the
13636         // application processes based on their current state.
13637         int i = mLruProcesses.size();
13638         int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13639         int nextHiddenAdj = curHiddenAdj+1;
13640         int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13641         int nextEmptyAdj = curEmptyAdj+2;
13642         int curClientHiddenAdj = curEmptyAdj;
13643         while (i > 0) {
13644             i--;
13645             ProcessRecord app = mLruProcesses.get(i);
13646             //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13647             updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true);
13648             if (!app.killedBackground) {
13649                 if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13650                     // This process was assigned as a hidden process...  step the
13651                     // hidden level.
13652                     mNumHiddenProcs++;
13653                     if (curHiddenAdj != nextHiddenAdj) {
13654                         stepHidden++;
13655                         if (stepHidden >= hiddenFactor) {
13656                             stepHidden = 0;
13657                             curHiddenAdj = nextHiddenAdj;
13658                             nextHiddenAdj += 2;
13659                             if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13660                                 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13661                             }
13662                             if (curClientHiddenAdj <= curHiddenAdj) {
13663                                 curClientHiddenAdj = curHiddenAdj + 1;
13664                                 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13665                                     curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13666                                 }
13667                             }
13668                         }
13669                     }
13670                     numHidden++;
13671                     if (numHidden > hiddenProcessLimit) {
13672                         Slog.i(TAG, "No longer want " + app.processName
13673                                 + " (pid " + app.pid + "): hidden #" + numHidden);
13674                         EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13675                                 app.processName, app.setAdj, "too many background");
13676                         app.killedBackground = true;
13677                         Process.killProcessQuiet(app.pid);
13678                     }
13679                 } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) {
13680                     // This process has a client that has activities.  We will have
13681                     // given it the current hidden adj; here we will just leave it
13682                     // without stepping the hidden adj.
13683                     curClientHiddenAdj++;
13684                     if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13685                         curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13686                     }
13687                 } else {
13688                     if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13689                         // This process was assigned as an empty process...  step the
13690                         // empty level.
13691                         if (curEmptyAdj != nextEmptyAdj) {
13692                             stepEmpty++;
13693                             if (stepEmpty >= emptyFactor) {
13694                                 stepEmpty = 0;
13695                                 curEmptyAdj = nextEmptyAdj;
13696                                 nextEmptyAdj += 2;
13697                                 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13698                                     nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13699                                 }
13700                             }
13701                         }
13702                     } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13703                         mNumNonHiddenProcs++;
13704                     }
13705                     if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13706                             && !app.hasClientActivities) {
13707                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
13708                                 && app.lastActivityTime < oldTime) {
13709                             Slog.i(TAG, "No longer want " + app.processName
13710                                     + " (pid " + app.pid + "): empty for "
13711                                     + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime)
13712                                             / 1000) + "s");
13713                             EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13714                                     app.processName, app.setAdj, "old background process");
13715                             app.killedBackground = true;
13716                             Process.killProcessQuiet(app.pid);
13717                         } else {
13718                             numEmpty++;
13719                             if (numEmpty > emptyProcessLimit) {
13720                                 Slog.i(TAG, "No longer want " + app.processName
13721                                         + " (pid " + app.pid + "): empty #" + numEmpty);
13722                                 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13723                                         app.processName, app.setAdj, "too many background");
13724                                 app.killedBackground = true;
13725                                 Process.killProcessQuiet(app.pid);
13726                             }
13727                         }
13728                     }
13729                 }
13730                 if (app.isolated && app.services.size() <= 0) {
13731                     // If this is an isolated process, and there are no
13732                     // services running in it, then the process is no longer
13733                     // needed.  We agressively kill these because we can by
13734                     // definition not re-use the same process again, and it is
13735                     // good to avoid having whatever code was running in them
13736                     // left sitting around after no longer needed.
13737                     Slog.i(TAG, "Isolated process " + app.processName
13738                             + " (pid " + app.pid + ") no longer needed");
13739                     EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13740                             app.processName, app.setAdj, "isolated not needed");
13741                     app.killedBackground = true;
13742                     Process.killProcessQuiet(app.pid);
13743                 }
13744                 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13745                         && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13746                         && !app.killedBackground) {
13747                     numTrimming++;
13748                 }
13749             }
13750         }
13751 
13752         mNumServiceProcs = mNewNumServiceProcs;
13753 
13754         // Now determine the memory trimming level of background processes.
13755         // Unfortunately we need to start at the back of the list to do this
13756         // properly.  We only do this if the number of background apps we
13757         // are managing to keep around is less than half the maximum we desire;
13758         // if we are keeping a good number around, we'll let them use whatever
13759         // memory they want.
13760         if (numHidden <= ProcessList.TRIM_HIDDEN_APPS
13761                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
13762             final int numHiddenAndEmpty = numHidden + numEmpty;
13763             final int N = mLruProcesses.size();
13764             int factor = numTrimming/3;
13765             int minFactor = 2;
13766             if (mHomeProcess != null) minFactor++;
13767             if (mPreviousProcess != null) minFactor++;
13768             if (factor < minFactor) factor = minFactor;
13769             int step = 0;
13770             int fgTrimLevel;
13771             if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
13772                 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13773             } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
13774                 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13775             } else {
13776                 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13777             }
13778             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13779             for (i=0; i<N; i++) {
13780                 ProcessRecord app = mLruProcesses.get(i);
13781                 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13782                         && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13783                         && !app.killedBackground) {
13784                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
13785                         try {
13786                             app.thread.scheduleTrimMemory(curLevel);
13787                         } catch (RemoteException e) {
13788                         }
13789                         if (false) {
13790                             // For now we won't do this; our memory trimming seems
13791                             // to be good enough at this point that destroying
13792                             // activities causes more harm than good.
13793                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13794                                     && app != mHomeProcess && app != mPreviousProcess) {
13795                                 // Need to do this on its own message because the stack may not
13796                                 // be in a consistent state at this point.
13797                                 // For these apps we will also finish their activities
13798                                 // to help them free memory.
13799                                 mMainStack.scheduleDestroyActivities(app, false, "trim");
13800                             }
13801                         }
13802                     }
13803                     app.trimMemoryLevel = curLevel;
13804                     step++;
13805                     if (step >= factor) {
13806                         step = 0;
13807                         switch (curLevel) {
13808                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13809                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13810                                 break;
13811                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13812                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13813                                 break;
13814                         }
13815                     }
13816                 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13817                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13818                             && app.thread != null) {
13819                         try {
13820                             app.thread.scheduleTrimMemory(
13821                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13822                         } catch (RemoteException e) {
13823                         }
13824                     }
13825                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13826                 } else {
13827                     if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13828                             && app.pendingUiClean) {
13829                         // If this application is now in the background and it
13830                         // had done UI, then give it the special trim level to
13831                         // have it free UI resources.
13832                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13833                         if (app.trimMemoryLevel < level && app.thread != null) {
13834                             try {
13835                                 app.thread.scheduleTrimMemory(level);
13836                             } catch (RemoteException e) {
13837                             }
13838                         }
13839                         app.pendingUiClean = false;
13840                     }
13841                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13842                         try {
13843                             app.thread.scheduleTrimMemory(fgTrimLevel);
13844                         } catch (RemoteException e) {
13845                         }
13846                     }
13847                     app.trimMemoryLevel = fgTrimLevel;
13848                 }
13849             }
13850         } else {
13851             final int N = mLruProcesses.size();
13852             for (i=0; i<N; i++) {
13853                 ProcessRecord app = mLruProcesses.get(i);
13854                 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13855                         && app.pendingUiClean) {
13856                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13857                             && app.thread != null) {
13858                         try {
13859                             app.thread.scheduleTrimMemory(
13860                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13861                         } catch (RemoteException e) {
13862                         }
13863                     }
13864                     app.pendingUiClean = false;
13865                 }
13866                 app.trimMemoryLevel = 0;
13867             }
13868         }
13869 
13870         if (mAlwaysFinishActivities) {
13871             // Need to do this on its own message because the stack may not
13872             // be in a consistent state at this point.
13873             mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13874         }
13875     }
13876 
trimApplications()13877     final void trimApplications() {
13878         synchronized (this) {
13879             int i;
13880 
13881             // First remove any unused application processes whose package
13882             // has been removed.
13883             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13884                 final ProcessRecord app = mRemovedProcesses.get(i);
13885                 if (app.activities.size() == 0
13886                         && app.curReceiver == null && app.services.size() == 0) {
13887                     Slog.i(
13888                         TAG, "Exiting empty application process "
13889                         + app.processName + " ("
13890                         + (app.thread != null ? app.thread.asBinder() : null)
13891                         + ")\n");
13892                     if (app.pid > 0 && app.pid != MY_PID) {
13893                         EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13894                                 app.processName, app.setAdj, "empty");
13895                         Process.killProcessQuiet(app.pid);
13896                     } else {
13897                         try {
13898                             app.thread.scheduleExit();
13899                         } catch (Exception e) {
13900                             // Ignore exceptions.
13901                         }
13902                     }
13903                     cleanUpApplicationRecordLocked(app, false, true, -1);
13904                     mRemovedProcesses.remove(i);
13905 
13906                     if (app.persistent) {
13907                         if (app.persistent) {
13908                             addAppLocked(app.info, false);
13909                         }
13910                     }
13911                 }
13912             }
13913 
13914             // Now update the oom adj for all processes.
13915             updateOomAdjLocked();
13916         }
13917     }
13918 
13919     /** This method sends the specified signal to each of the persistent apps */
signalPersistentProcesses(int sig)13920     public void signalPersistentProcesses(int sig) throws RemoteException {
13921         if (sig != Process.SIGNAL_USR1) {
13922             throw new SecurityException("Only SIGNAL_USR1 is allowed");
13923         }
13924 
13925         synchronized (this) {
13926             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13927                     != PackageManager.PERMISSION_GRANTED) {
13928                 throw new SecurityException("Requires permission "
13929                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13930             }
13931 
13932             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13933                 ProcessRecord r = mLruProcesses.get(i);
13934                 if (r.thread != null && r.persistent) {
13935                     Process.sendSignal(r.pid, sig);
13936                 }
13937             }
13938         }
13939     }
13940 
stopProfilerLocked(ProcessRecord proc, String path, int profileType)13941     private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13942         if (proc == null || proc == mProfileProc) {
13943             proc = mProfileProc;
13944             path = mProfileFile;
13945             profileType = mProfileType;
13946             clearProfilerLocked();
13947         }
13948         if (proc == null) {
13949             return;
13950         }
13951         try {
13952             proc.thread.profilerControl(false, path, null, profileType);
13953         } catch (RemoteException e) {
13954             throw new IllegalStateException("Process disappeared");
13955         }
13956     }
13957 
clearProfilerLocked()13958     private void clearProfilerLocked() {
13959         if (mProfileFd != null) {
13960             try {
13961                 mProfileFd.close();
13962             } catch (IOException e) {
13963             }
13964         }
13965         mProfileApp = null;
13966         mProfileProc = null;
13967         mProfileFile = null;
13968         mProfileType = 0;
13969         mAutoStopProfiler = false;
13970     }
13971 
profileControl(String process, int userId, boolean start, String path, ParcelFileDescriptor fd, int profileType)13972     public boolean profileControl(String process, int userId, boolean start,
13973             String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13974 
13975         try {
13976             synchronized (this) {
13977                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13978                 // its own permission.
13979                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13980                         != PackageManager.PERMISSION_GRANTED) {
13981                     throw new SecurityException("Requires permission "
13982                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13983                 }
13984 
13985                 if (start && fd == null) {
13986                     throw new IllegalArgumentException("null fd");
13987                 }
13988 
13989                 ProcessRecord proc = null;
13990                 if (process != null) {
13991                     proc = findProcessLocked(process, userId, "profileControl");
13992                 }
13993 
13994                 if (start && (proc == null || proc.thread == null)) {
13995                     throw new IllegalArgumentException("Unknown process: " + process);
13996                 }
13997 
13998                 if (start) {
13999                     stopProfilerLocked(null, null, 0);
14000                     setProfileApp(proc.info, proc.processName, path, fd, false);
14001                     mProfileProc = proc;
14002                     mProfileType = profileType;
14003                     try {
14004                         fd = fd.dup();
14005                     } catch (IOException e) {
14006                         fd = null;
14007                     }
14008                     proc.thread.profilerControl(start, path, fd, profileType);
14009                     fd = null;
14010                     mProfileFd = null;
14011                 } else {
14012                     stopProfilerLocked(proc, path, profileType);
14013                     if (fd != null) {
14014                         try {
14015                             fd.close();
14016                         } catch (IOException e) {
14017                         }
14018                     }
14019                 }
14020 
14021                 return true;
14022             }
14023         } catch (RemoteException e) {
14024             throw new IllegalStateException("Process disappeared");
14025         } finally {
14026             if (fd != null) {
14027                 try {
14028                     fd.close();
14029                 } catch (IOException e) {
14030                 }
14031             }
14032         }
14033     }
14034 
findProcessLocked(String process, int userId, String callName)14035     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
14036         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14037                 userId, true, true, callName, null);
14038         ProcessRecord proc = null;
14039         try {
14040             int pid = Integer.parseInt(process);
14041             synchronized (mPidsSelfLocked) {
14042                 proc = mPidsSelfLocked.get(pid);
14043             }
14044         } catch (NumberFormatException e) {
14045         }
14046 
14047         if (proc == null) {
14048             HashMap<String, SparseArray<ProcessRecord>> all
14049                     = mProcessNames.getMap();
14050             SparseArray<ProcessRecord> procs = all.get(process);
14051             if (procs != null && procs.size() > 0) {
14052                 proc = procs.valueAt(0);
14053                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
14054                     for (int i=1; i<procs.size(); i++) {
14055                         ProcessRecord thisProc = procs.valueAt(i);
14056                         if (thisProc.userId == userId) {
14057                             proc = thisProc;
14058                             break;
14059                         }
14060                     }
14061                 }
14062             }
14063         }
14064 
14065         return proc;
14066     }
14067 
dumpHeap(String process, int userId, boolean managed, String path, ParcelFileDescriptor fd)14068     public boolean dumpHeap(String process, int userId, boolean managed,
14069             String path, ParcelFileDescriptor fd) throws RemoteException {
14070 
14071         try {
14072             synchronized (this) {
14073                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14074                 // its own permission (same as profileControl).
14075                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14076                         != PackageManager.PERMISSION_GRANTED) {
14077                     throw new SecurityException("Requires permission "
14078                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14079                 }
14080 
14081                 if (fd == null) {
14082                     throw new IllegalArgumentException("null fd");
14083                 }
14084 
14085                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
14086                 if (proc == null || proc.thread == null) {
14087                     throw new IllegalArgumentException("Unknown process: " + process);
14088                 }
14089 
14090                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14091                 if (!isDebuggable) {
14092                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14093                         throw new SecurityException("Process not debuggable: " + proc);
14094                     }
14095                 }
14096 
14097                 proc.thread.dumpHeap(managed, path, fd);
14098                 fd = null;
14099                 return true;
14100             }
14101         } catch (RemoteException e) {
14102             throw new IllegalStateException("Process disappeared");
14103         } finally {
14104             if (fd != null) {
14105                 try {
14106                     fd.close();
14107                 } catch (IOException e) {
14108                 }
14109             }
14110         }
14111     }
14112 
14113     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
monitor()14114     public void monitor() {
14115         synchronized (this) { }
14116     }
14117 
onCoreSettingsChange(Bundle settings)14118     void onCoreSettingsChange(Bundle settings) {
14119         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14120             ProcessRecord processRecord = mLruProcesses.get(i);
14121             try {
14122                 if (processRecord.thread != null) {
14123                     processRecord.thread.setCoreSettings(settings);
14124                 }
14125             } catch (RemoteException re) {
14126                 /* ignore */
14127             }
14128         }
14129     }
14130 
14131     // Multi-user methods
14132 
14133     @Override
switchUser(final int userId)14134     public boolean switchUser(final int userId) {
14135         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14136                 != PackageManager.PERMISSION_GRANTED) {
14137             String msg = "Permission Denial: switchUser() from pid="
14138                     + Binder.getCallingPid()
14139                     + ", uid=" + Binder.getCallingUid()
14140                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14141             Slog.w(TAG, msg);
14142             throw new SecurityException(msg);
14143         }
14144 
14145         final long ident = Binder.clearCallingIdentity();
14146         try {
14147             synchronized (this) {
14148                 final int oldUserId = mCurrentUserId;
14149                 if (oldUserId == userId) {
14150                     return true;
14151                 }
14152 
14153                 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
14154                 if (userInfo == null) {
14155                     Slog.w(TAG, "No user info for user #" + userId);
14156                     return false;
14157                 }
14158 
14159                 mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
14160                         R.anim.screen_user_enter);
14161 
14162                 boolean needStart = false;
14163 
14164                 // If the user we are switching to is not currently started, then
14165                 // we need to start it now.
14166                 if (mStartedUsers.get(userId) == null) {
14167                     mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
14168                     updateStartedUserArrayLocked();
14169                     needStart = true;
14170                 }
14171 
14172                 mCurrentUserId = userId;
14173                 mCurrentUserArray = new int[] { userId };
14174                 final Integer userIdInt = Integer.valueOf(userId);
14175                 mUserLru.remove(userIdInt);
14176                 mUserLru.add(userIdInt);
14177 
14178                 mWindowManager.setCurrentUser(userId);
14179 
14180                 // Once the internal notion of the active user has switched, we lock the device
14181                 // with the option to show the user switcher on the keyguard.
14182                 mWindowManager.lockNow(null);
14183 
14184                 final UserStartedState uss = mStartedUsers.get(userId);
14185 
14186                 // Make sure user is in the started state.  If it is currently
14187                 // stopping, we need to knock that off.
14188                 if (uss.mState == UserStartedState.STATE_STOPPING) {
14189                     // If we are stopping, we haven't sent ACTION_SHUTDOWN,
14190                     // so we can just fairly silently bring the user back from
14191                     // the almost-dead.
14192                     uss.mState = UserStartedState.STATE_RUNNING;
14193                     updateStartedUserArrayLocked();
14194                     needStart = true;
14195                 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
14196                     // This means ACTION_SHUTDOWN has been sent, so we will
14197                     // need to treat this as a new boot of the user.
14198                     uss.mState = UserStartedState.STATE_BOOTING;
14199                     updateStartedUserArrayLocked();
14200                     needStart = true;
14201                 }
14202 
14203                 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
14204                 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14205                 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
14206                         oldUserId, userId, uss));
14207                 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
14208                         oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
14209                 if (needStart) {
14210                     Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14211                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14212                             | Intent.FLAG_RECEIVER_FOREGROUND);
14213                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14214                     broadcastIntentLocked(null, null, intent,
14215                             null, null, 0, null, null, null,
14216                             false, false, MY_PID, Process.SYSTEM_UID, userId);
14217                 }
14218 
14219                 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
14220                     if (userId != 0) {
14221                         Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
14222                         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14223                         broadcastIntentLocked(null, null, intent, null,
14224                                 new IIntentReceiver.Stub() {
14225                                     public void performReceive(Intent intent, int resultCode,
14226                                             String data, Bundle extras, boolean ordered,
14227                                             boolean sticky, int sendingUser) {
14228                                         userInitialized(uss, userId);
14229                                     }
14230                                 }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
14231                                 userId);
14232                         uss.initializing = true;
14233                     } else {
14234                         getUserManagerLocked().makeInitialized(userInfo.id);
14235                     }
14236                 }
14237 
14238                 boolean haveActivities = mMainStack.switchUserLocked(userId, uss);
14239                 if (!haveActivities) {
14240                     startHomeActivityLocked(userId);
14241                 }
14242 
14243                 EventLogTags.writeAmSwitchUser(userId);
14244                 getUserManagerLocked().userForeground(userId);
14245                 sendUserSwitchBroadcastsLocked(oldUserId, userId);
14246                 if (needStart) {
14247                     Intent intent = new Intent(Intent.ACTION_USER_STARTING);
14248                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14249                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14250                     broadcastIntentLocked(null, null, intent,
14251                             null, new IIntentReceiver.Stub() {
14252                                 @Override
14253                                 public void performReceive(Intent intent, int resultCode, String data,
14254                                         Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14255                                         throws RemoteException {
14256                                 }
14257                             }, 0, null, null,
14258                             android.Manifest.permission.INTERACT_ACROSS_USERS,
14259                             true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14260                 }
14261             }
14262         } finally {
14263             Binder.restoreCallingIdentity(ident);
14264         }
14265 
14266         return true;
14267     }
14268 
sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId)14269     void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
14270         long ident = Binder.clearCallingIdentity();
14271         try {
14272             Intent intent;
14273             if (oldUserId >= 0) {
14274                 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
14275                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14276                         | Intent.FLAG_RECEIVER_FOREGROUND);
14277                 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
14278                 broadcastIntentLocked(null, null, intent,
14279                         null, null, 0, null, null, null,
14280                         false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
14281             }
14282             if (newUserId >= 0) {
14283                 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
14284                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14285                         | Intent.FLAG_RECEIVER_FOREGROUND);
14286                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14287                 broadcastIntentLocked(null, null, intent,
14288                         null, null, 0, null, null, null,
14289                         false, false, MY_PID, Process.SYSTEM_UID, newUserId);
14290                 intent = new Intent(Intent.ACTION_USER_SWITCHED);
14291                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14292                         | Intent.FLAG_RECEIVER_FOREGROUND);
14293                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14294                 broadcastIntentLocked(null, null, intent,
14295                         null, null, 0, null, null,
14296                         android.Manifest.permission.MANAGE_USERS,
14297                         false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14298             }
14299         } finally {
14300             Binder.restoreCallingIdentity(ident);
14301         }
14302     }
14303 
dispatchUserSwitch(final UserStartedState uss, final int oldUserId, final int newUserId)14304     void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
14305             final int newUserId) {
14306         final int N = mUserSwitchObservers.beginBroadcast();
14307         if (N > 0) {
14308             final IRemoteCallback callback = new IRemoteCallback.Stub() {
14309                 int mCount = 0;
14310                 @Override
14311                 public void sendResult(Bundle data) throws RemoteException {
14312                     synchronized (ActivityManagerService.this) {
14313                         if (mCurUserSwitchCallback == this) {
14314                             mCount++;
14315                             if (mCount == N) {
14316                                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14317                             }
14318                         }
14319                     }
14320                 }
14321             };
14322             synchronized (this) {
14323                 uss.switching = true;
14324                 mCurUserSwitchCallback = callback;
14325             }
14326             for (int i=0; i<N; i++) {
14327                 try {
14328                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
14329                             newUserId, callback);
14330                 } catch (RemoteException e) {
14331                 }
14332             }
14333         } else {
14334             synchronized (this) {
14335                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14336             }
14337         }
14338         mUserSwitchObservers.finishBroadcast();
14339     }
14340 
timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId)14341     void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14342         synchronized (this) {
14343             Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
14344             sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14345         }
14346     }
14347 
sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId)14348     void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
14349         mCurUserSwitchCallback = null;
14350         mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14351         mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
14352                 oldUserId, newUserId, uss));
14353     }
14354 
userInitialized(UserStartedState uss, int newUserId)14355     void userInitialized(UserStartedState uss, int newUserId) {
14356         completeSwitchAndInitalize(uss, newUserId, true, false);
14357     }
14358 
continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId)14359     void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14360         completeSwitchAndInitalize(uss, newUserId, false, true);
14361     }
14362 
completeSwitchAndInitalize(UserStartedState uss, int newUserId, boolean clearInitializing, boolean clearSwitching)14363     void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
14364             boolean clearInitializing, boolean clearSwitching) {
14365         boolean unfrozen = false;
14366         synchronized (this) {
14367             if (clearInitializing) {
14368                 uss.initializing = false;
14369                 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
14370             }
14371             if (clearSwitching) {
14372                 uss.switching = false;
14373             }
14374             if (!uss.switching && !uss.initializing) {
14375                 mWindowManager.stopFreezingScreen();
14376                 unfrozen = true;
14377             }
14378         }
14379         if (unfrozen) {
14380             final int N = mUserSwitchObservers.beginBroadcast();
14381             for (int i=0; i<N; i++) {
14382                 try {
14383                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
14384                 } catch (RemoteException e) {
14385                 }
14386             }
14387             mUserSwitchObservers.finishBroadcast();
14388         }
14389     }
14390 
finishUserSwitch(UserStartedState uss)14391     void finishUserSwitch(UserStartedState uss) {
14392         synchronized (this) {
14393             if (uss.mState == UserStartedState.STATE_BOOTING
14394                     && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
14395                 uss.mState = UserStartedState.STATE_RUNNING;
14396                 final int userId = uss.mHandle.getIdentifier();
14397                 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
14398                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14399                 broadcastIntentLocked(null, null, intent,
14400                         null, null, 0, null, null,
14401                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
14402                         false, false, MY_PID, Process.SYSTEM_UID, userId);
14403             }
14404             int num = mUserLru.size();
14405             int i = 0;
14406             while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
14407                 Integer oldUserId = mUserLru.get(i);
14408                 UserStartedState oldUss = mStartedUsers.get(oldUserId);
14409                 if (oldUss == null) {
14410                     // Shouldn't happen, but be sane if it does.
14411                     mUserLru.remove(i);
14412                     num--;
14413                     continue;
14414                 }
14415                 if (oldUss.mState == UserStartedState.STATE_STOPPING
14416                         || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
14417                     // This user is already stopping, doesn't count.
14418                     num--;
14419                     i++;
14420                     continue;
14421                 }
14422                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
14423                     // Owner and current can't be stopped, but count as running.
14424                     i++;
14425                     continue;
14426                 }
14427                 // This is a user to be stopped.
14428                 stopUserLocked(oldUserId, null);
14429                 num--;
14430                 i++;
14431             }
14432         }
14433     }
14434 
14435     @Override
stopUser(final int userId, final IStopUserCallback callback)14436     public int stopUser(final int userId, final IStopUserCallback callback) {
14437         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14438                 != PackageManager.PERMISSION_GRANTED) {
14439             String msg = "Permission Denial: switchUser() from pid="
14440                     + Binder.getCallingPid()
14441                     + ", uid=" + Binder.getCallingUid()
14442                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14443             Slog.w(TAG, msg);
14444             throw new SecurityException(msg);
14445         }
14446         if (userId <= 0) {
14447             throw new IllegalArgumentException("Can't stop primary user " + userId);
14448         }
14449         synchronized (this) {
14450             return stopUserLocked(userId, callback);
14451         }
14452     }
14453 
stopUserLocked(final int userId, final IStopUserCallback callback)14454     private int stopUserLocked(final int userId, final IStopUserCallback callback) {
14455         if (mCurrentUserId == userId) {
14456             return ActivityManager.USER_OP_IS_CURRENT;
14457         }
14458 
14459         final UserStartedState uss = mStartedUsers.get(userId);
14460         if (uss == null) {
14461             // User is not started, nothing to do...  but we do need to
14462             // callback if requested.
14463             if (callback != null) {
14464                 mHandler.post(new Runnable() {
14465                     @Override
14466                     public void run() {
14467                         try {
14468                             callback.userStopped(userId);
14469                         } catch (RemoteException e) {
14470                         }
14471                     }
14472                 });
14473             }
14474             return ActivityManager.USER_OP_SUCCESS;
14475         }
14476 
14477         if (callback != null) {
14478             uss.mStopCallbacks.add(callback);
14479         }
14480 
14481         if (uss.mState != UserStartedState.STATE_STOPPING
14482                 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14483             uss.mState = UserStartedState.STATE_STOPPING;
14484             updateStartedUserArrayLocked();
14485 
14486             long ident = Binder.clearCallingIdentity();
14487             try {
14488                 // We are going to broadcast ACTION_USER_STOPPING and then
14489                 // once that is done send a final ACTION_SHUTDOWN and then
14490                 // stop the user.
14491                 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
14492                 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14493                 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14494                 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
14495                 // This is the result receiver for the final shutdown broadcast.
14496                 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
14497                     @Override
14498                     public void performReceive(Intent intent, int resultCode, String data,
14499                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14500                         finishUserStop(uss);
14501                     }
14502                 };
14503                 // This is the result receiver for the initial stopping broadcast.
14504                 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
14505                     @Override
14506                     public void performReceive(Intent intent, int resultCode, String data,
14507                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14508                         // On to the next.
14509                         synchronized (ActivityManagerService.this) {
14510                             if (uss.mState != UserStartedState.STATE_STOPPING) {
14511                                 // Whoops, we are being started back up.  Abort, abort!
14512                                 return;
14513                             }
14514                             uss.mState = UserStartedState.STATE_SHUTDOWN;
14515                         }
14516                         broadcastIntentLocked(null, null, shutdownIntent,
14517                                 null, shutdownReceiver, 0, null, null, null,
14518                                 true, false, MY_PID, Process.SYSTEM_UID, userId);
14519                     }
14520                 };
14521                 // Kick things off.
14522                 broadcastIntentLocked(null, null, stoppingIntent,
14523                         null, stoppingReceiver, 0, null, null,
14524                         android.Manifest.permission.INTERACT_ACROSS_USERS,
14525                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14526             } finally {
14527                 Binder.restoreCallingIdentity(ident);
14528             }
14529         }
14530 
14531         return ActivityManager.USER_OP_SUCCESS;
14532     }
14533 
finishUserStop(UserStartedState uss)14534     void finishUserStop(UserStartedState uss) {
14535         final int userId = uss.mHandle.getIdentifier();
14536         boolean stopped;
14537         ArrayList<IStopUserCallback> callbacks;
14538         synchronized (this) {
14539             callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
14540             if (mStartedUsers.get(userId) != uss) {
14541                 stopped = false;
14542             } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
14543                 stopped = false;
14544             } else {
14545                 stopped = true;
14546                 // User can no longer run.
14547                 mStartedUsers.remove(userId);
14548                 mUserLru.remove(Integer.valueOf(userId));
14549                 updateStartedUserArrayLocked();
14550 
14551                 // Clean up all state and processes associated with the user.
14552                 // Kill all the processes for the user.
14553                 forceStopUserLocked(userId);
14554                 AttributeCache ac = AttributeCache.instance();
14555                 if (ac != null) {
14556                     ac.removeUser(userId);
14557                 }
14558             }
14559         }
14560 
14561         for (int i=0; i<callbacks.size(); i++) {
14562             try {
14563                 if (stopped) callbacks.get(i).userStopped(userId);
14564                 else callbacks.get(i).userStopAborted(userId);
14565             } catch (RemoteException e) {
14566             }
14567         }
14568     }
14569 
14570     @Override
getCurrentUser()14571     public UserInfo getCurrentUser() {
14572         if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14573                 != PackageManager.PERMISSION_GRANTED) && (
14574                 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14575                 != PackageManager.PERMISSION_GRANTED)) {
14576             String msg = "Permission Denial: getCurrentUser() from pid="
14577                     + Binder.getCallingPid()
14578                     + ", uid=" + Binder.getCallingUid()
14579                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14580             Slog.w(TAG, msg);
14581             throw new SecurityException(msg);
14582         }
14583         synchronized (this) {
14584             return getUserManagerLocked().getUserInfo(mCurrentUserId);
14585         }
14586     }
14587 
getCurrentUserIdLocked()14588     int getCurrentUserIdLocked() {
14589         return mCurrentUserId;
14590     }
14591 
14592     @Override
isUserRunning(int userId, boolean orStopped)14593     public boolean isUserRunning(int userId, boolean orStopped) {
14594         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14595                 != PackageManager.PERMISSION_GRANTED) {
14596             String msg = "Permission Denial: isUserRunning() from pid="
14597                     + Binder.getCallingPid()
14598                     + ", uid=" + Binder.getCallingUid()
14599                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14600             Slog.w(TAG, msg);
14601             throw new SecurityException(msg);
14602         }
14603         synchronized (this) {
14604             return isUserRunningLocked(userId, orStopped);
14605         }
14606     }
14607 
isUserRunningLocked(int userId, boolean orStopped)14608     boolean isUserRunningLocked(int userId, boolean orStopped) {
14609         UserStartedState state = mStartedUsers.get(userId);
14610         if (state == null) {
14611             return false;
14612         }
14613         if (orStopped) {
14614             return true;
14615         }
14616         return state.mState != UserStartedState.STATE_STOPPING
14617                 && state.mState != UserStartedState.STATE_SHUTDOWN;
14618     }
14619 
14620     @Override
getRunningUserIds()14621     public int[] getRunningUserIds() {
14622         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14623                 != PackageManager.PERMISSION_GRANTED) {
14624             String msg = "Permission Denial: isUserRunning() from pid="
14625                     + Binder.getCallingPid()
14626                     + ", uid=" + Binder.getCallingUid()
14627                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14628             Slog.w(TAG, msg);
14629             throw new SecurityException(msg);
14630         }
14631         synchronized (this) {
14632             return mStartedUserArray;
14633         }
14634     }
14635 
updateStartedUserArrayLocked()14636     private void updateStartedUserArrayLocked() {
14637         int num = 0;
14638         for (int i=0; i<mStartedUsers.size();  i++) {
14639             UserStartedState uss = mStartedUsers.valueAt(i);
14640             // This list does not include stopping users.
14641             if (uss.mState != UserStartedState.STATE_STOPPING
14642                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14643                 num++;
14644             }
14645         }
14646         mStartedUserArray = new int[num];
14647         num = 0;
14648         for (int i=0; i<mStartedUsers.size();  i++) {
14649             UserStartedState uss = mStartedUsers.valueAt(i);
14650             if (uss.mState != UserStartedState.STATE_STOPPING
14651                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14652                 mStartedUserArray[num] = mStartedUsers.keyAt(i);
14653                 num++;
14654             }
14655         }
14656     }
14657 
14658     @Override
registerUserSwitchObserver(IUserSwitchObserver observer)14659     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
14660         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14661                 != PackageManager.PERMISSION_GRANTED) {
14662             String msg = "Permission Denial: registerUserSwitchObserver() from pid="
14663                     + Binder.getCallingPid()
14664                     + ", uid=" + Binder.getCallingUid()
14665                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14666             Slog.w(TAG, msg);
14667             throw new SecurityException(msg);
14668         }
14669 
14670         mUserSwitchObservers.register(observer);
14671     }
14672 
14673     @Override
unregisterUserSwitchObserver(IUserSwitchObserver observer)14674     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
14675         mUserSwitchObservers.unregister(observer);
14676     }
14677 
userExists(int userId)14678     private boolean userExists(int userId) {
14679         if (userId == 0) {
14680             return true;
14681         }
14682         UserManagerService ums = getUserManagerLocked();
14683         return ums != null ? (ums.getUserInfo(userId) != null) : false;
14684     }
14685 
getUsersLocked()14686     int[] getUsersLocked() {
14687         UserManagerService ums = getUserManagerLocked();
14688         return ums != null ? ums.getUserIds() : new int[] { 0 };
14689     }
14690 
getUserManagerLocked()14691     UserManagerService getUserManagerLocked() {
14692         if (mUserManager == null) {
14693             IBinder b = ServiceManager.getService(Context.USER_SERVICE);
14694             mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
14695         }
14696         return mUserManager;
14697     }
14698 
checkValidCaller(int uid, int userId)14699     private void checkValidCaller(int uid, int userId) {
14700         if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
14701 
14702         throw new SecurityException("Caller uid=" + uid
14703                 + " is not privileged to communicate with user=" + userId);
14704     }
14705 
applyUserId(int uid, int userId)14706     private int applyUserId(int uid, int userId) {
14707         return UserHandle.getUid(userId, uid);
14708     }
14709 
getAppInfoForUser(ApplicationInfo info, int userId)14710     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
14711         if (info == null) return null;
14712         ApplicationInfo newInfo = new ApplicationInfo(info);
14713         newInfo.uid = applyUserId(info.uid, userId);
14714         newInfo.dataDir = USER_DATA_DIR + userId + "/"
14715                 + info.packageName;
14716         return newInfo;
14717     }
14718 
getActivityInfoForUser(ActivityInfo aInfo, int userId)14719     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
14720         if (aInfo == null
14721                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
14722             return aInfo;
14723         }
14724 
14725         ActivityInfo info = new ActivityInfo(aInfo);
14726         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
14727         return info;
14728     }
14729 }
14730