am 36db9d08: Merge "Further work on issue #7307399: Framework needs a new pre-user-shutdown..." into jb-mr1-dev

* commit '36db9d0879640a1cb9a8723d6649068a1c4c08de':
  Further work on issue #7307399: Framework needs a new pre-user-shutdown...
This commit is contained in:
Dianne Hackborn
2012-10-09 19:13:13 -07:00
committed by Android Git Automerger
6 changed files with 131 additions and 50 deletions

View File

@@ -415,6 +415,10 @@ public class Am {
ComponentName cn = mAm.startService(null, intent, intent.getType(), mUserId);
if (cn == null) {
System.err.println("Error: Not found; no service started.");
} else if (cn.getPackageName().equals("!")) {
System.err.println("Error: Requires permission " + cn.getClassName());
} else if (cn.getPackageName().equals("!!")) {
System.err.println("Error: " + cn.getClassName());
}
}

View File

@@ -1352,10 +1352,16 @@ class ContextImpl extends Context {
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
if (cn != null && cn.getPackageName().equals("!")) {
throw new SecurityException(
"Not allowed to start service " + service
+ " without permission " + cn.getClassName());
if (cn != null) {
if (cn.getPackageName().equals("!")) {
throw new SecurityException(
"Not allowed to start service " + service
+ " without permission " + cn.getClassName());
} else if (cn.getPackageName().equals("!!")) {
throw new SecurityException(
"Unable to start service " + service
+ ": " + cn.getClassName());
}
}
return cn;
} catch (RemoteException e) {

View File

@@ -248,8 +248,9 @@ public class ActiveServices {
synchronized (r.stats.getBatteryStats()) {
r.stats.startRunningLocked();
}
if (!bringUpServiceLocked(r, service.getFlags(), false)) {
return new ComponentName("!", "Service process is bad");
String error = bringUpServiceLocked(r, service.getFlags(), false);
if (error != null) {
return new ComponentName("!!", error);
}
return r.name;
}
@@ -518,7 +519,7 @@ public class ActiveServices {
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
if (!bringUpServiceLocked(s, service.getFlags(), false)) {
if (bringUpServiceLocked(s, service.getFlags(), false) != null) {
return 0;
}
}
@@ -964,19 +965,19 @@ public class ActiveServices {
return true;
}
private final boolean bringUpServiceLocked(ServiceRecord r,
private final String bringUpServiceLocked(ServiceRecord r,
int intentFlags, boolean whileRestarting) {
//Slog.i(TAG, "Bring up service:");
//r.dump(" ");
if (r.app != null && r.app.thread != null) {
sendServiceArgsLocked(r, false);
return true;
return null;
}
if (!whileRestarting && r.restartDelay > 0) {
// If waiting for a restart, then do nothing.
return true;
return null;
}
if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
@@ -988,12 +989,13 @@ public class ActiveServices {
// Make sure that the user who owns this service is started. If not,
// we don't want to allow it to run.
if (mAm.mStartedUsers.get(r.userId) == null) {
Slog.w(TAG, "Unable to launch app "
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": user " + r.userId + " is stopped");
+ r.intent.getIntent() + ": user " + r.userId + " is stopped";
Slog.w(TAG, msg);
bringDownServiceLocked(r, true);
return false;
return msg;
}
// Service is now being launched, its package can't be stopped.
@@ -1018,7 +1020,7 @@ public class ActiveServices {
try {
app.addPackage(r.appInfo.packageName);
realStartServiceLocked(r, app);
return true;
return null;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortName, e);
}
@@ -1041,12 +1043,13 @@ public class ActiveServices {
if (app == null) {
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
"service", r.name, false, isolated)) == null) {
Slog.w(TAG, "Unable to launch app "
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": process is bad");
+ r.intent.getIntent() + ": process is bad";
Slog.w(TAG, msg);
bringDownServiceLocked(r, true);
return false;
return msg;
}
if (isolated) {
r.isolatedProc = app;
@@ -1057,7 +1060,7 @@ public class ActiveServices {
mPendingServices.add(r);
}
return true;
return null;
}
private final void requestServiceBindingsLocked(ServiceRecord r) {

View File

@@ -3739,7 +3739,8 @@ public final class ActivityManagerService extends ActivityManagerNative
private void forceStopUserLocked(int userId) {
forceStopPackageLocked(null, -1, false, false, true, false, userId);
Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
| Intent.FLAG_RECEIVER_FOREGROUND);
intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
broadcastIntentLocked(null, null, intent,
null, null, 0, null, null, null,
@@ -7904,6 +7905,19 @@ public final class ActivityManagerService extends ActivityManagerNative
broadcastIntentLocked(null, null, intent,
null, null, 0, null, null, null,
false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
intent = new Intent(Intent.ACTION_USER_STARTING);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
broadcastIntentLocked(null, null, intent,
null, new IIntentReceiver.Stub() {
@Override
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser)
throws RemoteException {
}
}, 0, null, null,
android.Manifest.permission.INTERACT_ACROSS_USERS,
false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -8879,7 +8893,7 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.println(" [-a] [-c] [-h] [cmd] ...");
pw.println(" cmd may be one of:");
pw.println(" a[ctivities]: activity stack state");
pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state");
pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
pw.println(" o[om]: out of memory management");
@@ -9713,6 +9727,9 @@ public final class ActivityManagerService extends ActivityManagerNative
boolean onlyHistory = false;
if ("history".equals(dumpPackage)) {
if (opti < args.length && "-s".equals(args[opti])) {
dumpAll = false;
}
onlyHistory = true;
dumpPackage = null;
}
@@ -14112,11 +14129,14 @@ public final class ActivityManagerService extends ActivityManagerNative
mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
R.anim.screen_user_enter);
boolean needStart = false;
// If the user we are switching to is not currently started, then
// we need to start it now.
if (mStartedUsers.get(userId) == null) {
mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
updateStartedUserArrayLocked();
needStart = true;
}
mCurrentUserId = userId;
@@ -14141,11 +14161,13 @@ public final class ActivityManagerService extends ActivityManagerNative
// the almost-dead.
uss.mState = UserStartedState.STATE_RUNNING;
updateStartedUserArrayLocked();
needStart = true;
} else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
// This means ACTION_SHUTDOWN has been sent, so we will
// need to treat this as a new boot of the user.
uss.mState = UserStartedState.STATE_BOOTING;
updateStartedUserArrayLocked();
needStart = true;
}
mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
@@ -14154,17 +14176,19 @@ public final class ActivityManagerService extends ActivityManagerNative
oldUserId, userId, uss));
mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
Intent intent = new Intent(Intent.ACTION_USER_STARTED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
| Intent.FLAG_RECEIVER_FOREGROUND);
intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
broadcastIntentLocked(null, null, intent,
null, null, 0, null, null, null,
false, false, MY_PID, Process.SYSTEM_UID, userId);
if (needStart) {
Intent intent = new Intent(Intent.ACTION_USER_STARTED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
| Intent.FLAG_RECEIVER_FOREGROUND);
intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
broadcastIntentLocked(null, null, intent,
null, null, 0, null, null, null,
false, false, MY_PID, Process.SYSTEM_UID, userId);
}
if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
if (userId != 0) {
intent = new Intent(Intent.ACTION_USER_INITIALIZE);
Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
broadcastIntentLocked(null, null, intent, null,
new IIntentReceiver.Stub() {
@@ -14188,6 +14212,21 @@ public final class ActivityManagerService extends ActivityManagerNative
getUserManagerLocked().userForeground(userId);
sendUserSwitchBroadcastsLocked(oldUserId, userId);
if (needStart) {
Intent intent = new Intent(Intent.ACTION_USER_STARTING);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
broadcastIntentLocked(null, null, intent,
null, new IIntentReceiver.Stub() {
@Override
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser)
throws RemoteException {
}
}, 0, null, null,
android.Manifest.permission.INTERACT_ACROSS_USERS,
false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
}
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -14225,19 +14264,6 @@ public final class ActivityManagerService extends ActivityManagerNative
null, null, 0, null, null,
android.Manifest.permission.MANAGE_USERS,
false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
intent = new Intent(Intent.ACTION_USER_STARTING);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
broadcastIntentLocked(null, null, intent,
null, new IIntentReceiver.Stub() {
@Override
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser)
throws RemoteException {
}
}, 0, null, null,
android.Manifest.permission.INTERACT_ACROSS_USERS,
false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
}
} finally {
Binder.restoreCallingIdentity(ident);

View File

@@ -54,6 +54,7 @@ public class BroadcastQueue {
static final boolean DEBUG_MU = ActivityManagerService.DEBUG_MU;
static final int MAX_BROADCAST_HISTORY = 25;
static final int MAX_BROADCAST_SUMMARY_HISTORY = 100;
final ActivityManagerService mService;
@@ -92,6 +93,12 @@ public class BroadcastQueue {
final BroadcastRecord[] mBroadcastHistory
= new BroadcastRecord[MAX_BROADCAST_HISTORY];
/**
* Summary of historical data of past broadcasts, for debugging.
*/
final Intent[] mBroadcastSummaryHistory
= new Intent[MAX_BROADCAST_SUMMARY_HISTORY];
/**
* Set when we current have a BROADCAST_INTENT_MSG in flight.
*/
@@ -922,6 +929,9 @@ public class BroadcastQueue {
MAX_BROADCAST_HISTORY-1);
r.finishTime = SystemClock.uptimeMillis();
mBroadcastHistory[0] = r;
System.arraycopy(mBroadcastSummaryHistory, 0, mBroadcastSummaryHistory, 1,
MAX_BROADCAST_SUMMARY_HISTORY-1);
mBroadcastSummaryHistory[0] = r.intent;
}
final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
@@ -1006,8 +1016,9 @@ public class BroadcastQueue {
}
}
int i;
boolean printed = false;
for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
for (i=0; i<MAX_BROADCAST_HISTORY; i++) {
BroadcastRecord r = mBroadcastHistory[i];
if (r == null) {
break;
@@ -1028,11 +1039,44 @@ public class BroadcastQueue {
pw.print(i); pw.println(":");
r.dump(pw, " ");
} else {
if (i >= 50) {
pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
pw.print(" ");
pw.println(r.intent.toShortString(false, true, true, false));
Bundle bundle = r.intent.getExtras();
if (bundle != null) {
pw.print(" extras: "); pw.println(bundle.toString());
}
}
}
if (dumpPackage == null) {
if (dumpAll) {
i = 0;
printed = false;
}
for (; i<MAX_BROADCAST_SUMMARY_HISTORY; i++) {
Intent intent = mBroadcastSummaryHistory[i];
if (intent == null) {
break;
}
if (!printed) {
if (needSep) {
pw.println();
}
needSep = true;
pw.println(" Historical broadcasts summary [" + mQueueName + "]:");
printed = true;
}
if (!dumpAll && i >= 50) {
pw.println(" ...");
break;
}
pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
pw.print(" #"); pw.print(i); pw.print(": ");
pw.println(intent.toShortString(false, true, true, false));
Bundle bundle = intent.getExtras();
if (bundle != null) {
pw.print(" extras: "); pw.println(bundle.toString());
}
}
}

View File

@@ -81,12 +81,10 @@ class BroadcastRecord extends Binder {
final long now = SystemClock.uptimeMillis();
pw.print(prefix); pw.print(this); pw.print(" to user "); pw.println(userId);
pw.print(prefix); pw.println(intent);
if (sticky) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
pw.print(prefix); pw.print("extras: "); pw.println(bundle.toString());
}
pw.print(prefix); pw.println(intent.toInsecureString());
Bundle bundle = intent.getExtras();
if (bundle != null) {
pw.print(prefix); pw.print("extras: "); pw.println(bundle.toString());
}
pw.print(prefix); pw.print("caller="); pw.print(callerPackage); pw.print(" ");
pw.print(callerApp != null ? callerApp.toShortString() : "null");