PackageSettingBase.java revision d4041db120d7500e73e0132b03dfeffb84d402f5
1602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel/*
2602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel * Copyright (C) 2011 The Android Open Source Project
3602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel *
4602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel * Licensed under the Apache License, Version 2.0 (the "License");
5602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel * you may not use this file except in compliance with the License.
6602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel * You may obtain a copy of the License at
7602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel *
8602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel *      http://www.apache.org/licenses/LICENSE-2.0
9602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel *
10602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel * Unless required by applicable law or agreed to in writing, software
11602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel * distributed under the License is distributed on an "AS IS" BASIS,
12602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel * See the License for the specific language governing permissions and
14602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel * limitations under the License.
15602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel */
16602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel
17602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Rousselpackage com.android.server.pm;
18602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel
19602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Rousselimport static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
20602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Rousselimport static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
21602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Rousselimport static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
22602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel
23602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Rousselimport android.content.pm.IntentFilterVerificationInfo;
24602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Rousselimport android.content.pm.PackageManager;
25602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Rousselimport android.content.pm.PackageUserState;
26602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Rousselimport android.os.storage.VolumeInfo;
27602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Rousselimport android.util.ArraySet;
28602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Rousselimport android.util.SparseArray;
29602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel
30602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Rousselimport java.io.File;
31602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Rousselimport java.util.ArrayList;
32602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Rousselimport java.util.List;
33602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Rousselimport java.util.Set;
34602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel
35602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel/**
36602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel * Settings base class for pending and resolved classes.
37602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel */
38602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Rousselabstract class PackageSettingBase extends SettingBase {
39602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    /**
40602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * Indicates the state of installation. Used by PackageManager to figure out
41602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * incomplete installations. Say a package is being installed (the state is
42602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * set to PKG_INSTALL_INCOMPLETE) and remains so till the package
43602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * installation is successful or unsuccessful in which case the
44602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * PackageManager will no longer maintain state information associated with
45602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * the package. If some exception(like device freeze or battery being pulled
46602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * out) occurs during installation of a package, the PackageManager needs
47602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * this information to clean up the previously failed installation.
48602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     */
49602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    static final int PKG_INSTALL_COMPLETE = 1;
50602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    static final int PKG_INSTALL_INCOMPLETE = 0;
51602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel
52602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    final String name;
53602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    final String realName;
54602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel
55602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    String parentPackageName;
56602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    List<String> childPackageNames;
57602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel
58602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    /**
59602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * Path where this package was found on disk. For monolithic packages
60602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * this is path to single base APK file; for cluster packages this is
61602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * path to the cluster directory.
62602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     */
63602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    File codePath;
64602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    String codePathString;
65602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    File resourcePath;
66602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    String resourcePathString;
67602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel
68602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    /**
69602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * The path under which native libraries have been unpacked. This path is
70602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * always derived at runtime, and is only stored here for cleanup when a
71602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * package is uninstalled.
72602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     */
73602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    @Deprecated
74602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    String legacyNativeLibraryPathString;
75602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel
76602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    /**
77602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * The primary CPU abi for this package. This value is regenerated at every
78602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * boot scan.
79602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     */
80602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    String primaryCpuAbiString;
81602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel
82602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    /**
83602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * The secondary CPU abi for this package. This value is regenerated at every
84602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * boot scan.
85602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     */
86602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    String secondaryCpuAbiString;
87602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel
88602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    /**
89602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * The install time CPU override, if any. This value is written at install time
90602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * and doesn't change during the life of an install. If non-null,
91602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * {@code primaryCpuAbiString} will contain the same value.
92602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     */
93602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    String cpuAbiOverrideString;
94602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel
95602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    long timeStamp;
96602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    long firstInstallTime;
97602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    long lastUpdateTime;
98602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    int versionCode;
99602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel
100602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    boolean uidError;
101602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel
102602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    PackageSignatures signatures = new PackageSignatures();
103602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel
104602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    boolean installPermissionsFixed;
105602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel
106602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    PackageKeySetData keySetData = new PackageKeySetData();
107602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel
108602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    private static final PackageUserState DEFAULT_USER_STATE = new PackageUserState();
109602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel
110602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    // Whether this package is currently stopped, thus can not be
111602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    // started until explicitly launched by the user.
112602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    private final SparseArray<PackageUserState> userState = new SparseArray<PackageUserState>();
113602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel
114602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    int installStatus = PKG_INSTALL_COMPLETE;
115602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel
116602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel    /**
117602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * Non-persisted value. During an "upgrade without restart", we need the set
118602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * of all previous code paths so we can surgically add the new APKs to the
119602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * active classloader. If at any point an application is upgraded with a
120602c6ca8cae4718ba8ff9f65e53305d002479359Yohann Roussel     * restart, this field will be cleared since the classloader would be created
121     * using the full set of code paths when the package's process is started.
122     */
123    Set<String> oldCodePaths;
124    PackageSettingBase origPackage;
125
126    /** Package name of the app that installed this package */
127    String installerPackageName;
128    /** UUID of {@link VolumeInfo} hosting this app */
129    String volumeUuid;
130
131    IntentFilterVerificationInfo verificationInfo;
132
133    PackageSettingBase(String name, String realName, File codePath, File resourcePath,
134            String legacyNativeLibraryPathString, String primaryCpuAbiString,
135            String secondaryCpuAbiString, String cpuAbiOverrideString,
136            int pVersionCode, int pkgFlags, int pkgPrivateFlags,
137            String parentPackageName, List<String> childPackageNames) {
138        super(pkgFlags, pkgPrivateFlags);
139        this.name = name;
140        this.realName = realName;
141        this.parentPackageName = parentPackageName;
142        this.childPackageNames = (childPackageNames != null)
143                ? new ArrayList<>(childPackageNames) : null;
144        init(codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbiString,
145                secondaryCpuAbiString, cpuAbiOverrideString, pVersionCode);
146    }
147
148    /**
149     * New instance of PackageSetting with one-level-deep cloning.
150     */
151    @SuppressWarnings("unchecked")
152    PackageSettingBase(PackageSettingBase base) {
153        super(base);
154
155        name = base.name;
156        realName = base.realName;
157        codePath = base.codePath;
158        codePathString = base.codePathString;
159        resourcePath = base.resourcePath;
160        resourcePathString = base.resourcePathString;
161        legacyNativeLibraryPathString = base.legacyNativeLibraryPathString;
162        primaryCpuAbiString = base.primaryCpuAbiString;
163        secondaryCpuAbiString = base.secondaryCpuAbiString;
164        cpuAbiOverrideString = base.cpuAbiOverrideString;
165        timeStamp = base.timeStamp;
166        firstInstallTime = base.firstInstallTime;
167        lastUpdateTime = base.lastUpdateTime;
168        versionCode = base.versionCode;
169
170        uidError = base.uidError;
171
172        signatures = new PackageSignatures(base.signatures);
173
174        installPermissionsFixed = base.installPermissionsFixed;
175        userState.clear();
176        for (int i=0; i<base.userState.size(); i++) {
177            userState.put(base.userState.keyAt(i),
178                    new PackageUserState(base.userState.valueAt(i)));
179        }
180        installStatus = base.installStatus;
181
182        origPackage = base.origPackage;
183
184        installerPackageName = base.installerPackageName;
185        volumeUuid = base.volumeUuid;
186
187        keySetData = new PackageKeySetData(base.keySetData);
188
189        parentPackageName = base.parentPackageName;
190        childPackageNames = (base.childPackageNames != null)
191                ? new ArrayList<>(base.childPackageNames) : null;
192    }
193
194    void init(File codePath, File resourcePath, String legacyNativeLibraryPathString,
195              String primaryCpuAbiString, String secondaryCpuAbiString,
196              String cpuAbiOverrideString, int pVersionCode) {
197        this.codePath = codePath;
198        this.codePathString = codePath.toString();
199        this.resourcePath = resourcePath;
200        this.resourcePathString = resourcePath.toString();
201        this.legacyNativeLibraryPathString = legacyNativeLibraryPathString;
202        this.primaryCpuAbiString = primaryCpuAbiString;
203        this.secondaryCpuAbiString = secondaryCpuAbiString;
204        this.cpuAbiOverrideString = cpuAbiOverrideString;
205        this.versionCode = pVersionCode;
206    }
207
208    public void setInstallerPackageName(String packageName) {
209        installerPackageName = packageName;
210    }
211
212    public String getInstallerPackageName() {
213        return installerPackageName;
214    }
215
216    public void setVolumeUuid(String volumeUuid) {
217        this.volumeUuid = volumeUuid;
218    }
219
220    public String getVolumeUuid() {
221        return volumeUuid;
222    }
223
224    public void setInstallStatus(int newStatus) {
225        installStatus = newStatus;
226    }
227
228    public int getInstallStatus() {
229        return installStatus;
230    }
231
232    public void setTimeStamp(long newStamp) {
233        timeStamp = newStamp;
234    }
235
236    /**
237     * Make a shallow copy of this package settings.
238     */
239    public void copyFrom(PackageSettingBase base) {
240        mPermissionsState.copyFrom(base.mPermissionsState);
241        primaryCpuAbiString = base.primaryCpuAbiString;
242        secondaryCpuAbiString = base.secondaryCpuAbiString;
243        cpuAbiOverrideString = base.cpuAbiOverrideString;
244        timeStamp = base.timeStamp;
245        firstInstallTime = base.firstInstallTime;
246        lastUpdateTime = base.lastUpdateTime;
247        signatures = base.signatures;
248        installPermissionsFixed = base.installPermissionsFixed;
249        userState.clear();
250        for (int i=0; i<base.userState.size(); i++) {
251            userState.put(base.userState.keyAt(i), base.userState.valueAt(i));
252        }
253        installStatus = base.installStatus;
254        keySetData = base.keySetData;
255        verificationInfo = base.verificationInfo;
256        installerPackageName = base.installerPackageName;
257        volumeUuid = base.volumeUuid;
258    }
259
260    private PackageUserState modifyUserState(int userId) {
261        PackageUserState state = userState.get(userId);
262        if (state == null) {
263            state = new PackageUserState();
264            userState.put(userId, state);
265        }
266        return state;
267    }
268
269    public PackageUserState readUserState(int userId) {
270        PackageUserState state = userState.get(userId);
271        if (state != null) {
272            return state;
273        }
274        return DEFAULT_USER_STATE;
275    }
276
277    void setEnabled(int state, int userId, String callingPackage) {
278        PackageUserState st = modifyUserState(userId);
279        st.enabled = state;
280        st.lastDisableAppCaller = callingPackage;
281    }
282
283    int getEnabled(int userId) {
284        return readUserState(userId).enabled;
285    }
286
287    String getLastDisabledAppCaller(int userId) {
288        return readUserState(userId).lastDisableAppCaller;
289    }
290
291    void setInstalled(boolean inst, int userId) {
292        modifyUserState(userId).installed = inst;
293    }
294
295    boolean getInstalled(int userId) {
296        return readUserState(userId).installed;
297    }
298
299    boolean isAnyInstalled(int[] users) {
300        for (int user: users) {
301            if (readUserState(user).installed) {
302                return true;
303            }
304        }
305        return false;
306    }
307
308    int[] queryInstalledUsers(int[] users, boolean installed) {
309        int num = 0;
310        for (int user : users) {
311            if (getInstalled(user) == installed) {
312                num++;
313            }
314        }
315        int[] res = new int[num];
316        num = 0;
317        for (int user : users) {
318            if (getInstalled(user) == installed) {
319                res[num] = user;
320                num++;
321            }
322        }
323        return res;
324    }
325
326    boolean getStopped(int userId) {
327        return readUserState(userId).stopped;
328    }
329
330    void setStopped(boolean stop, int userId) {
331        modifyUserState(userId).stopped = stop;
332    }
333
334    boolean getNotLaunched(int userId) {
335        return readUserState(userId).notLaunched;
336    }
337
338    void setNotLaunched(boolean stop, int userId) {
339        modifyUserState(userId).notLaunched = stop;
340    }
341
342    boolean getHidden(int userId) {
343        return readUserState(userId).hidden;
344    }
345
346    void setHidden(boolean hidden, int userId) {
347        modifyUserState(userId).hidden = hidden;
348    }
349
350    boolean getSuspended(int userId) {
351        return readUserState(userId).suspended;
352    }
353
354    void setSuspended(boolean suspended, int userId) {
355        modifyUserState(userId).suspended = suspended;
356    }
357
358    boolean getBlockUninstall(int userId) {
359        return readUserState(userId).blockUninstall;
360    }
361
362    void setBlockUninstall(boolean blockUninstall, int userId) {
363        modifyUserState(userId).blockUninstall = blockUninstall;
364    }
365
366    void setUserState(int userId, int enabled, boolean installed, boolean stopped,
367            boolean notLaunched, boolean hidden, boolean suspended,
368            String lastDisableAppCaller, ArraySet<String> enabledComponents,
369            ArraySet<String> disabledComponents, boolean blockUninstall, int domainVerifState,
370            int linkGeneration) {
371        PackageUserState state = modifyUserState(userId);
372        state.enabled = enabled;
373        state.installed = installed;
374        state.stopped = stopped;
375        state.notLaunched = notLaunched;
376        state.hidden = hidden;
377        state.suspended = suspended;
378        state.lastDisableAppCaller = lastDisableAppCaller;
379        state.enabledComponents = enabledComponents;
380        state.disabledComponents = disabledComponents;
381        state.blockUninstall = blockUninstall;
382        state.domainVerificationStatus = domainVerifState;
383        state.appLinkGeneration = linkGeneration;
384    }
385
386    ArraySet<String> getEnabledComponents(int userId) {
387        return readUserState(userId).enabledComponents;
388    }
389
390    ArraySet<String> getDisabledComponents(int userId) {
391        return readUserState(userId).disabledComponents;
392    }
393
394    void setEnabledComponents(ArraySet<String> components, int userId) {
395        modifyUserState(userId).enabledComponents = components;
396    }
397
398    void setDisabledComponents(ArraySet<String> components, int userId) {
399        modifyUserState(userId).disabledComponents = components;
400    }
401
402    void setEnabledComponentsCopy(ArraySet<String> components, int userId) {
403        modifyUserState(userId).enabledComponents = components != null
404                ? new ArraySet<String>(components) : null;
405    }
406
407    void setDisabledComponentsCopy(ArraySet<String> components, int userId) {
408        modifyUserState(userId).disabledComponents = components != null
409                ? new ArraySet<String>(components) : null;
410    }
411
412    PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) {
413        PackageUserState state = modifyUserState(userId);
414        if (disabled && state.disabledComponents == null) {
415            state.disabledComponents = new ArraySet<String>(1);
416        }
417        if (enabled && state.enabledComponents == null) {
418            state.enabledComponents = new ArraySet<String>(1);
419        }
420        return state;
421    }
422
423    void addDisabledComponent(String componentClassName, int userId) {
424        modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName);
425    }
426
427    void addEnabledComponent(String componentClassName, int userId) {
428        modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName);
429    }
430
431    boolean enableComponentLPw(String componentClassName, int userId) {
432        PackageUserState state = modifyUserStateComponents(userId, false, true);
433        boolean changed = state.disabledComponents != null
434                ? state.disabledComponents.remove(componentClassName) : false;
435        changed |= state.enabledComponents.add(componentClassName);
436        return changed;
437    }
438
439    boolean disableComponentLPw(String componentClassName, int userId) {
440        PackageUserState state = modifyUserStateComponents(userId, true, false);
441        boolean changed = state.enabledComponents != null
442                ? state.enabledComponents.remove(componentClassName) : false;
443        changed |= state.disabledComponents.add(componentClassName);
444        return changed;
445    }
446
447    boolean restoreComponentLPw(String componentClassName, int userId) {
448        PackageUserState state = modifyUserStateComponents(userId, true, true);
449        boolean changed = state.disabledComponents != null
450                ? state.disabledComponents.remove(componentClassName) : false;
451        changed |= state.enabledComponents != null
452                ? state.enabledComponents.remove(componentClassName) : false;
453        return changed;
454    }
455
456    int getCurrentEnabledStateLPr(String componentName, int userId) {
457        PackageUserState state = readUserState(userId);
458        if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) {
459            return COMPONENT_ENABLED_STATE_ENABLED;
460        } else if (state.disabledComponents != null
461                && state.disabledComponents.contains(componentName)) {
462            return COMPONENT_ENABLED_STATE_DISABLED;
463        } else {
464            return COMPONENT_ENABLED_STATE_DEFAULT;
465        }
466    }
467
468    void removeUser(int userId) {
469        userState.delete(userId);
470    }
471
472    IntentFilterVerificationInfo getIntentFilterVerificationInfo() {
473        return verificationInfo;
474    }
475
476    void setIntentFilterVerificationInfo(IntentFilterVerificationInfo info) {
477        verificationInfo = info;
478    }
479
480    // Returns a packed value as a long:
481    //
482    // high 'int'-sized word: link status: undefined/ask/never/always.
483    // low 'int'-sized word: relative priority among 'always' results.
484    long getDomainVerificationStatusForUser(int userId) {
485        PackageUserState state = readUserState(userId);
486        long result = (long) state.appLinkGeneration;
487        result |= ((long) state.domainVerificationStatus) << 32;
488        return result;
489    }
490
491    void setDomainVerificationStatusForUser(final int status, int generation, int userId) {
492        PackageUserState state = modifyUserState(userId);
493        state.domainVerificationStatus = status;
494        if (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
495            state.appLinkGeneration = generation;
496        }
497    }
498
499    void clearDomainVerificationStatusForUser(int userId) {
500        modifyUserState(userId).domainVerificationStatus =
501                PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
502    }
503}
504