Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a4f11979 authored by Makoto Onuki's avatar Makoto Onuki
Browse files

First cut of user restriction layering.

- Start persisting restrictions set by DO/PO.

- Also dump user restrictions on dumpsys

- More changes will follow, including migration.

- Now System settings are mockable.

Bug 23902097
Bug 23902477

Change-Id: I0bda22f484e1a8e259a1feb2df83c5f4a29116da
parent 7ed9df29
Loading
Loading
Loading
Loading
+14 −106
Original line number Diff line number Diff line
@@ -59,8 +59,6 @@ import android.util.SparseBooleanArray;
import android.util.TimeUtils;
import android.util.Xml;

import com.google.android.collect.Sets;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IAppOpsService;
import com.android.internal.util.FastXmlSerializer;
@@ -82,7 +80,6 @@ import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import libcore.io.IoUtils;

@@ -147,10 +144,6 @@ public class UserManagerService extends IUserManager.Stub {
     */
    private static final boolean CONFIG_PROFILES_SHARE_CREDENTIAL = true;

    // Set of user restrictions, which can only be enforced by the system
    private static final Set<String> SYSTEM_CONTROLLED_RESTRICTIONS = Sets.newArraySet(
            UserManager.DISALLOW_RECORD_AUDIO);

    static final int WRITE_USER_MSG = 1;
    static final int WRITE_USER_DELAY = 2*1000;  // 2 seconds

@@ -596,7 +589,7 @@ public class UserManagerService extends IUserManager.Stub {
    public void setUserRestriction(String key, boolean value, int userId) {
        checkManageUsersPermission("setUserRestriction");
        synchronized (mPackagesLock) {
            if (!SYSTEM_CONTROLLED_RESTRICTIONS.contains(key)) {
            if (!UserRestrictionsUtils.SYSTEM_CONTROLLED_USER_RESTRICTIONS.contains(key)) {
                Bundle restrictions = getUserRestrictions(userId);
                restrictions.putBoolean(key, value);
                setUserRestrictionsInternalLocked(restrictions, userId);
@@ -622,7 +615,7 @@ public class UserManagerService extends IUserManager.Stub {
        synchronized (mPackagesLock) {
            final Bundle oldUserRestrictions = mUserRestrictions.get(userId);
            // Restore the original state of system controlled restrictions from oldUserRestrictions
            for (String key : SYSTEM_CONTROLLED_RESTRICTIONS) {
            for (String key : UserRestrictionsUtils.SYSTEM_CONTROLLED_USER_RESTRICTIONS) {
                restrictions.remove(key);
                if (oldUserRestrictions.containsKey(key)) {
                    restrictions.putBoolean(key, oldUserRestrictions.getBoolean(key));
@@ -815,7 +808,8 @@ public class UserManagerService extends IUserManager.Stub {
                                && type != XmlPullParser.END_TAG) {
                            if (type == XmlPullParser.START_TAG) {
                                if (parser.getName().equals(TAG_RESTRICTIONS)) {
                                    readRestrictionsLocked(parser, mGuestRestrictions);
                                    UserRestrictionsUtils
                                            .readRestrictions(parser, mGuestRestrictions);
                                }
                                break;
                            }
@@ -978,7 +972,7 @@ public class UserManagerService extends IUserManager.Stub {
            serializer.endTag(null, TAG_NAME);
            Bundle restrictions = mUserRestrictions.get(userInfo.id);
            if (restrictions != null) {
                writeRestrictionsLocked(serializer, restrictions);
                UserRestrictionsUtils.writeRestrictions(serializer, restrictions, TAG_RESTRICTIONS);
            }
            serializer.endTag(null, TAG_USER);

@@ -1016,7 +1010,8 @@ public class UserManagerService extends IUserManager.Stub {
            serializer.attribute(null, ATTR_USER_VERSION, Integer.toString(mUserVersion));

            serializer.startTag(null, TAG_GUEST_RESTRICTIONS);
            writeRestrictionsLocked(serializer, mGuestRestrictions);
            UserRestrictionsUtils
                    .writeRestrictions(serializer, mGuestRestrictions, TAG_RESTRICTIONS);
            serializer.endTag(null, TAG_GUEST_RESTRICTIONS);
            final int userSize = mUsers.size();
            for (int i = 0; i < userSize; i++) {
@@ -1036,45 +1031,6 @@ public class UserManagerService extends IUserManager.Stub {
        }
    }

    private void writeRestrictionsLocked(XmlSerializer serializer, Bundle restrictions)
            throws IOException {
        serializer.startTag(null, TAG_RESTRICTIONS);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_WIFI);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_MODIFY_ACCOUNTS);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_INSTALL_APPS);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_UNINSTALL_APPS);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_SHARE_LOCATION);
        writeBoolean(serializer, restrictions,
                UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_BLUETOOTH);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_USB_FILE_TRANSFER);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_CREDENTIALS);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_REMOVE_USER);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_DEBUGGING_FEATURES);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_VPN);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_TETHERING);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_NETWORK_RESET);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_FACTORY_RESET);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_ADD_USER);
        writeBoolean(serializer, restrictions, UserManager.ENSURE_VERIFY_APPS);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_CELL_BROADCASTS);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_APPS_CONTROL);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_UNMUTE_MICROPHONE);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_ADJUST_VOLUME);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_OUTGOING_CALLS);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_SMS);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_FUN);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_CREATE_WINDOWS);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_OUTGOING_BEAM);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_WALLPAPER);
        writeBoolean(serializer, restrictions, UserManager.DISALLOW_SAFE_BOOT);
        writeBoolean(serializer, restrictions, UserManager.ALLOW_PARENT_PROFILE_APP_LINKING);
        serializer.endTag(null, TAG_RESTRICTIONS);
    }

    private UserInfo readUserLocked(int id) {
        int flags = 0;
        int serialNumber = id;
@@ -1143,7 +1099,7 @@ public class UserManagerService extends IUserManager.Stub {
                            name = parser.getText();
                        }
                    } else if (TAG_RESTRICTIONS.equals(tag)) {
                        readRestrictionsLocked(parser, restrictions);
                        UserRestrictionsUtils.readRestrictions(parser, restrictions);
                    }
                }
            }
@@ -1172,60 +1128,6 @@ public class UserManagerService extends IUserManager.Stub {
        return null;
    }

    private void readRestrictionsLocked(XmlPullParser parser, Bundle restrictions)
            throws IOException {
        readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_WIFI);
        readBoolean(parser, restrictions, UserManager.DISALLOW_MODIFY_ACCOUNTS);
        readBoolean(parser, restrictions, UserManager.DISALLOW_INSTALL_APPS);
        readBoolean(parser, restrictions, UserManager.DISALLOW_UNINSTALL_APPS);
        readBoolean(parser, restrictions, UserManager.DISALLOW_SHARE_LOCATION);
        readBoolean(parser, restrictions,
                UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
        readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_BLUETOOTH);
        readBoolean(parser, restrictions, UserManager.DISALLOW_USB_FILE_TRANSFER);
        readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_CREDENTIALS);
        readBoolean(parser, restrictions, UserManager.DISALLOW_REMOVE_USER);
        readBoolean(parser, restrictions, UserManager.DISALLOW_DEBUGGING_FEATURES);
        readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_VPN);
        readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_TETHERING);
        readBoolean(parser, restrictions, UserManager.DISALLOW_NETWORK_RESET);
        readBoolean(parser, restrictions, UserManager.DISALLOW_FACTORY_RESET);
        readBoolean(parser, restrictions, UserManager.DISALLOW_ADD_USER);
        readBoolean(parser, restrictions, UserManager.ENSURE_VERIFY_APPS);
        readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_CELL_BROADCASTS);
        readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
        readBoolean(parser, restrictions, UserManager.DISALLOW_APPS_CONTROL);
        readBoolean(parser, restrictions,
                UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA);
        readBoolean(parser, restrictions, UserManager.DISALLOW_UNMUTE_MICROPHONE);
        readBoolean(parser, restrictions, UserManager.DISALLOW_ADJUST_VOLUME);
        readBoolean(parser, restrictions, UserManager.DISALLOW_OUTGOING_CALLS);
        readBoolean(parser, restrictions, UserManager.DISALLOW_SMS);
        readBoolean(parser, restrictions, UserManager.DISALLOW_FUN);
        readBoolean(parser, restrictions, UserManager.DISALLOW_CREATE_WINDOWS);
        readBoolean(parser, restrictions, UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE);
        readBoolean(parser, restrictions, UserManager.DISALLOW_OUTGOING_BEAM);
        readBoolean(parser, restrictions, UserManager.DISALLOW_WALLPAPER);
        readBoolean(parser, restrictions, UserManager.DISALLOW_SAFE_BOOT);
        readBoolean(parser, restrictions, UserManager.ALLOW_PARENT_PROFILE_APP_LINKING);
    }

    private void readBoolean(XmlPullParser parser, Bundle restrictions,
            String restrictionKey) {
        String value = parser.getAttributeValue(null, restrictionKey);
        if (value != null) {
            restrictions.putBoolean(restrictionKey, Boolean.parseBoolean(value));
        }
    }

    private void writeBoolean(XmlSerializer xml, Bundle restrictions, String restrictionKey)
            throws IOException {
        if (restrictions.containsKey(restrictionKey)) {
            xml.attribute(null, restrictionKey,
                    Boolean.toString(restrictions.getBoolean(restrictionKey)));
        }
    }

    private int readIntAttribute(XmlPullParser parser, String attr, int defaultValue) {
        String valueString = parser.getAttributeValue(null, attr);
        if (valueString == null) return defaultValue;
@@ -2142,7 +2044,13 @@ public class UserManagerService extends IUserManager.Stub {
                    sb.append(" ago");
                    pw.println(sb);
                }
                pw.println("    Restrictions:");
                UserRestrictionsUtils.dumpRestrictions(
                        pw, "      ", mUserRestrictions.get(user.id));
            }
            pw.println();
            pw.println("Guest restrictions:");
            UserRestrictionsUtils.dumpRestrictions(pw, "  ", mGuestRestrictions);
        }
    }

+122 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 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 com.android.server.pm;

import com.google.android.collect.Sets;

import com.android.internal.util.Preconditions;

import android.os.Bundle;
import android.os.UserManager;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Set;

public class UserRestrictionsUtils {
    private UserRestrictionsUtils() {
    }

    public static final String[] USER_RESTRICTIONS = {
            UserManager.DISALLOW_CONFIG_WIFI,
            UserManager.DISALLOW_MODIFY_ACCOUNTS,
            UserManager.DISALLOW_INSTALL_APPS,
            UserManager.DISALLOW_UNINSTALL_APPS,
            UserManager.DISALLOW_SHARE_LOCATION,
            UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
            UserManager.DISALLOW_CONFIG_BLUETOOTH,
            UserManager.DISALLOW_USB_FILE_TRANSFER,
            UserManager.DISALLOW_CONFIG_CREDENTIALS,
            UserManager.DISALLOW_REMOVE_USER,
            UserManager.DISALLOW_DEBUGGING_FEATURES,
            UserManager.DISALLOW_CONFIG_VPN,
            UserManager.DISALLOW_CONFIG_TETHERING,
            UserManager.DISALLOW_NETWORK_RESET,
            UserManager.DISALLOW_FACTORY_RESET,
            UserManager.DISALLOW_ADD_USER,
            UserManager.ENSURE_VERIFY_APPS,
            UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
            UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
            UserManager.DISALLOW_APPS_CONTROL,
            UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
            UserManager.DISALLOW_UNMUTE_MICROPHONE,
            UserManager.DISALLOW_ADJUST_VOLUME,
            UserManager.DISALLOW_OUTGOING_CALLS,
            UserManager.DISALLOW_SMS,
            UserManager.DISALLOW_FUN,
            UserManager.DISALLOW_CREATE_WINDOWS,
            UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE,
            UserManager.DISALLOW_OUTGOING_BEAM,
            UserManager.DISALLOW_WALLPAPER,
            UserManager.DISALLOW_SAFE_BOOT,
            UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
            UserManager.DISALLOW_RECORD_AUDIO,
    };

    /**
     * Set of user restrictions, which can only be enforced by the system.
     */
    public static final Set<String> SYSTEM_CONTROLLED_USER_RESTRICTIONS = Sets.newArraySet(
            UserManager.DISALLOW_RECORD_AUDIO);

    /**
     * Set of user restriction which we don't want to persist.
     */
    public static final Set<String> NON_PERSIST_USER_RESTRICTIONS = Sets.newArraySet(
            UserManager.DISALLOW_RECORD_AUDIO);

    public static void writeRestrictions(XmlSerializer serializer, Bundle restrictions,
            String tag) throws IOException {
        serializer.startTag(null, tag);
        for (String key : USER_RESTRICTIONS) {
            //
            if (restrictions.getBoolean(key)
                    && !NON_PERSIST_USER_RESTRICTIONS.contains(key)) {
                serializer.attribute(null, key, "true");
            }
        }
        serializer.endTag(null, tag);
    }

    public static void readRestrictions(XmlPullParser parser, Bundle restrictions)
            throws IOException {
        for (String key : USER_RESTRICTIONS) {
            final String value = parser.getAttributeValue(null, key);
            if (value != null) {
                restrictions.putBoolean(key, Boolean.parseBoolean(value));
            }
        }
    }

    public static void dumpRestrictions(PrintWriter pw, String prefix, Bundle restrictions) {
        boolean noneSet = true;
        if (restrictions != null) {
            for (String key : restrictions.keySet()) {
                if (restrictions.getBoolean(key, false)) {
                    pw.println(prefix + key);
                    noneSet = false;
                }
            }
        }
        if (noneSet) {
            pw.println(prefix + "none");
        }
    }
}
+93 −28

File changed.

Preview size limit exceeded, changes collapsed.

+0 −5
Original line number Diff line number Diff line
@@ -16,16 +16,11 @@

package com.android.server.devicepolicy;

import android.app.AppGlobals;
import android.app.admin.SystemUpdatePolicy;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.UserInfo;
import android.os.Environment;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.ArrayMap;
+40 −0
Original line number Diff line number Diff line
@@ -225,5 +225,45 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi
        boolean userManagerIsSplitSystemUser() {
            return context.userManagerForMock.isSplitSystemUser();
        }

        @Override
        int settingsSecureGetIntForUser(String name, int def, int userHandle) {
            return context.settings.settingsSecureGetIntForUser(name, def, userHandle);
        }

        @Override
        void settingsSecurePutIntForUser(String name, int value, int userHandle) {
            context.settings.settingsSecurePutIntForUser(name, value, userHandle);
        }

        @Override
        void settingsSecurePutStringForUser(String name, String value, int userHandle) {
            context.settings.settingsSecurePutStringForUser(name, value, userHandle);
        }

        @Override
        void settingsGlobalPutStringForUser(String name, String value, int userHandle) {
            context.settings.settingsGlobalPutStringForUser(name, value, userHandle);
        }

        @Override
        void settingsSecurePutInt(String name, int value) {
            context.settings.settingsSecurePutInt(name, value);
        }

        @Override
        void settingsGlobalPutInt(String name, int value) {
            context.settings.settingsGlobalPutInt(name, value);
        }

        @Override
        void settingsSecurePutString(String name, String value) {
            context.settings.settingsSecurePutString(name, value);
        }

        @Override
        void settingsGlobalPutString(String name, String value) {
            context.settings.settingsGlobalPutString(name, value);
        }
    }
}
Loading