blob: 689a2915593b03cfc4f4f29ac0ae101c1735b0e7 [file] [log] [blame]
/*
* 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;
}
}
}