1/*
2 * Copyright (C) 2012 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 android.content.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_DISABLED_UNTIL_USED;
22import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
23import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
24import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
25import static android.content.pm.PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
26import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
27import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
28import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
29
30import android.util.ArraySet;
31
32import com.android.internal.util.ArrayUtils;
33
34/**
35 * Per-user state information about a package.
36 * @hide
37 */
38public class PackageUserState {
39    public long ceDataInode;
40    public boolean installed;
41    public boolean stopped;
42    public boolean notLaunched;
43    public boolean hidden; // Is the app restricted by owner / admin
44    public boolean suspended;
45    public boolean blockUninstall;
46    public int enabled;
47    public String lastDisableAppCaller;
48    public int domainVerificationStatus;
49    public int appLinkGeneration;
50
51    public ArraySet<String> disabledComponents;
52    public ArraySet<String> enabledComponents;
53
54    public PackageUserState() {
55        installed = true;
56        hidden = false;
57        suspended = false;
58        enabled = COMPONENT_ENABLED_STATE_DEFAULT;
59        domainVerificationStatus =
60                PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
61    }
62
63    public PackageUserState(PackageUserState o) {
64        ceDataInode = o.ceDataInode;
65        installed = o.installed;
66        stopped = o.stopped;
67        notLaunched = o.notLaunched;
68        hidden = o.hidden;
69        suspended = o.suspended;
70        blockUninstall = o.blockUninstall;
71        enabled = o.enabled;
72        lastDisableAppCaller = o.lastDisableAppCaller;
73        domainVerificationStatus = o.domainVerificationStatus;
74        appLinkGeneration = o.appLinkGeneration;
75        disabledComponents = ArrayUtils.cloneOrNull(o.disabledComponents);
76        enabledComponents = ArrayUtils.cloneOrNull(o.enabledComponents);
77    }
78
79    /**
80     * Test if this package is installed.
81     */
82    public boolean isInstalled(int flags) {
83        return (this.installed && !this.hidden)
84                || (flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0;
85    }
86
87    /**
88     * Test if the given component is considered installed, enabled and a match
89     * for the given flags.
90     *
91     * <p>
92     * Expects at least one of {@link PackageManager#MATCH_DIRECT_BOOT_AWARE} and
93     * {@link PackageManager#MATCH_DIRECT_BOOT_UNAWARE} are specified in {@code flags}.
94     * </p>
95     */
96    public boolean isMatch(ComponentInfo componentInfo, int flags) {
97        if (!isInstalled(flags)) return false;
98        if (!isEnabled(componentInfo, flags)) return false;
99
100        if ((flags & MATCH_SYSTEM_ONLY) != 0) {
101            if (!componentInfo.applicationInfo.isSystemApp()) {
102                return false;
103            }
104        }
105
106        final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
107                && !componentInfo.directBootAware;
108        final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
109                && componentInfo.directBootAware;
110        return matchesUnaware || matchesAware;
111    }
112
113    /**
114     * Test if the given component is considered enabled.
115     */
116    public boolean isEnabled(ComponentInfo componentInfo, int flags) {
117        if ((flags & MATCH_DISABLED_COMPONENTS) != 0) {
118            return true;
119        }
120
121        // First check if the overall package is disabled; if the package is
122        // enabled then fall through to check specific component
123        switch (this.enabled) {
124            case COMPONENT_ENABLED_STATE_DISABLED:
125            case COMPONENT_ENABLED_STATE_DISABLED_USER:
126                return false;
127            case COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
128                if ((flags & MATCH_DISABLED_UNTIL_USED_COMPONENTS) == 0) {
129                    return false;
130                }
131            case COMPONENT_ENABLED_STATE_DEFAULT:
132                if (!componentInfo.applicationInfo.enabled) {
133                    return false;
134                }
135            case COMPONENT_ENABLED_STATE_ENABLED:
136                break;
137        }
138
139        // Check if component has explicit state before falling through to
140        // the manifest default
141        if (ArrayUtils.contains(this.enabledComponents, componentInfo.name)) {
142            return true;
143        }
144        if (ArrayUtils.contains(this.disabledComponents, componentInfo.name)) {
145            return false;
146        }
147
148        return componentInfo.enabled;
149    }
150}
151