import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.app.ProcessMap;
- import com.android.internal.app.ProcessStats;
import com.android.internal.app.SystemUserHomeActivity;
+ import com.android.internal.app.procstats.ProcessStats;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.IResultReceiver;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.MemInfoReader;
import com.android.internal.util.Preconditions;
+import com.android.internal.util.ProgressReporter;
import com.android.server.AppOpsService;
import com.android.server.AttributeCache;
import com.android.server.DeviceIdleController;
import com.android.server.pm.Installer;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.vr.VrManagerInternal;
-import com.android.server.wm.AppTransition;
import com.android.server.wm.WindowManagerService;
import org.xmlpull.v1.XmlPullParser;
import android.app.ProfilerInfo;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManagerInternal;
-import android.app.admin.IDevicePolicyManager;
import android.app.assist.AssistContent;
import android.app.assist.AssistStructure;
import android.app.backup.IBackupManager;
import android.os.IBinder;
import android.os.IPermissionController;
import android.os.IProcessInfoService;
+import android.os.IProgressListener;
import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
import android.view.View;
import android.view.WindowManager;
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
+import static com.android.server.wm.AppTransition.TRANSIT_DOCK_TASK_FROM_RECENTS;
import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
- // File that stores last updated system version and called preboot receivers
- static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
-
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
static final int ALLOW_NON_FULL_IN_PROFILE = 1;
static final int ALLOW_FULL_ONLY = 2;
- static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
-
// Delay in notifying task stack change listeners (in millis)
static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
// Determines whether to take full screen screenshots
static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
+ public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
private static native int nativeMigrateToBoost();
private static native int nativeMigrateFromBoost();
boolean mBooting = false;
boolean mCallFinishBooting = false;
boolean mBootAnimationComplete = false;
- boolean mWaitingUpdate = false;
- boolean mDidUpdate = false;
boolean mOnBattery = false;
boolean mLaunchWarningShown = false;
static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
+ static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
/** The dimensions of the thumbnails in the Recents UI. */
int mThumbnailWidth;
int mThumbnailHeight;
+ float mFullscreenThumbnailScale;
final ServiceThread mHandlerThread;
final MainHandler mHandler;
}
break;
}
+ case NOTIFY_FORCED_RESIZABLE_MSG: {
+ synchronized (ActivityManagerService.this) {
+ for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
+ try {
+ // Make a one-way callback to the listener
+ mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
+ (String) msg.obj, msg.arg1);
+ } catch (RemoteException e){
+ // Handled by the RemoteCallbackList
+ }
+ }
+ mTaskStackListeners.finishBroadcast();
+ }
+ break;
+ }
case NOTIFY_CLEARTEXT_NETWORK_MSG: {
final int uid = msg.arg1;
final byte[] firstPacket = (byte[]) msg.obj;
}
final long origId = Binder.clearCallingIdentity();
try {
- return startActivityFromRecentsInner(taskId, bOptions);
+ synchronized (this) {
+ return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
+ }
} finally {
Binder.restoreCallingIdentity(origId);
}
}
- final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
- final TaskRecord task;
- final int callingUid;
- final String callingPackage;
- final Intent intent;
- final int userId;
- synchronized (this) {
- final ActivityOptions activityOptions = (bOptions != null)
- ? new ActivityOptions(bOptions) : null;
- final int launchStackId = (activityOptions != null)
- ? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
-
- if (launchStackId == HOME_STACK_ID) {
- throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
- + taskId + " can't be launch in the home stack.");
- }
- task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
- if (task == null) {
- throw new IllegalArgumentException(
- "startActivityFromRecentsInner: Task " + taskId + " not found.");
- }
-
- if (launchStackId != INVALID_STACK_ID) {
- if (launchStackId == DOCKED_STACK_ID && activityOptions != null) {
- mWindowManager.setDockedStackCreateState(
- activityOptions.getDockCreateMode(), null /* initialBounds */);
- }
- if (task.stack.mStackId != launchStackId) {
- mStackSupervisor.moveTaskToStackLocked(
- taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
- ANIMATE);
- }
- }
-
- // If the user must confirm credentials (e.g. when first launching a work app and the
- // Work Challenge is present) let startActivityInPackage handle the intercepting.
- if (!mUserController.shouldConfirmCredentials(task.userId)
- && task.getRootActivity() != null) {
- moveTaskToFrontLocked(task.taskId, 0, bOptions);
- return ActivityManager.START_TASK_TO_FRONT;
- }
- callingUid = task.mCallingUid;
- callingPackage = task.mCallingPackage;
- intent = task.intent;
- intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
- userId = task.userId;
- }
- return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
- bOptions, userId, null, task);
- }
-
final int startActivityInPackage(int uid, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
app.debugging = false;
app.cached = false;
app.killedByAm = false;
+ app.unlocked = mContext.getSystemService(UserManager.class).isUserUnlocked(app.userId);
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
continue;
}
}
- if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TASKS) != 0) {
- if (tr.stack != null && tr.stack.isDockedStack()) {
+ if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
+ final ActivityStack stack = tr.stack;
+ if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
- "Skipping, docked stack task: " + tr);
+ "Skipping, top task in docked stack: " + tr);
continue;
}
}
}
checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
- if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
+ if (!mProcessesReady
&& !cpi.processName.equals("system")) {
// If this content provider does not run in the system
// process, and the system is not yet ready to run other
final int NA = apps.size();
for (int ia = 0; ia < NA; ia++) {
final ProcessRecord app = apps.valueAt(ia);
- if (app.userId != userId || app.thread == null) continue;
+ if (app.userId != userId || app.thread == null || app.unlocked) continue;
final int NG = app.pkgList.size();
for (int ig = 0; ig < NG; ig++) {
try {
final int currentUserId = mUserController.getCurrentUserIdLocked();
// Get the focused task before launching launcher.
- final int taskId = (mFocusedActivity == null)
- ? -1 : mFocusedActivity.task.taskId;
- startHomeActivityLocked(currentUserId, "notifyLockedProfile");
+
if (mUserController.isLockScreenDisabled(currentUserId)) {
- // If there is no device lock, we first go to launcher and then resume the
- // original task. Work challenge will be shown because we intercepted
- // startActivityFromRecentsInner and the reason why we switch to home stack
- // first is to prevent pressing back button brings user back to the work
- // app.
- if (taskId != -1) {
- startActivityFromRecentsInner(taskId, null);
+
+ // If there is no device lock, we will show the profile's credential page.
+ // startActivityFromRecentsInner is intercepted and will forward user to it.
+ if (mFocusedActivity != null) {
+ mStackSupervisor.startActivityFromRecentsInner(
+ mFocusedActivity.task.taskId, null);
}
+ } else {
+ // Showing launcher to avoid user entering credential twice.
+ startHomeActivityLocked(currentUserId, "notifyLockedProfile");
}
} finally {
Binder.restoreCallingIdentity(ident);
com.android.internal.R.dimen.thumbnail_width);
mThumbnailHeight = res.getDimensionPixelSize(
com.android.internal.R.dimen.thumbnail_height);
+ mFullscreenThumbnailScale = res.getFraction(
+ com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
com.android.internal.R.string.config_defaultPictureInPictureBounds));
mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
return mSystemReady;
}
- private static File getCalledPreBootReceiversFile() {
- File dataDir = Environment.getDataDirectory();
- File systemDir = new File(dataDir, "system");
- File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
- return fname;
- }
-
- private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
- ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
- File file = getCalledPreBootReceiversFile();
- FileInputStream fis = null;
- try {
- fis = new FileInputStream(file);
- DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
- int fvers = dis.readInt();
- if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
- String vers = dis.readUTF();
- String codename = dis.readUTF();
- String build = dis.readUTF();
- if (android.os.Build.VERSION.RELEASE.equals(vers)
- && android.os.Build.VERSION.CODENAME.equals(codename)
- && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
- int num = dis.readInt();
- while (num > 0) {
- num--;
- String pkg = dis.readUTF();
- String cls = dis.readUTF();
- lastDoneReceivers.add(new ComponentName(pkg, cls));
- }
- }
- }
- } catch (FileNotFoundException e) {
- } catch (IOException e) {
- Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
- } finally {
- if (fis != null) {
- try {
- fis.close();
- } catch (IOException e) {
- }
- }
- }
- return lastDoneReceivers;
- }
-
- private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
- File file = getCalledPreBootReceiversFile();
- FileOutputStream fos = null;
- DataOutputStream dos = null;
- try {
- fos = new FileOutputStream(file);
- dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
- dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
- dos.writeUTF(android.os.Build.VERSION.RELEASE);
- dos.writeUTF(android.os.Build.VERSION.CODENAME);
- dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
- dos.writeInt(list.size());
- for (int i=0; i<list.size(); i++) {
- dos.writeUTF(list.get(i).getPackageName());
- dos.writeUTF(list.get(i).getClassName());
- }
- } catch (IOException e) {
- Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
- file.delete();
- } finally {
- FileUtils.sync(fos);
- if (dos != null) {
- try {
- dos.close();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
-
- final class PreBootContinuation extends IIntentReceiver.Stub {
- final Intent intent;
- final Runnable onFinishCallback;
- final ArrayList<ComponentName> doneReceivers;
- final List<ResolveInfo> ris;
- final int[] users;
- int lastRi = -1;
- int curRi = 0;
- int curUser = 0;
-
- PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
- ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
- intent = _intent;
- onFinishCallback = _onFinishCallback;
- doneReceivers = _doneReceivers;
- ris = _ris;
- users = _users;
- }
-
- void go() {
- if (lastRi != curRi) {
- ActivityInfo ai = ris.get(curRi).activityInfo;
- ComponentName comp = new ComponentName(ai.packageName, ai.name);
- intent.setComponent(comp);
- doneReceivers.add(comp);
- lastRi = curRi;
- CharSequence label = ai.loadLabel(mContext.getPackageManager());
- showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
- }
- Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
- + " for user " + users[curUser]);
- EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
- broadcastIntentLocked(null, null, intent, null, this,
- 0, null, null, null, AppOpsManager.OP_NONE,
- null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
- }
-
- public void performReceive(Intent intent, int resultCode,
- String data, Bundle extras, boolean ordered,
- boolean sticky, int sendingUser) {
- curUser++;
- if (curUser >= users.length) {
- curUser = 0;
- curRi++;
- if (curRi >= ris.size()) {
- // All done sending broadcasts!
- if (onFinishCallback != null) {
- // The raw IIntentReceiver interface is called
- // with the AM lock held, so redispatch to
- // execute our code without the lock.
- mHandler.post(onFinishCallback);
- }
- return;
- }
- }
- go();
- }
- }
-
- private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
- ArrayList<ComponentName> doneReceivers) {
- Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
- List<ResolveInfo> ris = null;
- try {
- ris = AppGlobals.getPackageManager().queryIntentReceivers(
- intent, null, MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM).getList();
- } catch (RemoteException e) {
- }
- if (ris == null) {
- return false;
- }
- intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE | Intent.FLAG_DEBUG_TRIAGED_MISSING);
-
- ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
- for (int i=0; i<ris.size(); i++) {
- ActivityInfo ai = ris.get(i).activityInfo;
- ComponentName comp = new ComponentName(ai.packageName, ai.name);
- if (lastDoneReceivers.contains(comp)) {
- // We already did the pre boot receiver for this app with the current
- // platform version, so don't do it again...
- ris.remove(i);
- i--;
- // ...however, do keep it as one that has been done, so we don't
- // forget about it when rewriting the file of last done receivers.
- doneReceivers.add(comp);
- }
- }
-
- if (ris.size() <= 0) {
- return false;
- }
-
- // TODO: can we still do this with per user encryption?
- final int[] users = mUserController.getUsers();
- if (users.length <= 0) {
- return false;
- }
-
- PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
- ris, users);
- cont.go();
- return true;
- }
-
public void systemReady(final Runnable goingCallback) {
synchronized(this) {
if (mSystemReady) {
// Make sure we have the current profile info, since it is needed for security checks.
mUserController.onSystemReady();
-
mRecentTasks.onSystemReadyLocked();
- // Check to see if there are any update receivers to run.
- if (!mDidUpdate) {
- if (mWaitingUpdate) {
- return;
- }
- final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
- mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
- public void run() {
- synchronized (ActivityManagerService.this) {
- mDidUpdate = true;
- }
- showBootMessage(mContext.getText(
- R.string.android_upgrading_complete),
- false);
- writeLastDonePreBootReceivers(doneReceivers);
- systemReady(goingCallback);
- }
- }, doneReceivers);
-
- if (mWaitingUpdate) {
- return;
- }
- mDidUpdate = true;
- }
-
mAppOpsService.systemReady();
mSystemReady = true;
}
for (int j = 0; j < activitiesSize; j++) {
final ActivityRecord r = app.activities.get(j);
if (r.app != app) {
- Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
- + app + "?!? Using " + r.app + " instead.");
- continue;
+ Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
+ + " instead of expected " + app);
+ if (r.app == null || (r.app.uid == app.uid)) {
+ // Only fix things up when they look sane
+ r.app = app;
+ } else {
+ continue;
+ }
}
if (r.visible) {
// App has a visible activity; only upgrade adjustment.
}
@Override
- public boolean unlockUser(int userId, byte[] token, byte[] secret) {
- return mUserController.unlockUser(userId, token, secret);
+ public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
+ return mUserController.unlockUser(userId, token, secret, new ProgressReporter(0, listener));
}
@Override
mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
}
}
+
+ @Override
+ public void notifyAppTransitionFinished() {
+ synchronized (ActivityManagerService.this) {
+ mStackSupervisor.notifyAppTransitionDone();
+ }
+ }
+
+ @Override
+ public void notifyAppTransitionCancelled() {
+ synchronized (ActivityManagerService.this) {
+ mStackSupervisor.notifyAppTransitionDone();
+ }
+ }
}
private final class SleepTokenImpl extends SleepToken {
// Will bring task to front if it already has a root activity.
final long origId = Binder.clearCallingIdentity();
try {
- startActivityFromRecentsInner(mTaskId, null);
+ synchronized (this) {
+ mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
+ }
} finally {
Binder.restoreCallingIdentity(origId);
}