OverlayManagerServiceImpl.java revision 607223f3b7a1c4dc3ac995f742f8d2da50d85ffc
1eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad/*
2eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * Copyright (C) 2016 The Android Open Source Project
3eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad *
4eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * Licensed under the Apache License, Version 2.0 (the "License");
5eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * you may not use this file except in compliance with the License.
6eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * You may obtain a copy of the License at
7eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad *
8eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad *      http://www.apache.org/licenses/LICENSE-2.0
9eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad *
10eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * Unless required by applicable law or agreed to in writing, software
11eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * distributed under the License is distributed on an "AS IS" BASIS,
12eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * See the License for the specific language governing permissions and
14eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * limitations under the License.
15eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad */
16eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
17eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadpackage com.android.server.om;
18eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
19eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport static android.content.om.OverlayInfo.STATE_DISABLED;
20eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport static android.content.om.OverlayInfo.STATE_ENABLED;
21eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport static android.content.om.OverlayInfo.STATE_MISSING_TARGET;
22eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport static android.content.om.OverlayInfo.STATE_NO_IDMAP;
23db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstadimport static android.content.om.OverlayInfo.STATE_OVERLAY_UPGRADING;
24db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstadimport static android.content.om.OverlayInfo.STATE_TARGET_UPGRADING;
25eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
26eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport static com.android.server.om.OverlayManagerService.DEBUG;
27eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport static com.android.server.om.OverlayManagerService.TAG;
28eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
29eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.annotation.NonNull;
30eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.annotation.Nullable;
31eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.content.om.OverlayInfo;
32eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.content.pm.PackageInfo;
33a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinskiimport android.text.TextUtils;
34eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.util.ArrayMap;
35eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.util.ArraySet;
36eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.util.Slog;
37eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
38eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.io.PrintWriter;
39eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.util.ArrayList;
40eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.util.Iterator;
41eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.util.List;
42eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.util.Map;
43607223f3b7a1c4dc3ac995f742f8d2da50d85ffcNarayan Kamathimport java.util.Objects;
44eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.util.Set;
45eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
46eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad/**
47eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * Internal implementation of OverlayManagerService.
48eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad *
49eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * Methods in this class should only be called by the OverlayManagerService.
50eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * This class is not thread-safe; the caller is expected to ensure the
51eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * necessary thread synchronization.
52eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad *
53eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * @see OverlayManagerService
54eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad */
55eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadfinal class OverlayManagerServiceImpl {
56db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad    // Flags to use in conjunction with updateState.
57db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad    private static final int FLAG_TARGET_IS_UPGRADING = 1<<0;
58db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad    private static final int FLAG_OVERLAY_IS_UPGRADING = 1<<1;
59db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
60eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    private final PackageManagerHelper mPackageManager;
61eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    private final IdmapManager mIdmapManager;
62eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    private final OverlayManagerSettings mSettings;
63a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski    private final Set<String> mDefaultOverlays;
64c745f42169df6687a764e48b65878f22965c1530Adam Lesinski    private final OverlayChangeListener mListener;
65eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
66eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    OverlayManagerServiceImpl(@NonNull final PackageManagerHelper packageManager,
67eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            @NonNull final IdmapManager idmapManager,
68a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski            @NonNull final OverlayManagerSettings settings,
69c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            @NonNull final Set<String> defaultOverlays,
70c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            @NonNull final OverlayChangeListener listener) {
71eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        mPackageManager = packageManager;
72eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        mIdmapManager = idmapManager;
73eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        mSettings = settings;
74a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski        mDefaultOverlays = defaultOverlays;
75c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        mListener = listener;
76eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
77eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
78ada8deb43649aed879ceba28daee4af69ae0cc8dAdam Lesinski    /**
79ada8deb43649aed879ceba28daee4af69ae0cc8dAdam Lesinski     * Call this to synchronize the Settings for a user with what PackageManager knows about a user.
80ada8deb43649aed879ceba28daee4af69ae0cc8dAdam Lesinski     * Returns a list of target packages that must refresh their overlays. This list is the union
81eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad     * of two sets: the set of targets with currently active overlays, and the
82eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad     * set of targets that had, but no longer have, active overlays.
83eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad     */
84ada8deb43649aed879ceba28daee4af69ae0cc8dAdam Lesinski    ArrayList<String> updateOverlaysForUser(final int newUserId) {
85eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
86ada8deb43649aed879ceba28daee4af69ae0cc8dAdam Lesinski            Slog.d(TAG, "updateOverlaysForUser newUserId=" + newUserId);
87eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
88eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
89eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final Set<String> packagesToUpdateAssets = new ArraySet<>();
90eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final ArrayMap<String, List<OverlayInfo>> tmp = mSettings.getOverlaysForUser(newUserId);
91eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final int tmpSize = tmp.size();
92eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final ArrayMap<String, OverlayInfo> storedOverlayInfos = new ArrayMap<>(tmpSize);
93eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        for (int i = 0; i < tmpSize; i++) {
94eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final List<OverlayInfo> chunk = tmp.valueAt(i);
95eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final int chunkSize = chunk.size();
96eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            for (int j = 0; j < chunkSize; j++) {
97eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                final OverlayInfo oi = chunk.get(j);
98eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                storedOverlayInfos.put(oi.packageName, oi);
99eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
100eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
101eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
102eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        List<PackageInfo> overlayPackages = mPackageManager.getOverlayPackages(newUserId);
103eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final int overlayPackagesSize = overlayPackages.size();
104eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        for (int i = 0; i < overlayPackagesSize; i++) {
105eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final PackageInfo overlayPackage = overlayPackages.get(i);
106eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final OverlayInfo oi = storedOverlayInfos.get(overlayPackage.packageName);
107c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos            if (oi == null || !oi.targetPackageName.equals(overlayPackage.overlayTarget)
108607223f3b7a1c4dc3ac995f742f8d2da50d85ffcNarayan Kamath                    || !Objects.equals(oi.category, overlayPackage.overlayCategory)) {
109a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski                // Update the overlay if it didn't exist or had the wrong target package.
110eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                mSettings.init(overlayPackage.packageName, newUserId,
111eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                        overlayPackage.overlayTarget,
11242d53f6b1883e3db514ad8d105d23fe6a1e9a59bJaekyun Seok                        overlayPackage.applicationInfo.getBaseCodePath(),
113c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                        overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority,
114c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                        overlayPackage.overlayCategory);
115a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski
116a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski                if (oi == null) {
117a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski                    // This overlay does not exist in our settings.
118ab56b9d9dfddcfb26dfdb553220719412df1e139Adam Lesinski                    if (overlayPackage.isStaticOverlayPackage() ||
11984d7f1ecfb962cb6c8e4adefa077729128c26d3bJaekyun Seok                            mDefaultOverlays.contains(overlayPackage.packageName)) {
120a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski                        // Enable this overlay by default.
121d11c5510b13171878f8d6f6a3424c7b2418c3031Adam Lesinski                        if (DEBUG) {
122d11c5510b13171878f8d6f6a3424c7b2418c3031Adam Lesinski                            Slog.d(TAG, "Enabling overlay " + overlayPackage.packageName
123d11c5510b13171878f8d6f6a3424c7b2418c3031Adam Lesinski                                    + " for user " + newUserId + " by default");
124d11c5510b13171878f8d6f6a3424c7b2418c3031Adam Lesinski                        }
125a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski                        mSettings.setEnabled(overlayPackage.packageName, newUserId, true);
126a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski                    }
127a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski                } else {
128a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski                    // The targetPackageName we have stored doesn't match the overlay's target.
129a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski                    // Queue the old target for an update as well.
130a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski                    packagesToUpdateAssets.add(oi.targetPackageName);
131a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski                }
132eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
133eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
134eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            try {
135db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                updateState(overlayPackage.overlayTarget, overlayPackage.packageName, newUserId, 0);
136eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            } catch (OverlayManagerSettings.BadKeyException e) {
137eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                Slog.e(TAG, "failed to update settings", e);
138eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                mSettings.remove(overlayPackage.packageName, newUserId);
139eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
140eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
141eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            packagesToUpdateAssets.add(overlayPackage.overlayTarget);
142eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            storedOverlayInfos.remove(overlayPackage.packageName);
143eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
144eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
145eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // any OverlayInfo left in storedOverlayInfos is no longer
146eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // installed and should be removed
147eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final int storedOverlayInfosSize = storedOverlayInfos.size();
148eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        for (int i = 0; i < storedOverlayInfosSize; i++) {
149c0bba8b18b41356721c2ebb25af83bc5bb5a74b0Mårten Kongstad            final OverlayInfo oi = storedOverlayInfos.valueAt(i);
150eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            mSettings.remove(oi.packageName, oi.userId);
151eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            removeIdmapIfPossible(oi);
152eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            packagesToUpdateAssets.add(oi.targetPackageName);
153eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
154eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
155eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // remove target packages that are not installed
156eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final Iterator<String> iter = packagesToUpdateAssets.iterator();
157eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        while (iter.hasNext()) {
158eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            String targetPackageName = iter.next();
159eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            if (mPackageManager.getPackageInfo(targetPackageName, newUserId) == null) {
160eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                iter.remove();
161eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
162eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
163a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski        return new ArrayList<>(packagesToUpdateAssets);
164eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
165eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
166eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onUserRemoved(final int userId) {
167eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
168eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.d(TAG, "onUserRemoved userId=" + userId);
169eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
170eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        mSettings.removeUser(userId);
171eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
172eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
173eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onTargetPackageAdded(@NonNull final String packageName, final int userId) {
174eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
175eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.d(TAG, "onTargetPackageAdded packageName=" + packageName + " userId=" + userId);
176eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
177eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
178db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (updateAllOverlaysForTarget(packageName, userId, 0)) {
179b6f19c98604fa25e2e33d5322f5eaa8acf3b4124Mårten Kongstad            mListener.onOverlaysChanged(packageName, userId);
180b6f19c98604fa25e2e33d5322f5eaa8acf3b4124Mårten Kongstad        }
181eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
182eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
183eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onTargetPackageChanged(@NonNull final String packageName, final int userId) {
184eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
185eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.d(TAG, "onTargetPackageChanged packageName=" + packageName + " userId=" + userId);
186eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
187eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
188db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (updateAllOverlaysForTarget(packageName, userId, 0)) {
189560830c9f06d07d97055426420709733571ca05bTodd Kennedy            mListener.onOverlaysChanged(packageName, userId);
190560830c9f06d07d97055426420709733571ca05bTodd Kennedy        }
191eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
192eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
193eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onTargetPackageUpgrading(@NonNull final String packageName, final int userId) {
194eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
195db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.d(TAG, "onTargetPackageUpgrading packageName=" + packageName + " userId="
196db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                    + userId);
197eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
198eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
199db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (updateAllOverlaysForTarget(packageName, userId, FLAG_TARGET_IS_UPGRADING)) {
200560830c9f06d07d97055426420709733571ca05bTodd Kennedy            mListener.onOverlaysChanged(packageName, userId);
201560830c9f06d07d97055426420709733571ca05bTodd Kennedy        }
202eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
203eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
204eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onTargetPackageUpgraded(@NonNull final String packageName, final int userId) {
205eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
206eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.d(TAG, "onTargetPackageUpgraded packageName=" + packageName + " userId=" + userId);
207eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
208eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
209db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (updateAllOverlaysForTarget(packageName, userId, 0)) {
210560830c9f06d07d97055426420709733571ca05bTodd Kennedy            mListener.onOverlaysChanged(packageName, userId);
211560830c9f06d07d97055426420709733571ca05bTodd Kennedy        }
212eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
213eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
214eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onTargetPackageRemoved(@NonNull final String packageName, final int userId) {
215eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
216eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.d(TAG, "onTargetPackageRemoved packageName=" + packageName + " userId=" + userId);
217eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
218eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
219db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (updateAllOverlaysForTarget(packageName, userId, 0)) {
220b6f19c98604fa25e2e33d5322f5eaa8acf3b4124Mårten Kongstad            mListener.onOverlaysChanged(packageName, userId);
221b6f19c98604fa25e2e33d5322f5eaa8acf3b4124Mårten Kongstad        }
222eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
223eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
224c745f42169df6687a764e48b65878f22965c1530Adam Lesinski    /**
225c745f42169df6687a764e48b65878f22965c1530Adam Lesinski     * Returns true if the settings were modified for this target.
226c745f42169df6687a764e48b65878f22965c1530Adam Lesinski     */
227db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad    private boolean updateAllOverlaysForTarget(@NonNull final String targetPackageName,
228db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            final int userId, final int flags) {
229c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        boolean modified = false;
230db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        final List<OverlayInfo> ois = mSettings.getOverlaysForTarget(targetPackageName, userId);
231eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final int N = ois.size();
232eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        for (int i = 0; i < N; i++) {
233eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final OverlayInfo oi = ois.get(i);
234db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            final PackageInfo overlayPackage = mPackageManager.getPackageInfo(oi.packageName,
235db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                    userId);
236eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            if (overlayPackage == null) {
237c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                modified |= mSettings.remove(oi.packageName, oi.userId);
238eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                removeIdmapIfPossible(oi);
239eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            } else {
240eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                try {
241db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                    modified |= updateState(targetPackageName, oi.packageName, userId, flags);
242eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                } catch (OverlayManagerSettings.BadKeyException e) {
243eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                    Slog.e(TAG, "failed to update settings", e);
244c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                    modified |= mSettings.remove(oi.packageName, userId);
245eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                }
246eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
247eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
248c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        return modified;
249eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
250eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
251eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onOverlayPackageAdded(@NonNull final String packageName, final int userId) {
252eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
253eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.d(TAG, "onOverlayPackageAdded packageName=" + packageName + " userId=" + userId);
254eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
255eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
256eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
257eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (overlayPackage == null) {
258eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.w(TAG, "overlay package " + packageName + " was added, but couldn't be found");
259eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            onOverlayPackageRemoved(packageName, userId);
260eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return;
261eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
262eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
263eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        mSettings.init(packageName, userId, overlayPackage.overlayTarget,
264ab56b9d9dfddcfb26dfdb553220719412df1e139Adam Lesinski                overlayPackage.applicationInfo.getBaseCodePath(),
265c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority,
266c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                overlayPackage.overlayCategory);
267eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        try {
268db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            if (updateState(overlayPackage.overlayTarget, packageName, userId, 0)) {
269c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId);
270c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            }
271eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        } catch (OverlayManagerSettings.BadKeyException e) {
272eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.e(TAG, "failed to update settings", e);
273eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            mSettings.remove(packageName, userId);
274eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
275eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
276eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
277eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onOverlayPackageChanged(@NonNull final String packageName, final int userId) {
278db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (DEBUG) {
279db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.d(TAG, "onOverlayPackageChanged packageName=" + packageName + " userId=" + userId);
280db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
281db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
282db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        try {
283db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId);
284db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            if (updateState(oi.targetPackageName, packageName, userId, 0)) {
285db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                mListener.onOverlaysChanged(oi.targetPackageName, userId);
286db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            }
287db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        } catch (OverlayManagerSettings.BadKeyException e) {
288db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.e(TAG, "failed to update settings", e);
289db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
290eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
291eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
292eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onOverlayPackageUpgrading(@NonNull final String packageName, final int userId) {
293db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (DEBUG) {
294db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.d(TAG, "onOverlayPackageUpgrading packageName=" + packageName + " userId="
295db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                    + userId);
296db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
297db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
298db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        try {
299db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId);
300db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            if (updateState(oi.targetPackageName, packageName, userId, FLAG_OVERLAY_IS_UPGRADING)) {
301db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                removeIdmapIfPossible(oi);
302db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                mListener.onOverlaysChanged(oi.targetPackageName, userId);
303db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            }
304db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        } catch (OverlayManagerSettings.BadKeyException e) {
305db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.e(TAG, "failed to update settings", e);
306db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
307eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
308eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
309eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onOverlayPackageUpgraded(@NonNull final String packageName, final int userId) {
310db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (DEBUG) {
311db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.d(TAG, "onOverlayPackageUpgraded packageName=" + packageName + " userId="
312db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                    + userId);
313db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
314db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
315db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        final PackageInfo pkg = mPackageManager.getPackageInfo(packageName, userId);
316db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (pkg == null) {
317db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.w(TAG, "overlay package " + packageName + " was upgraded, but couldn't be found");
318db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            onOverlayPackageRemoved(packageName, userId);
319db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            return;
320db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
321db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
322db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        try {
323db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            final OverlayInfo oldOi = mSettings.getOverlayInfo(packageName, userId);
324db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            if (!oldOi.targetPackageName.equals(pkg.overlayTarget)) {
325db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                mSettings.init(packageName, userId, pkg.overlayTarget,
326db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                        pkg.applicationInfo.getBaseCodePath(), pkg.isStaticOverlayPackage(),
327c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                        pkg.overlayPriority, pkg.overlayCategory);
328db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            }
329db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
330db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            if (updateState(pkg.overlayTarget, packageName, userId, 0)) {
331db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                mListener.onOverlaysChanged(pkg.overlayTarget, userId);
332db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            }
333db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        } catch (OverlayManagerSettings.BadKeyException e) {
334db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.e(TAG, "failed to update settings", e);
335db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
336eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
337eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
338eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onOverlayPackageRemoved(@NonNull final String packageName, final int userId) {
339b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski        try {
340b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski            final OverlayInfo overlayInfo = mSettings.getOverlayInfo(packageName, userId);
341b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski            if (mSettings.remove(packageName, userId)) {
342b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski                removeIdmapIfPossible(overlayInfo);
343b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski                if (overlayInfo.isEnabled()) {
344b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski                    // Only trigger updates if the overlay was enabled.
345b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski                    mListener.onOverlaysChanged(overlayInfo.targetPackageName, userId);
346b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski                }
347b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski            }
348b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski        } catch (OverlayManagerSettings.BadKeyException e) {
349b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski            Slog.e(TAG, "failed to remove overlay", e);
350b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski        }
351eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
352eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
353eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    OverlayInfo getOverlayInfo(@NonNull final String packageName, final int userId) {
354eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        try {
355eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return mSettings.getOverlayInfo(packageName, userId);
356eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        } catch (OverlayManagerSettings.BadKeyException e) {
357eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return null;
358eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
359eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
360eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
361eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    List<OverlayInfo> getOverlayInfosForTarget(@NonNull final String targetPackageName,
362eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final int userId) {
363eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        return mSettings.getOverlaysForTarget(targetPackageName, userId);
364eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
365eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
366eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    Map<String, List<OverlayInfo>> getOverlaysForUser(final int userId) {
367eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        return mSettings.getOverlaysForUser(userId);
368eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
369eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
370eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    boolean setEnabled(@NonNull final String packageName, final boolean enable,
371eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final int userId) {
372eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
373eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.d(TAG, String.format("setEnabled packageName=%s enable=%s userId=%d",
374eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                        packageName, enable, userId));
375eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
376eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
377eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
378eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (overlayPackage == null) {
379eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return false;
380eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
381c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
382c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        // Ignore static overlays.
383ab56b9d9dfddcfb26dfdb553220719412df1e139Adam Lesinski        if (overlayPackage.isStaticOverlayPackage()) {
3840434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok            return false;
3850434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok        }
386eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
387eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        try {
388eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId);
389c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            boolean modified = mSettings.setEnabled(packageName, userId, enable);
390db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            modified |= updateState(oi.targetPackageName, oi.packageName, userId, 0);
391c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
392c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            if (modified) {
393c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                mListener.onOverlaysChanged(oi.targetPackageName, userId);
394c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            }
395929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            return true;
396929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        } catch (OverlayManagerSettings.BadKeyException e) {
397929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            return false;
398929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        }
399929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk    }
400929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk
401c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos    boolean setEnabledExclusive(@NonNull final String packageName, boolean withinCategory,
402c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos            final int userId) {
403929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        if (DEBUG) {
404c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos            Slog.d(TAG, String.format("setEnabledExclusive packageName=%s"
405c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                    + " withinCategory=%s userId=%d", packageName, withinCategory, userId));
406929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        }
407929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk
408929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
409929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        if (overlayPackage == null) {
410929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            return false;
411929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        }
412929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk
413929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        try {
414929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId);
415db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            final String targetPackageName = oi.targetPackageName;
416c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
417db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            List<OverlayInfo> allOverlays = getOverlayInfosForTarget(targetPackageName, userId);
418929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk
419c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            boolean modified = false;
420c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
421929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            // Disable all other overlays.
422929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            allOverlays.remove(oi);
423929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            for (int i = 0; i < allOverlays.size(); i++) {
424c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                final String disabledOverlayPackageName = allOverlays.get(i).packageName;
425c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                final PackageInfo disabledOverlayPackageInfo = mPackageManager.getPackageInfo(
426c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                        disabledOverlayPackageName, userId);
427c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                if (disabledOverlayPackageInfo == null) {
428c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                    modified |= mSettings.remove(disabledOverlayPackageName, userId);
429c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                    continue;
430c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                }
431c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
432ab56b9d9dfddcfb26dfdb553220719412df1e139Adam Lesinski                if (disabledOverlayPackageInfo.isStaticOverlayPackage()) {
433c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                    // Don't touch static overlays.
434c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                    continue;
435c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                }
436607223f3b7a1c4dc3ac995f742f8d2da50d85ffcNarayan Kamath                if (withinCategory && !Objects.equals(disabledOverlayPackageInfo.overlayCategory,
437c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                        oi.category)) {
438c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                    // Don't touch overlays from other categories.
439c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                    continue;
440c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                }
441c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
442c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                // Disable the overlay.
443c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                modified |= mSettings.setEnabled(disabledOverlayPackageName, userId, false);
444db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                modified |= updateState(targetPackageName, disabledOverlayPackageName, userId, 0);
445929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            }
446929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk
447c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            // Enable the selected overlay.
448c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            modified |= mSettings.setEnabled(packageName, userId, true);
449db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            modified |= updateState(targetPackageName, packageName, userId, 0);
450c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
451c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            if (modified) {
452db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                mListener.onOverlaysChanged(targetPackageName, userId);
453c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            }
454eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return true;
455eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        } catch (OverlayManagerSettings.BadKeyException e) {
456eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return false;
457eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
458eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
459eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
460c745f42169df6687a764e48b65878f22965c1530Adam Lesinski    private boolean isPackageUpdatableOverlay(@NonNull final String packageName, final int userId) {
4610434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
462ab56b9d9dfddcfb26dfdb553220719412df1e139Adam Lesinski        if (overlayPackage == null || overlayPackage.isStaticOverlayPackage()) {
4630434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok            return false;
4640434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok        }
4650434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok        return true;
4660434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok    }
4670434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok
468eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    boolean setPriority(@NonNull final String packageName,
469eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            @NonNull final String newParentPackageName, final int userId) {
470c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (DEBUG) {
471c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            Slog.d(TAG, "setPriority packageName=" + packageName + " newParentPackageName="
472c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                    + newParentPackageName + " userId=" + userId);
473c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
474c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
475c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (!isPackageUpdatableOverlay(packageName, userId)) {
476c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            return false;
477c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
478c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
479c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
480c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (overlayPackage == null) {
481c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            return false;
482c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
483c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
484c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (mSettings.setPriority(packageName, newParentPackageName, userId)) {
485c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId);
486c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
487c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        return true;
488eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
489eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
490eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    boolean setHighestPriority(@NonNull final String packageName, final int userId) {
491c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (DEBUG) {
492c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            Slog.d(TAG, "setHighestPriority packageName=" + packageName + " userId=" + userId);
493c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
494c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
495c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (!isPackageUpdatableOverlay(packageName, userId)) {
496c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            return false;
497c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
498c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
499c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
500c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (overlayPackage == null) {
501c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            return false;
502c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
503c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
504c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (mSettings.setHighestPriority(packageName, userId)) {
505c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId);
506c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
507c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        return true;
508eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
509eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
510eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    boolean setLowestPriority(@NonNull final String packageName, final int userId) {
511c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (DEBUG) {
512c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            Slog.d(TAG, "setLowestPriority packageName=" + packageName + " userId=" + userId);
513c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
514c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
515c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (!isPackageUpdatableOverlay(packageName, userId)) {
516c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            return false;
517c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
518c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
519c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
520c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (overlayPackage == null) {
521c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            return false;
522c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
523c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
524c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (mSettings.setLowestPriority(packageName, userId)) {
525c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId);
526c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
527c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        return true;
528eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
529eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
530eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onDump(@NonNull final PrintWriter pw) {
531eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        mSettings.dump(pw);
532a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski        pw.println("Default overlays: " + TextUtils.join(";", mDefaultOverlays));
533eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
534eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
535eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    List<String> getEnabledOverlayPackageNames(@NonNull final String targetPackageName,
536eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final int userId) {
537db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        final List<OverlayInfo> overlays = mSettings.getOverlaysForTarget(targetPackageName,
538db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                userId);
539eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final List<String> paths = new ArrayList<>(overlays.size());
540eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final int N = overlays.size();
541eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        for (int i = 0; i < N; i++) {
542eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final OverlayInfo oi = overlays.get(i);
543eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            if (oi.isEnabled()) {
544eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                paths.add(oi.packageName);
545eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
546eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
547eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        return paths;
548eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
549eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
550c745f42169df6687a764e48b65878f22965c1530Adam Lesinski    /**
551c745f42169df6687a764e48b65878f22965c1530Adam Lesinski     * Returns true if the settings/state was modified, false otherwise.
552c745f42169df6687a764e48b65878f22965c1530Adam Lesinski     */
553db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad    private boolean updateState(@NonNull final String targetPackageName,
554db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            @NonNull final String overlayPackageName, final int userId, final int flags)
555c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            throws OverlayManagerSettings.BadKeyException {
556db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
557db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        final PackageInfo targetPackage = mPackageManager.getPackageInfo(targetPackageName, userId);
558db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(overlayPackageName,
559db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                userId);
560db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
5610434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok        // Static RROs targeting to "android", ie framework-res.apk, are handled by native layers.
562db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (targetPackage != null && overlayPackage != null &&
563db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                !("android".equals(targetPackageName)
564ab56b9d9dfddcfb26dfdb553220719412df1e139Adam Lesinski                        && overlayPackage.isStaticOverlayPackage())) {
565eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            mIdmapManager.createIdmap(targetPackage, overlayPackage, userId);
566eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
567eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
568db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        boolean modified = false;
569db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (overlayPackage != null) {
570db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            modified |= mSettings.setBaseCodePath(overlayPackageName, userId,
571db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                    overlayPackage.applicationInfo.getBaseCodePath());
572db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
573eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
574db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        final @OverlayInfo.State int currentState = mSettings.getState(overlayPackageName, userId);
575db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        final @OverlayInfo.State int newState = calculateNewState(targetPackage, overlayPackage,
576db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                userId, flags);
577eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (currentState != newState) {
578eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            if (DEBUG) {
579eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                Slog.d(TAG, String.format("%s:%d: %s -> %s",
580db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                            overlayPackageName, userId,
581eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                            OverlayInfo.stateToString(currentState),
582eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                            OverlayInfo.stateToString(newState)));
583eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
584db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            modified |= mSettings.setState(overlayPackageName, userId, newState);
585eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
586c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        return modified;
587eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
588eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
589db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad    private @OverlayInfo.State int calculateNewState(@Nullable final PackageInfo targetPackage,
590db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            @Nullable final PackageInfo overlayPackage, final int userId, final int flags)
591eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        throws OverlayManagerSettings.BadKeyException {
592db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
593db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if ((flags & FLAG_TARGET_IS_UPGRADING) != 0) {
594db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            return STATE_TARGET_UPGRADING;
595db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
596db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
597db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if ((flags & FLAG_OVERLAY_IS_UPGRADING) != 0) {
598db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            return STATE_OVERLAY_UPGRADING;
599db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
600db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
601db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        // assert expectation on overlay package: can only be null if the flags are used
602db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (DEBUG && overlayPackage == null) {
603db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            throw new IllegalArgumentException("null overlay package not compatible with no flags");
604db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
605db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
606eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (targetPackage == null) {
607eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return STATE_MISSING_TARGET;
608eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
609eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
610eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (!mIdmapManager.idmapExists(overlayPackage, userId)) {
611eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return STATE_NO_IDMAP;
612eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
613eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
614eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final boolean enabled = mSettings.getEnabled(overlayPackage.packageName, userId);
615eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        return enabled ? STATE_ENABLED : STATE_DISABLED;
616eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
617eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
618eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    private void removeIdmapIfPossible(@NonNull final OverlayInfo oi) {
619eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // For a given package, all Android users share the same idmap file.
620eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // This works because Android currently does not support users to
621eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // install different versions of the same package. It also means we
622eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // cannot remove an idmap file if any user still needs it.
623eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        //
624eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // When/if the Android framework allows different versions of the same
625eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // package to be installed for different users, idmap file handling
626eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // should be revised:
627eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        //
628eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // - an idmap file should be unique for each {user, package} pair
629eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        //
630eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // - the path to the idmap file should be passed to the native Asset
631eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        //   Manager layers, just like the path to the apk is passed today
632eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        //
633eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // As part of that change, calls to this method should be replaced by
634eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // direct calls to IdmapManager.removeIdmap, without looping over all
635eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // users.
636eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
637eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (!mIdmapManager.idmapExists(oi)) {
638eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return;
639eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
640c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        final int[] userIds = mSettings.getUsers();
641c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        for (int userId : userIds) {
642eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            try {
643eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                final OverlayInfo tmp = mSettings.getOverlayInfo(oi.packageName, userId);
644eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                if (tmp != null && tmp.isEnabled()) {
645eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                    // someone is still using the idmap file -> we cannot remove it
646eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                    return;
647eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                }
648eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            } catch (OverlayManagerSettings.BadKeyException e) {
649eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                // intentionally left empty
650eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
651eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
652eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        mIdmapManager.removeIdmap(oi, oi.userId);
653eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
654eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
655c745f42169df6687a764e48b65878f22965c1530Adam Lesinski    interface OverlayChangeListener {
656c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        void onOverlaysChanged(@NonNull String targetPackage, int userId);
657c745f42169df6687a764e48b65878f22965c1530Adam Lesinski    }
658c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
659eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    interface PackageManagerHelper {
660eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        PackageInfo getPackageInfo(@NonNull String packageName, int userId);
661eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        boolean signaturesMatching(@NonNull String packageName1, @NonNull String packageName2,
662eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                                   int userId);
663eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        List<PackageInfo> getOverlayPackages(int userId);
664eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
665eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad}
666