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