An API to check if running in a demo user

Add an API to query if the calling app is running
in a demo user sandbox. This allows apps to customize
the starting experience to a potential customer.

Change-Id: I50e40f9a8c66da4b5672c1dc64606d7bedba3f8c
Fixes: 29833923
diff --git a/api/current.txt b/api/current.txt
index c631627..08c9fd6 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -29362,6 +29362,7 @@
     method public android.os.Bundle getUserRestrictions();
     method public android.os.Bundle getUserRestrictions(android.os.UserHandle);
     method public boolean hasUserRestriction(java.lang.String);
+    method public boolean isDemoUser();
     method public boolean isQuietModeEnabled(android.os.UserHandle);
     method public boolean isSystemUser();
     method public boolean isUserAGoat();
diff --git a/api/system-current.txt b/api/system-current.txt
index 3fa518a..7aa5394 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -31887,6 +31887,7 @@
     method public android.os.Bundle getUserRestrictions();
     method public android.os.Bundle getUserRestrictions(android.os.UserHandle);
     method public boolean hasUserRestriction(java.lang.String);
+    method public boolean isDemoUser();
     method public boolean isManagedProfile();
     method public boolean isManagedProfile(int);
     method public boolean isQuietModeEnabled(android.os.UserHandle);
diff --git a/api/test-current.txt b/api/test-current.txt
index 993f388..003e50b 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -29433,6 +29433,7 @@
     method public android.os.Bundle getUserRestrictions();
     method public android.os.Bundle getUserRestrictions(android.os.UserHandle);
     method public boolean hasUserRestriction(java.lang.String);
+    method public boolean isDemoUser();
     method public boolean isQuietModeEnabled(android.os.UserHandle);
     method public boolean isSystemUser();
     method public boolean isUserAGoat();
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index b27cb32..eeb641d 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -81,4 +81,5 @@
     void clearSeedAccountData();
     boolean someUserHasSeedAccount(in String accountName, in String accountType);
     boolean isManagedProfile(int userId);
+    boolean isDemoUser(int userId);
 }
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index d742206..a44a9ee 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -859,15 +859,17 @@
     }
 
     /**
-     * Checks if the calling app is running in a demo user.
-     * <p>
-     * Caller must hold the MANAGE_USERS permission.
+     * Checks if the calling app is running in a demo user. When running in a demo user,
+     * apps can be more helpful to the user, or explain their features in more detail.
+     *
      * @return whether the caller is a demo user.
-     * @hide
      */
     public boolean isDemoUser() {
-        UserInfo user = getUserInfo(UserHandle.myUserId());
-        return user != null && user.isDemo();
+        try {
+            return mService.isDemoUser(UserHandle.myUserId());
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index d128252..4e8676d 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -869,12 +869,25 @@
             }
         }
         synchronized (mUsersLock) {
-            UserInfo userInfo =  getUserInfoLU(userId);
+            UserInfo userInfo = getUserInfoLU(userId);
             return userInfo != null && userInfo.isManagedProfile();
         }
     }
 
     @Override
+    public boolean isDemoUser(int userId) {
+        int callingUserId = UserHandle.getCallingUserId();
+        if (callingUserId != userId && !hasManageUsersPermission()) {
+            throw new SecurityException("You need MANAGE_USERS permission to query if u=" + userId
+                    + " is a demo user");
+        }
+        synchronized (mUsersLock) {
+            UserInfo userInfo = getUserInfoLU(userId);
+            return userInfo != null && userInfo.isDemo();
+        }
+    }
+
+    @Override
     public boolean isRestricted() {
         synchronized (mUsersLock) {
             return getUserInfoLU(UserHandle.getCallingUserId()).isRestricted();