1 /* 2 * Copyright (C) 2017 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.graph; 18 19 20 import android.content.Context; 21 import android.content.res.Resources; 22 import android.graphics.PorterDuff; 23 import android.graphics.PorterDuffColorFilter; 24 import android.graphics.drawable.Drawable; 25 import android.graphics.drawable.LayerDrawable; 26 import android.view.Gravity; 27 28 import androidx.annotation.NonNull; 29 import androidx.annotation.VisibleForTesting; 30 31 import com.android.settingslib.R; 32 import com.android.settingslib.Utils; 33 34 /** 35 * LayerDrawable contains the bluetooth device icon and battery gauge icon 36 */ 37 public class BluetoothDeviceLayerDrawable extends LayerDrawable { 38 39 private BluetoothDeviceLayerDrawableState mState; 40 BluetoothDeviceLayerDrawable(@onNull Drawable[] layers)41 private BluetoothDeviceLayerDrawable(@NonNull Drawable[] layers) { 42 super(layers); 43 } 44 45 /** 46 * Create the {@link LayerDrawable} that contains bluetooth device icon and battery icon. 47 * This is a horizontal layout drawable while bluetooth icon at start and battery icon at end. 48 * 49 * @param context used to get the spec for icon 50 * @param resId represents the bluetooth device drawable 51 * @param batteryLevel the battery level for bluetooth device 52 */ createLayerDrawable(Context context, int resId, int batteryLevel)53 public static BluetoothDeviceLayerDrawable createLayerDrawable(Context context, int resId, 54 int batteryLevel) { 55 return createLayerDrawable(context, resId, batteryLevel, 1 /*iconScale*/); 56 } 57 58 /** 59 * Create the {@link LayerDrawable} that contains bluetooth device icon and battery icon. 60 * This is a horizontal layout drawable while bluetooth icon at start and battery icon at end. 61 * 62 * @param context used to get the spec for icon 63 * @param resId represents the bluetooth device drawable 64 * @param batteryLevel the battery level for bluetooth device 65 * @param iconScale the ratio of height between battery icon and bluetooth icon 66 */ createLayerDrawable(Context context, int resId, int batteryLevel, float iconScale)67 public static BluetoothDeviceLayerDrawable createLayerDrawable(Context context, int resId, 68 int batteryLevel, float iconScale) { 69 final Drawable deviceDrawable = context.getDrawable(resId); 70 71 final BatteryMeterDrawable batteryDrawable = new BatteryMeterDrawable(context, 72 context.getColor(R.color.meter_background_color), batteryLevel); 73 final int pad = context.getResources().getDimensionPixelSize(R.dimen.bt_battery_padding); 74 batteryDrawable.setPadding(pad, pad, pad, pad); 75 76 final BluetoothDeviceLayerDrawable drawable = new BluetoothDeviceLayerDrawable( 77 new Drawable[]{deviceDrawable, batteryDrawable}); 78 // Set the bluetooth icon at the left 79 drawable.setLayerGravity(0 /* index of deviceDrawable */, Gravity.START); 80 // Set battery icon to the right of the bluetooth icon 81 drawable.setLayerInsetStart(1 /* index of batteryDrawable */, 82 deviceDrawable.getIntrinsicWidth()); 83 drawable.setLayerInsetTop(1 /* index of batteryDrawable */, 84 (int) (deviceDrawable.getIntrinsicHeight() * (1 - iconScale))); 85 86 drawable.setConstantState(context, resId, batteryLevel, iconScale); 87 88 return drawable; 89 } 90 setConstantState(Context context, int resId, int batteryLevel, float iconScale)91 public void setConstantState(Context context, int resId, int batteryLevel, float iconScale) { 92 mState = new BluetoothDeviceLayerDrawableState(context, resId, batteryLevel, iconScale); 93 } 94 95 @Override getConstantState()96 public ConstantState getConstantState() { 97 return mState; 98 } 99 100 /** 101 * Battery gauge icon with new spec. 102 */ 103 @VisibleForTesting 104 static class BatteryMeterDrawable extends BatteryMeterDrawableBase { 105 private final float mAspectRatio; 106 @VisibleForTesting 107 int mFrameColor; 108 BatteryMeterDrawable(Context context, int frameColor, int batteryLevel)109 public BatteryMeterDrawable(Context context, int frameColor, int batteryLevel) { 110 super(context, frameColor); 111 final Resources resources = context.getResources(); 112 mButtonHeightFraction = resources.getFraction( 113 R.fraction.bt_battery_button_height_fraction, 1, 1); 114 mAspectRatio = resources.getFraction(R.fraction.bt_battery_ratio_fraction, 1, 1); 115 116 final int tintColor = Utils.getColorAttrDefaultColor(context, 117 android.R.attr.colorControlNormal); 118 setColorFilter(new PorterDuffColorFilter(tintColor, PorterDuff.Mode.SRC_IN)); 119 setBatteryLevel(batteryLevel); 120 mFrameColor = frameColor; 121 } 122 123 @Override getAspectRatio()124 protected float getAspectRatio() { 125 return mAspectRatio; 126 } 127 128 @Override getRadiusRatio()129 protected float getRadiusRatio() { 130 // Remove the round edge 131 return 0; 132 } 133 } 134 135 /** 136 * {@link ConstantState} to restore the {@link BluetoothDeviceLayerDrawable} 137 */ 138 private static class BluetoothDeviceLayerDrawableState extends ConstantState { 139 Context context; 140 int resId; 141 int batteryLevel; 142 float iconScale; 143 BluetoothDeviceLayerDrawableState(Context context, int resId, int batteryLevel, float iconScale)144 public BluetoothDeviceLayerDrawableState(Context context, int resId, 145 int batteryLevel, float iconScale) { 146 this.context = context; 147 this.resId = resId; 148 this.batteryLevel = batteryLevel; 149 this.iconScale = iconScale; 150 } 151 152 @Override newDrawable()153 public Drawable newDrawable() { 154 return createLayerDrawable(context, resId, batteryLevel, iconScale); 155 } 156 157 @Override getChangingConfigurations()158 public int getChangingConfigurations() { 159 return 0; 160 } 161 } 162 } 163