Work on issue #9586838: Crash after waking up Hammerhead device

I made the power manager more rigid, not allowing different uids
to use the same wake lock.  This never should happen.  I would
guess there is somewhere that the activity manager is acquiring
the wake lock without clearing the calling identity...  but it is
hard to follow all the paths this may happen in.  So here we add
some checks when acquiring/releasing the wake lock to make sure
it is being done as the system uid.

Also:

- Protect the new activity stack calls with a permission, and
make sure to clear the calling uid once past that.
- Collect uid data from process stats so we can correctly
associate CPU use with a uid even if we don't know about the
pid for some reason.
- Fix battery stats dump commands to clear calling uid before
executing so they aren't broken.

Change-Id: I0030d4f7b614e3270d794ecfc3669139a5703ce9
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 9666d9a..97ea99d 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -60,6 +60,8 @@
 
     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 b63dce5..874bc0e 100644
--- a/core/java/com/android/internal/os/ProcessStats.java
+++ b/core/java/com/android/internal/os/ProcessStats.java
@@ -18,6 +18,7 @@
 
 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 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 @@
                 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 a07f5b7..0aaa2b1 100644
--- a/core/jni/android_os_FileUtils.cpp
+++ b/core/jni/android_os_FileUtils.cpp
@@ -55,6 +55,24 @@
     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 @@
 
 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 ae6d141..7ddb0dc 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 4b02a7d..75ff8b2 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. -->