diff options
| author | 2013-06-27 18:07:24 +0000 | |
|---|---|---|
| committer | 2013-06-27 18:07:24 +0000 | |
| commit | 9b43a604059a8d8dc8186862bddbf12082d67e93 (patch) | |
| tree | f0e211791eac981b531d6cc49023c65a38956049 | |
| parent | 4db614dbed10e74285eaa6d0e56c3e79a4afecc0 (diff) | |
| parent | 053f61d6a6e23825e680dc49982e55c5b4299d61 (diff) | |
Merge "Work on issue #9586838: Crash after waking up Hammerhead device"
| -rw-r--r-- | core/java/android/os/FileUtils.java | 2 | ||||
| -rw-r--r-- | core/java/com/android/internal/os/ProcessStats.java | 7 | ||||
| -rw-r--r-- | core/jni/android_os_FileUtils.cpp | 19 | ||||
| -rw-r--r-- | core/res/AndroidManifest.xml | 7 | ||||
| -rw-r--r-- | core/res/res/values/strings.xml | 9 | ||||
| -rw-r--r-- | services/java/com/android/server/BatteryService.java | 18 | ||||
| -rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 93 | ||||
| -rw-r--r-- | services/java/com/android/server/am/ActivityStack.java | 21 |
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(); } |