Skip to content

Commit 840590d

Browse files
Dianne HackbornAndroid (Google) Code Review
authored andcommitted
Merge "Fix issue #7311376: Add API to allow apps to know if they are..." into jb-mr1-dev
2 parents f966cf3 + a8a9bd6 commit 840590d

7 files changed

Lines changed: 83 additions & 13 deletions

File tree

api/17.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16620,6 +16620,8 @@ package android.os {
1662016620
method public android.os.UserHandle getUserForSerialNumber(long);
1662116621
method public java.lang.String getUserName();
1662216622
method public boolean isUserAGoat();
16623+
method public boolean isUserRunning(android.os.UserHandle);
16624+
method public boolean isUserRunningOrStopping(android.os.UserHandle);
1662316625
}
1662416626

1662516627
public abstract class Vibrator {

api/current.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16620,6 +16620,8 @@ package android.os {
1662016620
method public android.os.UserHandle getUserForSerialNumber(long);
1662116621
method public java.lang.String getUserName();
1662216622
method public boolean isUserAGoat();
16623+
method public boolean isUserRunning(android.os.UserHandle);
16624+
method public boolean isUserRunningOrStopping(android.os.UserHandle);
1662316625
}
1662416626

1662516627
public abstract class Vibrator {

core/java/android/app/ActivityManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1981,7 +1981,7 @@ public boolean switchUser(int userid) {
19811981
*/
19821982
public boolean isUserRunning(int userid) {
19831983
try {
1984-
return ActivityManagerNative.getDefault().isUserRunning(userid);
1984+
return ActivityManagerNative.getDefault().isUserRunning(userid, false);
19851985
} catch (RemoteException e) {
19861986
return false;
19871987
}

core/java/android/app/ActivityManagerNative.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1608,7 +1608,8 @@ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
16081608
case IS_USER_RUNNING_TRANSACTION: {
16091609
data.enforceInterface(IActivityManager.descriptor);
16101610
int userid = data.readInt();
1611-
boolean result = isUserRunning(userid);
1611+
boolean orStopping = data.readInt() != 0;
1612+
boolean result = isUserRunning(userid, orStopping);
16121613
reply.writeNoException();
16131614
reply.writeInt(result ? 1 : 0);
16141615
return true;
@@ -3865,11 +3866,12 @@ public UserInfo getCurrentUser() throws RemoteException {
38653866
return userInfo;
38663867
}
38673868

3868-
public boolean isUserRunning(int userid) throws RemoteException {
3869+
public boolean isUserRunning(int userid, boolean orStopping) throws RemoteException {
38693870
Parcel data = Parcel.obtain();
38703871
Parcel reply = Parcel.obtain();
38713872
data.writeInterfaceToken(IActivityManager.descriptor);
38723873
data.writeInt(userid);
3874+
data.writeInt(orStopping ? 1 : 0);
38733875
mRemote.transact(IS_USER_RUNNING_TRANSACTION, data, reply, 0);
38743876
reply.readException();
38753877
boolean result = reply.readInt() != 0;

core/java/android/app/IActivityManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ public void setPackageAskScreenCompat(String packageName, boolean ask)
326326
public boolean switchUser(int userid) throws RemoteException;
327327
public int stopUser(int userid, IStopUserCallback callback) throws RemoteException;
328328
public UserInfo getCurrentUser() throws RemoteException;
329-
public boolean isUserRunning(int userid) throws RemoteException;
329+
public boolean isUserRunning(int userid, boolean orStopping) throws RemoteException;
330330
public int[] getRunningUserIds() throws RemoteException;
331331

332332
public boolean removeSubTask(int taskId, int subTaskIndex) throws RemoteException;

core/java/android/os/UserManager.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
package android.os;
1717

1818
import com.android.internal.R;
19+
20+
import android.app.ActivityManagerNative;
1921
import android.content.Context;
2022
import android.content.pm.UserInfo;
2123
import android.graphics.Bitmap;
@@ -81,6 +83,39 @@ public boolean isUserAGoat() {
8183
return false;
8284
}
8385

86+
/**
87+
* Return whether the given user is actively running. This means that
88+
* the user is in the "started" state, not "stopped" -- it is currently
89+
* allowed to run code through scheduled alarms, receiving broadcasts,
90+
* etc. A started user may be either the current foreground user or a
91+
* background user; the result here does not distinguish between the two.
92+
* @param user The user to retrieve the running state for.
93+
*/
94+
public boolean isUserRunning(UserHandle user) {
95+
try {
96+
return ActivityManagerNative.getDefault().isUserRunning(
97+
user.getIdentifier(), false);
98+
} catch (RemoteException e) {
99+
return false;
100+
}
101+
}
102+
103+
/**
104+
* Return whether the given user is actively running <em>or</em> stopping.
105+
* This is like {@link #isUserRunning(UserHandle)}, but will also return
106+
* true if the user had been running but is in the process of being stopped
107+
* (but is not yet fully stopped, and still running some code).
108+
* @param user The user to retrieve the running state for.
109+
*/
110+
public boolean isUserRunningOrStopping(UserHandle user) {
111+
try {
112+
return ActivityManagerNative.getDefault().isUserRunning(
113+
user.getIdentifier(), true);
114+
} catch (RemoteException e) {
115+
return false;
116+
}
117+
}
118+
84119
/**
85120
* Returns the UserInfo object describing a specific user.
86121
* Requires {@link android.Manifest.permission#MANAGE_USERS} permission.

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

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3585,7 +3585,7 @@ public void forceStopPackage(final String packageName, int userId) {
35853585
Slog.w(TAG, "Failed trying to unstop package "
35863586
+ packageName + ": " + e);
35873587
}
3588-
if (isUserRunningLocked(user)) {
3588+
if (isUserRunningLocked(user, false)) {
35893589
forceStopPackageLocked(packageName, pkgUid);
35903590
}
35913591
}
@@ -9338,6 +9338,12 @@ boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
93389338
pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
93399339
pw.print(": "); uss.dump("", pw);
93409340
}
9341+
pw.print(" mStartedUserArray: [");
9342+
for (int i=0; i<mStartedUserArray.length; i++) {
9343+
if (i > 0) pw.print(", ");
9344+
pw.print(mStartedUserArray[i]);
9345+
}
9346+
pw.println("]");
93419347
pw.print(" mUserLru: [");
93429348
for (int i=0; i<mUserLru.size(); i++) {
93439349
if (i > 0) pw.print(", ");
@@ -14134,10 +14140,12 @@ public boolean switchUser(int userId) {
1413414140
// so we can just fairly silently bring the user back from
1413514141
// the almost-dead.
1413614142
uss.mState = UserStartedState.STATE_RUNNING;
14143+
updateStartedUserArrayLocked();
1413714144
} else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
1413814145
// This means ACTION_SHUTDOWN has been sent, so we will
1413914146
// need to treat this as a new boot of the user.
1414014147
uss.mState = UserStartedState.STATE_BOOTING;
14148+
updateStartedUserArrayLocked();
1414114149
}
1414214150

1414314151
mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
@@ -14318,8 +14326,7 @@ void completeSwitchAndInitalizeLocked(UserStartedState uss) {
1431814326

1431914327
void finishUserSwitch(UserStartedState uss) {
1432014328
synchronized (this) {
14321-
if ((uss.mState == UserStartedState.STATE_BOOTING
14322-
|| uss.mState == UserStartedState.STATE_SHUTDOWN)
14329+
if (uss.mState == UserStartedState.STATE_BOOTING
1432314330
&& mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
1432414331
uss.mState = UserStartedState.STATE_RUNNING;
1432514332
final int userId = uss.mHandle.getIdentifier();
@@ -14410,6 +14417,7 @@ public void run() {
1441014417
if (uss.mState != UserStartedState.STATE_STOPPING
1441114418
&& uss.mState != UserStartedState.STATE_SHUTDOWN) {
1441214419
uss.mState = UserStartedState.STATE_STOPPING;
14420+
updateStartedUserArrayLocked();
1441314421

1441414422
long ident = Binder.clearCallingIdentity();
1441514423
try {
@@ -14514,7 +14522,7 @@ int getCurrentUserIdLocked() {
1451414522
}
1451514523

1451614524
@Override
14517-
public boolean isUserRunning(int userId) {
14525+
public boolean isUserRunning(int userId, boolean orStopped) {
1451814526
if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
1451914527
!= PackageManager.PERMISSION_GRANTED) {
1452014528
String msg = "Permission Denial: isUserRunning() from pid="
@@ -14525,13 +14533,19 @@ public boolean isUserRunning(int userId) {
1452514533
throw new SecurityException(msg);
1452614534
}
1452714535
synchronized (this) {
14528-
return isUserRunningLocked(userId);
14536+
return isUserRunningLocked(userId, orStopped);
1452914537
}
1453014538
}
1453114539

14532-
boolean isUserRunningLocked(int userId) {
14540+
boolean isUserRunningLocked(int userId, boolean orStopped) {
1453314541
UserStartedState state = mStartedUsers.get(userId);
14534-
return state != null && state.mState != UserStartedState.STATE_STOPPING
14542+
if (state == null) {
14543+
return false;
14544+
}
14545+
if (orStopped) {
14546+
return true;
14547+
}
14548+
return state.mState != UserStartedState.STATE_STOPPING
1453514549
&& state.mState != UserStartedState.STATE_SHUTDOWN;
1453614550
}
1453714551

@@ -14552,9 +14566,24 @@ public int[] getRunningUserIds() {
1455214566
}
1455314567

1455414568
private void updateStartedUserArrayLocked() {
14555-
mStartedUserArray = new int[mStartedUsers.size()];
14569+
int num = 0;
1455614570
for (int i=0; i<mStartedUsers.size(); i++) {
14557-
mStartedUserArray[i] = mStartedUsers.keyAt(i);
14571+
UserStartedState uss = mStartedUsers.valueAt(i);
14572+
// This list does not include stopping users.
14573+
if (uss.mState != UserStartedState.STATE_STOPPING
14574+
&& uss.mState != UserStartedState.STATE_SHUTDOWN) {
14575+
num++;
14576+
}
14577+
}
14578+
mStartedUserArray = new int[num];
14579+
num = 0;
14580+
for (int i=0; i<mStartedUsers.size(); i++) {
14581+
UserStartedState uss = mStartedUsers.valueAt(i);
14582+
if (uss.mState != UserStartedState.STATE_STOPPING
14583+
&& uss.mState != UserStartedState.STATE_SHUTDOWN) {
14584+
mStartedUserArray[num] = mStartedUsers.keyAt(i);
14585+
num++;
14586+
}
1455814587
}
1455914588
}
1456014589

0 commit comments

Comments
 (0)