diff --git a/uidswap.c b/uidswap.c
index 8376483967a9f609f089a1879423ee6b3ea4d4d0..bc6194ec0a3d78bfafbfc5f487896f57f95760d8 100644
--- a/uidswap.c
+++ b/uidswap.c
@@ -27,6 +27,12 @@
 #include "uidswap.h"
 #include "xmalloc.h"
 
+#ifdef ANDROID
+#include <private/android_filesystem_config.h>
+#include <linux/capability.h>
+#include <linux/prctl.h>
+#endif
+
 /*
  * Note: all these functions must work in all of the following cases:
  *    1. euid=0, ruid=0
@@ -212,6 +218,10 @@ permanently_set_uid(struct passwd *pw)
 {
 	uid_t old_uid = getuid();
 	gid_t old_gid = getgid();
+#ifdef ANDROID
+	struct __user_cap_header_struct header;
+	struct __user_cap_data_struct cap;
+#endif
 
 	if (pw == NULL)
 		fatal("permanently_set_uid: no user given");
@@ -220,6 +230,27 @@ permanently_set_uid(struct passwd *pw)
 	debug("permanently_set_uid: %u/%u", (u_int)pw->pw_uid,
 	    (u_int)pw->pw_gid);
 
+#ifdef ANDROID
+	if (pw->pw_uid == AID_SHELL) {
+		prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
+
+		/* add extra groups needed for shell user:
+		** AID_LOG to read system logs (adb logcat)
+		** AID_INPUT to diagnose input issues (getevent)
+		** AID_INET to diagnose network issues (netcfg, ping)
+		** AID_GRAPHICS to access the frame buffer
+		** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)
+		** AID_SDCARD_RW to allow writing to the SD card
+		** AID_MOUNT to allow unmounting the SD card before rebooting
+		** AID_NET_BW_STATS to read out qtaguid statistics
+		*/
+		gid_t groups[] = { AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS,
+						   AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_RW,
+						   AID_MOUNT, AID_NET_BW_STATS };
+		setgroups(sizeof(groups)/sizeof(groups[0]), groups);
+	}
+#endif
+
 #if defined(HAVE_SETRESGID) && !defined(BROKEN_SETRESGID)
 	if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) < 0)
 		fatal("setresgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno));
@@ -285,4 +316,16 @@ permanently_set_uid(struct passwd *pw)
 		    __func__, (u_int)getuid(), (u_int)geteuid(),
 		    (u_int)pw->pw_uid);
 	}
+
+#ifdef ANDROID
+	if (pw->pw_uid == AID_SHELL) {
+		/* set CAP_SYS_BOOT capability, so "adb reboot" will succeed */
+		header.version = _LINUX_CAPABILITY_VERSION;
+		header.pid = 0;
+		cap.effective = cap.permitted = (1 << CAP_SYS_BOOT);
+		cap.inheritable = 0;
+		capset(&header, &cap);
+	}
+#endif
+
 }