Move UserManagerInternal into services.jar

Because SettingsProvider needs to call through the IUserManager
interface there is now a method to provide restricted-access information
via that route.  It has the same protection as the implicit local
service call surface that was previously used:  only system-uid callers
can invoke it.

Bug: 140833849
Test: system boots & runs normally
Change-Id: I05823ca57240ab10feb382c45590541212e406c1
diff --git a/services/core/java/android/os/UserManagerInternal.java b/services/core/java/android/os/UserManagerInternal.java
new file mode 100644
index 0000000..e5f8b49
--- /dev/null
+++ b/services/core/java/android/os/UserManagerInternal.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.os;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.graphics.Bitmap;
+
+/**
+ * @hide Only for use within the system server.
+ */
+public abstract class UserManagerInternal {
+    public static final int CAMERA_NOT_DISABLED = 0;
+    public static final int CAMERA_DISABLED_LOCALLY = 1;
+    public static final int CAMERA_DISABLED_GLOBALLY = 2;
+
+    public interface UserRestrictionsListener {
+        /**
+         * Called when a user restriction changes.
+         *
+         * @param userId target user id
+         * @param newRestrictions new user restrictions
+         * @param prevRestrictions user restrictions that were previously set
+         */
+        void onUserRestrictionsChanged(int userId, Bundle newRestrictions, Bundle prevRestrictions);
+    }
+
+    /**
+     * Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} to set
+     * restrictions enforced by the user.
+     *
+     * @param userId target user id for the local restrictions.
+     * @param restrictions a bundle of user restrictions.
+     * @param isDeviceOwner whether {@code userId} corresponds to device owner user id.
+     * @param cameraRestrictionScope is camera disabled and if so what is the scope of restriction.
+     *        Should be one of {@link #CAMERA_NOT_DISABLED}, {@link #CAMERA_DISABLED_LOCALLY} or
+     *                               {@link #CAMERA_DISABLED_GLOBALLY}
+     */
+    public abstract void setDevicePolicyUserRestrictions(int userId, @Nullable Bundle restrictions,
+            boolean isDeviceOwner, int cameraRestrictionScope);
+
+    /**
+     * Returns the "base" user restrictions.
+     *
+     * Used by {@link com.android.server.devicepolicy.DevicePolicyManagerService} for upgrading
+     * from MNC.
+     */
+    public abstract Bundle getBaseUserRestrictions(int userId);
+
+    /**
+     * Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} for upgrading
+     * from MNC.
+     */
+    public abstract void setBaseUserRestrictionsByDpmsForMigration(int userId,
+            Bundle baseRestrictions);
+
+    /** Return a user restriction. */
+    public abstract boolean getUserRestriction(int userId, String key);
+
+    /** Adds a listener to user restriction changes. */
+    public abstract void addUserRestrictionsListener(UserRestrictionsListener listener);
+
+    /** Remove a {@link UserRestrictionsListener}. */
+    public abstract void removeUserRestrictionsListener(UserRestrictionsListener listener);
+
+    /**
+     * Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} to update
+     * whether the device is managed by device owner.
+     */
+    public abstract void setDeviceManaged(boolean isManaged);
+
+    /**
+     * Returns whether the device is managed by device owner.
+     */
+    public abstract boolean isDeviceManaged();
+
+    /**
+     * Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} to update
+     * whether the user is managed by profile owner.
+     */
+    public abstract void setUserManaged(int userId, boolean isManaged);
+
+    /**
+     * whether a profile owner manages this user.
+     */
+    public abstract boolean isUserManaged(int userId);
+
+    /**
+     * Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} to omit
+     * restriction check, because DevicePolicyManager must always be able to set user icon
+     * regardless of any restriction.
+     * Also called by {@link com.android.server.pm.UserManagerService} because the logic of setting
+     * the icon is in this method.
+     */
+    public abstract void setUserIcon(int userId, Bitmap bitmap);
+
+    /**
+     * Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} to inform the
+     * user manager whether all users should be created ephemeral.
+     */
+    public abstract void setForceEphemeralUsers(boolean forceEphemeralUsers);
+
+    /**
+     * Switches to the system user and deletes all other users.
+     *
+     * <p>Called by the {@link com.android.server.devicepolicy.DevicePolicyManagerService} when
+     * the force-ephemeral-users policy is toggled on to make sure there are no pre-existing
+     * non-ephemeral users left.
+     */
+    public abstract void removeAllUsers();
+
+    /**
+     * Called by the activity manager when the ephemeral user goes to background and its removal
+     * starts as a result.
+     *
+     * <p>It marks the ephemeral user as disabled in order to prevent it from being re-entered
+     * before its removal finishes.
+     *
+     * @param userId the ID of the ephemeral user.
+     */
+    public abstract void onEphemeralUserStop(int userId);
+
+    /**
+     * Same as UserManager.createUser(), but bypasses the check for
+     * {@link UserManager#DISALLOW_ADD_USER} and {@link UserManager#DISALLOW_ADD_MANAGED_PROFILE}
+     *
+     * <p>Called by the {@link com.android.server.devicepolicy.DevicePolicyManagerService} when
+     * createAndManageUser is called by the device owner.
+     */
+    public abstract UserInfo createUserEvenWhenDisallowed(String name, int flags,
+            String[] disallowedPackages);
+
+    /**
+     * Same as {@link UserManager#removeUser(int userId)}, but bypasses the check for
+     * {@link UserManager#DISALLOW_REMOVE_USER} and
+     * {@link UserManager#DISALLOW_REMOVE_MANAGED_PROFILE} and does not require the
+     * {@link android.Manifest.permission#MANAGE_USERS} permission.
+     */
+    public abstract boolean removeUserEvenWhenDisallowed(int userId);
+
+    /**
+     * Return whether the given user is running in an
+     * {@code UserState.STATE_RUNNING_UNLOCKING} or
+     * {@code UserState.STATE_RUNNING_UNLOCKED} state.
+     */
+    public abstract boolean isUserUnlockingOrUnlocked(int userId);
+
+    /**
+     * Return whether the given user is running in an
+     * {@code UserState.STATE_RUNNING_UNLOCKED} state.
+     */
+    public abstract boolean isUserUnlocked(int userId);
+
+    /**
+     * Returns whether the given user is running
+     */
+    public abstract boolean isUserRunning(int userId);
+
+    /**
+     * Returns whether the given user is initialized
+     */
+    public abstract boolean isUserInitialized(int userId);
+
+    /**
+     * Returns whether the given user exists
+     */
+    public abstract boolean exists(int userId);
+
+    /**
+     * Set user's running state
+     */
+    public abstract void setUserState(int userId, int userState);
+
+    /**
+     * Remove user's running state
+     */
+    public abstract void removeUserState(int userId);
+
+    /**
+     * Returns an array of user ids. This array is cached in UserManagerService and passed as a
+     * reference, so do not modify the returned array.
+     *
+     * @return the array of user ids.
+     */
+    public abstract int[] getUserIds();
+
+    /**
+     * Checks if the {@code callingUserId} and {@code targetUserId} are same or in same group
+     * and that the {@code callingUserId} is not a managed profile and
+     * {@code targetUserId} is enabled.
+     *
+     * @return TRUE if the {@code callingUserId} can access {@code targetUserId}. FALSE
+     * otherwise
+     *
+     * @throws SecurityException if the calling user and {@code targetUser} are not in the same
+     * group and {@code throwSecurityException} is true, otherwise if will simply return false.
+     */
+    public abstract boolean isProfileAccessible(int callingUserId, int targetUserId,
+            String debugMsg, boolean throwSecurityException);
+
+    /**
+     * If {@code userId} is of a managed profile, return the parent user ID. Otherwise return
+     * itself.
+     */
+    public abstract int getProfileParentId(int userId);
+
+    /**
+     * Checks whether changing a setting to a value is prohibited by the corresponding user
+     * restriction.
+     *
+     * <p>See also {@link com.android.server.pm.UserRestrictionsUtils#applyUserRestriction(
+     * Context, int, String, boolean)}, which should be in sync with this method.
+     *
+     * @return {@code true} if the change is prohibited, {@code false} if the change is allowed.
+     *
+     * @hide
+     */
+    public abstract boolean isSettingRestrictedForUser(String setting, int userId, String value,
+            int callingUid);
+
+    /** @return a specific user restriction that's in effect currently. */
+    public abstract boolean hasUserRestriction(String restriction, int userId);
+
+    /**
+     * Gets an {@link UserInfo} for the given {@code userId}, or {@code null} if not
+     * found.
+     */
+    public abstract @Nullable UserInfo getUserInfo(@UserIdInt int userId);
+
+    /**
+     * Gets all {@link UserInfo UserInfos}.
+     */
+    public abstract @NonNull UserInfo[] getUserInfos();
+}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 95baa01..8814f6d 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -54,6 +54,7 @@
 import android.os.IBinder;
 import android.os.IProgressListener;
 import android.os.IUserManager;
+import android.os.IUserRestrictionsListener;
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.os.Parcelable;
@@ -1606,6 +1607,36 @@
         return false;
     }
 
+    @Override
+    public boolean isSettingRestrictedForUser(String setting, @UserIdInt int userId,
+            String value, int callingUid) {
+        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+            throw new SecurityException("Non-system caller");
+        }
+        return UserRestrictionsUtils.isSettingRestrictedForUser(mContext, setting, userId,
+                value, callingUid);
+    }
+
+    @Override
+    public void addUserRestrictionsListener(final IUserRestrictionsListener listener) {
+        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+            throw new SecurityException("Non-system caller");
+        }
+
+        // NOTE: unregistering not supported; only client is the settings provider,
+        // which installs a single static permanent listener.  If that listener goes
+        // bad it implies the whole system process is going to crash.
+        mLocalService.addUserRestrictionsListener(
+                (int userId, Bundle newRestrict, Bundle prevRestrict) -> {
+                    try {
+                        listener.onUserRestrictionsChanged(userId, newRestrict, prevRestrict);
+                    } catch (RemoteException re) {
+                        Slog.e("IUserRestrictionsListener",
+                                "Unable to invoke listener: " + re.getMessage());
+                    }
+                });
+    }
+
     /**
      * @hide
      *
@@ -4410,7 +4441,7 @@
         @Override
         public boolean isSettingRestrictedForUser(String setting, @UserIdInt int userId,
                 String value, int callingUid) {
-            return UserRestrictionsUtils.isSettingRestrictedForUser(mContext, setting, userId,
+            return UserManagerService.this.isSettingRestrictedForUser(setting, userId,
                     value, callingUid);
         }