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 17 package com.android.settingslib.widget; 18 19 import static androidx.annotation.VisibleForTesting.NONE; 20 21 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB; 22 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_HINT; 23 24 import android.content.Context; 25 import android.content.pm.PackageManager; 26 import android.graphics.PorterDuff; 27 import android.graphics.drawable.Drawable; 28 import android.graphics.drawable.LayerDrawable; 29 import android.os.Bundle; 30 import android.util.Log; 31 32 import androidx.annotation.VisibleForTesting; 33 34 import com.android.settingslib.drawer.Tile; 35 36 /** 37 * Adaptive icon that can set background color 38 */ 39 public class AdaptiveIcon extends LayerDrawable { 40 41 private static final String TAG = "AdaptiveHomepageIcon"; 42 43 @VisibleForTesting(otherwise = NONE) 44 int mBackgroundColor = -1; 45 private AdaptiveConstantState mAdaptiveConstantState; 46 AdaptiveIcon(Context context, Drawable foreground)47 public AdaptiveIcon(Context context, Drawable foreground) { 48 this(context, foreground, R.dimen.dashboard_tile_foreground_image_inset); 49 } 50 AdaptiveIcon(Context context, Drawable foreground, int insetResId)51 public AdaptiveIcon(Context context, Drawable foreground, int insetResId) { 52 super(new Drawable[]{ 53 new AdaptiveIconShapeDrawable(context.getResources()), 54 foreground 55 }); 56 final int insetPx = context.getResources().getDimensionPixelSize(insetResId); 57 setLayerInset(1 /* index */, insetPx, insetPx, insetPx, insetPx); 58 mAdaptiveConstantState = new AdaptiveConstantState(context, foreground); 59 } 60 61 /** 62 * According {@code tile} metaData to set background color 63 */ setBackgroundColor(Context context, Tile tile)64 public void setBackgroundColor(Context context, Tile tile) { 65 final Bundle metaData = tile.getMetaData(); 66 try { 67 if (metaData != null) { 68 // Load from bg.argb first 69 int bgColor = metaData.getInt(META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB, 70 0 /* default */); 71 // Not found, load from bg.hint 72 if (bgColor == 0) { 73 final int colorRes = metaData.getInt(META_DATA_PREFERENCE_ICON_BACKGROUND_HINT, 74 0 /* default */); 75 if (colorRes != 0) { 76 bgColor = context.getPackageManager() 77 .getResourcesForApplication(tile.getPackageName()) 78 .getColor(colorRes, null /* theme */); 79 } 80 } 81 // If found anything, use it. 82 if (bgColor != 0) { 83 setBackgroundColor(bgColor); 84 return; 85 } 86 } 87 } catch (PackageManager.NameNotFoundException e) { 88 Log.e(TAG, "Failed to set background color for " + tile.getPackageName()); 89 } 90 setBackgroundColor(context.getColor(R.color.homepage_generic_icon_background)); 91 } 92 93 /** 94 * Set background color by {@code color} 95 */ setBackgroundColor(int color)96 public void setBackgroundColor(int color) { 97 mBackgroundColor = color; 98 getDrawable(0).setColorFilter(color, PorterDuff.Mode.SRC_ATOP); 99 Log.d(TAG, "Setting background color " + mBackgroundColor); 100 mAdaptiveConstantState.mColor = color; 101 } 102 103 @Override getConstantState()104 public ConstantState getConstantState() { 105 return mAdaptiveConstantState; 106 } 107 108 @VisibleForTesting 109 static class AdaptiveConstantState extends ConstantState { 110 Context mContext; 111 Drawable mDrawable; 112 int mColor; 113 AdaptiveConstantState(Context context, Drawable drawable)114 AdaptiveConstantState(Context context, Drawable drawable) { 115 this.mContext = context; 116 this.mDrawable = drawable; 117 } 118 119 @Override newDrawable()120 public Drawable newDrawable() { 121 final AdaptiveIcon 122 icon = new AdaptiveIcon(mContext, mDrawable); 123 icon.setBackgroundColor(mColor); 124 125 return icon; 126 } 127 128 @Override getChangingConfigurations()129 public int getChangingConfigurations() { 130 return 0; 131 } 132 } 133 } 134