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 package com.android.keyguard.clock; 17 18 import android.app.WallpaperManager; 19 import android.content.res.Resources; 20 import android.graphics.Bitmap; 21 import android.graphics.BitmapFactory; 22 import android.graphics.Color; 23 import android.graphics.Paint.Style; 24 import android.view.LayoutInflater; 25 import android.view.View; 26 import android.widget.TextClock; 27 28 import com.android.internal.colorextraction.ColorExtractor; 29 import com.android.keyguard.R; 30 import com.android.systemui.colorextraction.SysuiColorExtractor; 31 import com.android.systemui.plugins.ClockPlugin; 32 33 import java.util.TimeZone; 34 35 /** 36 * Controller for Bubble clock that can appear on lock screen and AOD. 37 */ 38 public class BubbleClockController implements ClockPlugin { 39 40 /** 41 * Resources used to get title and thumbnail. 42 */ 43 private final Resources mResources; 44 45 /** 46 * LayoutInflater used to inflate custom clock views. 47 */ 48 private final LayoutInflater mLayoutInflater; 49 50 /** 51 * Extracts accent color from wallpaper. 52 */ 53 private final SysuiColorExtractor mColorExtractor; 54 55 /** 56 * Computes preferred position of clock. 57 */ 58 private final SmallClockPosition mClockPosition; 59 60 /** 61 * Renders preview from clock view. 62 */ 63 private final ViewPreviewer mRenderer = new ViewPreviewer(); 64 65 /** 66 * Custom clock shown on AOD screen and behind stack scroller on lock. 67 */ 68 private ClockLayout mView; 69 private ImageClock mAnalogClock; 70 71 /** 72 * Small clock shown on lock screen above stack scroller. 73 */ 74 private View mLockClockContainer; 75 private TextClock mLockClock; 76 77 /** 78 * Create a BubbleClockController instance. 79 * 80 * @param res Resources contains title and thumbnail. 81 * @param inflater Inflater used to inflate custom clock views. 82 * @param colorExtractor Extracts accent color from wallpaper. 83 */ 84 public BubbleClockController(Resources res, LayoutInflater inflater, 85 SysuiColorExtractor colorExtractor) { 86 mResources = res; 87 mLayoutInflater = inflater; 88 mColorExtractor = colorExtractor; 89 mClockPosition = new SmallClockPosition(res); 90 } 91 92 private void createViews() { 93 mView = (ClockLayout) mLayoutInflater.inflate(R.layout.bubble_clock, null); 94 mAnalogClock = (ImageClock) mView.findViewById(R.id.analog_clock); 95 96 mLockClockContainer = mLayoutInflater.inflate(R.layout.digital_clock, null); 97 mLockClock = (TextClock) mLockClockContainer.findViewById(R.id.lock_screen_clock); 98 } 99 100 @Override 101 public void onDestroyView() { 102 mView = null; 103 mAnalogClock = null; 104 mLockClockContainer = null; 105 mLockClock = null; 106 } 107 108 @Override 109 public String getName() { 110 return "bubble"; 111 } 112 113 @Override 114 public String getTitle() { 115 return mResources.getString(R.string.clock_title_bubble); 116 } 117 118 @Override 119 public Bitmap getThumbnail() { 120 return BitmapFactory.decodeResource(mResources, R.drawable.bubble_thumbnail); 121 } 122 123 @Override 124 public Bitmap getPreview(int width, int height) { 125 126 // Use the big clock view for the preview 127 View view = getBigClockView(); 128 129 // Initialize state of plugin before generating preview. 130 setDarkAmount(1f); 131 setTextColor(Color.WHITE); 132 ColorExtractor.GradientColors colors = mColorExtractor.getColors( 133 WallpaperManager.FLAG_LOCK); 134 setColorPalette(colors.supportsDarkText(), colors.getColorPalette()); 135 onTimeTick(); 136 137 return mRenderer.createPreview(view, width, height); 138 } 139 140 @Override 141 public View getView() { 142 if (mLockClockContainer == null) { 143 createViews(); 144 } 145 return mLockClockContainer; 146 } 147 148 @Override 149 public View getBigClockView() { 150 if (mView == null) { 151 createViews(); 152 } 153 return mView; 154 } 155 156 @Override 157 public int getPreferredY(int totalHeight) { 158 return mClockPosition.getPreferredY(); 159 } 160 161 @Override 162 public void setStyle(Style style) {} 163 164 @Override 165 public void setTextColor(int color) { } 166 167 @Override 168 public void setColorPalette(boolean supportsDarkText, int[] colorPalette) { 169 if (colorPalette == null || colorPalette.length == 0) { 170 return; 171 } 172 final int length = colorPalette.length; 173 final int color = colorPalette[Math.max(0, length - 3)]; 174 mLockClock.setTextColor(color); 175 mAnalogClock.setClockColors(color, color); 176 } 177 178 @Override 179 public void setDarkAmount(float darkAmount) { 180 mClockPosition.setDarkAmount(darkAmount); 181 mView.setDarkAmount(darkAmount); 182 } 183 184 @Override 185 public void onTimeTick() { 186 mAnalogClock.onTimeChanged(); 187 mView.onTimeChanged(); 188 mLockClock.refresh(); 189 } 190 191 @Override 192 public void onTimeZoneChanged(TimeZone timeZone) { 193 mAnalogClock.onTimeZoneChanged(timeZone); 194 } 195 196 @Override 197 public boolean shouldShowStatusArea() { 198 return true; 199 } 200 } 201