diff options
3 files changed, 91 insertions, 8 deletions
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index d2929aef8a63..a959fc10db49 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -3706,7 +3706,8 @@ public class UserManagerService extends IUserManager.Stub {                      if (type == XmlPullParser.START_TAG) {                          final String name = parser.getName();                          if (name.equals(TAG_USER)) { -                            UserData userData = readUserLP(parser.getAttributeInt(null, ATTR_ID)); +                            UserData userData = readUserLP(parser.getAttributeInt(null, ATTR_ID), +                                    mUserVersion);                              if (userData != null) {                                  synchronized (mUsersLock) { @@ -4387,7 +4388,7 @@ public class UserManagerService extends IUserManager.Stub {      }      @GuardedBy({"mPackagesLock"}) -    private UserData readUserLP(int id) { +    private UserData readUserLP(int id, int userVersion) {          try (ResilientAtomicFile file = getUserFile(id)) {              FileInputStream fis = null;              try { @@ -4396,19 +4397,19 @@ public class UserManagerService extends IUserManager.Stub {                      Slog.e(LOG_TAG, "User info not found, returning null, user id: " + id);                      return null;                  } -                return readUserLP(id, fis); +                return readUserLP(id, fis, userVersion);              } catch (Exception e) {                  // Remove corrupted file and retry.                  Slog.e(LOG_TAG, "Error reading user info, user id: " + id);                  file.failRead(fis, e); -                return readUserLP(id); +                return readUserLP(id, userVersion);              }          }      }      @GuardedBy({"mPackagesLock"})      @VisibleForTesting -    UserData readUserLP(int id, InputStream is) throws IOException, +    UserData readUserLP(int id, InputStream is, int userVersion) throws IOException,              XmlPullParserException {          int flags = 0;          String userType = null; @@ -4501,7 +4502,17 @@ public class UserManagerService extends IUserManager.Stub {                  } else if (TAG_DEVICE_POLICY_RESTRICTIONS.equals(tag)) {                      legacyLocalRestrictions = UserRestrictionsUtils.readRestrictions(parser);                  } else if (TAG_DEVICE_POLICY_LOCAL_RESTRICTIONS.equals(tag)) { -                    localRestrictions = UserRestrictionsUtils.readRestrictions(parser); +                    if (userVersion < 10) { +                        // Prior to version 10, the local user restrictions were stored as sub tags +                        // grouped by the user id of the source user. The source is no longer stored +                        // on versions 10+ as this is now stored in the DevicePolicyEngine. +                        RestrictionsSet oldLocalRestrictions = +                                RestrictionsSet.readRestrictions( +                                    parser, TAG_DEVICE_POLICY_LOCAL_RESTRICTIONS); +                        localRestrictions = oldLocalRestrictions.mergeAll(); +                    } else { +                        localRestrictions = UserRestrictionsUtils.readRestrictions(parser); +                    }                  } else if (TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS.equals(tag)) {                      globalRestrictions = UserRestrictionsUtils.readRestrictions(parser);                  } else if (TAG_ACCOUNT.equals(tag)) { diff --git a/services/tests/servicestests/res/xml/user_100_v9.xml b/services/tests/servicestests/res/xml/user_100_v9.xml new file mode 100644 index 000000000000..03c08ed40828 --- /dev/null +++ b/services/tests/servicestests/res/xml/user_100_v9.xml @@ -0,0 +1,20 @@ +<user id="100" +    serialNumber="0" +    flags="3091" +    type="android.os.usertype.full.SYSTEM" +    created="0" +    lastLoggedIn="0" +    lastLoggedInFingerprint="0" +    profileBadge="0"> +  <restrictions no_oem_unlock="true" /> +  <device_policy_local_restrictions> +    <restrictions_user user_id="0"> +      <restrictions no_camera="true" /> +    </restrictions_user> +    <restrictions_user user_id="100"> +      <restrictions no_camera="true" /> +      <restrictions no_install_unknown_sources="true" /> +    </restrictions_user> +  </device_policy_local_restrictions> +  <ignorePrepareStorageErrors>false</ignorePrepareStorageErrors> +</user>
\ No newline at end of file diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java index 9f75cf8d552e..429c58e768bf 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java @@ -43,27 +43,33 @@ import android.annotation.UserIdInt;  import android.app.PropertyInvalidatedCache;  import android.content.pm.UserInfo;  import android.content.pm.UserInfo.UserInfoFlag; +import android.content.res.Resources;  import android.os.Looper;  import android.os.Parcel;  import android.os.UserHandle;  import android.os.UserManager;  import android.platform.test.annotations.Presubmit;  import android.text.TextUtils; +import android.util.Xml;  import androidx.test.InstrumentationRegistry;  import androidx.test.filters.MediumTest;  import androidx.test.runner.AndroidJUnit4; +import com.android.frameworks.servicestests.R;  import com.android.server.LocalServices;  import com.android.server.pm.UserManagerService.UserData;  import org.junit.Before;  import org.junit.Test;  import org.junit.runner.RunWith; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlSerializer;  import java.io.ByteArrayInputStream;  import java.io.ByteArrayOutputStream;  import java.io.DataOutputStream; +import java.nio.charset.StandardCharsets;  import java.util.List;  /** @@ -76,6 +82,7 @@ import java.util.List;  @MediumTest  public class UserManagerServiceUserInfoTest {      private UserManagerService mUserManagerService; +    private Resources mResources;      @Before      public void setup() { @@ -95,6 +102,8 @@ public class UserManagerServiceUserInfoTest {          assertEquals("Multiple users so this test can't run.", 1, users.size());          assertEquals("Only user present isn't the system user.",                  UserHandle.USER_SYSTEM, users.get(0).id); + +        mResources = InstrumentationRegistry.getTargetContext().getResources();      }      @Test @@ -108,7 +117,7 @@ public class UserManagerServiceUserInfoTest {          byte[] bytes = baos.toByteArray();          UserData read = mUserManagerService.readUserLP( -                data.info.id, new ByteArrayInputStream(bytes)); +                data.info.id, new ByteArrayInputStream(bytes), 0);          assertUserInfoEquals(data.info, read.info, /* parcelCopy= */ false);      } @@ -135,7 +144,11 @@ public class UserManagerServiceUserInfoTest {          // Clear the restrictions to see if they are properly read in from the user file.          setUserRestrictions(data.info.id, globalRestriction, localRestriction, false); -        mUserManagerService.readUserLP(data.info.id, new ByteArrayInputStream(bytes)); +        final int userVersion = 10; +        //read the secondary and SYSTEM user file to fetch local/global device policy restrictions. +        mUserManagerService.readUserLP(data.info.id, new ByteArrayInputStream(bytes), +                userVersion); +          assertTrue(mUserManagerService.hasUserRestrictionOnAnyUser(globalRestriction));          assertTrue(mUserManagerService.hasUserRestrictionOnAnyUser(localRestriction));      } @@ -286,6 +299,45 @@ public class UserManagerServiceUserInfoTest {          assertTrue(mUserManagerService.isUserOfType(106, USER_TYPE_FULL_DEMO));      } +    /** Tests readUserLP upgrading from version 9 to 10+. */ +    @Test +    public void testUserRestrictionsUpgradeFromV9() throws Exception { +        final String[] localRestrictions = new String[] { +            UserManager.DISALLOW_CAMERA, +            UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, +        }; + +        final int userId = 100; +        UserData data = new UserData(); +        data.info = createUser(userId, FLAG_FULL, "A type"); + +        mUserManagerService.putUserInfo(data.info); + +        for (String restriction : localRestrictions) { +            assertFalse(mUserManagerService.hasBaseUserRestriction(restriction, userId)); +            assertFalse(mUserManagerService.hasUserRestriction(restriction, userId)); +        } + +        // Convert the xml resource to the system storage xml format. +        ByteArrayOutputStream baos = new ByteArrayOutputStream(); +        DataOutputStream os = new DataOutputStream(baos); +        XmlPullParser in = mResources.getXml(R.xml.user_100_v9); +        XmlSerializer out = Xml.newBinarySerializer(); +        out.setOutput(os, StandardCharsets.UTF_8.name()); +        Xml.copy(in, out); +        byte[] userBytes = baos.toByteArray(); +        baos.reset(); + +        final int userVersion = 9; +        mUserManagerService.readUserLP(data.info.id, new ByteArrayInputStream(userBytes), +                userVersion); + +        for (String restriction : localRestrictions) { +            assertFalse(mUserManagerService.hasBaseUserRestriction(restriction, userId)); +            assertTrue(mUserManagerService.hasUserRestriction(restriction, userId)); +        } +    } +      /** Creates a UserInfo with the given flags and userType. */      private UserInfo createUser(@UserIdInt int userId, @UserInfoFlag int flags, String userType) {          return new UserInfo(userId, "A Name", "A path", flags, userType);  |