1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.customization.model.theme.custom; 17 18 import static com.android.customization.model.ResourceConstants.ANDROID_PACKAGE; 19 import static com.android.customization.model.ResourceConstants.ICONS_FOR_PREVIEW; 20 import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_ANDROID; 21 import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_LAUNCHER; 22 import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SETTINGS; 23 import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SYSUI; 24 import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_THEMEPICKER; 25 26 import android.content.Context; 27 import android.content.pm.PackageManager.NameNotFoundException; 28 import android.content.res.Resources; 29 import android.content.res.Resources.NotFoundException; 30 import android.graphics.drawable.Drawable; 31 import android.os.UserHandle; 32 import android.util.Log; 33 34 import com.android.customization.model.ResourceConstants; 35 import com.android.customization.model.theme.OverlayManagerCompat; 36 import com.android.customization.model.theme.custom.ThemeComponentOption.IconOption; 37 import com.android.wallpaper.R; 38 39 import java.util.ArrayList; 40 import java.util.HashMap; 41 import java.util.List; 42 import java.util.Map; 43 44 /** 45 * Implementation of {@link ThemeComponentOptionProvider} that reads {@link IconOption}s from 46 * icon overlays. 47 */ 48 public class IconOptionsProvider extends ThemeComponentOptionProvider<IconOption> { 49 50 private static final String TAG = "IconOptionsProvider"; 51 52 private final List<String> mSysUiIconsOverlayPackages = new ArrayList<>(); 53 private final List<String> mSettingsIconsOverlayPackages = new ArrayList<>(); 54 private final List<String> mLauncherIconsOverlayPackages = new ArrayList<>(); 55 private final List<String> mThemePickerIconsOverlayPackages = new ArrayList<>(); 56 IconOptionsProvider(Context context, OverlayManagerCompat manager)57 public IconOptionsProvider(Context context, OverlayManagerCompat manager) { 58 super(context, manager, OVERLAY_CATEGORY_ICON_ANDROID); 59 String[] targetPackages = ResourceConstants.getPackagesToOverlay(context); 60 mSysUiIconsOverlayPackages.addAll(manager.getOverlayPackagesForCategory( 61 OVERLAY_CATEGORY_ICON_SYSUI, UserHandle.myUserId(), targetPackages)); 62 mSettingsIconsOverlayPackages.addAll(manager.getOverlayPackagesForCategory( 63 OVERLAY_CATEGORY_ICON_SETTINGS, UserHandle.myUserId(), targetPackages)); 64 mLauncherIconsOverlayPackages.addAll(manager.getOverlayPackagesForCategory( 65 OVERLAY_CATEGORY_ICON_LAUNCHER, UserHandle.myUserId(), targetPackages)); 66 mThemePickerIconsOverlayPackages.addAll(manager.getOverlayPackagesForCategory( 67 OVERLAY_CATEGORY_ICON_THEMEPICKER, UserHandle.myUserId(), targetPackages)); 68 } 69 70 @Override loadOptions()71 protected void loadOptions() { 72 addDefault(); 73 74 Map<String, IconOption> optionsByPrefix = new HashMap<>(); 75 for (String overlayPackage : mOverlayPackages) { 76 IconOption option = addOrUpdateOption(optionsByPrefix, overlayPackage, 77 OVERLAY_CATEGORY_ICON_ANDROID); 78 try{ 79 for (String iconName : ICONS_FOR_PREVIEW) { 80 option.addIcon(loadIconPreviewDrawable(iconName, overlayPackage)); 81 } 82 } catch (NotFoundException | NameNotFoundException e) { 83 Log.w(TAG, String.format("Couldn't load icon overlay details for %s, will skip it", 84 overlayPackage), e); 85 } 86 } 87 88 for (String overlayPackage : mSysUiIconsOverlayPackages) { 89 addOrUpdateOption(optionsByPrefix, overlayPackage, OVERLAY_CATEGORY_ICON_SYSUI); 90 } 91 92 for (String overlayPackage : mSettingsIconsOverlayPackages) { 93 addOrUpdateOption(optionsByPrefix, overlayPackage, OVERLAY_CATEGORY_ICON_SETTINGS); 94 } 95 96 for (String overlayPackage : mLauncherIconsOverlayPackages) { 97 addOrUpdateOption(optionsByPrefix, overlayPackage, OVERLAY_CATEGORY_ICON_LAUNCHER); 98 } 99 100 for (String overlayPackage : mThemePickerIconsOverlayPackages) { 101 addOrUpdateOption(optionsByPrefix, overlayPackage, OVERLAY_CATEGORY_ICON_THEMEPICKER); 102 } 103 104 for (IconOption option : optionsByPrefix.values()) { 105 if (option.isValid(mContext)) { 106 mOptions.add(option); 107 option.setLabel(mContext.getString(R.string.icon_component_label, mOptions.size())); 108 } 109 } 110 } 111 addOrUpdateOption(Map<String, IconOption> optionsByPrefix, String overlayPackage, String category)112 private IconOption addOrUpdateOption(Map<String, IconOption> optionsByPrefix, 113 String overlayPackage, String category) { 114 String prefix = overlayPackage.substring(0, overlayPackage.lastIndexOf(".")); 115 IconOption option; 116 if (!optionsByPrefix.containsKey(prefix)) { 117 option = new IconOption(); 118 optionsByPrefix.put(prefix, option); 119 } else { 120 option = optionsByPrefix.get(prefix); 121 } 122 option.addOverlayPackage(category, overlayPackage); 123 return option; 124 } 125 loadIconPreviewDrawable(String drawableName, String packageName)126 private Drawable loadIconPreviewDrawable(String drawableName, String packageName) 127 throws NameNotFoundException, NotFoundException { 128 final Resources resources = ANDROID_PACKAGE.equals(packageName) 129 ? Resources.getSystem() 130 : mContext.getPackageManager().getResourcesForApplication(packageName); 131 return resources.getDrawable( 132 resources.getIdentifier(drawableName, "drawable", packageName), null); 133 } 134 addDefault()135 private void addDefault() { 136 IconOption option = new IconOption(); 137 option.setLabel(mContext.getString(R.string.default_theme_title)); 138 try { 139 for (String iconName : ICONS_FOR_PREVIEW) { 140 option.addIcon(loadIconPreviewDrawable(iconName, ANDROID_PACKAGE)); 141 } 142 } catch (NameNotFoundException | NotFoundException e) { 143 Log.w(TAG, "Didn't find SystemUi package icons, will skip option", e); 144 } 145 option.addOverlayPackage(OVERLAY_CATEGORY_ICON_ANDROID, null); 146 option.addOverlayPackage(OVERLAY_CATEGORY_ICON_SYSUI, null); 147 option.addOverlayPackage(OVERLAY_CATEGORY_ICON_SETTINGS, null); 148 option.addOverlayPackage(OVERLAY_CATEGORY_ICON_LAUNCHER, null); 149 option.addOverlayPackage(OVERLAY_CATEGORY_ICON_THEMEPICKER, null); 150 mOptions.add(option); 151 } 152 153 } 154