OverlayManagerServiceImpl.java revision a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7
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;
637b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski    private final 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,
697b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski            @NonNull final 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);
1077b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski            if (oi == null || !oi.targetPackageName.equals(overlayPackage.overlayTarget)) {
1087b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                // Reset the overlay if it didn't exist or had the wrong target package.
109eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                mSettings.init(overlayPackage.packageName, newUserId,
110eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                        overlayPackage.overlayTarget,
11142d53f6b1883e3db514ad8d105d23fe6a1e9a59bJaekyun Seok                        overlayPackage.applicationInfo.getBaseCodePath(),
1127b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                        overlayPackage.isStaticOverlayPackage(),
1137b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                        overlayPackage.overlayPriority,
114c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                        overlayPackage.overlayCategory);
115a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski
1167b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                if (oi != null) {
117a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski                    // The targetPackageName we have stored doesn't match the overlay's target.
118a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski                    // Queue the old target for an update as well.
119a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski                    packagesToUpdateAssets.add(oi.targetPackageName);
120a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski                }
1217b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski            } else {
1227b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                // Update all other components of an overlay that don't require a hard reset.
1237b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                if (!Objects.equals(oi.category, overlayPackage.overlayCategory)) {
1247b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                    // When changing categories, it is ok just to update our internal state.
1257b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                    mSettings.setCategory(overlayPackage.packageName, newUserId,
1267b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                            overlayPackage.overlayCategory);
1277b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                }
128eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
129eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
130eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            try {
131db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                updateState(overlayPackage.overlayTarget, overlayPackage.packageName, newUserId, 0);
132eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            } catch (OverlayManagerSettings.BadKeyException e) {
133eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                Slog.e(TAG, "failed to update settings", e);
134eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                mSettings.remove(overlayPackage.packageName, newUserId);
135eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
136eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
137eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            packagesToUpdateAssets.add(overlayPackage.overlayTarget);
138eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            storedOverlayInfos.remove(overlayPackage.packageName);
139eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
140eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
141eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // any OverlayInfo left in storedOverlayInfos is no longer
142eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // installed and should be removed
143eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final int storedOverlayInfosSize = storedOverlayInfos.size();
144eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        for (int i = 0; i < storedOverlayInfosSize; i++) {
145c0bba8b18b41356721c2ebb25af83bc5bb5a74b0Mårten Kongstad            final OverlayInfo oi = storedOverlayInfos.valueAt(i);
146eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            mSettings.remove(oi.packageName, oi.userId);
147eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            removeIdmapIfPossible(oi);
148eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            packagesToUpdateAssets.add(oi.targetPackageName);
149eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
150eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
151eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // remove target packages that are not installed
152eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final Iterator<String> iter = packagesToUpdateAssets.iterator();
153eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        while (iter.hasNext()) {
154eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            String targetPackageName = iter.next();
155eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            if (mPackageManager.getPackageInfo(targetPackageName, newUserId) == null) {
156eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                iter.remove();
157eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
158eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
1597b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski
1607b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski        // Collect all of the categories in which we have at least one overlay enabled.
1617b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski        final ArraySet<String> enabledCategories = new ArraySet<>();
1627b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski        final ArrayMap<String, List<OverlayInfo>> userOverlays =
1637b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                mSettings.getOverlaysForUser(newUserId);
1647b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski        final int userOverlayTargetCount = userOverlays.size();
1657b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski        for (int i = 0; i < userOverlayTargetCount; i++) {
1667b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski            final List<OverlayInfo> overlayList = userOverlays.valueAt(i);
1677b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski            final int overlayCount = overlayList != null ? overlayList.size() : 0;
1687b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski            for (int j = 0; j < overlayCount; j++) {
1697b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                final OverlayInfo oi = overlayList.get(j);
1707b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                if (oi.isEnabled()) {
1717b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                    enabledCategories.add(oi.category);
1727b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                }
1737b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski            }
1747b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski        }
1757b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski
1767b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski        // Enable the default overlay if its category does not have a single overlay enabled.
1777b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski        for (final String defaultOverlay : mDefaultOverlays) {
1787b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski            try {
1797b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                final OverlayInfo oi = mSettings.getOverlayInfo(defaultOverlay, newUserId);
1807b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                if (!enabledCategories.contains(oi.category)) {
1817b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                    Slog.w(TAG, "Enabling default overlay '" + defaultOverlay + "' for target '"
1827b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                            + oi.targetPackageName + "' in category '" + oi.category + "' for user "
1837b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                            + newUserId);
1847b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                    mSettings.setEnabled(oi.packageName, newUserId, true);
1857b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                    if (updateState(oi.targetPackageName, oi.packageName, newUserId, 0)) {
1867b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                        packagesToUpdateAssets.add(oi.targetPackageName);
1877b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                    }
1887b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                }
1897b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski            } catch (OverlayManagerSettings.BadKeyException e) {
1907b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                Slog.e(TAG, "Failed to set default overlay '" + defaultOverlay + "' for user "
1917b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                        + newUserId, e);
1927b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski            }
1937b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski        }
1947b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski
195a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski        return new ArrayList<>(packagesToUpdateAssets);
196eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
197eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
198eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onUserRemoved(final int userId) {
199eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
200eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.d(TAG, "onUserRemoved userId=" + userId);
201eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
202eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        mSettings.removeUser(userId);
203eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
204eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
205eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onTargetPackageAdded(@NonNull final String packageName, final int userId) {
206eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
207eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.d(TAG, "onTargetPackageAdded packageName=" + packageName + " userId=" + userId);
208eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
209eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
210497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad        if (updateAllOverlaysForTarget(packageName, userId, 0)) {
211497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad            mListener.onOverlaysChanged(packageName, userId);
212497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad        }
213eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
214eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
215eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onTargetPackageChanged(@NonNull final String packageName, final int userId) {
216eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
217eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.d(TAG, "onTargetPackageChanged packageName=" + packageName + " userId=" + userId);
218eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
219eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
220497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad        if (updateAllOverlaysForTarget(packageName, userId, 0)) {
221497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad            mListener.onOverlaysChanged(packageName, userId);
222497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad        }
223eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
224eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
225eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onTargetPackageUpgrading(@NonNull final String packageName, final int userId) {
226eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
227db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.d(TAG, "onTargetPackageUpgrading packageName=" + packageName + " userId="
228db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                    + userId);
229eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
230eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
231497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad        if (updateAllOverlaysForTarget(packageName, userId, FLAG_TARGET_IS_UPGRADING)) {
232497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad            mListener.onOverlaysChanged(packageName, userId);
233497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad        }
234eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
235eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
236eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onTargetPackageUpgraded(@NonNull final String packageName, final int userId) {
237eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
238eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.d(TAG, "onTargetPackageUpgraded packageName=" + packageName + " userId=" + userId);
239eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
240eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
241497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad        if (updateAllOverlaysForTarget(packageName, userId, 0)) {
242497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad            mListener.onOverlaysChanged(packageName, userId);
243497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad        }
244eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
245eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
246eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onTargetPackageRemoved(@NonNull final String packageName, final int userId) {
247eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
248eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.d(TAG, "onTargetPackageRemoved packageName=" + packageName + " userId=" + userId);
249eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
250eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
251497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad        if (updateAllOverlaysForTarget(packageName, userId, 0)) {
252497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad            mListener.onOverlaysChanged(packageName, userId);
253497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad        }
254eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
255eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
256c745f42169df6687a764e48b65878f22965c1530Adam Lesinski    /**
257a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad     * Update the state of any overlays for this target.
258a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad     *
259a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad     * Returns true if the system should refresh the app's overlay paths (i.e.
260a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad     * if the settings were modified for this target, or there is at least one
261a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad     * enabled framework overlay).
262c745f42169df6687a764e48b65878f22965c1530Adam Lesinski     */
263497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad    private boolean updateAllOverlaysForTarget(@NonNull final String targetPackageName,
264db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            final int userId, final int flags) {
265497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad        boolean modified = false;
266db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        final List<OverlayInfo> ois = mSettings.getOverlaysForTarget(targetPackageName, userId);
267eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final int N = ois.size();
268eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        for (int i = 0; i < N; i++) {
269eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final OverlayInfo oi = ois.get(i);
270db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            final PackageInfo overlayPackage = mPackageManager.getPackageInfo(oi.packageName,
271db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                    userId);
272eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            if (overlayPackage == null) {
273497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad                modified |= mSettings.remove(oi.packageName, oi.userId);
274eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                removeIdmapIfPossible(oi);
275eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            } else {
276eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                try {
277497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad                    modified |= updateState(targetPackageName, oi.packageName, userId, flags);
278eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                } catch (OverlayManagerSettings.BadKeyException e) {
279eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                    Slog.e(TAG, "failed to update settings", e);
280497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad                    modified |= mSettings.remove(oi.packageName, userId);
281eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                }
282eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
283eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
284a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad
285a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad        // check for enabled framework overlays
286a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad        modified = modified || !getEnabledOverlayPackageNames("android", userId).isEmpty();
287a3bd3491cc32376bd43e5bfdcbb91b8fbff789d7Mårten Kongstad
288497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad        return modified;
289eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
290eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
291eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onOverlayPackageAdded(@NonNull final String packageName, final int userId) {
292eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
293eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.d(TAG, "onOverlayPackageAdded packageName=" + packageName + " userId=" + userId);
294eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
295eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
296eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
297eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (overlayPackage == null) {
298eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.w(TAG, "overlay package " + packageName + " was added, but couldn't be found");
299eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            onOverlayPackageRemoved(packageName, userId);
300eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return;
301eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
302eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
303eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        mSettings.init(packageName, userId, overlayPackage.overlayTarget,
304ab56b9d9dfddcfb26dfdb553220719412df1e139Adam Lesinski                overlayPackage.applicationInfo.getBaseCodePath(),
305c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority,
306c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                overlayPackage.overlayCategory);
307eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        try {
308db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            if (updateState(overlayPackage.overlayTarget, packageName, userId, 0)) {
309497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad                mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId);
310c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            }
311eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        } catch (OverlayManagerSettings.BadKeyException e) {
312eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.e(TAG, "failed to update settings", e);
313eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            mSettings.remove(packageName, userId);
314eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
315eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
316eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
317eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onOverlayPackageChanged(@NonNull final String packageName, final int userId) {
318db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (DEBUG) {
319db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.d(TAG, "onOverlayPackageChanged packageName=" + packageName + " userId=" + userId);
320db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
321db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
322db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        try {
323db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId);
324db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            if (updateState(oi.targetPackageName, packageName, userId, 0)) {
325497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad                mListener.onOverlaysChanged(oi.targetPackageName, userId);
326db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            }
327db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        } catch (OverlayManagerSettings.BadKeyException e) {
328db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.e(TAG, "failed to update settings", e);
329db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
330eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
331eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
332eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onOverlayPackageUpgrading(@NonNull final String packageName, final int userId) {
333db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (DEBUG) {
334db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.d(TAG, "onOverlayPackageUpgrading packageName=" + packageName + " userId="
335db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                    + userId);
336db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
337db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
338db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        try {
339db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId);
340db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            if (updateState(oi.targetPackageName, packageName, userId, FLAG_OVERLAY_IS_UPGRADING)) {
341db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                removeIdmapIfPossible(oi);
342497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad                mListener.onOverlaysChanged(oi.targetPackageName, userId);
343db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            }
344db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        } catch (OverlayManagerSettings.BadKeyException e) {
345db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.e(TAG, "failed to update settings", e);
346db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
347eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
348eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
349eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onOverlayPackageUpgraded(@NonNull final String packageName, final int userId) {
350db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (DEBUG) {
351db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.d(TAG, "onOverlayPackageUpgraded packageName=" + packageName + " userId="
352db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                    + userId);
353db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
354db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
355db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        final PackageInfo pkg = mPackageManager.getPackageInfo(packageName, userId);
356db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (pkg == null) {
357db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.w(TAG, "overlay package " + packageName + " was upgraded, but couldn't be found");
358db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            onOverlayPackageRemoved(packageName, userId);
359db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            return;
360db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
361db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
362db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        try {
363db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            final OverlayInfo oldOi = mSettings.getOverlayInfo(packageName, userId);
364db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            if (!oldOi.targetPackageName.equals(pkg.overlayTarget)) {
365db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                mSettings.init(packageName, userId, pkg.overlayTarget,
366db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                        pkg.applicationInfo.getBaseCodePath(), pkg.isStaticOverlayPackage(),
367c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                        pkg.overlayPriority, pkg.overlayCategory);
3687b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski            } else {
3697b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                if (!Objects.equals(oldOi.category, pkg.overlayCategory)) {
3707b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                    // Update the category in-place.
3717b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                    mSettings.setCategory(packageName, userId, pkg.overlayCategory);
3727b03181ab1d5001b6ed1fdcdeee9c2a6f4659c81Adam Lesinski                }
373db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            }
374db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
375db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            if (updateState(pkg.overlayTarget, packageName, userId, 0)) {
376497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad                mListener.onOverlaysChanged(pkg.overlayTarget, userId);
377db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            }
378db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        } catch (OverlayManagerSettings.BadKeyException e) {
379db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            Slog.e(TAG, "failed to update settings", e);
380db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
381eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
382eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
383eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onOverlayPackageRemoved(@NonNull final String packageName, final int userId) {
384b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski        try {
385b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski            final OverlayInfo overlayInfo = mSettings.getOverlayInfo(packageName, userId);
386b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski            if (mSettings.remove(packageName, userId)) {
387b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski                removeIdmapIfPossible(overlayInfo);
388b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski                if (overlayInfo.isEnabled()) {
389b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski                    // Only trigger updates if the overlay was enabled.
390497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad                    mListener.onOverlaysChanged(overlayInfo.targetPackageName, userId);
391b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski                }
392b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski            }
393b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski        } catch (OverlayManagerSettings.BadKeyException e) {
394b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski            Slog.e(TAG, "failed to remove overlay", e);
395b67fc5fbfc1e32f3cfe2eaea6d55cc07539c7f28Adam Lesinski        }
396eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
397eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
398eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    OverlayInfo getOverlayInfo(@NonNull final String packageName, final int userId) {
399eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        try {
400eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return mSettings.getOverlayInfo(packageName, userId);
401eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        } catch (OverlayManagerSettings.BadKeyException e) {
402eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return null;
403eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
404eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
405eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
406eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    List<OverlayInfo> getOverlayInfosForTarget(@NonNull final String targetPackageName,
407eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final int userId) {
408eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        return mSettings.getOverlaysForTarget(targetPackageName, userId);
409eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
410eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
411eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    Map<String, List<OverlayInfo>> getOverlaysForUser(final int userId) {
412eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        return mSettings.getOverlaysForUser(userId);
413eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
414eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
415eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    boolean setEnabled(@NonNull final String packageName, final boolean enable,
416eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final int userId) {
417eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (DEBUG) {
418eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            Slog.d(TAG, String.format("setEnabled packageName=%s enable=%s userId=%d",
419eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                        packageName, enable, userId));
420eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
421eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
422eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
423eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (overlayPackage == null) {
424eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return false;
425eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
426c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
427c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        // Ignore static overlays.
428ab56b9d9dfddcfb26dfdb553220719412df1e139Adam Lesinski        if (overlayPackage.isStaticOverlayPackage()) {
4290434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok            return false;
4300434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok        }
431eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
432eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        try {
433eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId);
434c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            boolean modified = mSettings.setEnabled(packageName, userId, enable);
435db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            modified |= updateState(oi.targetPackageName, oi.packageName, userId, 0);
436c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
437c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            if (modified) {
438497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad                mListener.onOverlaysChanged(oi.targetPackageName, userId);
439c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            }
440929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            return true;
441929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        } catch (OverlayManagerSettings.BadKeyException e) {
442929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            return false;
443929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        }
444929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk    }
445929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk
446c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos    boolean setEnabledExclusive(@NonNull final String packageName, boolean withinCategory,
447c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos            final int userId) {
448929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        if (DEBUG) {
449c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos            Slog.d(TAG, String.format("setEnabledExclusive packageName=%s"
450c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                    + " withinCategory=%s userId=%d", packageName, withinCategory, userId));
451929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        }
452929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk
453929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
454929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        if (overlayPackage == null) {
455929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            return false;
456929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        }
457929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk
458929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk        try {
459929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId);
460db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            final String targetPackageName = oi.targetPackageName;
461c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
462db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            List<OverlayInfo> allOverlays = getOverlayInfosForTarget(targetPackageName, userId);
463929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk
464c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            boolean modified = false;
465c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
466929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            // Disable all other overlays.
467929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            allOverlays.remove(oi);
468929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            for (int i = 0; i < allOverlays.size(); i++) {
469c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                final String disabledOverlayPackageName = allOverlays.get(i).packageName;
470c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                final PackageInfo disabledOverlayPackageInfo = mPackageManager.getPackageInfo(
471c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                        disabledOverlayPackageName, userId);
472c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                if (disabledOverlayPackageInfo == null) {
473c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                    modified |= mSettings.remove(disabledOverlayPackageName, userId);
474c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                    continue;
475c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                }
476c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
477ab56b9d9dfddcfb26dfdb553220719412df1e139Adam Lesinski                if (disabledOverlayPackageInfo.isStaticOverlayPackage()) {
478c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                    // Don't touch static overlays.
479c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                    continue;
480c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                }
481607223f3b7a1c4dc3ac995f742f8d2da50d85ffcNarayan Kamath                if (withinCategory && !Objects.equals(disabledOverlayPackageInfo.overlayCategory,
482c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                        oi.category)) {
483c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                    // Don't touch overlays from other categories.
484c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                    continue;
485c84df7755c4682d6ff3e47818846d2a2c384f9fbAdrian Roos                }
486c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
487c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                // Disable the overlay.
488c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                modified |= mSettings.setEnabled(disabledOverlayPackageName, userId, false);
489db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                modified |= updateState(targetPackageName, disabledOverlayPackageName, userId, 0);
490929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk            }
491929ed8d2f46209026cfa6f4baa68b551d54401a0Jason Monk
492c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            // Enable the selected overlay.
493c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            modified |= mSettings.setEnabled(packageName, userId, true);
494db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            modified |= updateState(targetPackageName, packageName, userId, 0);
495c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
496c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            if (modified) {
497497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad                mListener.onOverlaysChanged(targetPackageName, userId);
498c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            }
499eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return true;
500eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        } catch (OverlayManagerSettings.BadKeyException e) {
501eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return false;
502eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
503eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
504eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
505c745f42169df6687a764e48b65878f22965c1530Adam Lesinski    private boolean isPackageUpdatableOverlay(@NonNull final String packageName, final int userId) {
5060434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
507ab56b9d9dfddcfb26dfdb553220719412df1e139Adam Lesinski        if (overlayPackage == null || overlayPackage.isStaticOverlayPackage()) {
5080434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok            return false;
5090434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok        }
5100434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok        return true;
5110434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok    }
5120434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok
513eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    boolean setPriority(@NonNull final String packageName,
514eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            @NonNull final String newParentPackageName, final int userId) {
515c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (DEBUG) {
516c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            Slog.d(TAG, "setPriority packageName=" + packageName + " newParentPackageName="
517c745f42169df6687a764e48b65878f22965c1530Adam Lesinski                    + newParentPackageName + " userId=" + userId);
518c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
519c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
520c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (!isPackageUpdatableOverlay(packageName, userId)) {
521c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            return false;
522c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
523c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
524c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
525c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (overlayPackage == null) {
526c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            return false;
527c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
528c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
529c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (mSettings.setPriority(packageName, newParentPackageName, userId)) {
530497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad            mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId);
531c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
532c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        return true;
533eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
534eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
535eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    boolean setHighestPriority(@NonNull final String packageName, final int userId) {
536c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (DEBUG) {
537c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            Slog.d(TAG, "setHighestPriority packageName=" + packageName + " userId=" + userId);
538c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
539c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
540c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (!isPackageUpdatableOverlay(packageName, userId)) {
541c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            return false;
542c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
543c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
544c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
545c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (overlayPackage == null) {
546c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            return false;
547c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
548c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
549c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (mSettings.setHighestPriority(packageName, userId)) {
550497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad            mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId);
551c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
552c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        return true;
553eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
554eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
555eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    boolean setLowestPriority(@NonNull final String packageName, final int userId) {
556c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (DEBUG) {
557c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            Slog.d(TAG, "setLowestPriority packageName=" + packageName + " userId=" + userId);
558c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
559c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
560c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (!isPackageUpdatableOverlay(packageName, userId)) {
561c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            return false;
562c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
563c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
564c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
565c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (overlayPackage == null) {
566c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            return false;
567c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
568c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
569c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        if (mSettings.setLowestPriority(packageName, userId)) {
570497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad            mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId);
571c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        }
572c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        return true;
573eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
574eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
575eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    void onDump(@NonNull final PrintWriter pw) {
576eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        mSettings.dump(pw);
577a5ca62408381058c12bd5a1fe3b30f2512a73e03Adam Lesinski        pw.println("Default overlays: " + TextUtils.join(";", mDefaultOverlays));
578eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
579eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
580eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    List<String> getEnabledOverlayPackageNames(@NonNull final String targetPackageName,
581eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final int userId) {
582db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        final List<OverlayInfo> overlays = mSettings.getOverlaysForTarget(targetPackageName,
583db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                userId);
584eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final List<String> paths = new ArrayList<>(overlays.size());
585eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final int N = overlays.size();
586eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        for (int i = 0; i < N; i++) {
587eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            final OverlayInfo oi = overlays.get(i);
588eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            if (oi.isEnabled()) {
589eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                paths.add(oi.packageName);
590eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
591eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
592eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        return paths;
593eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
594eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
595c745f42169df6687a764e48b65878f22965c1530Adam Lesinski    /**
596c745f42169df6687a764e48b65878f22965c1530Adam Lesinski     * Returns true if the settings/state was modified, false otherwise.
597c745f42169df6687a764e48b65878f22965c1530Adam Lesinski     */
598db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad    private boolean updateState(@NonNull final String targetPackageName,
599db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            @NonNull final String overlayPackageName, final int userId, final int flags)
600c745f42169df6687a764e48b65878f22965c1530Adam Lesinski            throws OverlayManagerSettings.BadKeyException {
601db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
602db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        final PackageInfo targetPackage = mPackageManager.getPackageInfo(targetPackageName, userId);
603db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(overlayPackageName,
604db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                userId);
605db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
6060434289c45bc18f81f26d66e6bcbf8facf128665Jaekyun Seok        // Static RROs targeting to "android", ie framework-res.apk, are handled by native layers.
607db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (targetPackage != null && overlayPackage != null &&
608db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                !("android".equals(targetPackageName)
609ab56b9d9dfddcfb26dfdb553220719412df1e139Adam Lesinski                        && overlayPackage.isStaticOverlayPackage())) {
610eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            mIdmapManager.createIdmap(targetPackage, overlayPackage, userId);
611eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
612eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
613db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        boolean modified = false;
614db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (overlayPackage != null) {
615db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            modified |= mSettings.setBaseCodePath(overlayPackageName, userId,
616db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                    overlayPackage.applicationInfo.getBaseCodePath());
617db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
618eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
619db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        final @OverlayInfo.State int currentState = mSettings.getState(overlayPackageName, userId);
620db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        final @OverlayInfo.State int newState = calculateNewState(targetPackage, overlayPackage,
621db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                userId, flags);
622eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (currentState != newState) {
623eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            if (DEBUG) {
624eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                Slog.d(TAG, String.format("%s:%d: %s -> %s",
625db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad                            overlayPackageName, userId,
626eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                            OverlayInfo.stateToString(currentState),
627eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                            OverlayInfo.stateToString(newState)));
628eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
629db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            modified |= mSettings.setState(overlayPackageName, userId, newState);
630eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
631c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        return modified;
632eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
633eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
634db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad    private @OverlayInfo.State int calculateNewState(@Nullable final PackageInfo targetPackage,
635db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            @Nullable final PackageInfo overlayPackage, final int userId, final int flags)
636eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        throws OverlayManagerSettings.BadKeyException {
637db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
638db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if ((flags & FLAG_TARGET_IS_UPGRADING) != 0) {
639db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            return STATE_TARGET_UPGRADING;
640db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
641db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
642db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if ((flags & FLAG_OVERLAY_IS_UPGRADING) != 0) {
643db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            return STATE_OVERLAY_UPGRADING;
644db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
645db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
646db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        // assert expectation on overlay package: can only be null if the flags are used
647db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        if (DEBUG && overlayPackage == null) {
648db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad            throw new IllegalArgumentException("null overlay package not compatible with no flags");
649db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad        }
650db0e34ed83cad511fb61e921ba80d3aba4f1bb6dMårten Kongstad
651eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (targetPackage == null) {
652eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return STATE_MISSING_TARGET;
653eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
654eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
655eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (!mIdmapManager.idmapExists(overlayPackage, userId)) {
656eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return STATE_NO_IDMAP;
657eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
658eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
659eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        final boolean enabled = mSettings.getEnabled(overlayPackage.packageName, userId);
660eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        return enabled ? STATE_ENABLED : STATE_DISABLED;
661eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
662eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
663eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    private void removeIdmapIfPossible(@NonNull final OverlayInfo oi) {
664eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // For a given package, all Android users share the same idmap file.
665eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // This works because Android currently does not support users to
666eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // install different versions of the same package. It also means we
667eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // cannot remove an idmap file if any user still needs it.
668eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        //
669eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // When/if the Android framework allows different versions of the same
670eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // package to be installed for different users, idmap file handling
671eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // should be revised:
672eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        //
673eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // - an idmap file should be unique for each {user, package} pair
674eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        //
675eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // - the path to the idmap file should be passed to the native Asset
676eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        //   Manager layers, just like the path to the apk is passed today
677eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        //
678eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // As part of that change, calls to this method should be replaced by
679eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // direct calls to IdmapManager.removeIdmap, without looping over all
680eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        // users.
681eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
682eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        if (!mIdmapManager.idmapExists(oi)) {
683eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            return;
684eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
685c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        final int[] userIds = mSettings.getUsers();
686c745f42169df6687a764e48b65878f22965c1530Adam Lesinski        for (int userId : userIds) {
687eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            try {
688eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                final OverlayInfo tmp = mSettings.getOverlayInfo(oi.packageName, userId);
689eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                if (tmp != null && tmp.isEnabled()) {
690eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                    // someone is still using the idmap file -> we cannot remove it
691eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                    return;
692eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                }
693eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            } catch (OverlayManagerSettings.BadKeyException e) {
694eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                // intentionally left empty
695eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad            }
696eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        }
697eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        mIdmapManager.removeIdmap(oi, oi.userId);
698eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
699eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad
700c745f42169df6687a764e48b65878f22965c1530Adam Lesinski    interface OverlayChangeListener {
701497945cfa1d11fa3a51bb6410c6c9ef8e513c67fMårten Kongstad        void onOverlaysChanged(@NonNull String targetPackage, int userId);
702c745f42169df6687a764e48b65878f22965c1530Adam Lesinski    }
703c745f42169df6687a764e48b65878f22965c1530Adam Lesinski
704eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    interface PackageManagerHelper {
705eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        PackageInfo getPackageInfo(@NonNull String packageName, int userId);
706eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        boolean signaturesMatching(@NonNull String packageName1, @NonNull String packageName2,
707eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad                                   int userId);
708eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad        List<PackageInfo> getOverlayPackages(int userId);
709eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad    }
710eabc9e95768e7ac9acc3b32dc9ac2edf99c9e2c5Mårten Kongstad}
711