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 Stretch clock that can appear on lock screen and AOD. 37 */ 38 public class AnalogClockController 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 mBigClockView; 69 private ImageClock mAnalogClock; 70 71 /** 72 * Small clock shown on lock screen above stack scroller. 73 */ 74 private View mView; 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 AnalogClockController(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 mBigClockView = (ClockLayout) mLayoutInflater.inflate(R.layout.analog_clock, null); 94 mAnalogClock = mBigClockView.findViewById(R.id.analog_clock); 95 96 mView = mLayoutInflater.inflate(R.layout.digital_clock, null); 97 mLockClock = mView.findViewById(R.id.lock_screen_clock); 98 } 99 100 @Override 101 public void onDestroyView() { 102 mBigClockView = null; 103 mAnalogClock = null; 104 mView = null; 105 mLockClock = null; 106 } 107 108 @Override 109 public String getName() { 110 return "analog"; 111 } 112 113 @Override 114 public String getTitle() { 115 return mResources.getString(R.string.clock_title_analog); 116 } 117 118 @Override 119 public Bitmap getThumbnail() { 120 return BitmapFactory.decodeResource(mResources, R.drawable.analog_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 (mView == null) { 143 createViews(); 144 } 145 return mView; 146 } 147 148 @Override 149 public View getBigClockView() { 150 if (mBigClockView == null) { 151 createViews(); 152 } 153 return mBigClockView; 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 mLockClock.setTextColor(colorPalette[Math.max(0, length - 2)]); 174 mAnalogClock.setClockColors(colorPalette[Math.max(0, length - 5)], 175 colorPalette[Math.max(0, length - 2)]); 176 } 177 178 @Override 179 public void onTimeTick() { 180 mAnalogClock.onTimeChanged(); 181 mBigClockView.onTimeChanged(); 182 mLockClock.refresh(); 183 } 184 185 @Override 186 public void setDarkAmount(float darkAmount) { 187 mClockPosition.setDarkAmount(darkAmount); 188 mBigClockView.setDarkAmount(darkAmount); 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