Merge "Fix issue #7311376: Add API to allow apps to know if they are..." into jb-mr1-dev

This commit is contained in:
Dianne Hackborn
2012-10-09 17:46:36 -07:00
committed by Android (Google) Code Review
7 changed files with 83 additions and 13 deletions

View File

@@ -16620,6 +16620,8 @@ package android.os {
method public android.os.UserHandle getUserForSerialNumber(long);
method public java.lang.String getUserName();
method public boolean isUserAGoat();
method public boolean isUserRunning(android.os.UserHandle);
method public boolean isUserRunningOrStopping(android.os.UserHandle);
}
public abstract class Vibrator {

View File

@@ -16620,6 +16620,8 @@ package android.os {
method public android.os.UserHandle getUserForSerialNumber(long);
method public java.lang.String getUserName();
method public boolean isUserAGoat();
method public boolean isUserRunning(android.os.UserHandle);
method public boolean isUserRunningOrStopping(android.os.UserHandle);
}
public abstract class Vibrator {

View File

@@ -1981,7 +1981,7 @@ public class ActivityManager {
*/
public boolean isUserRunning(int userid) {
try {
return ActivityManagerNative.getDefault().isUserRunning(userid);
return ActivityManagerNative.getDefault().isUserRunning(userid, false);
} catch (RemoteException e) {
return false;
}

View File

@@ -1608,7 +1608,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
case IS_USER_RUNNING_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
int userid = data.readInt();
boolean result = isUserRunning(userid);
boolean orStopping = data.readInt() != 0;
boolean result = isUserRunning(userid, orStopping);
reply.writeNoException();
reply.writeInt(result ? 1 : 0);
return true;
@@ -3865,11 +3866,12 @@ class ActivityManagerProxy implements IActivityManager
return userInfo;
}
public boolean isUserRunning(int userid) throws RemoteException {
public boolean isUserRunning(int userid, boolean orStopping) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeInt(userid);
data.writeInt(orStopping ? 1 : 0);
mRemote.transact(IS_USER_RUNNING_TRANSACTION, data, reply, 0);
reply.readException();
boolean result = reply.readInt() != 0;

View File

@@ -326,7 +326,7 @@ public interface IActivityManager extends IInterface {
public boolean switchUser(int userid) throws RemoteException;
public int stopUser(int userid, IStopUserCallback callback) throws RemoteException;
public UserInfo getCurrentUser() throws RemoteException;
public boolean isUserRunning(int userid) throws RemoteException;
public boolean isUserRunning(int userid, boolean orStopping) throws RemoteException;
public int[] getRunningUserIds() throws RemoteException;
public boolean removeSubTask(int taskId, int subTaskIndex) throws RemoteException;

View File

@@ -16,6 +16,8 @@
package android.os;
import com.android.internal.R;
import android.app.ActivityManagerNative;
import android.content.Context;
import android.content.pm.UserInfo;
import android.graphics.Bitmap;
@@ -81,6 +83,39 @@ public class UserManager {
return false;
}
/**
* Return whether the given user is actively running. This means that
* the user is in the "started" state, not "stopped" -- it is currently
* allowed to run code through scheduled alarms, receiving broadcasts,
* etc. A started user may be either the current foreground user or a
* background user; the result here does not distinguish between the two.
* @param user The user to retrieve the running state for.
*/
public boolean isUserRunning(UserHandle user) {
try {
return ActivityManagerNative.getDefault().isUserRunning(
user.getIdentifier(), false);
} catch (RemoteException e) {
return false;
}
}
/**
* Return whether the given user is actively running <em>or</em> stopping.
* This is like {@link #isUserRunning(UserHandle)}, but will also return
* true if the user had been running but is in the process of being stopped
* (but is not yet fully stopped, and still running some code).
* @param user The user to retrieve the running state for.
*/
public boolean isUserRunningOrStopping(UserHandle user) {
try {
return ActivityManagerNative.getDefault().isUserRunning(
user.getIdentifier(), true);
} catch (RemoteException e) {
return false;
}
}
/**
* Returns the UserInfo object describing a specific user.
* Requires {@link android.Manifest.permission#MANAGE_USERS} permission.

View File

@@ -3585,7 +3585,7 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.w(TAG, "Failed trying to unstop package "
+ packageName + ": " + e);
}
if (isUserRunningLocked(user)) {
if (isUserRunningLocked(user, false)) {
forceStopPackageLocked(packageName, pkgUid);
}
}
@@ -9338,6 +9338,12 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
pw.print(": "); uss.dump("", pw);
}
pw.print(" mStartedUserArray: [");
for (int i=0; i<mStartedUserArray.length; i++) {
if (i > 0) pw.print(", ");
pw.print(mStartedUserArray[i]);
}
pw.println("]");
pw.print(" mUserLru: [");
for (int i=0; i<mUserLru.size(); i++) {
if (i > 0) pw.print(", ");
@@ -14134,10 +14140,12 @@ public final class ActivityManagerService extends ActivityManagerNative
// so we can just fairly silently bring the user back from
// the almost-dead.
uss.mState = UserStartedState.STATE_RUNNING;
updateStartedUserArrayLocked();
} 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();
}
mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
@@ -14318,8 +14326,7 @@ public final class ActivityManagerService extends ActivityManagerNative
void finishUserSwitch(UserStartedState uss) {
synchronized (this) {
if ((uss.mState == UserStartedState.STATE_BOOTING
|| uss.mState == UserStartedState.STATE_SHUTDOWN)
if (uss.mState == UserStartedState.STATE_BOOTING
&& mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
uss.mState = UserStartedState.STATE_RUNNING;
final int userId = uss.mHandle.getIdentifier();
@@ -14410,6 +14417,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (uss.mState != UserStartedState.STATE_STOPPING
&& uss.mState != UserStartedState.STATE_SHUTDOWN) {
uss.mState = UserStartedState.STATE_STOPPING;
updateStartedUserArrayLocked();
long ident = Binder.clearCallingIdentity();
try {
@@ -14514,7 +14522,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
@Override
public boolean isUserRunning(int userId) {
public boolean isUserRunning(int userId, boolean orStopped) {
if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
!= PackageManager.PERMISSION_GRANTED) {
String msg = "Permission Denial: isUserRunning() from pid="
@@ -14525,13 +14533,19 @@ public final class ActivityManagerService extends ActivityManagerNative
throw new SecurityException(msg);
}
synchronized (this) {
return isUserRunningLocked(userId);
return isUserRunningLocked(userId, orStopped);
}
}
boolean isUserRunningLocked(int userId) {
boolean isUserRunningLocked(int userId, boolean orStopped) {
UserStartedState state = mStartedUsers.get(userId);
return state != null && state.mState != UserStartedState.STATE_STOPPING
if (state == null) {
return false;
}
if (orStopped) {
return true;
}
return state.mState != UserStartedState.STATE_STOPPING
&& state.mState != UserStartedState.STATE_SHUTDOWN;
}
@@ -14552,9 +14566,24 @@ public final class ActivityManagerService extends ActivityManagerNative
}
private void updateStartedUserArrayLocked() {
mStartedUserArray = new int[mStartedUsers.size()];
int num = 0;
for (int i=0; i<mStartedUsers.size(); i++) {
mStartedUserArray[i] = mStartedUsers.keyAt(i);
UserStartedState uss = mStartedUsers.valueAt(i);
// This list does not include stopping users.
if (uss.mState != UserStartedState.STATE_STOPPING
&& uss.mState != UserStartedState.STATE_SHUTDOWN) {
num++;
}
}
mStartedUserArray = new int[num];
num = 0;
for (int i=0; i<mStartedUsers.size(); i++) {
UserStartedState uss = mStartedUsers.valueAt(i);
if (uss.mState != UserStartedState.STATE_STOPPING
&& uss.mState != UserStartedState.STATE_SHUTDOWN) {
mStartedUserArray[num] = mStartedUsers.keyAt(i);
num++;
}
}
}