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.systemui.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 * Helper to extract colors from wallpaper palette for clock face. 79 */ 80 private final ClockPalette mPalette = new ClockPalette(); 81 82 /** 83 * Create a BubbleClockController instance. 84 * 85 * @param res Resources contains title and thumbnail. 86 * @param inflater Inflater used to inflate custom clock views. 87 * @param colorExtractor Extracts accent color from wallpaper. 88 */ AnalogClockController(Resources res, LayoutInflater inflater, SysuiColorExtractor colorExtractor)89 public AnalogClockController(Resources res, LayoutInflater inflater, 90 SysuiColorExtractor colorExtractor) { 91 mResources = res; 92 mLayoutInflater = inflater; 93 mColorExtractor = colorExtractor; 94 mClockPosition = new SmallClockPosition(inflater.getContext()); 95 } 96 createViews()97 private void createViews() { 98 mBigClockView = (ClockLayout) mLayoutInflater.inflate(R.layout.analog_clock, null); 99 mAnalogClock = mBigClockView.findViewById(R.id.analog_clock); 100 101 mView = mLayoutInflater.inflate(R.layout.digital_clock, null); 102 mLockClock = mView.findViewById(R.id.lock_screen_clock); 103 } 104 105 @Override onDestroyView()106 public void onDestroyView() { 107 mBigClockView = null; 108 mAnalogClock = null; 109 mView = null; 110 mLockClock = null; 111 } 112 113 @Override getName()114 public String getName() { 115 return "analog"; 116 } 117 118 @Override getTitle()119 public String getTitle() { 120 return mResources.getString(R.string.clock_title_analog); 121 } 122 123 @Override getThumbnail()124 public Bitmap getThumbnail() { 125 return BitmapFactory.decodeResource(mResources, R.drawable.analog_thumbnail); 126 } 127 128 @Override getPreview(int width, int height)129 public Bitmap getPreview(int width, int height) { 130 131 // Use the big clock view for the preview 132 View view = getBigClockView(); 133 134 // Initialize state of plugin before generating preview. 135 setDarkAmount(1f); 136 setTextColor(Color.WHITE); 137 ColorExtractor.GradientColors colors = mColorExtractor.getColors( 138 WallpaperManager.FLAG_LOCK); 139 setColorPalette(colors.supportsDarkText(), colors.getColorPalette()); 140 onTimeTick(); 141 142 return mRenderer.createPreview(view, width, height); 143 } 144 145 @Override getView()146 public View getView() { 147 if (mView == null) { 148 createViews(); 149 } 150 return mView; 151 } 152 153 @Override getBigClockView()154 public View getBigClockView() { 155 if (mBigClockView == null) { 156 createViews(); 157 } 158 return mBigClockView; 159 } 160 161 @Override getPreferredY(int totalHeight)162 public int getPreferredY(int totalHeight) { 163 return mClockPosition.getPreferredY(); 164 } 165 166 @Override setStyle(Style style)167 public void setStyle(Style style) {} 168 169 @Override setTextColor(int color)170 public void setTextColor(int color) { 171 updateColor(); 172 } 173 174 @Override setColorPalette(boolean supportsDarkText, int[] colorPalette)175 public void setColorPalette(boolean supportsDarkText, int[] colorPalette) { 176 mPalette.setColorPalette(supportsDarkText, colorPalette); 177 updateColor(); 178 } 179 updateColor()180 private void updateColor() { 181 final int primary = mPalette.getPrimaryColor(); 182 final int secondary = mPalette.getSecondaryColor(); 183 mLockClock.setTextColor(secondary); 184 mAnalogClock.setClockColors(primary, secondary); 185 } 186 187 @Override onTimeTick()188 public void onTimeTick() { 189 mAnalogClock.onTimeChanged(); 190 mBigClockView.onTimeChanged(); 191 mLockClock.refreshTime(); 192 } 193 194 @Override setDarkAmount(float darkAmount)195 public void setDarkAmount(float darkAmount) { 196 mPalette.setDarkAmount(darkAmount); 197 mClockPosition.setDarkAmount(darkAmount); 198 mBigClockView.setDarkAmount(darkAmount); 199 } 200 201 @Override onTimeZoneChanged(TimeZone timeZone)202 public void onTimeZoneChanged(TimeZone timeZone) { 203 mAnalogClock.onTimeZoneChanged(timeZone); 204 } 205 206 @Override shouldShowStatusArea()207 public boolean shouldShowStatusArea() { 208 return true; 209 } 210 } 211