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