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;
21a525e2239a95c79d62e27b18fc5e4f13789ab352Mårten Kongstadimport static android.content.om.OverlayInfo.STATE_ENABLED_STATIC;
22eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport static android.content.om.OverlayInfo.STATE_MISSING_TARGET;
23eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport static android.content.om.OverlayInfo.STATE_NO_IDMAP;
24db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstadimport static android.content.om.OverlayInfo.STATE_OVERLAY_UPGRADING;
25db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstadimport static android.content.om.OverlayInfo.STATE_TARGET_UPGRADING;
26eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
27eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport static com.android.server.om.OverlayManagerService.DEBUG;
28eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport static com.android.server.om.OverlayManagerService.TAG;
29eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
30eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.annotation.NonNull;
31eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.annotation.Nullable;
32eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.content.om.OverlayInfo;
33eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.content.pm.PackageInfo;
34a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinskiimport android.text.TextUtils;
35eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.util.ArrayMap;
36eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.util.ArraySet;
37eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport android.util.Slog;
38eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
39eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.io.PrintWriter;
40eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.util.ArrayList;
41eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.util.Iterator;
42eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.util.List;
43eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.util.Map;
44607223f3b7a1c4dc3ac995f742f8d2da50d85ffcNarayan Kamathimport java.util.Objects;
45eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadimport java.util.Set;
46eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
47eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad/**
48eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * Internal implementation of OverlayManagerService.
49eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad *
50eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * Methods in this class should only be called by the OverlayManagerService.
51eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * This class is not thread-safe; the caller is expected to ensure the
52eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * necessary thread synchronization.
53eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad *
54eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad * @see OverlayManagerService
55eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad */
56eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstadfinal class OverlayManagerServiceImpl {
57db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad    // Flags to use in conjunction with updateState.
58db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad    private static final int FLAG_TARGET_IS_UPGRADING = 1<<0;
59db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad    private static final int FLAG_OVERLAY_IS_UPGRADING = 1<<1;
60db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
61eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    private final PackageManagerHelper mPackageManager;
62eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    private final IdmapManager mIdmapManager;
63eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    private final OverlayManagerSettings mSettings;
647b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski    private final String[] mDefaultOverlays;
65c745f42169df6687a764e48b65878f22965c1530Adam Lesinski    private final OverlayChangeListener mListener;
66eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
672f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad    /**
682f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad     * Helper method to merge the overlay manager's (as read from overlays.xml)
692f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad     * and package manager's (as parsed from AndroidManifest.xml files) views
702f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad     * on overlays.
712f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad     *
722f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad     * Both managers are usually in agreement, but especially after an OTA things
732f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad     * may differ. The package manager is always providing the truth; the overlay
742f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad     * manager has to adapt. Depending on what has changed about an overlay, we
752f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad     * should either scrap the overlay manager's previous settings or merge the old
762f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad     * settings with the new.
772f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad     */
782f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad    private static boolean mustReinitializeOverlay(@NonNull final PackageInfo theTruth,
792f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad            @Nullable final OverlayInfo oldSettings) {
802f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad        if (oldSettings == null) {
812f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad            return true;
822f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad        }
832f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad        if (!Objects.equals(theTruth.overlayTarget, oldSettings.targetPackageName)) {
842f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad            return true;
852f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad        }
862f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad        if (theTruth.isStaticOverlayPackage() != oldSettings.isStatic) {
872f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad            return true;
882f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad        }
892f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad        // a change in priority is only relevant for static RROs: specifically,
902f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad        // a regular RRO should not have its state reset only because a change
912f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad        // in priority
922f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad        if (theTruth.isStaticOverlayPackage() &&
932f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad                theTruth.overlayPriority != oldSettings.priority) {
942f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad            return true;
952f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad        }
962f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad        return false;
972f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad    }
982f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad
99eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    OverlayManagerServiceImpl(@NonNull final PackageManagerHelper packageManager,
100eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            @NonNull final IdmapManager idmapManager,
101a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski            @NonNull final OverlayManagerSettings settings,
1027b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski            @NonNull final String[] defaultOverlays,
103c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            @NonNull final OverlayChangeListener listener) {
104eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        mPackageManager = packageManager;
105eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        mIdmapManager = idmapManager;
106eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        mSettings = settings;
107a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski        mDefaultOverlays = defaultOverlays;
108c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        mListener = listener;
109eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
110eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
111ada8deb43649aed879ceba28daee4af69ae0cc8dAdam Lesinski    /**
112ada8deb43649aed879ceba28daee4af69ae0cc8dAdam Lesinski     * Call this to synchronize the Settings for a user with what PackageManager knows about a user.
113ada8deb43649aed879ceba28daee4af69ae0cc8dAdam Lesinski     * Returns a list of target packages that must refresh their overlays. This list is the union
114eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad     * of two sets: the set of targets with currently active overlays, and the
115eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad     * set of targets that had, but no longer have, active overlays.
116eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad     */
117ada8deb43649aed879ceba28daee4af69ae0cc8dAdam Lesinski    ArrayList<String> updateOverlaysForUser(final int newUserId) {
118eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
119ada8deb43649aed879ceba28daee4af69ae0cc8dAdam Lesinski            Slog.d(TAG, "updateOverlaysForUser newUserId=" + newUserId);
120eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
121eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
122eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final Set<String> packagesToUpdateAssets = new ArraySet<>();
123eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final ArrayMap<String, List<OverlayInfo>> tmp = mSettings.getOverlaysForUser(newUserId);
124eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final int tmpSize = tmp.size();
125eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final ArrayMap<String, OverlayInfo> storedOverlayInfos = new ArrayMap<>(tmpSize);
126eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        for (int i = 0; i < tmpSize; i++) {
127eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final List<OverlayInfo> chunk = tmp.valueAt(i);
128eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final int chunkSize = chunk.size();
129eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            for (int j = 0; j < chunkSize; j++) {
130eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                final OverlayInfo oi = chunk.get(j);
131eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                storedOverlayInfos.put(oi.packageName, oi);
132eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
133eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
134eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
1352f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad        // Reset overlays if something critical like the target package name
1362f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad        // has changed
137eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        List<PackageInfo> overlayPackages = mPackageManager.getOverlayPackages(newUserId);
138eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final int overlayPackagesSize = overlayPackages.size();
139eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        for (int i = 0; i < overlayPackagesSize; i++) {
140eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final PackageInfo overlayPackage = overlayPackages.get(i);
141eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final OverlayInfo oi = storedOverlayInfos.get(overlayPackage.packageName);
1422f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad
1432f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad            if (mustReinitializeOverlay(overlayPackage, oi)) {
1442f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad                // if targetPackageName has changed the package that *used* to
1452f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad                // be the target must also update its assets
1462f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad                if (oi != null) {
1472f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad                    packagesToUpdateAssets.add(oi.targetPackageName);
1482f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad                }
1492f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad
150eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                mSettings.init(overlayPackage.packageName, newUserId,
151eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                        overlayPackage.overlayTarget,
15242d53f6b1883e3db514ad8d105d23fe6a1e9a59bJaekyun Seok                        overlayPackage.applicationInfo.getBaseCodePath(),
1537b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                        overlayPackage.isStaticOverlayPackage(),
1547b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                        overlayPackage.overlayPriority,
155c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                        overlayPackage.overlayCategory);
156eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
157eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
158eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            storedOverlayInfos.remove(overlayPackage.packageName);
159eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
160eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
161eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // any OverlayInfo left in storedOverlayInfos is no longer
162eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // installed and should be removed
163eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final int storedOverlayInfosSize = storedOverlayInfos.size();
164eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        for (int i = 0; i < storedOverlayInfosSize; i++) {
165c0bba8b18b41356721c2ebb25af83bc5bb5a74b0Mårten Kongstad            final OverlayInfo oi = storedOverlayInfos.valueAt(i);
166eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            mSettings.remove(oi.packageName, oi.userId);
167eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            removeIdmapIfPossible(oi);
168eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            packagesToUpdateAssets.add(oi.targetPackageName);
169eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
170eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
1712f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad        // make sure every overlay's state is up-to-date; this needs to happen
1722f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad        // after old overlays have been removed, or we risk removing a
1732f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad        // legitimate idmap file if a new overlay package has the same apk path
1742f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad        // as the removed overlay package used to have
1752f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad        for (int i = 0; i < overlayPackagesSize; i++) {
1762f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad            final PackageInfo overlayPackage = overlayPackages.get(i);
1772f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad            try {
1782f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad                updateState(overlayPackage.overlayTarget, overlayPackage.packageName,
1792f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad                        newUserId, 0);
1802f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad            } catch (OverlayManagerSettings.BadKeyException e) {
1812f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad                Slog.e(TAG, "failed to update settings", e);
1822f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad                mSettings.remove(overlayPackage.packageName, newUserId);
1832f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad            }
1842f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad            packagesToUpdateAssets.add(overlayPackage.overlayTarget);
1852f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad        }
1862f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad
187eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // remove target packages that are not installed
188eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final Iterator<String> iter = packagesToUpdateAssets.iterator();
189eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        while (iter.hasNext()) {
190eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            String targetPackageName = iter.next();
191eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            if (mPackageManager.getPackageInfo(targetPackageName, newUserId) == null) {
192eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                iter.remove();
193eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
194eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
1957b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski
1967b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski        // Collect all of the categories in which we have at least one overlay enabled.
1977b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski        final ArraySet<String> enabledCategories = new ArraySet<>();
1987b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski        final ArrayMap<String, List<OverlayInfo>> userOverlays =
1997b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                mSettings.getOverlaysForUser(newUserId);
2007b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski        final int userOverlayTargetCount = userOverlays.size();
2017b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski        for (int i = 0; i < userOverlayTargetCount; i++) {
2027b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski            final List<OverlayInfo> overlayList = userOverlays.valueAt(i);
2037b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski            final int overlayCount = overlayList != null ? overlayList.size() : 0;
2047b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski            for (int j = 0; j < overlayCount; j++) {
2057b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                final OverlayInfo oi = overlayList.get(j);
2067b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                if (oi.isEnabled()) {
2077b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                    enabledCategories.add(oi.category);
2087b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                }
2097b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski            }
2107b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski        }
2117b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski
2127b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski        // Enable the default overlay if its category does not have a single overlay enabled.
2137b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski        for (final String defaultOverlay : mDefaultOverlays) {
2147b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski            try {
2157b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                final OverlayInfo oi = mSettings.getOverlayInfo(defaultOverlay, newUserId);
2167b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                if (!enabledCategories.contains(oi.category)) {
2177b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                    Slog.w(TAG, "Enabling default overlay '" + defaultOverlay + "' for target '"
2187b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                            + oi.targetPackageName + "' in category '" + oi.category + "' for user "
2197b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                            + newUserId);
2207b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                    mSettings.setEnabled(oi.packageName, newUserId, true);
2217b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                    if (updateState(oi.targetPackageName, oi.packageName, newUserId, 0)) {
2227b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                        packagesToUpdateAssets.add(oi.targetPackageName);
2237b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                    }
2247b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                }
2257b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski            } catch (OverlayManagerSettings.BadKeyException e) {
2267b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                Slog.e(TAG, "Failed to set default overlay '" + defaultOverlay + "' for user "
2277b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                        + newUserId, e);
2287b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski            }
2297b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski        }
2307b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski
231a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski        return new ArrayList<>(packagesToUpdateAssets);
232eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
233eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
234eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onUserRemoved(final int userId) {
235eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
236eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.d(TAG, "onUserRemoved userId=" + userId);
237eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
238eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        mSettings.removeUser(userId);
239eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
240eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
241eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onTargetPackageAdded(@NonNull final String packageName, final int userId) {
242eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
243eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.d(TAG, "onTargetPackageAdded packageName=" + packageName + " userId=" + userId);
244eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
245eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
246497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad        if (updateAllOverlaysForTarget(packageName, userId, 0)) {
247497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad            mListener.onOverlaysChanged(packageName, userId);
248497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad        }
249eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
250eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
251d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell    void onTargetPackageChanged(@NonNull final String packageName, final int userId) {
252d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell        if (DEBUG) {
253d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell            Slog.d(TAG, "onTargetPackageChanged packageName=" + packageName + " userId=" + userId);
254d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell        }
255d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell
256d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell        updateAllOverlaysForTarget(packageName, userId, 0);
257d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell    }
258d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell
259eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onTargetPackageUpgrading(@NonNull final String packageName, final int userId) {
260eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
261db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.d(TAG, "onTargetPackageUpgrading packageName=" + packageName + " userId="
262db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                    + userId);
263eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
264eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
265d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell        updateAllOverlaysForTarget(packageName, userId, FLAG_TARGET_IS_UPGRADING);
266eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
267eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
268eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onTargetPackageUpgraded(@NonNull final String packageName, final int userId) {
269eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
270eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.d(TAG, "onTargetPackageUpgraded packageName=" + packageName + " userId=" + userId);
271eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
272eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
273d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell        updateAllOverlaysForTarget(packageName, userId, 0);
274eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
275eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
276eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onTargetPackageRemoved(@NonNull final String packageName, final int userId) {
277eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
278eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.d(TAG, "onTargetPackageRemoved packageName=" + packageName + " userId=" + userId);
279eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
280eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
281497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad        if (updateAllOverlaysForTarget(packageName, userId, 0)) {
282497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad            mListener.onOverlaysChanged(packageName, userId);
283497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad        }
284eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
285eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
286c745f42169df6687a764e48b65878f22965c1530Adam Lesinski    /**
287a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad     * Update the state of any overlays for this target.
288a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad     *
289a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad     * Returns true if the system should refresh the app's overlay paths (i.e.
290a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad     * if the settings were modified for this target, or there is at least one
291a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad     * enabled framework overlay).
292c745f42169df6687a764e48b65878f22965c1530Adam Lesinski     */
293497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad    private boolean updateAllOverlaysForTarget(@NonNull final String targetPackageName,
294db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            final int userId, final int flags) {
295497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad        boolean modified = false;
296db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        final List<OverlayInfo> ois = mSettings.getOverlaysForTarget(targetPackageName, userId);
297eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final int N = ois.size();
298eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        for (int i = 0; i < N; i++) {
299eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final OverlayInfo oi = ois.get(i);
300db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            final PackageInfo overlayPackage = mPackageManager.getPackageInfo(oi.packageName,
301db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                    userId);
302eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            if (overlayPackage == null) {
303497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad                modified |= mSettings.remove(oi.packageName, oi.userId);
304eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                removeIdmapIfPossible(oi);
305eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            } else {
306eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                try {
307497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad                    modified |= updateState(targetPackageName, oi.packageName, userId, flags);
308eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                } catch (OverlayManagerSettings.BadKeyException e) {
309eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                    Slog.e(TAG, "failed to update settings", e);
310497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad                    modified |= mSettings.remove(oi.packageName, userId);
311eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                }
312eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
313eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
314a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad
315a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad        // check for enabled framework overlays
316a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad        modified = modified || !getEnabledOverlayPackageNames("android", userId).isEmpty();
317a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad
318497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad        return modified;
319eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
320eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
321eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onOverlayPackageAdded(@NonNull final String packageName, final int userId) {
322eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
323eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.d(TAG, "onOverlayPackageAdded packageName=" + packageName + " userId=" + userId);
324eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
325eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
326eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
327eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (overlayPackage == null) {
328eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.w(TAG, "overlay package " + packageName + " was added, but couldn't be found");
329eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            onOverlayPackageRemoved(packageName, userId);
330eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return;
331eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
332eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
333eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        mSettings.init(packageName, userId, overlayPackage.overlayTarget,
334ab56b9d9dfddcfb26dfdb553220719412df1e139Adam Lesinski                overlayPackage.applicationInfo.getBaseCodePath(),
335c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority,
336c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                overlayPackage.overlayCategory);
337eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        try {
338db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            if (updateState(overlayPackage.overlayTarget, packageName, userId, 0)) {
339497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad                mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId);
340c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            }
341eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        } catch (OverlayManagerSettings.BadKeyException e) {
342eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.e(TAG, "failed to update settings", e);
343eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            mSettings.remove(packageName, userId);
344eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
345eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
346eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
347eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onOverlayPackageChanged(@NonNull final String packageName, final int userId) {
348db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (DEBUG) {
349db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.d(TAG, "onOverlayPackageChanged packageName=" + packageName + " userId=" + userId);
350db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
351db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
352db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        try {
353db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId);
354db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            if (updateState(oi.targetPackageName, packageName, userId, 0)) {
355497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad                mListener.onOverlaysChanged(oi.targetPackageName, userId);
356db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            }
357db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        } catch (OverlayManagerSettings.BadKeyException e) {
358db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.e(TAG, "failed to update settings", e);
359db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
360eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
361eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
362eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onOverlayPackageUpgrading(@NonNull final String packageName, final int userId) {
363db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (DEBUG) {
364db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.d(TAG, "onOverlayPackageUpgrading packageName=" + packageName + " userId="
365db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                    + userId);
366db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
367db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
368db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        try {
369db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId);
370db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            if (updateState(oi.targetPackageName, packageName, userId, FLAG_OVERLAY_IS_UPGRADING)) {
371db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                removeIdmapIfPossible(oi);
372497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad                mListener.onOverlaysChanged(oi.targetPackageName, userId);
373db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            }
374db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        } catch (OverlayManagerSettings.BadKeyException e) {
375db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.e(TAG, "failed to update settings", e);
376db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
377eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
378eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
379eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onOverlayPackageUpgraded(@NonNull final String packageName, final int userId) {
380db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (DEBUG) {
381db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.d(TAG, "onOverlayPackageUpgraded packageName=" + packageName + " userId="
382db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                    + userId);
383db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
384db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
385db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        final PackageInfo pkg = mPackageManager.getPackageInfo(packageName, userId);
386db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (pkg == null) {
387db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.w(TAG, "overlay package " + packageName + " was upgraded, but couldn't be found");
388db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            onOverlayPackageRemoved(packageName, userId);
389db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            return;
390db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
391db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
392db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        try {
393db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            final OverlayInfo oldOi = mSettings.getOverlayInfo(packageName, userId);
3942f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad            if (mustReinitializeOverlay(pkg, oldOi)) {
3952f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad                if (oldOi != null && !oldOi.targetPackageName.equals(pkg.overlayTarget)) {
3962f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad                    mListener.onOverlaysChanged(pkg.overlayTarget, userId);
3972f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad                }
398db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                mSettings.init(packageName, userId, pkg.overlayTarget,
399db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                        pkg.applicationInfo.getBaseCodePath(), pkg.isStaticOverlayPackage(),
400c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                        pkg.overlayPriority, pkg.overlayCategory);
401db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            }
402db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
403db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            if (updateState(pkg.overlayTarget, packageName, userId, 0)) {
404497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad                mListener.onOverlaysChanged(pkg.overlayTarget, userId);
405db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            }
406db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        } catch (OverlayManagerSettings.BadKeyException e) {
407db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.e(TAG, "failed to update settings", e);
408db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
409eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
410eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
411eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onOverlayPackageRemoved(@NonNull final String packageName, final int userId) {
412b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski        try {
413b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski            final OverlayInfo overlayInfo = mSettings.getOverlayInfo(packageName, userId);
414b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski            if (mSettings.remove(packageName, userId)) {
415b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski                removeIdmapIfPossible(overlayInfo);
416b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski                if (overlayInfo.isEnabled()) {
417b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski                    // Only trigger updates if the overlay was enabled.
418497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad                    mListener.onOverlaysChanged(overlayInfo.targetPackageName, userId);
419b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski                }
420b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski            }
421b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski        } catch (OverlayManagerSettings.BadKeyException e) {
422b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski            Slog.e(TAG, "failed to remove overlay", e);
423b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski        }
424eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
425eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
426eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    OverlayInfo getOverlayInfo(@NonNull final String packageName, final int userId) {
427eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        try {
428eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return mSettings.getOverlayInfo(packageName, userId);
429eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        } catch (OverlayManagerSettings.BadKeyException e) {
430eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return null;
431eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
432eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
433eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
434eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    List<OverlayInfo> getOverlayInfosForTarget(@NonNull final String targetPackageName,
435eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final int userId) {
436eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        return mSettings.getOverlaysForTarget(targetPackageName, userId);
437eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
438eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
439eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    Map<String, List<OverlayInfo>> getOverlaysForUser(final int userId) {
440eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        return mSettings.getOverlaysForUser(userId);
441eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
442eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
443eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    boolean setEnabled(@NonNull final String packageName, final boolean enable,
444eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final int userId) {
445eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
446eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.d(TAG, String.format("setEnabled packageName=%s enable=%s userId=%d",
447eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                        packageName, enable, userId));
448eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
449eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
450eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
451eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (overlayPackage == null) {
452eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return false;
453eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
454c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
455c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        // Ignore static overlays.
456ab56b9d9dfddcfb26dfdb553220719412df1e139Adam Lesinski        if (overlayPackage.isStaticOverlayPackage()) {
4570434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok            return false;
4580434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok        }
459eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
460eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        try {
461eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId);
462c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            boolean modified = mSettings.setEnabled(packageName, userId, enable);
463db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            modified |= updateState(oi.targetPackageName, oi.packageName, userId, 0);
464c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
465c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            if (modified) {
466497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad                mListener.onOverlaysChanged(oi.targetPackageName, userId);
467c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            }
468929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            return true;
469929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        } catch (OverlayManagerSettings.BadKeyException e) {
470929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            return false;
471929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        }
472929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk    }
473929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk
474c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos    boolean setEnabledExclusive(@NonNull final String packageName, boolean withinCategory,
475c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos            final int userId) {
476929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        if (DEBUG) {
477c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos            Slog.d(TAG, String.format("setEnabledExclusive packageName=%s"
478c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                    + " withinCategory=%s userId=%d", packageName, withinCategory, userId));
479929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        }
480929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk
481929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
482929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        if (overlayPackage == null) {
483929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            return false;
484929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        }
485929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk
486929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        try {
487929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId);
488db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            final String targetPackageName = oi.targetPackageName;
489c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
490db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            List<OverlayInfo> allOverlays = getOverlayInfosForTarget(targetPackageName, userId);
491929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk
492c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            boolean modified = false;
493c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
494929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            // Disable all other overlays.
495929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            allOverlays.remove(oi);
496929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            for (int i = 0; i < allOverlays.size(); i++) {
497c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                final String disabledOverlayPackageName = allOverlays.get(i).packageName;
498c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                final PackageInfo disabledOverlayPackageInfo = mPackageManager.getPackageInfo(
499c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                        disabledOverlayPackageName, userId);
500c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                if (disabledOverlayPackageInfo == null) {
501c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                    modified |= mSettings.remove(disabledOverlayPackageName, userId);
502c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                    continue;
503c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                }
504c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
505ab56b9d9dfddcfb26dfdb553220719412df1e139Adam Lesinski                if (disabledOverlayPackageInfo.isStaticOverlayPackage()) {
506c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                    // Don't touch static overlays.
507c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                    continue;
508c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                }
509607223f3b7a1c4dc3ac995f742f8d2da50d85ffcNarayan Kamath                if (withinCategory && !Objects.equals(disabledOverlayPackageInfo.overlayCategory,
510c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                        oi.category)) {
511c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                    // Don't touch overlays from other categories.
512c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                    continue;
513c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                }
514c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
515c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                // Disable the overlay.
516c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                modified |= mSettings.setEnabled(disabledOverlayPackageName, userId, false);
517db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                modified |= updateState(targetPackageName, disabledOverlayPackageName, userId, 0);
518929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            }
519929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk
520c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            // Enable the selected overlay.
521c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            modified |= mSettings.setEnabled(packageName, userId, true);
522db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            modified |= updateState(targetPackageName, packageName, userId, 0);
523c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
524c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            if (modified) {
525497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad                mListener.onOverlaysChanged(targetPackageName, userId);
526c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            }
527eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return true;
528eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        } catch (OverlayManagerSettings.BadKeyException e) {
529eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return false;
530eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
531eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
532eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
533c745f42169df6687a764e48b65878f22965c1530Adam Lesinski    private boolean isPackageUpdatableOverlay(@NonNull final String packageName, final int userId) {
5340434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
535ab56b9d9dfddcfb26dfdb553220719412df1e139Adam Lesinski        if (overlayPackage == null || overlayPackage.isStaticOverlayPackage()) {
5360434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok            return false;
5370434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok        }
5380434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok        return true;
5390434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok    }
5400434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok
541eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    boolean setPriority(@NonNull final String packageName,
542eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            @NonNull final String newParentPackageName, final int userId) {
543c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (DEBUG) {
544c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            Slog.d(TAG, "setPriority packageName=" + packageName + " newParentPackageName="
545c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                    + newParentPackageName + " userId=" + userId);
546c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
547c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
548c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (!isPackageUpdatableOverlay(packageName, userId)) {
549c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            return false;
550c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
551c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
552c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
553c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (overlayPackage == null) {
554c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            return false;
555c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
556c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
557c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (mSettings.setPriority(packageName, newParentPackageName, userId)) {
558497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad            mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId);
559c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
560c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        return true;
561eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
562eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
563eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    boolean setHighestPriority(@NonNull final String packageName, final int userId) {
564c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (DEBUG) {
565c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            Slog.d(TAG, "setHighestPriority packageName=" + packageName + " userId=" + userId);
566c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
567c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
568c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (!isPackageUpdatableOverlay(packageName, userId)) {
569c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            return false;
570c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
571c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
572c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
573c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (overlayPackage == null) {
574c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            return false;
575c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
576c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
577c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (mSettings.setHighestPriority(packageName, userId)) {
578497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad            mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId);
579c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
580c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        return true;
581eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
582eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
583eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    boolean setLowestPriority(@NonNull final String packageName, final int userId) {
584c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (DEBUG) {
585c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            Slog.d(TAG, "setLowestPriority packageName=" + packageName + " userId=" + userId);
586c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
587c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
588c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (!isPackageUpdatableOverlay(packageName, userId)) {
589c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            return false;
590c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
591c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
592c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
593c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (overlayPackage == null) {
594c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            return false;
595c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
596c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
597c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (mSettings.setLowestPriority(packageName, userId)) {
598497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad            mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId);
599c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
600c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        return true;
601eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
602eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
603eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onDump(@NonNull final PrintWriter pw) {
604eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        mSettings.dump(pw);
605a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski        pw.println("Default overlays: " + TextUtils.join(";", mDefaultOverlays));
606eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
607eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
608eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    List<String> getEnabledOverlayPackageNames(@NonNull final String targetPackageName,
609eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final int userId) {
610db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        final List<OverlayInfo> overlays = mSettings.getOverlaysForTarget(targetPackageName,
611db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                userId);
612eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final List<String> paths = new ArrayList<>(overlays.size());
613eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final int N = overlays.size();
614eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        for (int i = 0; i < N; i++) {
615eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final OverlayInfo oi = overlays.get(i);
616eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            if (oi.isEnabled()) {
617eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                paths.add(oi.packageName);
618eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
619eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
620eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        return paths;
621eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
622eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
623c745f42169df6687a764e48b65878f22965c1530Adam Lesinski    /**
624c745f42169df6687a764e48b65878f22965c1530Adam Lesinski     * Returns true if the settings/state was modified, false otherwise.
625c745f42169df6687a764e48b65878f22965c1530Adam Lesinski     */
626db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad    private boolean updateState(@NonNull final String targetPackageName,
627db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            @NonNull final String overlayPackageName, final int userId, final int flags)
628c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            throws OverlayManagerSettings.BadKeyException {
629db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
630db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        final PackageInfo targetPackage = mPackageManager.getPackageInfo(targetPackageName, userId);
631db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(overlayPackageName,
632db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                userId);
633db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
6340434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok        // Static RROs targeting to "android", ie framework-res.apk, are handled by native layers.
635db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (targetPackage != null && overlayPackage != null &&
636db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                !("android".equals(targetPackageName)
637ab56b9d9dfddcfb26dfdb553220719412df1e139Adam Lesinski                        && overlayPackage.isStaticOverlayPackage())) {
638eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            mIdmapManager.createIdmap(targetPackage, overlayPackage, userId);
639eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
640eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
641db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        boolean modified = false;
642db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (overlayPackage != null) {
643db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            modified |= mSettings.setBaseCodePath(overlayPackageName, userId,
644db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                    overlayPackage.applicationInfo.getBaseCodePath());
6452f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad            modified |= mSettings.setCategory(overlayPackageName, userId,
6462f1944bf0e225b0fd96d57cfbca40fb717e4f475Mårten Kongstad                    overlayPackage.overlayCategory);
647db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
648eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
649db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        final @OverlayInfo.State int currentState = mSettings.getState(overlayPackageName, userId);
650db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        final @OverlayInfo.State int newState = calculateNewState(targetPackage, overlayPackage,
651db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                userId, flags);
652eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (currentState != newState) {
653eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            if (DEBUG) {
654eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                Slog.d(TAG, String.format("%s:%d: %s -> %s",
655db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                            overlayPackageName, userId,
656eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                            OverlayInfo.stateToString(currentState),
657eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                            OverlayInfo.stateToString(newState)));
658eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
659db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            modified |= mSettings.setState(overlayPackageName, userId, newState);
660eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
661c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        return modified;
662eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
663eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
664db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad    private @OverlayInfo.State int calculateNewState(@Nullable final PackageInfo targetPackage,
665db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            @Nullable final PackageInfo overlayPackage, final int userId, final int flags)
666eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        throws OverlayManagerSettings.BadKeyException {
667db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
668db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if ((flags & FLAG_TARGET_IS_UPGRADING) != 0) {
669db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            return STATE_TARGET_UPGRADING;
670db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
671db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
672db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if ((flags & FLAG_OVERLAY_IS_UPGRADING) != 0) {
673db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            return STATE_OVERLAY_UPGRADING;
674db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
675db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
676db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        // assert expectation on overlay package: can only be null if the flags are used
677db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (DEBUG && overlayPackage == null) {
678db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            throw new IllegalArgumentException("null overlay package not compatible with no flags");
679db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
680db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
681eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (targetPackage == null) {
682eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return STATE_MISSING_TARGET;
683eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
684eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
685eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (!mIdmapManager.idmapExists(overlayPackage, userId)) {
686eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return STATE_NO_IDMAP;
687eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
688eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
689a525e2239a95c79d62e27b18fc5e4f13789ab352Mårten Kongstad        if (overlayPackage.isStaticOverlayPackage()) {
690a525e2239a95c79d62e27b18fc5e4f13789ab352Mårten Kongstad            return STATE_ENABLED_STATIC;
691a525e2239a95c79d62e27b18fc5e4f13789ab352Mårten Kongstad        }
692a525e2239a95c79d62e27b18fc5e4f13789ab352Mårten Kongstad
693eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final boolean enabled = mSettings.getEnabled(overlayPackage.packageName, userId);
694eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        return enabled ? STATE_ENABLED : STATE_DISABLED;
695eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
696eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
697eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    private void removeIdmapIfPossible(@NonNull final OverlayInfo oi) {
698eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // For a given package, all Android users share the same idmap file.
699eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // This works because Android currently does not support users to
700eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // install different versions of the same package. It also means we
701eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // cannot remove an idmap file if any user still needs it.
702eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        //
703eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // When/if the Android framework allows different versions of the same
704eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // package to be installed for different users, idmap file handling
705eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // should be revised:
706eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        //
707eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // - an idmap file should be unique for each {user, package} pair
708eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        //
709eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // - the path to the idmap file should be passed to the native Asset
710eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        //   Manager layers, just like the path to the apk is passed today
711eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        //
712eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // As part of that change, calls to this method should be replaced by
713eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // direct calls to IdmapManager.removeIdmap, without looping over all
714eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // users.
715eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
716eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (!mIdmapManager.idmapExists(oi)) {
717eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return;
718eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
719c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        final int[] userIds = mSettings.getUsers();
720c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        for (int userId : userIds) {
721eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            try {
722eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                final OverlayInfo tmp = mSettings.getOverlayInfo(oi.packageName, userId);
723eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                if (tmp != null && tmp.isEnabled()) {
724eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                    // someone is still using the idmap file -> we cannot remove it
725eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                    return;
726eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                }
727eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            } catch (OverlayManagerSettings.BadKeyException e) {
728eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                // intentionally left empty
729eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
730eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
731eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        mIdmapManager.removeIdmap(oi, oi.userId);
732eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
733eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
734c745f42169df6687a764e48b65878f22965c1530Adam Lesinski    interface OverlayChangeListener {
735d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell
736d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell        /**
737d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell         * An event triggered by changes made to overlay state or settings as well as changes that
738d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell         * add or remove target packages of overlays.
739d41d0db01baef0fb410908eafbc99a110d140df9Ryan Mitchell         **/
740497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad        void onOverlaysChanged(@NonNull String targetPackage, int userId);
741c745f42169df6687a764e48b65878f22965c1530Adam Lesinski    }
742c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
743eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    interface PackageManagerHelper {
744eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        PackageInfo getPackageInfo(@NonNull String packageName, int userId);
745eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        boolean signaturesMatching(@NonNull String packageName1, @NonNull String packageName2,
746eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                                   int userId);
747eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        List<PackageInfo> getOverlayPackages(int userId);
748eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
749eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad}
750