PackageSettingBase.java revision 2f5811dcfd840e149851a9333e27ef3cdddf7a46
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    boolean getInstantApp(int userId) {
398        return readUserState(userId).instantApp;
399    }
400
401    void setInstantApp(boolean instantApp, int userId) {
402        modifyUserState(userId).instantApp = instantApp;
403    }
404
405    void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped,
406            boolean notLaunched, boolean hidden, boolean suspended, boolean instantApp,
407            String lastDisableAppCaller, ArraySet<String> enabledComponents,
408            ArraySet<String> disabledComponents, boolean blockUninstall,
409            int domainVerifState, int linkGeneration, int installReason) {
410        PackageUserState state = modifyUserState(userId);
411        state.ceDataInode = ceDataInode;
412        state.enabled = enabled;
413        state.installed = installed;
414        state.stopped = stopped;
415        state.notLaunched = notLaunched;
416        state.hidden = hidden;
417        state.suspended = suspended;
418        state.lastDisableAppCaller = lastDisableAppCaller;
419        state.enabledComponents = enabledComponents;
420        state.disabledComponents = disabledComponents;
421        state.blockUninstall = blockUninstall;
422        state.domainVerificationStatus = domainVerifState;
423        state.appLinkGeneration = linkGeneration;
424        state.installReason = installReason;
425        state.instantApp = instantApp;
426    }
427
428    ArraySet<String> getEnabledComponents(int userId) {
429        return readUserState(userId).enabledComponents;
430    }
431
432    ArraySet<String> getDisabledComponents(int userId) {
433        return readUserState(userId).disabledComponents;
434    }
435
436    void setEnabledComponents(ArraySet<String> components, int userId) {
437        modifyUserState(userId).enabledComponents = components;
438    }
439
440    void setDisabledComponents(ArraySet<String> components, int userId) {
441        modifyUserState(userId).disabledComponents = components;
442    }
443
444    void setEnabledComponentsCopy(ArraySet<String> components, int userId) {
445        modifyUserState(userId).enabledComponents = components != null
446                ? new ArraySet<String>(components) : null;
447    }
448
449    void setDisabledComponentsCopy(ArraySet<String> components, int userId) {
450        modifyUserState(userId).disabledComponents = components != null
451                ? new ArraySet<String>(components) : null;
452    }
453
454    PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) {
455        PackageUserState state = modifyUserState(userId);
456        if (disabled && state.disabledComponents == null) {
457            state.disabledComponents = new ArraySet<String>(1);
458        }
459        if (enabled && state.enabledComponents == null) {
460            state.enabledComponents = new ArraySet<String>(1);
461        }
462        return state;
463    }
464
465    void addDisabledComponent(String componentClassName, int userId) {
466        modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName);
467    }
468
469    void addEnabledComponent(String componentClassName, int userId) {
470        modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName);
471    }
472
473    boolean enableComponentLPw(String componentClassName, int userId) {
474        PackageUserState state = modifyUserStateComponents(userId, false, true);
475        boolean changed = state.disabledComponents != null
476                ? state.disabledComponents.remove(componentClassName) : false;
477        changed |= state.enabledComponents.add(componentClassName);
478        return changed;
479    }
480
481    boolean disableComponentLPw(String componentClassName, int userId) {
482        PackageUserState state = modifyUserStateComponents(userId, true, false);
483        boolean changed = state.enabledComponents != null
484                ? state.enabledComponents.remove(componentClassName) : false;
485        changed |= state.disabledComponents.add(componentClassName);
486        return changed;
487    }
488
489    boolean restoreComponentLPw(String componentClassName, int userId) {
490        PackageUserState state = modifyUserStateComponents(userId, true, true);
491        boolean changed = state.disabledComponents != null
492                ? state.disabledComponents.remove(componentClassName) : false;
493        changed |= state.enabledComponents != null
494                ? state.enabledComponents.remove(componentClassName) : false;
495        return changed;
496    }
497
498    int getCurrentEnabledStateLPr(String componentName, int userId) {
499        PackageUserState state = readUserState(userId);
500        if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) {
501            return COMPONENT_ENABLED_STATE_ENABLED;
502        } else if (state.disabledComponents != null
503                && state.disabledComponents.contains(componentName)) {
504            return COMPONENT_ENABLED_STATE_DISABLED;
505        } else {
506            return COMPONENT_ENABLED_STATE_DEFAULT;
507        }
508    }
509
510    void removeUser(int userId) {
511        userState.delete(userId);
512    }
513
514    IntentFilterVerificationInfo getIntentFilterVerificationInfo() {
515        return verificationInfo;
516    }
517
518    void setIntentFilterVerificationInfo(IntentFilterVerificationInfo info) {
519        verificationInfo = info;
520    }
521
522    // Returns a packed value as a long:
523    //
524    // high 'int'-sized word: link status: undefined/ask/never/always.
525    // low 'int'-sized word: relative priority among 'always' results.
526    long getDomainVerificationStatusForUser(int userId) {
527        PackageUserState state = readUserState(userId);
528        long result = (long) state.appLinkGeneration;
529        result |= ((long) state.domainVerificationStatus) << 32;
530        return result;
531    }
532
533    void setDomainVerificationStatusForUser(final int status, int generation, int userId) {
534        PackageUserState state = modifyUserState(userId);
535        state.domainVerificationStatus = status;
536        if (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
537            state.appLinkGeneration = generation;
538        }
539    }
540
541    void clearDomainVerificationStatusForUser(int userId) {
542        modifyUserState(userId).domainVerificationStatus =
543                PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
544    }
545}
546