PackageSettingBase.java revision 8c57aeaa8f27423b843fa043fb86b0b57c906ead
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    /** Indicates if the package that installed this app has been uninstalled */
129    boolean isOrphaned;
130    /** UUID of {@link VolumeInfo} hosting this app */
131    String volumeUuid;
132
133    IntentFilterVerificationInfo verificationInfo;
134
135    PackageSettingBase(String name, String realName, File codePath, File resourcePath,
136            String legacyNativeLibraryPathString, String primaryCpuAbiString,
137            String secondaryCpuAbiString, String cpuAbiOverrideString,
138            int pVersionCode, int pkgFlags, int pkgPrivateFlags,
139            String parentPackageName, List<String> childPackageNames) {
140        super(pkgFlags, pkgPrivateFlags);
141        this.name = name;
142        this.realName = realName;
143        this.parentPackageName = parentPackageName;
144        this.childPackageNames = (childPackageNames != null)
145                ? new ArrayList<>(childPackageNames) : null;
146        init(codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbiString,
147                secondaryCpuAbiString, cpuAbiOverrideString, pVersionCode);
148    }
149
150    /**
151     * New instance of PackageSetting with one-level-deep cloning.
152     */
153    @SuppressWarnings("unchecked")
154    PackageSettingBase(PackageSettingBase base) {
155        super(base);
156
157        name = base.name;
158        realName = base.realName;
159        codePath = base.codePath;
160        codePathString = base.codePathString;
161        resourcePath = base.resourcePath;
162        resourcePathString = base.resourcePathString;
163        legacyNativeLibraryPathString = base.legacyNativeLibraryPathString;
164        primaryCpuAbiString = base.primaryCpuAbiString;
165        secondaryCpuAbiString = base.secondaryCpuAbiString;
166        cpuAbiOverrideString = base.cpuAbiOverrideString;
167        timeStamp = base.timeStamp;
168        firstInstallTime = base.firstInstallTime;
169        lastUpdateTime = base.lastUpdateTime;
170        versionCode = base.versionCode;
171
172        uidError = base.uidError;
173
174        signatures = new PackageSignatures(base.signatures);
175
176        installPermissionsFixed = base.installPermissionsFixed;
177        userState.clear();
178        for (int i=0; i<base.userState.size(); i++) {
179            userState.put(base.userState.keyAt(i),
180                    new PackageUserState(base.userState.valueAt(i)));
181        }
182        installStatus = base.installStatus;
183
184        origPackage = base.origPackage;
185
186        installerPackageName = base.installerPackageName;
187        isOrphaned = base.isOrphaned;
188        volumeUuid = base.volumeUuid;
189
190        keySetData = new PackageKeySetData(base.keySetData);
191
192        parentPackageName = base.parentPackageName;
193        childPackageNames = (base.childPackageNames != null)
194                ? new ArrayList<>(base.childPackageNames) : null;
195    }
196
197    void init(File codePath, File resourcePath, String legacyNativeLibraryPathString,
198              String primaryCpuAbiString, String secondaryCpuAbiString,
199              String cpuAbiOverrideString, int pVersionCode) {
200        this.codePath = codePath;
201        this.codePathString = codePath.toString();
202        this.resourcePath = resourcePath;
203        this.resourcePathString = resourcePath.toString();
204        this.legacyNativeLibraryPathString = legacyNativeLibraryPathString;
205        this.primaryCpuAbiString = primaryCpuAbiString;
206        this.secondaryCpuAbiString = secondaryCpuAbiString;
207        this.cpuAbiOverrideString = cpuAbiOverrideString;
208        this.versionCode = pVersionCode;
209    }
210
211    public void setInstallerPackageName(String packageName) {
212        installerPackageName = packageName;
213    }
214
215    public String getInstallerPackageName() {
216        return installerPackageName;
217    }
218
219    public void setVolumeUuid(String volumeUuid) {
220        this.volumeUuid = volumeUuid;
221    }
222
223    public String getVolumeUuid() {
224        return volumeUuid;
225    }
226
227    public void setInstallStatus(int newStatus) {
228        installStatus = newStatus;
229    }
230
231    public int getInstallStatus() {
232        return installStatus;
233    }
234
235    public void setTimeStamp(long newStamp) {
236        timeStamp = newStamp;
237    }
238
239    /**
240     * Make a shallow copy of this package settings.
241     */
242    public void copyFrom(PackageSettingBase base) {
243        mPermissionsState.copyFrom(base.mPermissionsState);
244        primaryCpuAbiString = base.primaryCpuAbiString;
245        secondaryCpuAbiString = base.secondaryCpuAbiString;
246        cpuAbiOverrideString = base.cpuAbiOverrideString;
247        timeStamp = base.timeStamp;
248        firstInstallTime = base.firstInstallTime;
249        lastUpdateTime = base.lastUpdateTime;
250        signatures = base.signatures;
251        installPermissionsFixed = base.installPermissionsFixed;
252        userState.clear();
253        for (int i=0; i<base.userState.size(); i++) {
254            userState.put(base.userState.keyAt(i), base.userState.valueAt(i));
255        }
256        installStatus = base.installStatus;
257        keySetData = base.keySetData;
258        verificationInfo = base.verificationInfo;
259        installerPackageName = base.installerPackageName;
260        volumeUuid = base.volumeUuid;
261    }
262
263    private PackageUserState modifyUserState(int userId) {
264        PackageUserState state = userState.get(userId);
265        if (state == null) {
266            state = new PackageUserState();
267            userState.put(userId, state);
268        }
269        return state;
270    }
271
272    public PackageUserState readUserState(int userId) {
273        PackageUserState state = userState.get(userId);
274        if (state != null) {
275            return state;
276        }
277        return DEFAULT_USER_STATE;
278    }
279
280    void setEnabled(int state, int userId, String callingPackage) {
281        PackageUserState st = modifyUserState(userId);
282        st.enabled = state;
283        st.lastDisableAppCaller = callingPackage;
284    }
285
286    int getEnabled(int userId) {
287        return readUserState(userId).enabled;
288    }
289
290    String getLastDisabledAppCaller(int userId) {
291        return readUserState(userId).lastDisableAppCaller;
292    }
293
294    void setInstalled(boolean inst, int userId) {
295        modifyUserState(userId).installed = inst;
296    }
297
298    boolean getInstalled(int userId) {
299        return readUserState(userId).installed;
300    }
301
302    boolean isAnyInstalled(int[] users) {
303        for (int user: users) {
304            if (readUserState(user).installed) {
305                return true;
306            }
307        }
308        return false;
309    }
310
311    int[] queryInstalledUsers(int[] users, boolean installed) {
312        int num = 0;
313        for (int user : users) {
314            if (getInstalled(user) == installed) {
315                num++;
316            }
317        }
318        int[] res = new int[num];
319        num = 0;
320        for (int user : users) {
321            if (getInstalled(user) == installed) {
322                res[num] = user;
323                num++;
324            }
325        }
326        return res;
327    }
328
329    long getCeDataInode(int userId) {
330        return readUserState(userId).ceDataInode;
331    }
332
333    void setCeDataInode(long ceDataInode, int userId) {
334        modifyUserState(userId).ceDataInode = ceDataInode;
335    }
336
337    boolean getStopped(int userId) {
338        return readUserState(userId).stopped;
339    }
340
341    void setStopped(boolean stop, int userId) {
342        modifyUserState(userId).stopped = stop;
343    }
344
345    boolean getNotLaunched(int userId) {
346        return readUserState(userId).notLaunched;
347    }
348
349    void setNotLaunched(boolean stop, int userId) {
350        modifyUserState(userId).notLaunched = stop;
351    }
352
353    boolean getHidden(int userId) {
354        return readUserState(userId).hidden;
355    }
356
357    void setHidden(boolean hidden, int userId) {
358        modifyUserState(userId).hidden = hidden;
359    }
360
361    boolean getSuspended(int userId) {
362        return readUserState(userId).suspended;
363    }
364
365    void setSuspended(boolean suspended, int userId) {
366        modifyUserState(userId).suspended = suspended;
367    }
368
369    boolean getBlockUninstall(int userId) {
370        return readUserState(userId).blockUninstall;
371    }
372
373    void setBlockUninstall(boolean blockUninstall, int userId) {
374        modifyUserState(userId).blockUninstall = blockUninstall;
375    }
376
377    void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped,
378            boolean notLaunched, boolean hidden, boolean suspended,
379            String lastDisableAppCaller, ArraySet<String> enabledComponents,
380            ArraySet<String> disabledComponents, boolean blockUninstall, int domainVerifState,
381            int linkGeneration) {
382        PackageUserState state = modifyUserState(userId);
383        state.ceDataInode = ceDataInode;
384        state.enabled = enabled;
385        state.installed = installed;
386        state.stopped = stopped;
387        state.notLaunched = notLaunched;
388        state.hidden = hidden;
389        state.suspended = suspended;
390        state.lastDisableAppCaller = lastDisableAppCaller;
391        state.enabledComponents = enabledComponents;
392        state.disabledComponents = disabledComponents;
393        state.blockUninstall = blockUninstall;
394        state.domainVerificationStatus = domainVerifState;
395        state.appLinkGeneration = linkGeneration;
396    }
397
398    ArraySet<String> getEnabledComponents(int userId) {
399        return readUserState(userId).enabledComponents;
400    }
401
402    ArraySet<String> getDisabledComponents(int userId) {
403        return readUserState(userId).disabledComponents;
404    }
405
406    void setEnabledComponents(ArraySet<String> components, int userId) {
407        modifyUserState(userId).enabledComponents = components;
408    }
409
410    void setDisabledComponents(ArraySet<String> components, int userId) {
411        modifyUserState(userId).disabledComponents = components;
412    }
413
414    void setEnabledComponentsCopy(ArraySet<String> components, int userId) {
415        modifyUserState(userId).enabledComponents = components != null
416                ? new ArraySet<String>(components) : null;
417    }
418
419    void setDisabledComponentsCopy(ArraySet<String> components, int userId) {
420        modifyUserState(userId).disabledComponents = components != null
421                ? new ArraySet<String>(components) : null;
422    }
423
424    PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) {
425        PackageUserState state = modifyUserState(userId);
426        if (disabled && state.disabledComponents == null) {
427            state.disabledComponents = new ArraySet<String>(1);
428        }
429        if (enabled && state.enabledComponents == null) {
430            state.enabledComponents = new ArraySet<String>(1);
431        }
432        return state;
433    }
434
435    void addDisabledComponent(String componentClassName, int userId) {
436        modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName);
437    }
438
439    void addEnabledComponent(String componentClassName, int userId) {
440        modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName);
441    }
442
443    boolean enableComponentLPw(String componentClassName, int userId) {
444        PackageUserState state = modifyUserStateComponents(userId, false, true);
445        boolean changed = state.disabledComponents != null
446                ? state.disabledComponents.remove(componentClassName) : false;
447        changed |= state.enabledComponents.add(componentClassName);
448        return changed;
449    }
450
451    boolean disableComponentLPw(String componentClassName, int userId) {
452        PackageUserState state = modifyUserStateComponents(userId, true, false);
453        boolean changed = state.enabledComponents != null
454                ? state.enabledComponents.remove(componentClassName) : false;
455        changed |= state.disabledComponents.add(componentClassName);
456        return changed;
457    }
458
459    boolean restoreComponentLPw(String componentClassName, int userId) {
460        PackageUserState state = modifyUserStateComponents(userId, true, true);
461        boolean changed = state.disabledComponents != null
462                ? state.disabledComponents.remove(componentClassName) : false;
463        changed |= state.enabledComponents != null
464                ? state.enabledComponents.remove(componentClassName) : false;
465        return changed;
466    }
467
468    int getCurrentEnabledStateLPr(String componentName, int userId) {
469        PackageUserState state = readUserState(userId);
470        if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) {
471            return COMPONENT_ENABLED_STATE_ENABLED;
472        } else if (state.disabledComponents != null
473                && state.disabledComponents.contains(componentName)) {
474            return COMPONENT_ENABLED_STATE_DISABLED;
475        } else {
476            return COMPONENT_ENABLED_STATE_DEFAULT;
477        }
478    }
479
480    void removeUser(int userId) {
481        userState.delete(userId);
482    }
483
484    IntentFilterVerificationInfo getIntentFilterVerificationInfo() {
485        return verificationInfo;
486    }
487
488    void setIntentFilterVerificationInfo(IntentFilterVerificationInfo info) {
489        verificationInfo = info;
490    }
491
492    // Returns a packed value as a long:
493    //
494    // high 'int'-sized word: link status: undefined/ask/never/always.
495    // low 'int'-sized word: relative priority among 'always' results.
496    long getDomainVerificationStatusForUser(int userId) {
497        PackageUserState state = readUserState(userId);
498        long result = (long) state.appLinkGeneration;
499        result |= ((long) state.domainVerificationStatus) << 32;
500        return result;
501    }
502
503    void setDomainVerificationStatusForUser(final int status, int generation, int userId) {
504        PackageUserState state = modifyUserState(userId);
505        state.domainVerificationStatus = status;
506        if (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
507            state.appLinkGeneration = generation;
508        }
509    }
510
511    void clearDomainVerificationStatusForUser(int userId) {
512        modifyUserState(userId).domainVerificationStatus =
513                PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
514    }
515}
516