Use GID "wakelock" to control access to kernel wakelock

 * Added GID "wakelock" (3010) to the list of groups the System Server
   belongs to.

 * Added GID "wakelock" to the list of assigned groups for the
   "android.permission.BLUETOOTH_STACK" Android permission.

 * Grant CAP_BLOCK_SUSPEND to processes that belong to GID "wakelock"

Bug: 25864142
Change-Id: I8a9a5f11e4a9ecd1abf2d4f4b90ec89b3101332e
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 8e318a2..4a1f7f4 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -534,7 +534,7 @@
         String args[] = {
             "--setuid=1000",
             "--setgid=1000",
-            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007,3009",
+            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007,3009,3010",
             "--capabilities=" + capabilities + "," + capabilities,
             "--nice-name=system_server",
             "--runtime-args",
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 96d150b..041e693 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -605,10 +605,32 @@
         jint debug_flags, jobjectArray rlimits,
         jint mount_external, jstring se_info, jstring se_name,
         jintArray fdsToClose, jstring instructionSet, jstring appDataDir) {
-    // Grant CAP_WAKE_ALARM to the Bluetooth process.
     jlong capabilities = 0;
+
+    // Grant CAP_WAKE_ALARM to the Bluetooth process.
     if (uid == AID_BLUETOOTH) {
-        capabilities |= (1LL << CAP_WAKE_ALARM);
+      capabilities |= (1LL << CAP_WAKE_ALARM);
+    }
+
+    // Grant CAP_BLOCK_SUSPEND to processes that belong to GID "wakelock"
+    bool gid_wakelock_found = false;
+    if (gid == AID_WAKELOCK) {
+      gid_wakelock_found = true;
+    } else if (gids != NULL) {
+      jsize gids_num = env->GetArrayLength(gids);
+      ScopedIntArrayRO ar(env, gids);
+      if (ar.get() == NULL) {
+        RuntimeAbort(env, __LINE__, "Bad gids array");
+      }
+      for (int i = 0; i < gids_num; i++) {
+        if (ar[i] == AID_WAKELOCK) {
+          gid_wakelock_found = true;
+          break;
+        }
+      }
+    }
+    if (gid_wakelock_found) {
+      capabilities |= (1LL << CAP_BLOCK_SUSPEND);
     }
 
     return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags,
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index b4f88c33..999d47b 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -44,6 +44,7 @@
 
     <permission name="android.permission.BLUETOOTH_STACK" >
         <group gid="net_bt_stack" />
+        <group gid="wakelock" />
     </permission>
 
     <permission name="android.permission.NET_TUNNELING" >