Merge "[pm] use snapshot instead of deep-copy of PackageUserState"
This commit is contained in:
@@ -7558,7 +7558,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
if (packageState == null) {
|
||||
return new ArraySet<>();
|
||||
}
|
||||
return packageState.getUserStateOrDefault(userId).getEnabledComponentsNoCopy();
|
||||
return packageState.getUserStateOrDefault(userId).getEnabledComponents();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -7567,7 +7567,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
if (packageState == null) {
|
||||
return new ArraySet<>();
|
||||
}
|
||||
return packageState.getUserStateOrDefault(userId).getDisabledComponentsNoCopy();
|
||||
return packageState.getUserStateOrDefault(userId).getDisabledComponents();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -52,6 +52,7 @@ import com.android.server.pm.pkg.PackageUserStateImpl;
|
||||
import com.android.server.pm.pkg.PackageUserStateInternal;
|
||||
import com.android.server.pm.pkg.SuspendParams;
|
||||
import com.android.server.utils.SnapshotCache;
|
||||
import com.android.server.utils.WatchedArraySet;
|
||||
|
||||
import libcore.util.EmptyArray;
|
||||
|
||||
@@ -249,7 +250,7 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
|
||||
|
||||
PackageSetting(@NonNull PackageSetting original, boolean sealedSnapshot) {
|
||||
super(original);
|
||||
copyPackageSetting(original);
|
||||
copyPackageSetting(original, sealedSnapshot);
|
||||
if (sealedSnapshot) {
|
||||
mSnapshot = new SnapshotCache.Sealed();
|
||||
} else {
|
||||
@@ -515,7 +516,7 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
|
||||
|
||||
/** Updates all fields in the current setting from another. */
|
||||
public void updateFrom(PackageSetting other) {
|
||||
copyPackageSetting(other);
|
||||
copyPackageSetting(other, false /* sealedSnapshot */);
|
||||
|
||||
Set<String> mimeGroupNames = other.mimeGroups != null ? other.mimeGroups.keySet() : null;
|
||||
updateMimeGroups(mimeGroupNames);
|
||||
@@ -608,7 +609,7 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
|
||||
return this;
|
||||
}
|
||||
|
||||
public void copyPackageSetting(PackageSetting other) {
|
||||
public void copyPackageSetting(PackageSetting other, boolean sealedSnapshot) {
|
||||
super.copySettingBase(other);
|
||||
mSharedUserAppId = other.mSharedUserAppId;
|
||||
mLoadingProgress = other.mLoadingProgress;
|
||||
@@ -650,8 +651,12 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
|
||||
other.usesStaticLibrariesVersions.length) : null;
|
||||
mUserStates.clear();
|
||||
for (int i = 0; i < other.mUserStates.size(); i++) {
|
||||
mUserStates.put(other.mUserStates.keyAt(i),
|
||||
new PackageUserStateImpl(this, other.mUserStates.valueAt(i)));
|
||||
if (sealedSnapshot) {
|
||||
mUserStates.put(other.mUserStates.keyAt(i),
|
||||
other.mUserStates.valueAt(i).snapshot());
|
||||
} else {
|
||||
mUserStates.put(other.mUserStates.keyAt(i), other.mUserStates.valueAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
if (mOldCodePaths != null) {
|
||||
@@ -871,42 +876,48 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
|
||||
setUserState(userId, otherState.getCeDataInode(), otherState.getEnabledState(),
|
||||
otherState.isInstalled(), otherState.isStopped(), otherState.isNotLaunched(),
|
||||
otherState.isHidden(), otherState.getDistractionFlags(),
|
||||
otherState.getSuspendParams(), otherState.isInstantApp(),
|
||||
otherState.getSuspendParams() == null
|
||||
? null : otherState.getSuspendParams().untrackedStorage(),
|
||||
otherState.isInstantApp(),
|
||||
otherState.isVirtualPreload(), otherState.getLastDisableAppCaller(),
|
||||
new ArraySet<>(otherState.getEnabledComponentsNoCopy()),
|
||||
new ArraySet<>(otherState.getDisabledComponentsNoCopy()),
|
||||
otherState.getEnabledComponentsNoCopy() == null
|
||||
? null : otherState.getEnabledComponentsNoCopy().untrackedStorage(),
|
||||
otherState.getDisabledComponentsNoCopy() == null
|
||||
? null : otherState.getDisabledComponentsNoCopy().untrackedStorage(),
|
||||
otherState.getInstallReason(), otherState.getUninstallReason(),
|
||||
otherState.getHarmfulAppWarning(), otherState.getSplashScreenTheme(),
|
||||
otherState.getFirstInstallTime());
|
||||
}
|
||||
|
||||
ArraySet<String> getEnabledComponents(int userId) {
|
||||
WatchedArraySet<String> getEnabledComponents(int userId) {
|
||||
return readUserState(userId).getEnabledComponentsNoCopy();
|
||||
}
|
||||
|
||||
ArraySet<String> getDisabledComponents(int userId) {
|
||||
WatchedArraySet<String> getDisabledComponents(int userId) {
|
||||
return readUserState(userId).getDisabledComponentsNoCopy();
|
||||
}
|
||||
|
||||
void setEnabledComponents(ArraySet<String> components, int userId) {
|
||||
/** Test only */
|
||||
void setEnabledComponents(WatchedArraySet<String> components, int userId) {
|
||||
modifyUserState(userId).setEnabledComponents(components);
|
||||
onChanged();
|
||||
}
|
||||
|
||||
void setDisabledComponents(ArraySet<String> components, int userId) {
|
||||
/** Test only */
|
||||
void setDisabledComponents(WatchedArraySet<String> components, int userId) {
|
||||
modifyUserState(userId).setDisabledComponents(components);
|
||||
onChanged();
|
||||
}
|
||||
|
||||
void setEnabledComponentsCopy(ArraySet<String> components, int userId) {
|
||||
void setEnabledComponentsCopy(WatchedArraySet<String> components, int userId) {
|
||||
modifyUserState(userId).setEnabledComponents(components != null
|
||||
? new ArraySet<String>(components) : null);
|
||||
? components.untrackedStorage() : null);
|
||||
onChanged();
|
||||
}
|
||||
|
||||
void setDisabledComponentsCopy(ArraySet<String> components, int userId) {
|
||||
void setDisabledComponentsCopy(WatchedArraySet<String> components, int userId) {
|
||||
modifyUserState(userId).setDisabledComponents(components != null
|
||||
? new ArraySet<String>(components) : null);
|
||||
? components.untrackedStorage() : null);
|
||||
onChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -2142,20 +2142,24 @@ public final class Settings implements Watchable, Snappable {
|
||||
serializer.endTag(null, TAG_SUSPEND_PARAMS);
|
||||
}
|
||||
}
|
||||
if (!ArrayUtils.isEmpty(ustate.getEnabledComponentsNoCopy())) {
|
||||
final ArraySet<String> enabledComponents = ustate.getEnabledComponents();
|
||||
if (enabledComponents != null && enabledComponents.size() > 0) {
|
||||
serializer.startTag(null, TAG_ENABLED_COMPONENTS);
|
||||
for (final String name : ustate.getEnabledComponentsNoCopy()) {
|
||||
for (int i = 0; i < enabledComponents.size(); i++) {
|
||||
serializer.startTag(null, TAG_ITEM);
|
||||
serializer.attribute(null, ATTR_NAME, name);
|
||||
serializer.attribute(null, ATTR_NAME,
|
||||
enabledComponents.valueAt(i));
|
||||
serializer.endTag(null, TAG_ITEM);
|
||||
}
|
||||
serializer.endTag(null, TAG_ENABLED_COMPONENTS);
|
||||
}
|
||||
if (!ArrayUtils.isEmpty(ustate.getDisabledComponentsNoCopy())) {
|
||||
final ArraySet<String> disabledComponents = ustate.getDisabledComponents();
|
||||
if (disabledComponents != null && disabledComponents.size() > 0) {
|
||||
serializer.startTag(null, TAG_DISABLED_COMPONENTS);
|
||||
for (final String name : ustate.getDisabledComponentsNoCopy()) {
|
||||
for (int i = 0; i < disabledComponents.size(); i++) {
|
||||
serializer.startTag(null, TAG_ITEM);
|
||||
serializer.attribute(null, ATTR_NAME, name);
|
||||
serializer.attribute(null, ATTR_NAME,
|
||||
disabledComponents.valueAt(i));
|
||||
serializer.endTag(null, TAG_ITEM);
|
||||
}
|
||||
serializer.endTag(null, TAG_DISABLED_COMPONENTS);
|
||||
@@ -4987,18 +4991,18 @@ public final class Settings implements Watchable, Snappable {
|
||||
}
|
||||
|
||||
if (permissionNames == null) {
|
||||
Set<String> cmp = userState.getDisabledComponents();
|
||||
WatchedArraySet<String> cmp = userState.getDisabledComponentsNoCopy();
|
||||
if (cmp != null && cmp.size() > 0) {
|
||||
pw.print(prefix); pw.println(" disabledComponents:");
|
||||
for (String s : cmp) {
|
||||
pw.print(prefix); pw.print(" "); pw.println(s);
|
||||
for (int i = 0; i < cmp.size(); i++) {
|
||||
pw.print(prefix); pw.print(" "); pw.println(cmp.valueAt(i));
|
||||
}
|
||||
}
|
||||
cmp = userState.getEnabledComponents();
|
||||
cmp = userState.getEnabledComponentsNoCopy();
|
||||
if (cmp != null && cmp.size() > 0) {
|
||||
pw.print(prefix); pw.println(" enabledComponents:");
|
||||
for (String s : cmp) {
|
||||
pw.print(prefix); pw.print(" "); pw.println(s);
|
||||
for (int i = 0; i < cmp.size(); i++) {
|
||||
pw.print(prefix); pw.print(" "); pw.println(cmp.valueAt(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ import com.android.server.pm.pkg.PackageStateInternal;
|
||||
import com.android.server.pm.pkg.PackageUserStateInternal;
|
||||
import com.android.server.pm.pkg.SuspendParams;
|
||||
import com.android.server.pm.pkg.mutate.PackageUserStateWrite;
|
||||
import com.android.server.utils.WatchedArrayMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -145,7 +146,7 @@ public final class SuspendPackageHelper {
|
||||
continue;
|
||||
}
|
||||
|
||||
final ArrayMap<String, SuspendParams> suspendParamsMap =
|
||||
final WatchedArrayMap<String, SuspendParams> suspendParamsMap =
|
||||
packageState.getUserStateOrDefault(userId).getSuspendParams();
|
||||
final SuspendParams suspendParams = suspendParamsMap == null
|
||||
? null : suspendParamsMap.get(packageName);
|
||||
@@ -297,7 +298,8 @@ public final class SuspendPackageHelper {
|
||||
continue;
|
||||
}
|
||||
|
||||
ArrayMap<String, SuspendParams> suspendParamsMap = packageUserState.getSuspendParams();
|
||||
WatchedArrayMap<String, SuspendParams> suspendParamsMap =
|
||||
packageUserState.getSuspendParams();
|
||||
int countRemoved = 0;
|
||||
for (int index = 0; index < suspendParamsMap.size(); index++) {
|
||||
String suspendingPackage = suspendParamsMap.keyAt(index);
|
||||
@@ -440,7 +442,8 @@ public final class SuspendPackageHelper {
|
||||
return null;
|
||||
}
|
||||
|
||||
final ArrayMap<String, SuspendParams> suspendParamsMap = userState.getSuspendParams();
|
||||
final WatchedArrayMap<String, SuspendParams> suspendParamsMap =
|
||||
userState.getSuspendParams();
|
||||
if (suspendParamsMap == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.content.pm.PackageManagerInternal;
|
||||
import android.content.pm.SharedLibraryInfo;
|
||||
import android.content.pm.SigningInfo;
|
||||
import android.content.pm.overlay.OverlayPaths;
|
||||
import android.util.ArraySet;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.internal.util.DataClass;
|
||||
@@ -329,11 +330,11 @@ public class PackageStateImpl implements PackageState {
|
||||
|
||||
private final long mCeDataInode;
|
||||
@NonNull
|
||||
private final Set<String> mDisabledComponents;
|
||||
private final ArraySet<String> mDisabledComponents;
|
||||
@PackageManager.DistractionRestriction
|
||||
private final int mDistractionFlags;
|
||||
@NonNull
|
||||
private final Set<String> mEnabledComponents;
|
||||
private final ArraySet<String> mEnabledComponents;
|
||||
private final int mEnabledState;
|
||||
@Nullable
|
||||
private final String mHarmfulAppWarning;
|
||||
@@ -460,7 +461,8 @@ public class PackageStateImpl implements PackageState {
|
||||
}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Set<String> getDisabledComponents() {
|
||||
public @NonNull
|
||||
ArraySet<String> getDisabledComponents() {
|
||||
return mDisabledComponents;
|
||||
}
|
||||
|
||||
@@ -470,7 +472,7 @@ public class PackageStateImpl implements PackageState {
|
||||
}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull Set<String> getEnabledComponents() {
|
||||
public @NonNull ArraySet<String> getEnabledComponents() {
|
||||
return mEnabledComponents;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,14 +18,12 @@ package com.android.server.pm.pkg;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.SystemApi;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.overlay.OverlayPaths;
|
||||
import android.os.UserHandle;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The API surface for {@link PackageUserStateInternal}, for use by in-process mainline consumers.
|
||||
@@ -59,7 +57,7 @@ public interface PackageUserState {
|
||||
* Fully qualified class names of components explicitly disabled.
|
||||
*/
|
||||
@NonNull
|
||||
Set<String> getDisabledComponents();
|
||||
ArraySet<String> getDisabledComponents();
|
||||
|
||||
@PackageManager.DistractionRestriction
|
||||
int getDistractionFlags();
|
||||
@@ -68,7 +66,7 @@ public interface PackageUserState {
|
||||
* Fully qualified class names of components explicitly enabled.
|
||||
*/
|
||||
@NonNull
|
||||
Set<String> getEnabledComponents();
|
||||
ArraySet<String> getEnabledComponents();
|
||||
|
||||
/**
|
||||
* Retrieve the effective enabled state of the package itself.
|
||||
|
||||
@@ -21,13 +21,14 @@ import android.annotation.Nullable;
|
||||
import android.content.ComponentName;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.overlay.OverlayPaths;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.android.server.utils.WatchedArrayMap;
|
||||
import com.android.server.utils.WatchedArraySet;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
class PackageUserStateDefault implements PackageUserStateInternal {
|
||||
|
||||
@@ -59,14 +60,14 @@ class PackageUserStateDefault implements PackageUserStateInternal {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Set<String> getDisabledComponents() {
|
||||
return Collections.emptySet();
|
||||
public ArraySet<String> getDisabledComponents() {
|
||||
return new ArraySet<>();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Set<String> getEnabledComponents() {
|
||||
return Collections.emptySet();
|
||||
public ArraySet<String> getEnabledComponents() {
|
||||
return new ArraySet<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -156,19 +157,19 @@ class PackageUserStateDefault implements PackageUserStateInternal {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ArrayMap<String, SuspendParams> getSuspendParams() {
|
||||
public WatchedArrayMap<String, SuspendParams> getSuspendParams() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ArraySet<String> getDisabledComponentsNoCopy() {
|
||||
public WatchedArraySet<String> getDisabledComponentsNoCopy() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ArraySet<String> getEnabledComponentsNoCopy() {
|
||||
public WatchedArraySet<String> getEnabledComponentsNoCopy() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -20,10 +20,11 @@ import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.ComponentName;
|
||||
import android.content.pm.pkg.FrameworkPackageUserState;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.android.server.utils.WatchedArrayMap;
|
||||
import com.android.server.utils.WatchedArraySet;
|
||||
|
||||
/**
|
||||
* Internal variant of {@link PackageUserState} that includes data not exposed as API. This is
|
||||
* still read-only and should be used inside system server code when possible over the
|
||||
@@ -35,13 +36,13 @@ public interface PackageUserStateInternal extends PackageUserState, FrameworkPac
|
||||
|
||||
// TODO: Make non-null with emptyMap()
|
||||
@Nullable
|
||||
ArrayMap<String, SuspendParams> getSuspendParams();
|
||||
WatchedArrayMap<String, SuspendParams> getSuspendParams();
|
||||
|
||||
@Nullable
|
||||
ArraySet<String> getDisabledComponentsNoCopy();
|
||||
WatchedArraySet<String> getDisabledComponentsNoCopy();
|
||||
|
||||
@Nullable
|
||||
ArraySet<String> getEnabledComponentsNoCopy();
|
||||
WatchedArraySet<String> getEnabledComponentsNoCopy();
|
||||
|
||||
@Nullable
|
||||
Pair<String, Integer> getOverrideLabelIconForComponent(@NonNull ComponentName componentName);
|
||||
|
||||
@@ -70,6 +70,7 @@ import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
|
||||
import com.android.server.utils.Watchable;
|
||||
import com.android.server.utils.WatchableTester;
|
||||
import com.android.server.utils.WatchedArrayMap;
|
||||
import com.android.server.utils.WatchedArraySet;
|
||||
import com.android.server.utils.Watcher;
|
||||
|
||||
import com.google.common.truth.Truth;
|
||||
@@ -595,13 +596,13 @@ public class PackageManagerSettingsTests {
|
||||
watcher.verifyNoChangeReported("getEnabled");
|
||||
|
||||
// Enable/Disable a component
|
||||
ArraySet<String> components = new ArraySet<String>();
|
||||
WatchedArraySet<String> components = new WatchedArraySet<String>();
|
||||
String component1 = PACKAGE_NAME_1 + "/.Component1";
|
||||
components.add(component1);
|
||||
ps.setDisabledComponents(components, 0);
|
||||
ArraySet<String> componentsDisabled = ps.getDisabledComponents(0);
|
||||
WatchedArraySet<String> componentsDisabled = ps.getDisabledComponents(0);
|
||||
assertThat(componentsDisabled.size(), is(1));
|
||||
assertThat(componentsDisabled.toArray()[0], is(component1));
|
||||
assertThat(componentsDisabled.untrackedStorage().toArray()[0], is(component1));
|
||||
boolean hasEnabled =
|
||||
ps.getEnabledComponents(0) != null && ps.getEnabledComponents(1).size() > 0;
|
||||
assertThat(hasEnabled, is(false));
|
||||
@@ -704,7 +705,7 @@ public class PackageManagerSettingsTests {
|
||||
null /*usesStaticLibrariesVersions*/,
|
||||
null /*mimeGroups*/,
|
||||
UUID.randomUUID());
|
||||
testPkgSetting01.copyPackageSetting(origPkgSetting01);
|
||||
testPkgSetting01.copyPackageSetting(origPkgSetting01, true);
|
||||
verifySettingCopy(origPkgSetting01, testPkgSetting01);
|
||||
verifyUserStatesCopy(origPkgSetting01.readUserState(0),
|
||||
testPkgSetting01.readUserState(0));
|
||||
|
||||
@@ -39,6 +39,7 @@ import com.android.server.pm.pkg.PackageStateUnserialized;
|
||||
import com.android.server.pm.pkg.PackageUserStateImpl;
|
||||
import com.android.server.pm.pkg.SuspendParams;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
@@ -238,9 +239,12 @@ public class PackageUserStateTest {
|
||||
PackageUserStateImpl testUserState2 =
|
||||
new PackageUserStateImpl(null, testUserState1);
|
||||
assertThat(testUserState1.equals(testUserState2), is(true));
|
||||
testUserState2.setSuspendParams(paramsMap2);
|
||||
// Should not be equal since suspendParams maps are different
|
||||
assertThat(testUserState1.equals(testUserState2), is(false));
|
||||
try {
|
||||
testUserState2.setSuspendParams(paramsMap2);
|
||||
Assert.fail("Changing sealed snapshot of suspendParams should throw");
|
||||
} catch (IllegalStateException e) {
|
||||
assertThat(e.getMessage().contains("attempt to change a sealed object"), is(true));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user