blob: 163eca1b6e7e44ffa0623209c48381c44565b5c7 [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.customization.model.theme;
import android.content.Context;
import android.content.om.OverlayInfo;
import android.content.om.OverlayManager;
import android.os.UserHandle;
import androidx.annotation.Nullable;
import com.android.customization.model.ResourceConstants;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Wrapper over {@link OverlayManager} that abstracts away its internals and can be mocked for
* testing.
*/
public class OverlayManagerCompat {
private final OverlayManager mOverlayManager;
private final String[] mTargetPackages;
private Map<Integer, Map<String, List<OverlayInfo>>> mOverlayByUser;
public OverlayManagerCompat(Context context) {
mOverlayManager = context.getSystemService(OverlayManager.class);
mTargetPackages = ResourceConstants.getPackagesToOverlay(context);
}
public boolean isAvailable() {
return mOverlayManager != null;
}
/**
* Enables the overlay provided by the given package for the given user Id
* @return true if the operation succeeded
*/
public boolean setEnabledExclusiveInCategory(String packageName, int userId) {
mOverlayManager.setEnabledExclusiveInCategory(packageName, UserHandle.of(userId));
return true;
}
/**
* Disables the overlay provided by the given package for the given user Id
* @return true if the operation succeeded
*/
public boolean disableOverlay(String packageName, int userId) {
mOverlayManager.setEnabled(packageName, false, UserHandle.of(userId));
return true;
}
/**
* @return the package name of the currently enabled overlay for the given target package, in
* the given category, or {@code null} if none is currently enabled.
*/
@Nullable
public String getEnabledPackageName(String targetPackageName, String category) {
// Can't use mOverlayByUser map as the enabled state might change
List<OverlayInfo> overlayInfos = getOverlayInfosForTarget(targetPackageName,
UserHandle.myUserId());
for (OverlayInfo overlayInfo : overlayInfos) {
if (category.equals(overlayInfo.getCategory()) && overlayInfo.isEnabled()) {
return overlayInfo.getPackageName();
}
}
return null;
}
/**
* @return a Map of Category -> PackageName of all the overlays enabled for the given target
* packages. It might be empty if no overlay is enabled for those targets.
*/
public Map<String, String> getEnabledOverlaysForTargets(String... targetPackages) {
Map<String, String> overlays = new HashMap<>();
for (String target : targetPackages) {
addAllEnabledOverlaysForTarget(overlays, target);
}
return overlays;
}
public List<String> getOverlayPackagesForCategory(String category, int userId,
String... targetPackages) {
List<String> overlays = new ArrayList<>();
ensureCategoryMapForUser(userId);
for (String target : targetPackages) {
for (OverlayInfo info
: mOverlayByUser.get(userId).getOrDefault(target, Collections.emptyList())) {
if (category.equals(info.getCategory())) {
overlays.add(info.getPackageName());
}
}
}
return overlays;
}
private void ensureCategoryMapForUser(int userId) {
if (mOverlayByUser == null) {
mOverlayByUser = new HashMap<>();
}
if (!mOverlayByUser.containsKey(userId)) {
Map<String, List<OverlayInfo>> overlaysByTarget = new HashMap<>();
for (String target : mTargetPackages) {
overlaysByTarget.put(target, getOverlayInfosForTarget(target, userId));
}
mOverlayByUser.put(userId, overlaysByTarget);
}
}
private List<OverlayInfo> getOverlayInfosForTarget(String targetPackageName, int userId) {
return mOverlayManager.getOverlayInfosForTarget(targetPackageName, UserHandle.of(userId));
}
private void addAllEnabledOverlaysForTarget(Map<String, String> overlays, String target) {
// Can't use mOverlayByUser map as the enabled state might change
for (OverlayInfo overlayInfo : getOverlayInfosForTarget(target, UserHandle.myUserId())) {
if (overlayInfo.isEnabled()) {
overlays.put(overlayInfo.getCategory(), overlayInfo.getPackageName());
}
}
}
}