Loading core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java +4 −4 Original line number Diff line number Diff line Loading @@ -727,11 +727,11 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, this.usesSdkLibraries = CollectionUtils.add(this.usesSdkLibraries, TextUtils.safeIntern(libraryName)); this.usesSdkLibrariesVersionsMajor = ArrayUtils.appendLong( this.usesSdkLibrariesVersionsMajor, versionMajor, true); this.usesSdkLibrariesVersionsMajor, versionMajor, /* allowDuplicates= */ true); this.usesSdkLibrariesCertDigests = ArrayUtils.appendElement(String[].class, this.usesSdkLibrariesCertDigests, certSha256Digests, true); this.usesSdkLibrariesOptional = ArrayUtils.appendBoolean(this.usesSdkLibrariesOptional, usesSdkLibrariesOptional); this.usesSdkLibrariesCertDigests, certSha256Digests, /* allowDuplicates= */ true); this.usesSdkLibrariesOptional = ArrayUtils.appendBooleanDuplicatesAllowed( this.usesSdkLibrariesOptional, usesSdkLibrariesOptional); return this; } Loading core/java/com/android/internal/util/ArrayUtils.java +3 −3 Original line number Diff line number Diff line Loading @@ -620,10 +620,10 @@ public class ArrayUtils { } /** * Adds value to given array if not already present, providing set-like * behavior. * Adds value to given array. The method allows duplicate values. */ public static boolean[] appendBoolean(@Nullable boolean[] cur, boolean val) { public static boolean[] appendBooleanDuplicatesAllowed(@Nullable boolean[] cur, boolean val) { if (cur == null) { return new boolean[] { val }; } Loading core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java +5 −5 Original line number Diff line number Diff line Loading @@ -161,15 +161,15 @@ public class ArrayUtilsTest { } @Test public void testAppendBoolean() throws Exception { public void testAppendBooleanDuplicatesAllowed() throws Exception { assertArrayEquals(new boolean[] { true }, ArrayUtils.appendBoolean(null, true)); ArrayUtils.appendBooleanDuplicatesAllowed(null, true)); assertArrayEquals(new boolean[] { true }, ArrayUtils.appendBoolean(new boolean[] { }, true)); ArrayUtils.appendBooleanDuplicatesAllowed(new boolean[] { }, true)); assertArrayEquals(new boolean[] { true, false }, ArrayUtils.appendBoolean(new boolean[] { true }, false)); ArrayUtils.appendBooleanDuplicatesAllowed(new boolean[] { true }, false)); assertArrayEquals(new boolean[] { true, true }, ArrayUtils.appendBoolean(new boolean[] { true }, true)); ArrayUtils.appendBooleanDuplicatesAllowed(new boolean[] { true }, true)); } @Test Loading services/core/java/com/android/server/pm/Settings.java +39 −6 Original line number Diff line number Diff line Loading @@ -2585,13 +2585,32 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile boolean optional = parser.getAttributeBoolean(null, ATTR_OPTIONAL, true); if (libName != null && libVersion >= 0) { final int beforeUsesSdkLibrariesLength = outPs.getUsesSdkLibraries().length; // If the lib already exists in the outPs#getUsesSdkLibraries, don't add it // into the array and update its information below outPs.setUsesSdkLibraries(ArrayUtils.appendElement(String.class, outPs.getUsesSdkLibraries(), libName)); // If the lib has already been added before, update the other information final int afterUsesSdkLibrariesLength = outPs.getUsesSdkLibraries().length; if (beforeUsesSdkLibrariesLength == afterUsesSdkLibrariesLength) { final int index = ArrayUtils.indexOf(outPs.getUsesSdkLibraries(), libName); final long[] usesSdkLibrariesVersionsMajor = outPs.getUsesSdkLibrariesVersionsMajor(); usesSdkLibrariesVersionsMajor[index] = libVersion; outPs.setUsesSdkLibrariesVersionsMajor(usesSdkLibrariesVersionsMajor); final boolean[] usesSdkLibrariesOptional = outPs.getUsesSdkLibrariesOptional(); usesSdkLibrariesOptional[index] = optional; outPs.setUsesSdkLibrariesOptional(usesSdkLibrariesOptional); } else { outPs.setUsesSdkLibrariesVersionsMajor(ArrayUtils.appendLong( outPs.getUsesSdkLibrariesVersionsMajor(), libVersion)); outPs.setUsesSdkLibrariesOptional(ArrayUtils.appendBoolean( outPs.getUsesSdkLibrariesVersionsMajor(), libVersion, /* allowDuplicates= */ true)); outPs.setUsesSdkLibrariesOptional(ArrayUtils.appendBooleanDuplicatesAllowed( outPs.getUsesSdkLibrariesOptional(), optional)); } } XmlUtils.skipCurrentTag(parser); } Loading @@ -2602,10 +2621,24 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile long libVersion = parser.getAttributeLong(null, ATTR_VERSION, -1); if (libName != null && libVersion >= 0) { final int beforeUsesStaticLibrariesLength = outPs.getUsesStaticLibraries().length; // If the lib already exists in the outPs#getUsesStaticLibraries, don't add it // into the array and update its information below outPs.setUsesStaticLibraries(ArrayUtils.appendElement(String.class, outPs.getUsesStaticLibraries(), libName)); // If the lib has already been added before, update the version final int afterUsesStaticLibrariesLength = outPs.getUsesStaticLibraries().length; if (beforeUsesStaticLibrariesLength == afterUsesStaticLibrariesLength) { final int index = ArrayUtils.indexOf(outPs.getUsesStaticLibraries(), libName); final long[] usesStaticLibrariesVersions = outPs.getUsesStaticLibrariesVersions(); usesStaticLibrariesVersions[index] = libVersion; outPs.setUsesStaticLibrariesVersions(usesStaticLibrariesVersions); } else { outPs.setUsesStaticLibrariesVersions(ArrayUtils.appendLong( outPs.getUsesStaticLibrariesVersions(), libVersion)); outPs.getUsesStaticLibrariesVersions(), libVersion, /* allowDuplicates= */ true)); } } XmlUtils.skipCurrentTag(parser); Loading services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java +107 −0 Original line number Diff line number Diff line Loading @@ -923,6 +923,54 @@ public class PackageManagerSettingsTests { .containsExactlyElementsIn(ps2VersionsAsList).inOrder(); } @Test public void testSameVersions_writeReadUsesStaticLibraries() { Settings settings = makeSettings(); PackageSetting packageSetting = createPackageSetting(PACKAGE_NAME_1); packageSetting.setAppId(Process.FIRST_APPLICATION_UID); final String libOne = "one"; final String libTwo = "two"; final long versionOne = 311; packageSetting.setUsesStaticLibraries(new String[] { libOne, libTwo }); packageSetting.setUsesStaticLibrariesVersions(new long[] { versionOne, versionOne }); settings.mPackages.put(PACKAGE_NAME_1, packageSetting); settings.writeLPr(computer, /* sync= */ true); settings.mPackages.clear(); assertThat(settings.readLPw(computer, createFakeUsers()), is(true)); PackageSetting resultSetting = settings.getPackageLPr(PACKAGE_NAME_1); assertThat(resultSetting.getUsesStaticLibraries()[0], is(libOne)); assertThat(resultSetting.getUsesStaticLibraries()[1], is(libTwo)); assertThat(resultSetting.getUsesStaticLibrariesVersions()[0], is(versionOne)); assertThat(resultSetting.getUsesStaticLibrariesVersions()[1], is(versionOne)); } @Test public void testSameLibNames_writeReadUsesStaticLibraries() { Settings settings = makeSettings(); PackageSetting packageSetting = createPackageSetting(PACKAGE_NAME_1); packageSetting.setAppId(Process.FIRST_APPLICATION_UID); final String libOne = "one"; final long versionOne = 311; final long versionTwo = 330; packageSetting.setUsesStaticLibraries(new String[] { libOne, libOne}); packageSetting.setUsesStaticLibrariesVersions(new long[] { versionOne, versionTwo }); settings.mPackages.put(PACKAGE_NAME_1, packageSetting); settings.writeLPr(computer, /* sync= */ true); settings.mPackages.clear(); assertThat(settings.readLPw(computer, createFakeUsers()), is(true)); PackageSetting resultSetting = settings.getPackageLPr(PACKAGE_NAME_1); assertThat(resultSetting.getUsesStaticLibraries().length, is(1)); assertThat(resultSetting.getUsesStaticLibrariesVersions().length, is(1)); assertThat(resultSetting.getUsesStaticLibraries()[0], is(libOne)); assertThat(resultSetting.getUsesStaticLibrariesVersions()[0], is(versionTwo)); } @Test public void testWriteReadUsesSdkLibraries() { final Settings settingsUnderTest = makeSettings(); Loading Loading @@ -1007,6 +1055,65 @@ public class PackageManagerSettingsTests { .containsExactlyElementsIn(ps2RequireAsList).inOrder(); } @Test public void testSameVersions_writeReadUsesSdkLibraries() { Settings settings = makeSettings(); PackageSetting packageSetting = createPackageSetting(PACKAGE_NAME_1); packageSetting.setAppId(Process.FIRST_APPLICATION_UID); final String libOne = "one"; final String libTwo = "two"; final long versionOne = 311; final boolean optional = false; packageSetting.setUsesSdkLibraries(new String[] { libOne, libTwo }); packageSetting.setUsesSdkLibrariesVersionsMajor(new long[] { versionOne, versionOne }); packageSetting.setUsesSdkLibrariesOptional(new boolean[] { optional, optional }); settings.mPackages.put(PACKAGE_NAME_1, packageSetting); settings.writeLPr(computer, /* sync= */ true); settings.mPackages.clear(); assertThat(settings.readLPw(computer, createFakeUsers()), is(true)); PackageSetting resultSetting = settings.getPackageLPr(PACKAGE_NAME_1); assertThat(resultSetting.getUsesSdkLibraries()[0], is(libOne)); assertThat(resultSetting.getUsesSdkLibraries()[1], is(libTwo)); assertThat(resultSetting.getUsesSdkLibrariesVersionsMajor()[0], is(versionOne)); assertThat(resultSetting.getUsesSdkLibrariesVersionsMajor()[1], is(versionOne)); assertThat(resultSetting.getUsesSdkLibrariesOptional()[0], is(optional)); assertThat(resultSetting.getUsesSdkLibrariesOptional()[1], is(optional)); } @Test public void testSameLibNames_writeReadUsesSdkLibraries() { Settings settings = makeSettings(); PackageSetting packageSetting = createPackageSetting(PACKAGE_NAME_1); packageSetting.setAppId(Process.FIRST_APPLICATION_UID); final String libOne = "one"; final long versionOne = 311; final long versionTwo = 330; final boolean optionalOne = false; final boolean optionalTwo = true; packageSetting.setUsesSdkLibraries(new String[] { libOne, libOne }); packageSetting.setUsesSdkLibrariesVersionsMajor(new long[] { versionOne, versionTwo }); packageSetting.setUsesSdkLibrariesOptional(new boolean[] { optionalOne, optionalTwo }); settings.mPackages.put(PACKAGE_NAME_1, packageSetting); settings.writeLPr(computer, /* sync= */ true); settings.mPackages.clear(); assertThat(settings.readLPw(computer, createFakeUsers()), is(true)); PackageSetting resultSetting = settings.getPackageLPr(PACKAGE_NAME_1); assertThat(resultSetting.getUsesSdkLibraries().length, is(1)); assertThat(resultSetting.getUsesSdkLibrariesVersionsMajor().length, is(1)); assertThat(resultSetting.getUsesSdkLibrariesOptional().length, is(1)); assertThat(resultSetting.getUsesSdkLibraries()[0], is(libOne)); assertThat(resultSetting.getUsesSdkLibrariesVersionsMajor()[0], is(versionTwo)); assertThat(resultSetting.getUsesSdkLibrariesOptional()[0], is(optionalTwo)); } @Test public void testWriteReadPendingRestore() { Settings settings = makeSettings(); Loading Loading
core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java +4 −4 Original line number Diff line number Diff line Loading @@ -727,11 +727,11 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, this.usesSdkLibraries = CollectionUtils.add(this.usesSdkLibraries, TextUtils.safeIntern(libraryName)); this.usesSdkLibrariesVersionsMajor = ArrayUtils.appendLong( this.usesSdkLibrariesVersionsMajor, versionMajor, true); this.usesSdkLibrariesVersionsMajor, versionMajor, /* allowDuplicates= */ true); this.usesSdkLibrariesCertDigests = ArrayUtils.appendElement(String[].class, this.usesSdkLibrariesCertDigests, certSha256Digests, true); this.usesSdkLibrariesOptional = ArrayUtils.appendBoolean(this.usesSdkLibrariesOptional, usesSdkLibrariesOptional); this.usesSdkLibrariesCertDigests, certSha256Digests, /* allowDuplicates= */ true); this.usesSdkLibrariesOptional = ArrayUtils.appendBooleanDuplicatesAllowed( this.usesSdkLibrariesOptional, usesSdkLibrariesOptional); return this; } Loading
core/java/com/android/internal/util/ArrayUtils.java +3 −3 Original line number Diff line number Diff line Loading @@ -620,10 +620,10 @@ public class ArrayUtils { } /** * Adds value to given array if not already present, providing set-like * behavior. * Adds value to given array. The method allows duplicate values. */ public static boolean[] appendBoolean(@Nullable boolean[] cur, boolean val) { public static boolean[] appendBooleanDuplicatesAllowed(@Nullable boolean[] cur, boolean val) { if (cur == null) { return new boolean[] { val }; } Loading
core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java +5 −5 Original line number Diff line number Diff line Loading @@ -161,15 +161,15 @@ public class ArrayUtilsTest { } @Test public void testAppendBoolean() throws Exception { public void testAppendBooleanDuplicatesAllowed() throws Exception { assertArrayEquals(new boolean[] { true }, ArrayUtils.appendBoolean(null, true)); ArrayUtils.appendBooleanDuplicatesAllowed(null, true)); assertArrayEquals(new boolean[] { true }, ArrayUtils.appendBoolean(new boolean[] { }, true)); ArrayUtils.appendBooleanDuplicatesAllowed(new boolean[] { }, true)); assertArrayEquals(new boolean[] { true, false }, ArrayUtils.appendBoolean(new boolean[] { true }, false)); ArrayUtils.appendBooleanDuplicatesAllowed(new boolean[] { true }, false)); assertArrayEquals(new boolean[] { true, true }, ArrayUtils.appendBoolean(new boolean[] { true }, true)); ArrayUtils.appendBooleanDuplicatesAllowed(new boolean[] { true }, true)); } @Test Loading
services/core/java/com/android/server/pm/Settings.java +39 −6 Original line number Diff line number Diff line Loading @@ -2585,13 +2585,32 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile boolean optional = parser.getAttributeBoolean(null, ATTR_OPTIONAL, true); if (libName != null && libVersion >= 0) { final int beforeUsesSdkLibrariesLength = outPs.getUsesSdkLibraries().length; // If the lib already exists in the outPs#getUsesSdkLibraries, don't add it // into the array and update its information below outPs.setUsesSdkLibraries(ArrayUtils.appendElement(String.class, outPs.getUsesSdkLibraries(), libName)); // If the lib has already been added before, update the other information final int afterUsesSdkLibrariesLength = outPs.getUsesSdkLibraries().length; if (beforeUsesSdkLibrariesLength == afterUsesSdkLibrariesLength) { final int index = ArrayUtils.indexOf(outPs.getUsesSdkLibraries(), libName); final long[] usesSdkLibrariesVersionsMajor = outPs.getUsesSdkLibrariesVersionsMajor(); usesSdkLibrariesVersionsMajor[index] = libVersion; outPs.setUsesSdkLibrariesVersionsMajor(usesSdkLibrariesVersionsMajor); final boolean[] usesSdkLibrariesOptional = outPs.getUsesSdkLibrariesOptional(); usesSdkLibrariesOptional[index] = optional; outPs.setUsesSdkLibrariesOptional(usesSdkLibrariesOptional); } else { outPs.setUsesSdkLibrariesVersionsMajor(ArrayUtils.appendLong( outPs.getUsesSdkLibrariesVersionsMajor(), libVersion)); outPs.setUsesSdkLibrariesOptional(ArrayUtils.appendBoolean( outPs.getUsesSdkLibrariesVersionsMajor(), libVersion, /* allowDuplicates= */ true)); outPs.setUsesSdkLibrariesOptional(ArrayUtils.appendBooleanDuplicatesAllowed( outPs.getUsesSdkLibrariesOptional(), optional)); } } XmlUtils.skipCurrentTag(parser); } Loading @@ -2602,10 +2621,24 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile long libVersion = parser.getAttributeLong(null, ATTR_VERSION, -1); if (libName != null && libVersion >= 0) { final int beforeUsesStaticLibrariesLength = outPs.getUsesStaticLibraries().length; // If the lib already exists in the outPs#getUsesStaticLibraries, don't add it // into the array and update its information below outPs.setUsesStaticLibraries(ArrayUtils.appendElement(String.class, outPs.getUsesStaticLibraries(), libName)); // If the lib has already been added before, update the version final int afterUsesStaticLibrariesLength = outPs.getUsesStaticLibraries().length; if (beforeUsesStaticLibrariesLength == afterUsesStaticLibrariesLength) { final int index = ArrayUtils.indexOf(outPs.getUsesStaticLibraries(), libName); final long[] usesStaticLibrariesVersions = outPs.getUsesStaticLibrariesVersions(); usesStaticLibrariesVersions[index] = libVersion; outPs.setUsesStaticLibrariesVersions(usesStaticLibrariesVersions); } else { outPs.setUsesStaticLibrariesVersions(ArrayUtils.appendLong( outPs.getUsesStaticLibrariesVersions(), libVersion)); outPs.getUsesStaticLibrariesVersions(), libVersion, /* allowDuplicates= */ true)); } } XmlUtils.skipCurrentTag(parser); Loading
services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java +107 −0 Original line number Diff line number Diff line Loading @@ -923,6 +923,54 @@ public class PackageManagerSettingsTests { .containsExactlyElementsIn(ps2VersionsAsList).inOrder(); } @Test public void testSameVersions_writeReadUsesStaticLibraries() { Settings settings = makeSettings(); PackageSetting packageSetting = createPackageSetting(PACKAGE_NAME_1); packageSetting.setAppId(Process.FIRST_APPLICATION_UID); final String libOne = "one"; final String libTwo = "two"; final long versionOne = 311; packageSetting.setUsesStaticLibraries(new String[] { libOne, libTwo }); packageSetting.setUsesStaticLibrariesVersions(new long[] { versionOne, versionOne }); settings.mPackages.put(PACKAGE_NAME_1, packageSetting); settings.writeLPr(computer, /* sync= */ true); settings.mPackages.clear(); assertThat(settings.readLPw(computer, createFakeUsers()), is(true)); PackageSetting resultSetting = settings.getPackageLPr(PACKAGE_NAME_1); assertThat(resultSetting.getUsesStaticLibraries()[0], is(libOne)); assertThat(resultSetting.getUsesStaticLibraries()[1], is(libTwo)); assertThat(resultSetting.getUsesStaticLibrariesVersions()[0], is(versionOne)); assertThat(resultSetting.getUsesStaticLibrariesVersions()[1], is(versionOne)); } @Test public void testSameLibNames_writeReadUsesStaticLibraries() { Settings settings = makeSettings(); PackageSetting packageSetting = createPackageSetting(PACKAGE_NAME_1); packageSetting.setAppId(Process.FIRST_APPLICATION_UID); final String libOne = "one"; final long versionOne = 311; final long versionTwo = 330; packageSetting.setUsesStaticLibraries(new String[] { libOne, libOne}); packageSetting.setUsesStaticLibrariesVersions(new long[] { versionOne, versionTwo }); settings.mPackages.put(PACKAGE_NAME_1, packageSetting); settings.writeLPr(computer, /* sync= */ true); settings.mPackages.clear(); assertThat(settings.readLPw(computer, createFakeUsers()), is(true)); PackageSetting resultSetting = settings.getPackageLPr(PACKAGE_NAME_1); assertThat(resultSetting.getUsesStaticLibraries().length, is(1)); assertThat(resultSetting.getUsesStaticLibrariesVersions().length, is(1)); assertThat(resultSetting.getUsesStaticLibraries()[0], is(libOne)); assertThat(resultSetting.getUsesStaticLibrariesVersions()[0], is(versionTwo)); } @Test public void testWriteReadUsesSdkLibraries() { final Settings settingsUnderTest = makeSettings(); Loading Loading @@ -1007,6 +1055,65 @@ public class PackageManagerSettingsTests { .containsExactlyElementsIn(ps2RequireAsList).inOrder(); } @Test public void testSameVersions_writeReadUsesSdkLibraries() { Settings settings = makeSettings(); PackageSetting packageSetting = createPackageSetting(PACKAGE_NAME_1); packageSetting.setAppId(Process.FIRST_APPLICATION_UID); final String libOne = "one"; final String libTwo = "two"; final long versionOne = 311; final boolean optional = false; packageSetting.setUsesSdkLibraries(new String[] { libOne, libTwo }); packageSetting.setUsesSdkLibrariesVersionsMajor(new long[] { versionOne, versionOne }); packageSetting.setUsesSdkLibrariesOptional(new boolean[] { optional, optional }); settings.mPackages.put(PACKAGE_NAME_1, packageSetting); settings.writeLPr(computer, /* sync= */ true); settings.mPackages.clear(); assertThat(settings.readLPw(computer, createFakeUsers()), is(true)); PackageSetting resultSetting = settings.getPackageLPr(PACKAGE_NAME_1); assertThat(resultSetting.getUsesSdkLibraries()[0], is(libOne)); assertThat(resultSetting.getUsesSdkLibraries()[1], is(libTwo)); assertThat(resultSetting.getUsesSdkLibrariesVersionsMajor()[0], is(versionOne)); assertThat(resultSetting.getUsesSdkLibrariesVersionsMajor()[1], is(versionOne)); assertThat(resultSetting.getUsesSdkLibrariesOptional()[0], is(optional)); assertThat(resultSetting.getUsesSdkLibrariesOptional()[1], is(optional)); } @Test public void testSameLibNames_writeReadUsesSdkLibraries() { Settings settings = makeSettings(); PackageSetting packageSetting = createPackageSetting(PACKAGE_NAME_1); packageSetting.setAppId(Process.FIRST_APPLICATION_UID); final String libOne = "one"; final long versionOne = 311; final long versionTwo = 330; final boolean optionalOne = false; final boolean optionalTwo = true; packageSetting.setUsesSdkLibraries(new String[] { libOne, libOne }); packageSetting.setUsesSdkLibrariesVersionsMajor(new long[] { versionOne, versionTwo }); packageSetting.setUsesSdkLibrariesOptional(new boolean[] { optionalOne, optionalTwo }); settings.mPackages.put(PACKAGE_NAME_1, packageSetting); settings.writeLPr(computer, /* sync= */ true); settings.mPackages.clear(); assertThat(settings.readLPw(computer, createFakeUsers()), is(true)); PackageSetting resultSetting = settings.getPackageLPr(PACKAGE_NAME_1); assertThat(resultSetting.getUsesSdkLibraries().length, is(1)); assertThat(resultSetting.getUsesSdkLibrariesVersionsMajor().length, is(1)); assertThat(resultSetting.getUsesSdkLibrariesOptional().length, is(1)); assertThat(resultSetting.getUsesSdkLibraries()[0], is(libOne)); assertThat(resultSetting.getUsesSdkLibrariesVersionsMajor()[0], is(versionTwo)); assertThat(resultSetting.getUsesSdkLibrariesOptional()[0], is(optionalTwo)); } @Test public void testWriteReadPendingRestore() { Settings settings = makeSettings(); Loading