/* * Copyright (C) 2021 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.car.settings.common; import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB; import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_HINT; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.ColorStateList; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.os.Bundle; import androidx.annotation.ColorInt; import androidx.annotation.VisibleForTesting; import com.android.car.settings.R; import com.android.internal.graphics.ColorUtils; import com.android.settingslib.utils.ColorUtil; /** * Top-level icon that can set background color. * * Adapted from {@link com.android.settingslib.widget.AdaptiveIcon} */ public class TopLevelIcon extends LayerDrawable { private static final Logger LOG = new Logger("TopLevelIcon"); private static final int BACKGROUND_INDEX = 0; private static final int FOREGROUND_INDEX = 1; private Context mContext; private AdaptiveConstantState mAdaptiveConstantState; private boolean mAlwaysDefaultColor; @VisibleForTesting ColorStateList mBackgroundColorStateList; public TopLevelIcon(Context context, Drawable foreground) { this(context, foreground, R.dimen.top_level_foreground_icon_inset); } public TopLevelIcon(Context context, Drawable foreground, int insetResId) { super(new Drawable[]{ new TopLevelIconShapeDrawable(context.getResources()), foreground }); mContext = context; int insetPx = context.getResources().getDimensionPixelSize(insetResId); setLayerInset(FOREGROUND_INDEX , insetPx, insetPx, insetPx, insetPx); mAdaptiveConstantState = new AdaptiveConstantState(context, foreground); mAlwaysDefaultColor = context.getResources().getBoolean( R.bool.config_top_level_injection_background_always_use_default); } /** * Sets background color based on injected metaData. */ public void setBackgroundColor(Context context, Bundle metaData, String packageName) { try { if (metaData != null && packageName != null && !mAlwaysDefaultColor) { // Load from bg.argb first int bgColor = metaData.getInt(META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB, /* defaultValue= */ 0); // If not found, load from bg.hint if (bgColor == 0) { int colorRes = metaData.getInt(META_DATA_PREFERENCE_ICON_BACKGROUND_HINT, /* defaultValue= */ 0); if (colorRes != 0) { bgColor = context.getPackageManager() .getResourcesForApplication(packageName) .getColor(colorRes, /* theme= */ null); } } // If a color was found, use it. if (bgColor != 0) { setBackgroundColor(bgColor); return; } } } catch (PackageManager.NameNotFoundException e) { LOG.e("Failed to set background color for " + packageName); } setBackgroundColor(context.getColor(R.color.top_level_injected_default_background)); } /** * Sets background color by {@code color}. */ public void setBackgroundColor(@ColorInt int color) { mBackgroundColorStateList = createBackgroundColorStateList(color); getDrawable(BACKGROUND_INDEX).setTintList(mBackgroundColorStateList); mAdaptiveConstantState.mColor = color; } @Override public ConstantState getConstantState() { return mAdaptiveConstantState; } private ColorStateList createBackgroundColorStateList(@ColorInt int color) { return new ColorStateList( new int[][]{ new int[]{-android.R.attr.state_enabled}, // disabled state new int[]{R.attr.state_ux_restricted}, // ux restricted state new int[]{} // default state }, new int[]{ getDisabledAlphaColor(color), getDisabledAlphaColor(color), color } ); } @ColorInt private int getDisabledAlphaColor(@ColorInt int color) { return ColorUtils.setAlphaComponent(color, (int) (ColorUtil.getDisabledAlpha(mContext) * 255)); } @VisibleForTesting static class AdaptiveConstantState extends ConstantState { Context mContext; Drawable mDrawable; int mColor; AdaptiveConstantState(Context context, Drawable drawable) { this.mContext = context; this.mDrawable = drawable; } @Override public Drawable newDrawable() { TopLevelIcon icon = new TopLevelIcon(mContext, mDrawable); icon.setBackgroundColor(mColor); return icon; } @Override public int getChangingConfigurations() { return 0; } } }