Skip to content

Commit 4efbab4

Browse files
Dianne HackbornAndroid (Google) Code Review
authored andcommitted
Merge "Framework side of issue #7302511: GCM client needs to use new framework API..." into jb-mr1-dev
2 parents bd03f5a + 36d337a commit 4efbab4

File tree

5 files changed

+145
-29
lines changed

5 files changed

+145
-29
lines changed

core/java/android/content/Intent.java

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2327,7 +2327,9 @@ public static Intent createChooser(Intent target, CharSequence title) {
23272327
* party applications because a newly initialized user does not have any
23282328
* third party applications installed for it.) This is sent early in
23292329
* starting the user, around the time the home app is started, before
2330-
* {@link #ACTION_BOOT_COMPLETED} is sent.
2330+
* {@link #ACTION_BOOT_COMPLETED} is sent. This is sent as a foreground
2331+
* broadcast, since it is part of a visible user interaction; be as quick
2332+
* as possible when handling it.
23312333
*/
23322334
public static final String ACTION_USER_INITIALIZE =
23332335
"android.intent.action.USER_INITIALIZE";
@@ -2337,7 +2339,9 @@ public static Intent createChooser(Intent target, CharSequence title) {
23372339
* brought to the foreground. This is only sent to receivers registered
23382340
* through {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
23392341
* Context.registerReceiver}. It is sent to the user that is going to the
2340-
* foreground.
2342+
* foreground. This is sent as a foreground
2343+
* broadcast, since it is part of a visible user interaction; be as quick
2344+
* as possible when handling it.
23412345
*/
23422346
public static final String ACTION_USER_FOREGROUND =
23432347
"android.intent.action.USER_FOREGROUND";
@@ -2347,37 +2351,77 @@ public static Intent createChooser(Intent target, CharSequence title) {
23472351
* sent to the background. This is only sent to receivers registered
23482352
* through {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
23492353
* Context.registerReceiver}. It is sent to the user that is going to the
2350-
* background.
2354+
* background. This is sent as a foreground
2355+
* broadcast, since it is part of a visible user interaction; be as quick
2356+
* as possible when handling it.
23512357
*/
23522358
public static final String ACTION_USER_BACKGROUND =
23532359
"android.intent.action.USER_BACKGROUND";
23542360

23552361
/**
2356-
* Broadcast sent to the system when a user is added. Carries an extra EXTRA_USER_HANDLE that has the
2357-
* userHandle of the new user. It is sent to all running users. You must hold
2362+
* Broadcast sent to the system when a user is added. Carries an extra
2363+
* EXTRA_USER_HANDLE that has the userHandle of the new user. It is sent to
2364+
* all running users. You must hold
23582365
* {@link android.Manifest.permission#MANAGE_USERS} to receive this broadcast.
23592366
* @hide
23602367
*/
23612368
public static final String ACTION_USER_ADDED =
23622369
"android.intent.action.USER_ADDED";
23632370

23642371
/**
2365-
* Broadcast sent to the system when a user is started. Carries an extra EXTRA_USER_HANDLE that has
2366-
* the userHandle of the user. This is only sent to
2372+
* Broadcast sent by the system when a user is started. Carries an extra
2373+
* EXTRA_USER_HANDLE that has the userHandle of the user. This is only sent to
23672374
* registered receivers, not manifest receivers. It is sent to the user
2368-
* that has been started.
2375+
* that has been started. This is sent as a foreground
2376+
* broadcast, since it is part of a visible user interaction; be as quick
2377+
* as possible when handling it.
23692378
* @hide
23702379
*/
23712380
public static final String ACTION_USER_STARTED =
23722381
"android.intent.action.USER_STARTED";
23732382

23742383
/**
2375-
* Broadcast sent to the system when a user is stopped. Carries an extra EXTRA_USER_HANDLE that has
2376-
* the userHandle of the user. This is similar to {@link #ACTION_PACKAGE_RESTARTED},
2377-
* but for an entire user instead of a specific package. This is only sent to
2378-
* registered receivers, not manifest receivers. It is sent to all running
2379-
* users <em>except</em> the one that has just been stopped (which is no
2380-
* longer running).
2384+
* Broadcast sent when a user is in the process of starting. Carries an extra
2385+
* EXTRA_USER_HANDLE that has the userHandle of the user. This is only
2386+
* sent to registered receivers, not manifest receivers. It is sent to all
2387+
* users (including the one that is being started). You must hold
2388+
* {@link android.Manifest.permission#INTERACT_ACROSS_USERS} to receive
2389+
* this broadcast. This is sent as a background broadcast, since
2390+
* its result is not part of the primary UX flow; to safely keep track of
2391+
* started/stopped state of a user you can use this in conjunction with
2392+
* {@link #ACTION_USER_STOPPING}. It is <b>not</b> generally safe to use with
2393+
* other user state broadcasts since those are foreground broadcasts so can
2394+
* execute in a different order.
2395+
* @hide
2396+
*/
2397+
public static final String ACTION_USER_STARTING =
2398+
"android.intent.action.USER_STARTING";
2399+
2400+
/**
2401+
* Broadcast sent when a user is going to be stopped. Carries an extra
2402+
* EXTRA_USER_HANDLE that has the userHandle of the user. This is only
2403+
* sent to registered receivers, not manifest receivers. It is sent to all
2404+
* users (including the one that is being stopped). You must hold
2405+
* {@link android.Manifest.permission#INTERACT_ACROSS_USERS} to receive
2406+
* this broadcast. The user will not stop until all receivers have
2407+
* handled the broadcast. This is sent as a background broadcast, since
2408+
* its result is not part of the primary UX flow; to safely keep track of
2409+
* started/stopped state of a user you can use this in conjunction with
2410+
* {@link #ACTION_USER_STARTING}. It is <b>not</b> generally safe to use with
2411+
* other user state broadcasts since those are foreground broadcasts so can
2412+
* execute in a different order.
2413+
* @hide
2414+
*/
2415+
public static final String ACTION_USER_STOPPING =
2416+
"android.intent.action.USER_STOPPING";
2417+
2418+
/**
2419+
* Broadcast sent to the system when a user is stopped. Carries an extra
2420+
* EXTRA_USER_HANDLE that has the userHandle of the user. This is similar to
2421+
* {@link #ACTION_PACKAGE_RESTARTED}, but for an entire user instead of a
2422+
* specific package. This is only sent to registered receivers, not manifest
2423+
* receivers. It is sent to all running users <em>except</em> the one that
2424+
* has just been stopped (which is no longer running).
23812425
* @hide
23822426
*/
23832427
public static final String ACTION_USER_STOPPED =

core/res/res/anim/wallpaper_enter.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919

2020
<set xmlns:android="http://schemas.android.com/apk/res/android"
2121
android:interpolator="@interpolator/decelerate_quad">
22+
<!-- Having trouble avoiding this when switching users, so simple fade for now
2223
<scale android:fromXScale="3.0" android:toXScale="1.0"
2324
android:fromYScale="3.0" android:toYScale="1.0"
2425
android:pivotX="50%" android:pivotY="50%"
2526
android:duration="@android:integer/config_longAnimTime" />
27+
-->
2628
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
2729
android:duration="@android:integer/config_longAnimTime" />
2830
</set>

core/res/res/anim/wallpaper_exit.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919

2020
<set xmlns:android="http://schemas.android.com/apk/res/android"
2121
android:interpolator="@interpolator/accelerate_quad">
22+
<!-- Having trouble avoiding this when switching users, so simple fade for now
2223
<scale android:fromXScale="1.0" android:toXScale="3.0"
2324
android:fromYScale="1.0" android:toYScale="3.0"
2425
android:pivotX="50%" android:pivotY="50%"
2526
android:duration="@android:integer/config_longAnimTime" />
27+
-->
2628
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
2729
android:duration="@android:integer/config_longAnimTime"/>
2830
</set>

services/java/com/android/server/am/ActivityManagerService.java

Lines changed: 70 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3739,8 +3739,7 @@ private void forceStopPackageLocked(final String packageName, int uid) {
37393739
private void forceStopUserLocked(int userId) {
37403740
forceStopPackageLocked(null, -1, false, false, true, false, userId);
37413741
Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3742-
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3743-
| Intent.FLAG_RECEIVER_FOREGROUND);
3742+
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
37443743
intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
37453744
broadcastIntentLocked(null, null, intent,
37463745
null, null, 0, null, null, null,
@@ -14128,6 +14127,19 @@ public boolean switchUser(int userId) {
1412814127

1412914128
final UserStartedState uss = mStartedUsers.get(userId);
1413014129

14130+
// Make sure user is in the started state. If it is currently
14131+
// stopping, we need to knock that off.
14132+
if (uss.mState == UserStartedState.STATE_STOPPING) {
14133+
// If we are stopping, we haven't sent ACTION_SHUTDOWN,
14134+
// so we can just fairly silently bring the user back from
14135+
// the almost-dead.
14136+
uss.mState = UserStartedState.STATE_RUNNING;
14137+
} else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
14138+
// This means ACTION_SHUTDOWN has been sent, so we will
14139+
// need to treat this as a new boot of the user.
14140+
uss.mState = UserStartedState.STATE_BOOTING;
14141+
}
14142+
1413114143
mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
1413214144
mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
1413314145
mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
@@ -14205,6 +14217,19 @@ void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
1420514217
null, null, 0, null, null,
1420614218
android.Manifest.permission.MANAGE_USERS,
1420714219
false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14220+
intent = new Intent(Intent.ACTION_USER_STARTING);
14221+
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14222+
intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14223+
broadcastIntentLocked(null, null, intent,
14224+
null, new IIntentReceiver.Stub() {
14225+
@Override
14226+
public void performReceive(Intent intent, int resultCode, String data,
14227+
Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14228+
throws RemoteException {
14229+
}
14230+
}, 0, null, null,
14231+
android.Manifest.permission.INTERACT_ACROSS_USERS,
14232+
false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
1420814233
}
1420914234
} finally {
1421014235
Binder.restoreCallingIdentity(ident);
@@ -14293,7 +14318,8 @@ void completeSwitchAndInitalizeLocked(UserStartedState uss) {
1429314318

1429414319
void finishUserSwitch(UserStartedState uss) {
1429514320
synchronized (this) {
14296-
if (uss.mState == UserStartedState.STATE_BOOTING
14321+
if ((uss.mState == UserStartedState.STATE_BOOTING
14322+
|| uss.mState == UserStartedState.STATE_SHUTDOWN)
1429714323
&& mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
1429814324
uss.mState = UserStartedState.STATE_RUNNING;
1429914325
final int userId = uss.mHandle.getIdentifier();
@@ -14315,7 +14341,8 @@ void finishUserSwitch(UserStartedState uss) {
1431514341
num--;
1431614342
continue;
1431714343
}
14318-
if (oldUss.mState == UserStartedState.STATE_STOPPING) {
14344+
if (oldUss.mState == UserStartedState.STATE_STOPPING
14345+
|| oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
1431914346
// This user is already stopping, doesn't count.
1432014347
num--;
1432114348
i++;
@@ -14380,23 +14407,50 @@ public void run() {
1438014407
uss.mStopCallbacks.add(callback);
1438114408
}
1438214409

14383-
if (uss.mState != UserStartedState.STATE_STOPPING) {
14410+
if (uss.mState != UserStartedState.STATE_STOPPING
14411+
&& uss.mState != UserStartedState.STATE_SHUTDOWN) {
1438414412
uss.mState = UserStartedState.STATE_STOPPING;
1438514413

1438614414
long ident = Binder.clearCallingIdentity();
1438714415
try {
14388-
// Inform of user switch
14389-
Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
14390-
final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() {
14416+
// We are going to broadcast ACTION_USER_STOPPING and then
14417+
// once that is down send a final ACTION_SHUTDOWN and then
14418+
// stop the user.
14419+
final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
14420+
stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14421+
stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14422+
final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
14423+
// This is the result receiver for the final shutdown broadcast.
14424+
final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
1439114425
@Override
1439214426
public void performReceive(Intent intent, int resultCode, String data,
1439314427
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
1439414428
finishUserStop(uss);
1439514429
}
1439614430
};
14397-
broadcastIntentLocked(null, null, intent,
14398-
null, resultReceiver, 0, null, null, null,
14399-
true, false, MY_PID, Process.SYSTEM_UID, userId);
14431+
// This is the result receiver for the initial stopping broadcast.
14432+
final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
14433+
@Override
14434+
public void performReceive(Intent intent, int resultCode, String data,
14435+
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14436+
// On to the next.
14437+
synchronized (ActivityManagerService.this) {
14438+
if (uss.mState != UserStartedState.STATE_STOPPING) {
14439+
// Whoops, we are being started back up. Abort, abort!
14440+
return;
14441+
}
14442+
uss.mState = UserStartedState.STATE_SHUTDOWN;
14443+
}
14444+
broadcastIntentLocked(null, null, shutdownIntent,
14445+
null, shutdownReceiver, 0, null, null, null,
14446+
true, false, MY_PID, Process.SYSTEM_UID, userId);
14447+
}
14448+
};
14449+
// Kick things off.
14450+
broadcastIntentLocked(null, null, stoppingIntent,
14451+
null, stoppingReceiver, 0, null, null,
14452+
android.Manifest.permission.INTERACT_ACROSS_USERS,
14453+
true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
1440014454
} finally {
1440114455
Binder.restoreCallingIdentity(ident);
1440214456
}
@@ -14411,8 +14465,9 @@ void finishUserStop(UserStartedState uss) {
1441114465
ArrayList<IStopUserCallback> callbacks;
1441214466
synchronized (this) {
1441314467
callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
14414-
if (uss.mState != UserStartedState.STATE_STOPPING
14415-
|| mStartedUsers.get(userId) != uss) {
14468+
if (mStartedUsers.get(userId) != uss) {
14469+
stopped = false;
14470+
} else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
1441614471
stopped = false;
1441714472
} else {
1441814473
stopped = true;
@@ -14476,7 +14531,8 @@ public boolean isUserRunning(int userId) {
1447614531

1447714532
boolean isUserRunningLocked(int userId) {
1447814533
UserStartedState state = mStartedUsers.get(userId);
14479-
return state != null && state.mState != UserStartedState.STATE_STOPPING;
14534+
return state != null && state.mState != UserStartedState.STATE_STOPPING
14535+
&& state.mState != UserStartedState.STATE_SHUTDOWN;
1448014536
}
1448114537

1448214538
@Override

services/java/com/android/server/am/UserStartedState.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,14 @@
2323
import android.os.UserHandle;
2424

2525
public class UserStartedState {
26+
// User is first coming up.
2627
public final static int STATE_BOOTING = 0;
28+
// User is in the normal running state.
2729
public final static int STATE_RUNNING = 1;
30+
// User is in the initial process of being stopped.
2831
public final static int STATE_STOPPING = 2;
32+
// User is in the final phase of stopping, sending Intent.ACTION_SHUTDOWN.
33+
public final static int STATE_SHUTDOWN = 3;
2934

3035
public final UserHandle mHandle;
3136
public final ArrayList<IStopUserCallback> mStopCallbacks
@@ -40,7 +45,14 @@ public UserStartedState(UserHandle handle, boolean initial) {
4045
}
4146

4247
void dump(String prefix, PrintWriter pw) {
43-
pw.print(prefix); pw.print("mState="); pw.print(mState);
48+
pw.print(prefix); pw.print("mState=");
49+
switch (mState) {
50+
case STATE_BOOTING: pw.print("BOOTING"); break;
51+
case STATE_RUNNING: pw.print("RUNNING"); break;
52+
case STATE_STOPPING: pw.print("STOPPING"); break;
53+
case STATE_SHUTDOWN: pw.print("SHUTDOWN"); break;
54+
default: pw.print(mState); break;
55+
}
4456
if (switching) pw.print(" SWITCHING");
4557
if (initializing) pw.print(" INITIALIZING");
4658
pw.println();

0 commit comments

Comments
 (0)