PackageSettingBase.java revision f0d6cb38c47ee37583034dc3a68238ed13c91742
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;
31
32/**
33 * Settings base class for pending and resolved classes.
34 */
35abstract class PackageSettingBase extends SettingBase {
36    /**
37     * Indicates the state of installation. Used by PackageManager to figure out
38     * incomplete installations. Say a package is being installed (the state is
39     * set to PKG_INSTALL_INCOMPLETE) and remains so till the package
40     * installation is successful or unsuccessful in which case the
41     * PackageManager will no longer maintain state information associated with
42     * the package. If some exception(like device freeze or battery being pulled
43     * out) occurs during installation of a package, the PackageManager needs
44     * this information to clean up the previously failed installation.
45     */
46    static final int PKG_INSTALL_COMPLETE = 1;
47    static final int PKG_INSTALL_INCOMPLETE = 0;
48
49    final String name;
50    final String realName;
51
52    /**
53     * Path where this package was found on disk. For monolithic packages
54     * this is path to single base APK file; for cluster packages this is
55     * path to the cluster directory.
56     */
57    File codePath;
58    String codePathString;
59    File resourcePath;
60    String resourcePathString;
61
62    /**
63     * The path under which native libraries have been unpacked. This path is
64     * always derived at runtime, and is only stored here for cleanup when a
65     * package is uninstalled.
66     */
67    @Deprecated
68    String legacyNativeLibraryPathString;
69
70    /**
71     * The primary CPU abi for this package. This value is regenerated at every
72     * boot scan.
73     */
74    String primaryCpuAbiString;
75
76    /**
77     * The secondary CPU abi for this package. This value is regenerated at every
78     * boot scan.
79     */
80    String secondaryCpuAbiString;
81
82    /**
83     * The install time CPU override, if any. This value is written at install time
84     * and doesn't change during the life of an install. If non-null,
85     * {@code primaryCpuAbiString} will contain the same value.
86     */
87    String cpuAbiOverrideString;
88
89    long timeStamp;
90    long firstInstallTime;
91    long lastUpdateTime;
92    int versionCode;
93
94    boolean uidError;
95
96    PackageSignatures signatures = new PackageSignatures();
97
98    boolean installPermissionsFixed;
99
100    PackageKeySetData keySetData = new PackageKeySetData();
101
102    private static final PackageUserState DEFAULT_USER_STATE = new PackageUserState();
103
104    // Whether this package is currently stopped, thus can not be
105    // started until explicitly launched by the user.
106    private final SparseArray<PackageUserState> userState = new SparseArray<PackageUserState>();
107
108    int installStatus = PKG_INSTALL_COMPLETE;
109
110    /**
111     * Non-persisted value indicating this package has been temporarily frozen,
112     * usually during a critical section of the package update pipeline. The
113     * platform will refuse to launch packages in a frozen state.
114     */
115    boolean frozen = false;
116
117    PackageSettingBase origPackage;
118
119    /** Package name of the app that installed this package */
120    String installerPackageName;
121    /** UUID of {@link VolumeInfo} hosting this app */
122    String volumeUuid;
123
124    IntentFilterVerificationInfo verificationInfo;
125
126    PackageSettingBase(String name, String realName, File codePath, File resourcePath,
127            String legacyNativeLibraryPathString, String primaryCpuAbiString,
128            String secondaryCpuAbiString, String cpuAbiOverrideString,
129            int pVersionCode, int pkgFlags, int pkgPrivateFlags) {
130        super(pkgFlags, pkgPrivateFlags);
131        this.name = name;
132        this.realName = realName;
133        init(codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbiString,
134                secondaryCpuAbiString, cpuAbiOverrideString, pVersionCode);
135    }
136
137    /**
138     * New instance of PackageSetting with one-level-deep cloning.
139     */
140    @SuppressWarnings("unchecked")
141    PackageSettingBase(PackageSettingBase base) {
142        super(base);
143
144        name = base.name;
145        realName = base.realName;
146        codePath = base.codePath;
147        codePathString = base.codePathString;
148        resourcePath = base.resourcePath;
149        resourcePathString = base.resourcePathString;
150        legacyNativeLibraryPathString = base.legacyNativeLibraryPathString;
151        primaryCpuAbiString = base.primaryCpuAbiString;
152        secondaryCpuAbiString = base.secondaryCpuAbiString;
153        cpuAbiOverrideString = base.cpuAbiOverrideString;
154        timeStamp = base.timeStamp;
155        firstInstallTime = base.firstInstallTime;
156        lastUpdateTime = base.lastUpdateTime;
157        versionCode = base.versionCode;
158
159        uidError = base.uidError;
160
161        signatures = new PackageSignatures(base.signatures);
162
163        installPermissionsFixed = base.installPermissionsFixed;
164        userState.clear();
165        for (int i=0; i<base.userState.size(); i++) {
166            userState.put(base.userState.keyAt(i),
167                    new PackageUserState(base.userState.valueAt(i)));
168        }
169        installStatus = base.installStatus;
170
171        origPackage = base.origPackage;
172
173        installerPackageName = base.installerPackageName;
174        volumeUuid = base.volumeUuid;
175
176        keySetData = new PackageKeySetData(base.keySetData);
177    }
178
179    void init(File codePath, File resourcePath, String legacyNativeLibraryPathString,
180              String primaryCpuAbiString, String secondaryCpuAbiString,
181              String cpuAbiOverrideString, int pVersionCode) {
182        this.codePath = codePath;
183        this.codePathString = codePath.toString();
184        this.resourcePath = resourcePath;
185        this.resourcePathString = resourcePath.toString();
186        this.legacyNativeLibraryPathString = legacyNativeLibraryPathString;
187        this.primaryCpuAbiString = primaryCpuAbiString;
188        this.secondaryCpuAbiString = secondaryCpuAbiString;
189        this.cpuAbiOverrideString = cpuAbiOverrideString;
190        this.versionCode = pVersionCode;
191    }
192
193    public void setInstallerPackageName(String packageName) {
194        installerPackageName = packageName;
195    }
196
197    public String getInstallerPackageName() {
198        return installerPackageName;
199    }
200
201    public void setVolumeUuid(String volumeUuid) {
202        this.volumeUuid = volumeUuid;
203    }
204
205    public String getVolumeUuid() {
206        return volumeUuid;
207    }
208
209    public void setInstallStatus(int newStatus) {
210        installStatus = newStatus;
211    }
212
213    public int getInstallStatus() {
214        return installStatus;
215    }
216
217    public void setTimeStamp(long newStamp) {
218        timeStamp = newStamp;
219    }
220
221    /**
222     * Make a shallow copy of this package settings.
223     */
224    public void copyFrom(PackageSettingBase base) {
225        mPermissionsState.copyFrom(base.mPermissionsState);
226        primaryCpuAbiString = base.primaryCpuAbiString;
227        secondaryCpuAbiString = base.secondaryCpuAbiString;
228        cpuAbiOverrideString = base.cpuAbiOverrideString;
229        timeStamp = base.timeStamp;
230        firstInstallTime = base.firstInstallTime;
231        lastUpdateTime = base.lastUpdateTime;
232        signatures = base.signatures;
233        installPermissionsFixed = base.installPermissionsFixed;
234        userState.clear();
235        for (int i=0; i<base.userState.size(); i++) {
236            userState.put(base.userState.keyAt(i), base.userState.valueAt(i));
237        }
238        installStatus = base.installStatus;
239        keySetData = base.keySetData;
240        verificationInfo = base.verificationInfo;
241    }
242
243    private PackageUserState modifyUserState(int userId) {
244        PackageUserState state = userState.get(userId);
245        if (state == null) {
246            state = new PackageUserState();
247            userState.put(userId, state);
248        }
249        return state;
250    }
251
252    public PackageUserState readUserState(int userId) {
253        PackageUserState state = userState.get(userId);
254        if (state != null) {
255            return state;
256        }
257        return DEFAULT_USER_STATE;
258    }
259
260    void setEnabled(int state, int userId, String callingPackage) {
261        PackageUserState st = modifyUserState(userId);
262        st.enabled = state;
263        st.lastDisableAppCaller = callingPackage;
264    }
265
266    int getEnabled(int userId) {
267        return readUserState(userId).enabled;
268    }
269
270    String getLastDisabledAppCaller(int userId) {
271        return readUserState(userId).lastDisableAppCaller;
272    }
273
274    void setInstalled(boolean inst, int userId) {
275        modifyUserState(userId).installed = inst;
276    }
277
278    boolean getInstalled(int userId) {
279        return readUserState(userId).installed;
280    }
281
282    boolean isAnyInstalled(int[] users) {
283        for (int user: users) {
284            if (readUserState(user).installed) {
285                return true;
286            }
287        }
288        return false;
289    }
290
291    int[] queryInstalledUsers(int[] users, boolean installed) {
292        int num = 0;
293        for (int user : users) {
294            if (getInstalled(user) == installed) {
295                num++;
296            }
297        }
298        int[] res = new int[num];
299        num = 0;
300        for (int user : users) {
301            if (getInstalled(user) == installed) {
302                res[num] = user;
303                num++;
304            }
305        }
306        return res;
307    }
308
309    boolean getStopped(int userId) {
310        return readUserState(userId).stopped;
311    }
312
313    void setStopped(boolean stop, int userId) {
314        modifyUserState(userId).stopped = stop;
315    }
316
317    boolean getNotLaunched(int userId) {
318        return readUserState(userId).notLaunched;
319    }
320
321    void setNotLaunched(boolean stop, int userId) {
322        modifyUserState(userId).notLaunched = stop;
323    }
324
325    boolean getHidden(int userId) {
326        return readUserState(userId).hidden;
327    }
328
329    void setHidden(boolean hidden, int userId) {
330        modifyUserState(userId).hidden = hidden;
331    }
332
333    boolean getBlockUninstall(int userId) {
334        return readUserState(userId).blockUninstall;
335    }
336
337    void setBlockUninstall(boolean blockUninstall, int userId) {
338        modifyUserState(userId).blockUninstall = blockUninstall;
339    }
340
341    void setUserState(int userId, int enabled, boolean installed, boolean stopped,
342            boolean notLaunched, boolean hidden,
343            String lastDisableAppCaller, ArraySet<String> enabledComponents,
344            ArraySet<String> disabledComponents, boolean blockUninstall, int domainVerifState,
345            int linkGeneration) {
346        PackageUserState state = modifyUserState(userId);
347        state.enabled = enabled;
348        state.installed = installed;
349        state.stopped = stopped;
350        state.notLaunched = notLaunched;
351        state.hidden = hidden;
352        state.lastDisableAppCaller = lastDisableAppCaller;
353        state.enabledComponents = enabledComponents;
354        state.disabledComponents = disabledComponents;
355        state.blockUninstall = blockUninstall;
356        state.domainVerificationStatus = domainVerifState;
357        state.appLinkGeneration = linkGeneration;
358    }
359
360    ArraySet<String> getEnabledComponents(int userId) {
361        return readUserState(userId).enabledComponents;
362    }
363
364    ArraySet<String> getDisabledComponents(int userId) {
365        return readUserState(userId).disabledComponents;
366    }
367
368    void setEnabledComponents(ArraySet<String> components, int userId) {
369        modifyUserState(userId).enabledComponents = components;
370    }
371
372    void setDisabledComponents(ArraySet<String> components, int userId) {
373        modifyUserState(userId).disabledComponents = components;
374    }
375
376    void setEnabledComponentsCopy(ArraySet<String> components, int userId) {
377        modifyUserState(userId).enabledComponents = components != null
378                ? new ArraySet<String>(components) : null;
379    }
380
381    void setDisabledComponentsCopy(ArraySet<String> components, int userId) {
382        modifyUserState(userId).disabledComponents = components != null
383                ? new ArraySet<String>(components) : null;
384    }
385
386    PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) {
387        PackageUserState state = modifyUserState(userId);
388        if (disabled && state.disabledComponents == null) {
389            state.disabledComponents = new ArraySet<String>(1);
390        }
391        if (enabled && state.enabledComponents == null) {
392            state.enabledComponents = new ArraySet<String>(1);
393        }
394        return state;
395    }
396
397    void addDisabledComponent(String componentClassName, int userId) {
398        modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName);
399    }
400
401    void addEnabledComponent(String componentClassName, int userId) {
402        modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName);
403    }
404
405    boolean enableComponentLPw(String componentClassName, int userId) {
406        PackageUserState state = modifyUserStateComponents(userId, false, true);
407        boolean changed = state.disabledComponents != null
408                ? state.disabledComponents.remove(componentClassName) : false;
409        changed |= state.enabledComponents.add(componentClassName);
410        return changed;
411    }
412
413    boolean disableComponentLPw(String componentClassName, int userId) {
414        PackageUserState state = modifyUserStateComponents(userId, true, false);
415        boolean changed = state.enabledComponents != null
416                ? state.enabledComponents.remove(componentClassName) : false;
417        changed |= state.disabledComponents.add(componentClassName);
418        return changed;
419    }
420
421    boolean restoreComponentLPw(String componentClassName, int userId) {
422        PackageUserState state = modifyUserStateComponents(userId, true, true);
423        boolean changed = state.disabledComponents != null
424                ? state.disabledComponents.remove(componentClassName) : false;
425        changed |= state.enabledComponents != null
426                ? state.enabledComponents.remove(componentClassName) : false;
427        return changed;
428    }
429
430    int getCurrentEnabledStateLPr(String componentName, int userId) {
431        PackageUserState state = readUserState(userId);
432        if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) {
433            return COMPONENT_ENABLED_STATE_ENABLED;
434        } else if (state.disabledComponents != null
435                && state.disabledComponents.contains(componentName)) {
436            return COMPONENT_ENABLED_STATE_DISABLED;
437        } else {
438            return COMPONENT_ENABLED_STATE_DEFAULT;
439        }
440    }
441
442    void removeUser(int userId) {
443        userState.delete(userId);
444    }
445
446    IntentFilterVerificationInfo getIntentFilterVerificationInfo() {
447        return verificationInfo;
448    }
449
450    void setIntentFilterVerificationInfo(IntentFilterVerificationInfo info) {
451        verificationInfo = info;
452    }
453
454    // Returns a packed value as a long:
455    //
456    // high 'int'-sized word: link status: undefined/ask/never/always.
457    // low 'int'-sized word: relative priority among 'always' results.
458    long getDomainVerificationStatusForUser(int userId) {
459        PackageUserState state = readUserState(userId);
460        long result = (long) state.appLinkGeneration;
461        result |= ((long) state.domainVerificationStatus) << 32;
462        return result;
463    }
464
465    void setDomainVerificationStatusForUser(final int status, int generation, int userId) {
466        PackageUserState state = modifyUserState(userId);
467        state.domainVerificationStatus = status;
468        if (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
469            state.appLinkGeneration = generation;
470        }
471    }
472
473    void clearDomainVerificationStatusForUser(int userId) {
474        modifyUserState(userId).domainVerificationStatus =
475                PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
476    }
477}
478