blob: d214d5525655a4aae5780c9ba64387e23110caf5 [file] [log] [blame]
Jim Millerdcb3d842012-08-23 19:18:12 -07001/*
2 * Copyright (C) 2012 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
Jim Miller5ecd8112013-01-09 18:50:26 -080017package com.android.keyguard;
Jim Millerdcb3d842012-08-23 19:18:12 -070018
Selim Cinek9c4a7072014-11-21 17:44:34 +010019import android.app.ActivityManager;
Jose Lima235510e2014-08-13 12:50:01 -070020import android.app.AlarmManager;
Jim Millerdcb3d842012-08-23 19:18:12 -070021import android.content.Context;
Jorim Jaggie210cc82014-08-12 23:44:59 +020022import android.content.res.Configuration;
Jim Miller0c486892013-10-11 16:21:45 -070023import android.content.res.Resources;
Adrian Roos9dd16eb2015-01-08 16:20:49 +010024import android.os.UserHandle;
Jim Milleredc74ab2012-11-06 21:46:11 -080025import android.text.TextUtils;
Jim Miller38ab2772013-10-08 15:32:09 -070026import android.text.format.DateFormat;
Jim Millerdcb3d842012-08-23 19:18:12 -070027import android.util.AttributeSet;
Jim Miller20daffd2013-10-07 14:59:53 -070028import android.util.Log;
Jim Milleredc74ab2012-11-06 21:46:11 -080029import android.util.Slog;
Jorim Jaggie210cc82014-08-12 23:44:59 +020030import android.util.TypedValue;
Jim Milleredc74ab2012-11-06 21:46:11 -080031import android.view.View;
Adrian Roos7907ff22017-01-17 15:44:11 -080032import android.view.ViewGroup;
Jim Millerdcb3d842012-08-23 19:18:12 -070033import android.widget.GridLayout;
Jim Miller38ab2772013-10-08 15:32:09 -070034import android.widget.TextClock;
Jim Milleredc74ab2012-11-06 21:46:11 -080035import android.widget.TextView;
Jim Millerdcb3d842012-08-23 19:18:12 -070036
Adrian Roosd83e9992017-03-16 15:17:57 -070037import com.android.internal.util.ArrayUtils;
Michael Jurka1254f2f2012-10-25 11:44:31 -070038import com.android.internal.widget.LockPatternUtils;
Adrian Roos56021892017-02-27 20:25:09 +010039import com.android.systemui.ChargingView;
Adrian Roos59de4f32017-05-31 15:22:38 -070040import com.android.systemui.statusbar.policy.DateView;
Michael Jurka1254f2f2012-10-25 11:44:31 -070041
Chris Wren56018e52013-01-15 10:59:43 -050042import java.util.Locale;
43
Jim Millerdcb3d842012-08-23 19:18:12 -070044public class KeyguardStatusView extends GridLayout {
Jorim Jaggi5cf17872014-03-26 18:31:48 +010045 private static final boolean DEBUG = KeyguardConstants.DEBUG;
Jim Milleredc74ab2012-11-06 21:46:11 -080046 private static final String TAG = "KeyguardStatusView";
47
Adrian Roos9dd16eb2015-01-08 16:20:49 +010048 private final LockPatternUtils mLockPatternUtils;
49 private final AlarmManager mAlarmManager;
Jim Milleredc74ab2012-11-06 21:46:11 -080050
Jim Milleredc74ab2012-11-06 21:46:11 -080051 private TextView mAlarmStatusView;
Adrian Roos59de4f32017-05-31 15:22:38 -070052 private DateView mDateView;
Jim Miller0c486892013-10-11 16:21:45 -070053 private TextClock mClockView;
Jorim Jaggi93afa1d2014-06-03 20:56:32 +020054 private TextView mOwnerInfo;
Adrian Roos7907ff22017-01-17 15:44:11 -080055 private ViewGroup mClockContainer;
Adrian Roos56021892017-02-27 20:25:09 +010056 private ChargingView mBatteryDoze;
Jim Milleredc74ab2012-11-06 21:46:11 -080057
Adrian Roosd83e9992017-03-16 15:17:57 -070058 private View[] mVisibleInDoze;
59 private boolean mPulsing;
60 private boolean mDark;
61
Jim Milleredc74ab2012-11-06 21:46:11 -080062 private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
63
64 @Override
65 public void onTimeChanged() {
66 refresh();
67 }
68
69 @Override
Jorim Jaggi5cf17872014-03-26 18:31:48 +010070 public void onKeyguardVisibilityChanged(boolean showing) {
Jim Milleredc74ab2012-11-06 21:46:11 -080071 if (showing) {
72 if (DEBUG) Slog.v(TAG, "refresh statusview showing:" + showing);
73 refresh();
Jorim Jaggi93afa1d2014-06-03 20:56:32 +020074 updateOwnerInfo();
Jim Milleredc74ab2012-11-06 21:46:11 -080075 }
Jorim Jaggi5cf17872014-03-26 18:31:48 +010076 }
Jim Miller20daffd2013-10-07 14:59:53 -070077
Jim Miller38ab2772013-10-08 15:32:09 -070078 @Override
Jorim Jaggi0d210f62015-07-10 14:24:44 -070079 public void onStartedWakingUp() {
Jim Miller20daffd2013-10-07 14:59:53 -070080 setEnableMarquee(true);
Jorim Jaggi5cf17872014-03-26 18:31:48 +010081 }
Jim Miller20daffd2013-10-07 14:59:53 -070082
Jim Miller38ab2772013-10-08 15:32:09 -070083 @Override
Jorim Jaggi0d210f62015-07-10 14:24:44 -070084 public void onFinishedGoingToSleep(int why) {
Jim Miller20daffd2013-10-07 14:59:53 -070085 setEnableMarquee(false);
Jorim Jaggi5cf17872014-03-26 18:31:48 +010086 }
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020087
88 @Override
89 public void onUserSwitchComplete(int userId) {
90 refresh();
Adrian Roose32dac82014-07-28 15:58:50 +020091 updateOwnerInfo();
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020092 }
Jim Milleredc74ab2012-11-06 21:46:11 -080093 };
Jim Miller6212cc02012-09-05 17:35:31 -070094
Jim Millerdcb3d842012-08-23 19:18:12 -070095 public KeyguardStatusView(Context context) {
96 this(context, null, 0);
97 }
98
99 public KeyguardStatusView(Context context, AttributeSet attrs) {
100 this(context, attrs, 0);
101 }
102
103 public KeyguardStatusView(Context context, AttributeSet attrs, int defStyle) {
104 super(context, attrs, defStyle);
Adrian Roos9dd16eb2015-01-08 16:20:49 +0100105 mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
106 mLockPatternUtils = new LockPatternUtils(getContext());
Jim Millerdcb3d842012-08-23 19:18:12 -0700107 }
108
Jim Miller20daffd2013-10-07 14:59:53 -0700109 private void setEnableMarquee(boolean enabled) {
110 if (DEBUG) Log.v(TAG, (enabled ? "Enable" : "Disable") + " transport text marquee");
Adam Powell31049d72013-10-07 12:58:42 -0700111 if (mAlarmStatusView != null) mAlarmStatusView.setSelected(enabled);
John Spurlock1e6eb172014-07-13 11:59:50 -0400112 if (mOwnerInfo != null) mOwnerInfo.setSelected(enabled);
Jim Miller20daffd2013-10-07 14:59:53 -0700113 }
114
Jim Milleredc74ab2012-11-06 21:46:11 -0800115 @Override
116 protected void onFinishInflate() {
117 super.onFinishInflate();
Alan Viverette51efddb2017-04-05 10:00:01 -0400118 mClockContainer = findViewById(R.id.keyguard_clock_container);
119 mAlarmStatusView = findViewById(R.id.alarm_status);
120 mDateView = findViewById(R.id.date_view);
121 mClockView = findViewById(R.id.clock_view);
Selim Cinek9c4a7072014-11-21 17:44:34 +0100122 mClockView.setShowCurrentUserTime(true);
Adrian Roos2edb63b2017-04-26 10:43:21 -0700123 mClockView.setAccessibilityDelegate(new KeyguardClockAccessibilityDelegate(mContext));
Alan Viverette51efddb2017-04-05 10:00:01 -0400124 mOwnerInfo = findViewById(R.id.owner_info);
125 mBatteryDoze = findViewById(R.id.battery_doze);
Adrian Roosd83e9992017-03-16 15:17:57 -0700126 mVisibleInDoze = new View[]{mBatteryDoze, mClockView};
Adrian Roos9dd16eb2015-01-08 16:20:49 +0100127
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700128 boolean shouldMarquee = KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive();
129 setEnableMarquee(shouldMarquee);
Jim Milleredc74ab2012-11-06 21:46:11 -0800130 refresh();
Jorim Jaggi93afa1d2014-06-03 20:56:32 +0200131 updateOwnerInfo();
Jorim Jaggicc12a9d2014-05-26 01:55:29 +0200132
133 // Disable elegant text height because our fancy colon makes the ymin value huge for no
134 // reason.
135 mClockView.setElegantTextHeight(false);
Jim Milleredc74ab2012-11-06 21:46:11 -0800136 }
137
Jorim Jaggie210cc82014-08-12 23:44:59 +0200138 @Override
139 protected void onConfigurationChanged(Configuration newConfig) {
140 super.onConfigurationChanged(newConfig);
141 mClockView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
142 getResources().getDimensionPixelSize(R.dimen.widget_big_font_size));
Selim Cinekb6143c12016-07-14 16:32:23 -0700143 // Some layouts like burmese have a different margin for the clock
144 MarginLayoutParams layoutParams = (MarginLayoutParams) mClockView.getLayoutParams();
145 layoutParams.bottomMargin = getResources().getDimensionPixelSize(
146 R.dimen.bottom_text_spacing_digital);
147 mClockView.setLayoutParams(layoutParams);
Jorim Jaggie210cc82014-08-12 23:44:59 +0200148 mDateView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
149 getResources().getDimensionPixelSize(R.dimen.widget_label_font_size));
Jorim Jaggiad15b492017-05-30 18:01:49 -0700150 if (mOwnerInfo != null) {
151 mOwnerInfo.setTextSize(TypedValue.COMPLEX_UNIT_PX,
152 getResources().getDimensionPixelSize(R.dimen.widget_label_font_size));
153 }
Jorim Jaggie210cc82014-08-12 23:44:59 +0200154 }
155
Jorim Jaggid09def7512014-09-02 18:36:45 +0200156 public void refreshTime() {
Adrian Roos59de4f32017-05-31 15:22:38 -0700157 mDateView.setDatePattern(Patterns.dateViewSkel);
Jim Miller0c486892013-10-11 16:21:45 -0700158
John Spurlock385a63d2013-10-30 19:40:48 -0400159 mClockView.setFormat12Hour(Patterns.clockView12);
160 mClockView.setFormat24Hour(Patterns.clockView24);
Jorim Jaggid09def7512014-09-02 18:36:45 +0200161 }
Jim Miller0c486892013-10-11 16:21:45 -0700162
Jorim Jaggid09def7512014-09-02 18:36:45 +0200163 private void refresh() {
Adrian Roos9dd16eb2015-01-08 16:20:49 +0100164 AlarmManager.AlarmClockInfo nextAlarm =
165 mAlarmManager.getNextAlarmClock(UserHandle.USER_CURRENT);
Jorim Jaggid09def7512014-09-02 18:36:45 +0200166 Patterns.update(mContext, nextAlarm != null);
167
168 refreshTime();
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200169 refreshAlarmStatus(nextAlarm);
Jim Milleredc74ab2012-11-06 21:46:11 -0800170 }
171
Jose Lima235510e2014-08-13 12:50:01 -0700172 void refreshAlarmStatus(AlarmManager.AlarmClockInfo nextAlarm) {
Adrian Roosedad7b24c2014-07-13 14:38:22 +0200173 if (nextAlarm != null) {
Jorim Jaggi321583d2014-08-22 01:33:33 +0200174 String alarm = formatNextAlarm(mContext, nextAlarm);
175 mAlarmStatusView.setText(alarm);
176 mAlarmStatusView.setContentDescription(
177 getResources().getString(R.string.keyguard_accessibility_next_alarm, alarm));
Jim Milleredc74ab2012-11-06 21:46:11 -0800178 mAlarmStatusView.setVisibility(View.VISIBLE);
179 } else {
180 mAlarmStatusView.setVisibility(View.GONE);
181 }
182 }
183
Adrian Roosc934c432017-01-13 11:44:56 -0800184 public int getClockBottom() {
185 return mClockView.getBottom() +
186 ((MarginLayoutParams) mClockView.getLayoutParams()).bottomMargin;
187 }
188
Jose Lima235510e2014-08-13 12:50:01 -0700189 public static String formatNextAlarm(Context context, AlarmManager.AlarmClockInfo info) {
Adrian Roosedad7b24c2014-07-13 14:38:22 +0200190 if (info == null) {
191 return "";
192 }
Selim Cinek9c4a7072014-11-21 17:44:34 +0100193 String skeleton = DateFormat.is24HourFormat(context, ActivityManager.getCurrentUser())
194 ? "EHm"
195 : "Ehma";
Adrian Roosedad7b24c2014-07-13 14:38:22 +0200196 String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton);
197 return DateFormat.format(pattern, info.getTriggerTime()).toString();
198 }
199
Jorim Jaggi93afa1d2014-06-03 20:56:32 +0200200 private void updateOwnerInfo() {
John Spurlock1e6eb172014-07-13 11:59:50 -0400201 if (mOwnerInfo == null) return;
Jorim Jaggi93afa1d2014-06-03 20:56:32 +0200202 String ownerInfo = getOwnerInfo();
203 if (!TextUtils.isEmpty(ownerInfo)) {
204 mOwnerInfo.setVisibility(View.VISIBLE);
205 mOwnerInfo.setText(ownerInfo);
206 } else {
207 mOwnerInfo.setVisibility(View.GONE);
208 }
209 }
210
Jim Milleredc74ab2012-11-06 21:46:11 -0800211 @Override
212 protected void onAttachedToWindow() {
213 super.onAttachedToWindow();
214 KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mInfoCallback);
215 }
216
217 @Override
218 protected void onDetachedFromWindow() {
219 super.onDetachedFromWindow();
220 KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mInfoCallback);
221 }
222
Jorim Jaggi93afa1d2014-06-03 20:56:32 +0200223 private String getOwnerInfo() {
Jorim Jaggi93afa1d2014-06-03 20:56:32 +0200224 String info = null;
Andrei Stingaceanu04e245b2015-11-12 12:15:56 +0000225 if (mLockPatternUtils.isDeviceOwnerInfoEnabled()) {
226 // Use the device owner information set by device policy client via
227 // device policy manager.
228 info = mLockPatternUtils.getDeviceOwnerInfo();
229 } else {
230 // Use the current user owner information if enabled.
231 final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled(
232 KeyguardUpdateMonitor.getCurrentUser());
233 if (ownerInfoEnabled) {
234 info = mLockPatternUtils.getOwnerInfo(KeyguardUpdateMonitor.getCurrentUser());
235 }
Jorim Jaggi93afa1d2014-06-03 20:56:32 +0200236 }
237 return info;
238 }
239
Selim Cinekf99d0002014-06-13 07:36:01 +0200240 @Override
241 public boolean hasOverlappingRendering() {
242 return false;
243 }
244
John Spurlock385a63d2013-10-30 19:40:48 -0400245 // DateFormat.getBestDateTimePattern is extremely expensive, and refresh is called often.
246 // This is an optimization to ensure we only recompute the patterns when the inputs change.
247 private static final class Patterns {
Adrian Roos59de4f32017-05-31 15:22:38 -0700248 static String dateViewSkel;
John Spurlock385a63d2013-10-30 19:40:48 -0400249 static String clockView12;
250 static String clockView24;
251 static String cacheKey;
252
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200253 static void update(Context context, boolean hasAlarm) {
John Spurlock385a63d2013-10-30 19:40:48 -0400254 final Locale locale = Locale.getDefault();
255 final Resources res = context.getResources();
Adrian Roos59de4f32017-05-31 15:22:38 -0700256 dateViewSkel = res.getString(hasAlarm
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200257 ? R.string.abbrev_wday_month_day_no_year_alarm
258 : R.string.abbrev_wday_month_day_no_year);
John Spurlock385a63d2013-10-30 19:40:48 -0400259 final String clockView12Skel = res.getString(R.string.clock_12hr_format);
260 final String clockView24Skel = res.getString(R.string.clock_24hr_format);
261 final String key = locale.toString() + dateViewSkel + clockView12Skel + clockView24Skel;
262 if (key.equals(cacheKey)) return;
263
John Spurlock385a63d2013-10-30 19:40:48 -0400264 clockView12 = DateFormat.getBestDateTimePattern(locale, clockView12Skel);
265 // CLDR insists on adding an AM/PM indicator even though it wasn't in the skeleton
266 // format. The following code removes the AM/PM indicator if we didn't want it.
267 if (!clockView12Skel.contains("a")) {
268 clockView12 = clockView12.replaceAll("a", "").trim();
269 }
270
271 clockView24 = DateFormat.getBestDateTimePattern(locale, clockView24Skel);
272
Jorim Jaggicc12a9d2014-05-26 01:55:29 +0200273 // Use fancy colon.
274 clockView24 = clockView24.replace(':', '\uee01');
275 clockView12 = clockView12.replace(':', '\uee01');
276
John Spurlock385a63d2013-10-30 19:40:48 -0400277 cacheKey = key;
278 }
279 }
Adrian Roos7907ff22017-01-17 15:44:11 -0800280
281 public void setDark(boolean dark) {
Adrian Roos52414e32017-04-28 09:23:19 -0700282 if (mDark == dark) {
283 return;
284 }
Adrian Roosd83e9992017-03-16 15:17:57 -0700285 mDark = dark;
286
Adrian Roos7907ff22017-01-17 15:44:11 -0800287 final int N = mClockContainer.getChildCount();
288 for (int i = 0; i < N; i++) {
289 View child = mClockContainer.getChildAt(i);
Adrian Roosd83e9992017-03-16 15:17:57 -0700290 if (ArrayUtils.contains(mVisibleInDoze, child)) {
Adrian Roos7907ff22017-01-17 15:44:11 -0800291 continue;
292 }
293 child.setAlpha(dark ? 0 : 1);
294 }
Adrian Roosd83e9992017-03-16 15:17:57 -0700295 updateDozeVisibleViews();
Adrian Roos56021892017-02-27 20:25:09 +0100296 mBatteryDoze.setDark(dark);
Adrian Roos7907ff22017-01-17 15:44:11 -0800297 }
Adrian Roosd83e9992017-03-16 15:17:57 -0700298
299 public void setPulsing(boolean pulsing) {
300 mPulsing = pulsing;
301 updateDozeVisibleViews();
302 }
303
304 private void updateDozeVisibleViews() {
305 for (View child : mVisibleInDoze) {
Adrian Roos0bcaa272017-04-06 15:39:22 -0700306 child.setAlpha(mDark && mPulsing ? 0.8f : 1);
Adrian Roosd83e9992017-03-16 15:17:57 -0700307 }
308 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700309}