PackageSettingBase.java revision 4288419787120ce85a241a4b315d7d2123aa2d4a
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.pm;
18
19import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
20import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
21import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
22
23import android.content.pm.IntentFilterVerificationInfo;
24import android.content.pm.PackageManager;
25import android.content.pm.PackageUserState;
26import android.os.storage.VolumeInfo;
27import android.util.ArraySet;
28import android.util.SparseArray;
29
30import java.io.File;
31import java.util.ArrayList;
32import java.util.List;
33import java.util.Set;
34
35/**
36 * Settings base class for pending and resolved classes.
37 */
38abstract class PackageSettingBase extends SettingBase {
39    /**
40     * Indicates the state of installation. Used by PackageManager to figure out
41     * incomplete installations. Say a package is being installed (the state is
42     * set to PKG_INSTALL_INCOMPLETE) and remains so till the package
43     * installation is successful or unsuccessful in which case the
44     * PackageManager will no longer maintain state information associated with
45     * the package. If some exception(like device freeze or battery being pulled
46     * out) occurs during installation of a package, the PackageManager needs
47     * this information to clean up the previously failed installation.
48     */
49    static final int PKG_INSTALL_COMPLETE = 1;
50    static final int PKG_INSTALL_INCOMPLETE = 0;
51
52    final String name;
53    final String realName;
54
55    String parentPackageName;
56    List<String> childPackageNames;
57
58    /**
59     * Path where this package was found on disk. For monolithic packages
60     * this is path to single base APK file; for cluster packages this is
61     * path to the cluster directory.
62     */
63    File codePath;
64    String codePathString;
65    File resourcePath;
66    String resourcePathString;
67
68    /**
69     * The path under which native libraries have been unpacked. This path is
70     * always derived at runtime, and is only stored here for cleanup when a
71     * package is uninstalled.
72     */
73    @Deprecated
74    String legacyNativeLibraryPathString;
75
76    /**
77     * The primary CPU abi for this package. This value is regenerated at every
78     * boot scan.
79     */
80    String primaryCpuAbiString;
81
82    /**
83     * The secondary CPU abi for this package. This value is regenerated at every
84     * boot scan.
85     */
86    String secondaryCpuAbiString;
87
88    /**
89     * The install time CPU override, if any. This value is written at install time
90     * and doesn't change during the life of an install. If non-null,
91     * {@code primaryCpuAbiString} will contain the same value.
92     */
93    String cpuAbiOverrideString;
94
95    long timeStamp;
96    long firstInstallTime;
97    long lastUpdateTime;
98    int versionCode;
99
100    boolean uidError;
101
102    PackageSignatures signatures = new PackageSignatures();
103
104    boolean installPermissionsFixed;
105
106    PackageKeySetData keySetData = new PackageKeySetData();
107
108    private static final PackageUserState DEFAULT_USER_STATE = new PackageUserState();
109
110    // Whether this package is currently stopped, thus can not be
111    // started until explicitly launched by the user.
112    private final SparseArray<PackageUserState> userState = new SparseArray<PackageUserState>();
113
114    int installStatus = PKG_INSTALL_COMPLETE;
115
116    /**
117     * Non-persisted value. During an "upgrade without restart", we need the set
118     * of all previous code paths so we can surgically add the new APKs to the
119     * active classloader. If at any point an application is upgraded with a
120     * 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    long getCeDataInode(int userId) {
327        return readUserState(userId).ceDataInode;
328    }
329
330    void setCeDataInode(long ceDataInode, int userId) {
331        modifyUserState(userId).ceDataInode = ceDataInode;
332    }
333
334    boolean getStopped(int userId) {
335        return readUserState(userId).stopped;
336    }
337
338    void setStopped(boolean stop, int userId) {
339        modifyUserState(userId).stopped = stop;
340    }
341
342    boolean getNotLaunched(int userId) {
343        return readUserState(userId).notLaunched;
344    }
345
346    void setNotLaunched(boolean stop, int userId) {
347        modifyUserState(userId).notLaunched = stop;
348    }
349
350    boolean getHidden(int userId) {
351        return readUserState(userId).hidden;
352    }
353
354    void setHidden(boolean hidden, int userId) {
355        modifyUserState(userId).hidden = hidden;
356    }
357
358    boolean getSuspended(int userId) {
359        return readUserState(userId).suspended;
360    }
361
362    void setSuspended(boolean suspended, int userId) {
363        modifyUserState(userId).suspended = suspended;
364    }
365
366    boolean getBlockUninstall(int userId) {
367        return readUserState(userId).blockUninstall;
368    }
369
370    void setBlockUninstall(boolean blockUninstall, int userId) {
371        modifyUserState(userId).blockUninstall = blockUninstall;
372    }
373
374    void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped,
375            boolean notLaunched, boolean hidden, boolean suspended,
376            String lastDisableAppCaller, ArraySet<String> enabledComponents,
377            ArraySet<String> disabledComponents, boolean blockUninstall, int domainVerifState,
378            int linkGeneration) {
379        PackageUserState state = modifyUserState(userId);
380        state.ceDataInode = ceDataInode;
381        state.enabled = enabled;
382        state.installed = installed;
383        state.stopped = stopped;
384        state.notLaunched = notLaunched;
385        state.hidden = hidden;
386        state.suspended = suspended;
387        state.lastDisableAppCaller = lastDisableAppCaller;
388        state.enabledComponents = enabledComponents;
389        state.disabledComponents = disabledComponents;
390        state.blockUninstall = blockUninstall;
391        state.domainVerificationStatus = domainVerifState;
392        state.appLinkGeneration = linkGeneration;
393    }
394
395    ArraySet<String> getEnabledComponents(int userId) {
396        return readUserState(userId).enabledComponents;
397    }
398
399    ArraySet<String> getDisabledComponents(int userId) {
400        return readUserState(userId).disabledComponents;
401    }
402
403    void setEnabledComponents(ArraySet<String> components, int userId) {
404        modifyUserState(userId).enabledComponents = components;
405    }
406
407    void setDisabledComponents(ArraySet<String> components, int userId) {
408        modifyUserState(userId).disabledComponents = components;
409    }
410
411    void setEnabledComponentsCopy(ArraySet<String> components, int userId) {
412        modifyUserState(userId).enabledComponents = components != null
413                ? new ArraySet<String>(components) : null;
414    }
415
416    void setDisabledComponentsCopy(ArraySet<String> components, int userId) {
417        modifyUserState(userId).disabledComponents = components != null
418                ? new ArraySet<String>(components) : null;
419    }
420
421    PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) {
422        PackageUserState state = modifyUserState(userId);
423        if (disabled && state.disabledComponents == null) {
424            state.disabledComponents = new ArraySet<String>(1);
425        }
426        if (enabled && state.enabledComponents == null) {
427            state.enabledComponents = new ArraySet<String>(1);
428        }
429        return state;
430    }
431
432    void addDisabledComponent(String componentClassName, int userId) {
433        modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName);
434    }
435
436    void addEnabledComponent(String componentClassName, int userId) {
437        modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName);
438    }
439
440    boolean enableComponentLPw(String componentClassName, int userId) {
441        PackageUserState state = modifyUserStateComponents(userId, false, true);
442        boolean changed = state.disabledComponents != null
443                ? state.disabledComponents.remove(componentClassName) : false;
444        changed |= state.enabledComponents.add(componentClassName);
445        return changed;
446    }
447
448    boolean disableComponentLPw(String componentClassName, int userId) {
449        PackageUserState state = modifyUserStateComponents(userId, true, false);
450        boolean changed = state.enabledComponents != null
451                ? state.enabledComponents.remove(componentClassName) : false;
452        changed |= state.disabledComponents.add(componentClassName);
453        return changed;
454    }
455
456    boolean restoreComponentLPw(String componentClassName, int userId) {
457        PackageUserState state = modifyUserStateComponents(userId, true, true);
458        boolean changed = state.disabledComponents != null
459                ? state.disabledComponents.remove(componentClassName) : false;
460        changed |= state.enabledComponents != null
461                ? state.enabledComponents.remove(componentClassName) : false;
462        return changed;
463    }
464
465    int getCurrentEnabledStateLPr(String componentName, int userId) {
466        PackageUserState state = readUserState(userId);
467        if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) {
468            return COMPONENT_ENABLED_STATE_ENABLED;
469        } else if (state.disabledComponents != null
470                && state.disabledComponents.contains(componentName)) {
471            return COMPONENT_ENABLED_STATE_DISABLED;
472        } else {
473            return COMPONENT_ENABLED_STATE_DEFAULT;
474        }
475    }
476
477    void removeUser(int userId) {
478        userState.delete(userId);
479    }
480
481    IntentFilterVerificationInfo getIntentFilterVerificationInfo() {
482        return verificationInfo;
483    }
484
485    void setIntentFilterVerificationInfo(IntentFilterVerificationInfo info) {
486        verificationInfo = info;
487    }
488
489    // Returns a packed value as a long:
490    //
491    // high 'int'-sized word: link status: undefined/ask/never/always.
492    // low 'int'-sized word: relative priority among 'always' results.
493    long getDomainVerificationStatusForUser(int userId) {
494        PackageUserState state = readUserState(userId);
495        long result = (long) state.appLinkGeneration;
496        result |= ((long) state.domainVerificationStatus) << 32;
497        return result;
498    }
499
500    void setDomainVerificationStatusForUser(final int status, int generation, int userId) {
501        PackageUserState state = modifyUserState(userId);
502        state.domainVerificationStatus = status;
503        if (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
504            state.appLinkGeneration = generation;
505        }
506    }
507
508    void clearDomainVerificationStatusForUser(int userId) {
509        modifyUserState(userId).domainVerificationStatus =
510                PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
511    }
512}
513