summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Dianne Hackborn <hackbod@google.com> 2013-06-27 18:07:24 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2013-06-27 18:07:24 +0000
commit9b43a604059a8d8dc8186862bddbf12082d67e93 (patch)
treef0e211791eac981b531d6cc49023c65a38956049
parent4db614dbed10e74285eaa6d0e56c3e79a4afecc0 (diff)
parent053f61d6a6e23825e680dc49982e55c5b4299d61 (diff)
Merge "Work on issue #9586838: Crash after waking up Hammerhead device"
-rw-r--r--core/java/android/os/FileUtils.java2
-rw-r--r--core/java/com/android/internal/os/ProcessStats.java7
-rw-r--r--core/jni/android_os_FileUtils.cpp19
-rw-r--r--core/res/AndroidManifest.xml7
-rw-r--r--core/res/res/values/strings.xml9
-rw-r--r--services/java/com/android/server/BatteryService.java18
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java93
-rw-r--r--services/java/com/android/server/am/ActivityStack.java21
8 files changed, 147 insertions, 29 deletions
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 9666d9af8cc4..97ea99ddb419 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -60,6 +60,8 @@ public class FileUtils {
public static native int setPermissions(String file, int mode, int uid, int gid);
+ public static native int getUid(String file);
+
/** returns the FAT file system volume ID for the volume mounted
* at the given mount point, or -1 for failure
* @param mountPoint point for FAT volume
diff --git a/core/java/com/android/internal/os/ProcessStats.java b/core/java/com/android/internal/os/ProcessStats.java
index b63dce5b7163..874bc0eb4dcb 100644
--- a/core/java/com/android/internal/os/ProcessStats.java
+++ b/core/java/com/android/internal/os/ProcessStats.java
@@ -18,6 +18,7 @@ package com.android.internal.os;
import static android.os.Process.*;
+import android.os.FileUtils;
import android.os.Process;
import android.os.StrictMode;
import android.os.SystemClock;
@@ -174,12 +175,15 @@ public class ProcessStats {
public static class Stats {
public final int pid;
+ public final int uid;
final String statFile;
final String cmdlineFile;
final String threadsDir;
final ArrayList<Stats> threadStats;
final ArrayList<Stats> workingThreads;
-
+
+ public BatteryStatsImpl.Uid.Proc batteryStats;
+
public boolean interesting;
public String baseName;
@@ -229,6 +233,7 @@ public class ProcessStats {
threadStats = null;
workingThreads = null;
}
+ uid = FileUtils.getUid(statFile.toString());
}
}
diff --git a/core/jni/android_os_FileUtils.cpp b/core/jni/android_os_FileUtils.cpp
index a07f5b770b12..0aaa2b158da8 100644
--- a/core/jni/android_os_FileUtils.cpp
+++ b/core/jni/android_os_FileUtils.cpp
@@ -55,6 +55,24 @@ jint android_os_FileUtils_setPermissions(JNIEnv* env, jobject clazz,
return chmod(file8.string(), mode) == 0 ? 0 : errno;
}
+jint android_os_FileUtils_getUid(JNIEnv* env, jobject clazz, jstring file)
+{
+ struct stat stats;
+ const jchar* str = env->GetStringCritical(file, 0);
+ String8 file8;
+ if (str) {
+ file8 = String8(str, env->GetStringLength(file));
+ env->ReleaseStringCritical(file, str);
+ }
+ if (file8.size() <= 0) {
+ return ENOENT;
+ }
+ if (stat(file8.string(), &stats) < 0) {
+ return -1;
+ }
+ return stats.st_uid;
+}
+
jint android_os_FileUtils_getFatVolumeId(JNIEnv* env, jobject clazz, jstring path)
{
if (path == NULL) {
@@ -78,6 +96,7 @@ jint android_os_FileUtils_getFatVolumeId(JNIEnv* env, jobject clazz, jstring pat
static const JNINativeMethod methods[] = {
{"setPermissions", "(Ljava/lang/String;III)I", (void*)android_os_FileUtils_setPermissions},
+ {"getUid", "(Ljava/lang/String;)I", (void*)android_os_FileUtils_getUid},
{"getFatVolumeId", "(Ljava/lang/String;)I", (void*)android_os_FileUtils_getFatVolumeId},
};
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index ae6d141d6956..7ddb0dc9fa17 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1222,6 +1222,13 @@
android:label="@string/permlab_removeTasks"
android:description="@string/permdesc_removeTasks" />
+ <!-- @hide Allows an application to create/manage/remove stacks -->
+ <permission android:name="android.permission.MANAGE_ACTIVITY_STACKS"
+ android:permissionGroup="android.permission-group.APP_INFO"
+ android:protectionLevel="signature"
+ android:label="@string/permlab_manageActivityStacks"
+ android:description="@string/permdesc_manageActivityStacks" />
+
<!-- Allows an application to start any activity, regardless of permission
protection or exported state. @hide -->
<permission android:name="android.permission.START_ANY_ACTIVITY"
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4b02a7d28454..75ff8b2facc1 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -712,6 +712,15 @@
tasks and kill their apps. Malicious apps may disrupt
the behavior of other apps.</string>
+ <!-- [CHAR LIMIT=NONE] Title of an application permission, allowing an application to create,
+ change, remove activity stacks. -->
+ <string name="permlab_manageActivityStacks">manage activity stacks</string>
+ <!-- [CHAR LIMIT=NONE] Description of an application permission, allowing an application to create,
+ change, remove activity stacks. -->
+ <string name="permdesc_manageActivityStacks">Allows the app to add, remove, and
+ modify the activity stacks in which other apps run. Malicious apps may disrupt
+ the behavior of other apps.</string>
+
<!-- Title of an application permission, allowing an application to start any activity, regardless of permission protection or exported state. -->
<string name="permlab_startAnyActivity">start any activity</string>
<!-- Description of an application permission, allowing an application to start any activity, regardless of permission protection or exported state. -->
diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java
index 12a05496426d..de58496884df 100644
--- a/services/java/com/android/server/BatteryService.java
+++ b/services/java/com/android/server/BatteryService.java
@@ -642,15 +642,25 @@ public final class BatteryService extends Binder {
update = false;
}
if (update) {
- mUpdatesStopped = true;
- processValuesLocked();
+ long ident = Binder.clearCallingIdentity();
+ try {
+ mUpdatesStopped = true;
+ processValuesLocked();
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
}
} catch (NumberFormatException ex) {
pw.println("Bad value: " + value);
}
} else if (args.length == 1 && "reset".equals(args[0])) {
- mUpdatesStopped = false;
- updateLocked();
+ long ident = Binder.clearCallingIdentity();
+ try {
+ mUpdatesStopped = false;
+ updateLocked();
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
} else {
pw.println("Dump current battery state, or:");
pw.println(" set ac|usb|wireless|status|level|invalid <value>");
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 6f367e0edb71..475092aa26dd 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1923,6 +1923,16 @@ public final class ActivityManagerService extends ActivityManagerNative
st.rel_stime-otherSTime);
ps.addSpeedStepTimes(cpuSpeedTimes);
pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
+ } else if (st.uid >= Process.FIRST_APPLICATION_UID) {
+ BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
+ if (ps == null) {
+ st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid,
+ "(Unknown)");
+ }
+ ps.addCpuTimeLocked(st.rel_utime-otherUTime,
+ st.rel_stime-otherSTime);
+ ps.addSpeedStepTimes(cpuSpeedTimes);
+ pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
} else {
BatteryStatsImpl.Uid.Proc ps =
bstats.getProcessStatsLocked(st.name, st.pid);
@@ -6370,34 +6380,55 @@ public final class ActivityManagerService extends ActivityManagerNative
@Override
public int createStack(int taskId, int relativeStackBoxId, int position, float weight) {
+ enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
+ "createStack()");
if (DEBUG_STACK) Slog.d(TAG, "createStack: taskId=" + taskId + " relStackBoxId=" +
relativeStackBoxId + " position=" + position + " weight=" + weight);
synchronized (this) {
- int stackId = mStackSupervisor.createStack();
- mWindowManager.createStack(stackId, relativeStackBoxId, position, weight);
- if (taskId > 0) {
- moveTaskToStack(taskId, stackId, true);
+ long ident = Binder.clearCallingIdentity();
+ try {
+ int stackId = mStackSupervisor.createStack();
+ mWindowManager.createStack(stackId, relativeStackBoxId, position, weight);
+ if (taskId > 0) {
+ moveTaskToStack(taskId, stackId, true);
+ }
+ return stackId;
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
- return stackId;
}
}
@Override
public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
+ enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
+ "moveTaskToStack()");
if (stackId == HOME_STACK_ID) {
Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
new RuntimeException("here").fillInStackTrace());
}
synchronized (this) {
- if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
- + stackId + " toTop=" + toTop);
- mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
+ long ident = Binder.clearCallingIdentity();
+ try {
+ if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
+ + stackId + " toTop=" + toTop);
+ mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
}
}
@Override
public void resizeStackBox(int stackBoxId, float weight) {
- mWindowManager.resizeStackBox(stackBoxId, weight);
+ enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
+ "resizeStackBox()");
+ long ident = Binder.clearCallingIdentity();
+ try {
+ mWindowManager.resizeStackBox(stackBoxId, weight);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
}
private ArrayList<StackInfo> getStacks() {
@@ -6447,30 +6478,44 @@ public final class ActivityManagerService extends ActivityManagerNative
@Override
public List<StackBoxInfo> getStackBoxes() {
- List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos();
- synchronized (this) {
- List<StackInfo> stackInfos = getStacks();
- for (StackBoxInfo stackBoxInfo : stackBoxInfos) {
- addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos);
+ enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
+ "getStackBoxes()");
+ long ident = Binder.clearCallingIdentity();
+ try {
+ List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos();
+ synchronized (this) {
+ List<StackInfo> stackInfos = getStacks();
+ for (StackBoxInfo stackBoxInfo : stackBoxInfos) {
+ addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos);
+ }
}
+ return stackBoxInfos;
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
- return stackBoxInfos;
}
@Override
public StackBoxInfo getStackBoxInfo(int stackBoxId) {
- List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos();
- StackBoxInfo info = null;
- synchronized (this) {
- List<StackInfo> stackInfos = getStacks();
- for (StackBoxInfo stackBoxInfo : stackBoxInfos) {
- addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos);
- if (stackBoxInfo.stackBoxId == stackBoxId) {
- info = stackBoxInfo;
+ enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
+ "getStackBoxInfo()");
+ long ident = Binder.clearCallingIdentity();
+ try {
+ List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos();
+ StackBoxInfo info = null;
+ synchronized (this) {
+ List<StackInfo> stackInfos = getStacks();
+ for (StackBoxInfo stackBoxInfo : stackBoxInfos) {
+ addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos);
+ if (stackBoxInfo.stackBoxId == stackBoxId) {
+ info = stackBoxInfo;
+ }
}
}
+ return info;
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
- return info;
}
@Override
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 1e19989ce48b..a9ab53d969f0 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -69,6 +69,7 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
+import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
@@ -120,6 +121,10 @@ final class ActivityStack {
// is being started.
static final boolean SHOW_APP_STARTING_PREVIEW = true;
+ // For debugging to make sure the caller when acquiring/releasing our
+ // wake lock is the system process.
+ static final boolean VALIDATE_WAKE_LOCK_CALLER = true;
+
enum ActivityState {
INITIALIZING,
RESUMED,
@@ -288,6 +293,10 @@ final class ActivityStack {
synchronized (mService) {
if (mLaunchingActivity.isHeld()) {
Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
+ if (VALIDATE_WAKE_LOCK_CALLER
+ && Binder.getCallingUid() != Process.myUid()) {
+ throw new IllegalStateException("Calling must be system uid");
+ }
mLaunchingActivity.release();
}
}
@@ -328,6 +337,9 @@ final class ActivityStack {
mStackSupervisor = service.mStackSupervisor;
mContext = context;
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+ if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
+ throw new IllegalStateException("Calling must be system uid");
+ }
mLaunchingActivity =
pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
mLaunchingActivity.setReferenceCounted(false);
@@ -595,6 +607,9 @@ final class ActivityStack {
void stopIfSleepingLocked() {
if (mLaunchingActivity.isHeld()) {
+ if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
+ throw new IllegalStateException("Calling must be system uid");
+ }
mLaunchingActivity.release();
mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
}
@@ -722,6 +737,9 @@ final class ActivityStack {
// If we are not going to sleep, we want to ensure the device is
// awake until the next activity is started.
if (!mService.isSleepingOrShuttingDown()) {
+ if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
+ throw new IllegalStateException("Calling must be system uid");
+ }
mLaunchingActivity.acquire();
if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
// To be safe, don't allow the wake lock to be held for too long.
@@ -2092,6 +2110,9 @@ final class ActivityStack {
// No longer need to keep the device awake.
if (mResumedActivity == res && mLaunchingActivity.isHeld()) {
mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
+ if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
+ throw new IllegalStateException("Calling must be system uid");
+ }
mLaunchingActivity.release();
}