blob: 37e89c095575831a7df119720a5ad0695122da23 [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
Alex Chauff7653d2018-02-01 17:18:08 +000019import android.app.ActivityManager;
Alex Chauff7653d2018-02-01 17:18:08 +000020import android.app.IActivityManager;
Jim Millerdcb3d842012-08-23 19:18:12 -070021import android.content.Context;
Jim Miller0c486892013-10-11 16:21:45 -070022import android.content.res.Resources;
Lucas Dupin76d38e72017-05-13 22:04:22 -070023import android.graphics.Color;
Geoffrey Pitschc239fef2017-07-14 09:55:16 -040024import android.os.Handler;
25import android.os.Looper;
Alex Chauff7653d2018-02-01 17:18:08 +000026import android.os.RemoteException;
Adrian Roos9dd16eb2015-01-08 16:20:49 +010027import android.os.UserHandle;
Jim Milleredc74ab2012-11-06 21:46:11 -080028import android.text.TextUtils;
Jim Miller38ab2772013-10-08 15:32:09 -070029import android.text.format.DateFormat;
Jim Millerdcb3d842012-08-23 19:18:12 -070030import android.util.AttributeSet;
Jim Miller20daffd2013-10-07 14:59:53 -070031import android.util.Log;
Jim Milleredc74ab2012-11-06 21:46:11 -080032import android.util.Slog;
Jorim Jaggie210cc82014-08-12 23:44:59 +020033import android.util.TypedValue;
Jim Milleredc74ab2012-11-06 21:46:11 -080034import android.view.View;
Jim Millerdcb3d842012-08-23 19:18:12 -070035import android.widget.GridLayout;
Robert Snoeberger78a79d22019-05-07 16:47:07 -040036import android.widget.LinearLayout;
Jim Milleredc74ab2012-11-06 21:46:11 -080037import android.widget.TextView;
Jim Millerdcb3d842012-08-23 19:18:12 -070038
Lucas Dupin43976f82018-10-22 19:52:59 -070039import androidx.core.graphics.ColorUtils;
40
Michael Jurka1254f2f2012-10-25 11:44:31 -070041import com.android.internal.widget.LockPatternUtils;
Lucas Dupin4e023812018-04-02 21:19:23 -070042import com.android.systemui.Dependency;
Lucas Dupin4e023812018-04-02 21:19:23 -070043import com.android.systemui.statusbar.policy.ConfigurationController;
Michael Jurka1254f2f2012-10-25 11:44:31 -070044
Lucas Dupin43499522019-03-04 16:45:58 -080045import java.io.FileDescriptor;
46import java.io.PrintWriter;
Chris Wren56018e52013-01-15 10:59:43 -050047import java.util.Locale;
Robert Snoeberger9c1074f2018-12-07 17:35:21 -050048import java.util.TimeZone;
Chris Wren56018e52013-01-15 10:59:43 -050049
Lucas Dupin4e023812018-04-02 21:19:23 -070050public class KeyguardStatusView extends GridLayout implements
Lucas Dupine570af62019-02-10 14:52:30 -080051 ConfigurationController.ConfigurationListener {
Jorim Jaggi5cf17872014-03-26 18:31:48 +010052 private static final boolean DEBUG = KeyguardConstants.DEBUG;
Jim Milleredc74ab2012-11-06 21:46:11 -080053 private static final String TAG = "KeyguardStatusView";
Geoffrey Pitschc239fef2017-07-14 09:55:16 -040054 private static final int MARQUEE_DELAY_MS = 2000;
Jim Milleredc74ab2012-11-06 21:46:11 -080055
Adrian Roos9dd16eb2015-01-08 16:20:49 +010056 private final LockPatternUtils mLockPatternUtils;
Alex Chauff7653d2018-02-01 17:18:08 +000057 private final IActivityManager mIActivityManager;
Jim Milleredc74ab2012-11-06 21:46:11 -080058
Robert Snoeberger78a79d22019-05-07 16:47:07 -040059 private LinearLayout mStatusViewContainer;
Alex Chauff7653d2018-02-01 17:18:08 +000060 private TextView mLogoutView;
Kunhung Li29007e62018-07-30 19:30:25 +080061 private KeyguardClockSwitch mClockView;
Jorim Jaggi93afa1d2014-06-03 20:56:32 +020062 private TextView mOwnerInfo;
Lucas Dupin957e50c2017-10-10 11:23:27 -070063 private KeyguardSliceView mKeyguardSlice;
Selim Cinek8fd0cca2019-06-10 21:01:18 -070064 private View mNotificationIcons;
Geoffrey Pitschc239fef2017-07-14 09:55:16 -040065 private Runnable mPendingMarqueeStart;
66 private Handler mHandler;
Jim Milleredc74ab2012-11-06 21:46:11 -080067
Adrian Roosd83e9992017-03-16 15:17:57 -070068 private boolean mPulsing;
Adrian Roos7f910722017-07-12 19:15:59 +020069 private float mDarkAmount = 0;
Lucas Dupin76d38e72017-05-13 22:04:22 -070070 private int mTextColor;
Adrian Roosd83e9992017-03-16 15:17:57 -070071
Robert Snoeberger78a79d22019-05-07 16:47:07 -040072 /**
73 * Bottom margin that defines the margin between bottom of smart space and top of notification
74 * icons on AOD.
75 */
Selim Cinekb543f842019-06-12 16:39:43 -070076 private int mIconTopMargin;
77 private int mIconTopMarginWithHeader;
Robert Snoeberger78a79d22019-05-07 16:47:07 -040078 private boolean mShowingHeader;
79
Jim Milleredc74ab2012-11-06 21:46:11 -080080 private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
81
82 @Override
83 public void onTimeChanged() {
Lucas Dupin08c013e2018-04-26 17:45:14 -070084 refreshTime();
Jim Milleredc74ab2012-11-06 21:46:11 -080085 }
86
87 @Override
Robert Snoeberger9c1074f2018-12-07 17:35:21 -050088 public void onTimeZoneChanged(TimeZone timeZone) {
89 updateTimeZone(timeZone);
90 }
91
92 @Override
Jorim Jaggi5cf17872014-03-26 18:31:48 +010093 public void onKeyguardVisibilityChanged(boolean showing) {
Jim Milleredc74ab2012-11-06 21:46:11 -080094 if (showing) {
95 if (DEBUG) Slog.v(TAG, "refresh statusview showing:" + showing);
Lucas Dupin08c013e2018-04-26 17:45:14 -070096 refreshTime();
Jorim Jaggi93afa1d2014-06-03 20:56:32 +020097 updateOwnerInfo();
Alex Chauff7653d2018-02-01 17:18:08 +000098 updateLogoutView();
Jim Milleredc74ab2012-11-06 21:46:11 -080099 }
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100100 }
Jim Miller20daffd2013-10-07 14:59:53 -0700101
Jim Miller38ab2772013-10-08 15:32:09 -0700102 @Override
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700103 public void onStartedWakingUp() {
Jim Miller20daffd2013-10-07 14:59:53 -0700104 setEnableMarquee(true);
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100105 }
Jim Miller20daffd2013-10-07 14:59:53 -0700106
Jim Miller38ab2772013-10-08 15:32:09 -0700107 @Override
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700108 public void onFinishedGoingToSleep(int why) {
Jim Miller20daffd2013-10-07 14:59:53 -0700109 setEnableMarquee(false);
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100110 }
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200111
112 @Override
113 public void onUserSwitchComplete(int userId) {
Lucas Dupin08c013e2018-04-26 17:45:14 -0700114 refreshFormat();
Adrian Roose32dac82014-07-28 15:58:50 +0200115 updateOwnerInfo();
Alex Chauff7653d2018-02-01 17:18:08 +0000116 updateLogoutView();
117 }
118
119 @Override
120 public void onLogoutEnabledChanged() {
121 updateLogoutView();
Jorim Jaggic7dea6e2014-07-26 14:36:57 +0200122 }
Jim Milleredc74ab2012-11-06 21:46:11 -0800123 };
Jim Miller6212cc02012-09-05 17:35:31 -0700124
Jim Millerdcb3d842012-08-23 19:18:12 -0700125 public KeyguardStatusView(Context context) {
126 this(context, null, 0);
127 }
128
129 public KeyguardStatusView(Context context, AttributeSet attrs) {
130 this(context, attrs, 0);
131 }
132
133 public KeyguardStatusView(Context context, AttributeSet attrs, int defStyle) {
134 super(context, attrs, defStyle);
Alex Chauff7653d2018-02-01 17:18:08 +0000135 mIActivityManager = ActivityManager.getService();
Adrian Roos9dd16eb2015-01-08 16:20:49 +0100136 mLockPatternUtils = new LockPatternUtils(getContext());
Geoffrey Pitschc239fef2017-07-14 09:55:16 -0400137 mHandler = new Handler(Looper.myLooper());
Lucas Dupin4e023812018-04-02 21:19:23 -0700138 onDensityOrFontScaleChanged();
Jim Millerdcb3d842012-08-23 19:18:12 -0700139 }
140
Lucas Dupin7fc9dc12019-01-03 09:19:43 -0800141 /**
142 * If we're presenting a custom clock of just the default one.
143 */
144 public boolean hasCustomClock() {
145 return mClockView.hasCustomClock();
146 }
147
Robert Snoeberger146ab3c2019-06-13 14:12:10 -0400148 /**
149 * Set whether or not the lock screen is showing notifications.
150 */
151 public void setHasVisibleNotifications(boolean hasVisibleNotifications) {
152 mClockView.setHasVisibleNotifications(hasVisibleNotifications);
153 }
154
Jim Miller20daffd2013-10-07 14:59:53 -0700155 private void setEnableMarquee(boolean enabled) {
Geoffrey Pitschc239fef2017-07-14 09:55:16 -0400156 if (DEBUG) Log.v(TAG, "Schedule setEnableMarquee: " + (enabled ? "Enable" : "Disable"));
157 if (enabled) {
158 if (mPendingMarqueeStart == null) {
159 mPendingMarqueeStart = () -> {
160 setEnableMarqueeImpl(true);
161 mPendingMarqueeStart = null;
162 };
163 mHandler.postDelayed(mPendingMarqueeStart, MARQUEE_DELAY_MS);
164 }
165 } else {
166 if (mPendingMarqueeStart != null) {
167 mHandler.removeCallbacks(mPendingMarqueeStart);
168 mPendingMarqueeStart = null;
169 }
170 setEnableMarqueeImpl(false);
171 }
172 }
173
174 private void setEnableMarqueeImpl(boolean enabled) {
Jim Miller20daffd2013-10-07 14:59:53 -0700175 if (DEBUG) Log.v(TAG, (enabled ? "Enable" : "Disable") + " transport text marquee");
John Spurlock1e6eb172014-07-13 11:59:50 -0400176 if (mOwnerInfo != null) mOwnerInfo.setSelected(enabled);
Jim Miller20daffd2013-10-07 14:59:53 -0700177 }
178
Jim Milleredc74ab2012-11-06 21:46:11 -0800179 @Override
180 protected void onFinishInflate() {
181 super.onFinishInflate();
Robert Snoeberger78a79d22019-05-07 16:47:07 -0400182 mStatusViewContainer = findViewById(R.id.status_view_container);
Alex Chauff7653d2018-02-01 17:18:08 +0000183 mLogoutView = findViewById(R.id.logout);
Selim Cinek8fd0cca2019-06-10 21:01:18 -0700184 mNotificationIcons = findViewById(R.id.clock_notification_icon_container);
Lucas Dupin0cf5e4a2018-05-02 00:33:17 -0700185 if (mLogoutView != null) {
186 mLogoutView.setOnClickListener(this::onLogoutClicked);
187 }
Alex Chauff7653d2018-02-01 17:18:08 +0000188
Robert Snoebergere3b3e782018-12-17 13:32:15 -0500189 mClockView = findViewById(R.id.keyguard_clock_container);
Selim Cinek9c4a7072014-11-21 17:44:34 +0100190 mClockView.setShowCurrentUserTime(true);
Adrian Roosb670f4b2017-07-20 20:06:54 +0200191 if (KeyguardClockAccessibilityDelegate.isNeeded(mContext)) {
192 mClockView.setAccessibilityDelegate(new KeyguardClockAccessibilityDelegate(mContext));
193 }
Alan Viverette51efddb2017-04-05 10:00:01 -0400194 mOwnerInfo = findViewById(R.id.owner_info);
Lucas Dupin957e50c2017-10-10 11:23:27 -0700195 mKeyguardSlice = findViewById(R.id.keyguard_status_area);
Lucas Dupin76d38e72017-05-13 22:04:22 -0700196 mTextColor = mClockView.getCurrentTextColor();
Adrian Roos9dd16eb2015-01-08 16:20:49 +0100197
Lucas Dupin4e023812018-04-02 21:19:23 -0700198 mKeyguardSlice.setContentChangeListener(this::onSliceContentChanged);
Lucas Dupin3978e6e2018-05-22 18:08:35 -0700199 onSliceContentChanged();
Lucas Dupin6bd86012017-12-05 17:58:57 -0800200
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700201 boolean shouldMarquee = KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive();
202 setEnableMarquee(shouldMarquee);
Lucas Dupin08c013e2018-04-26 17:45:14 -0700203 refreshFormat();
Jorim Jaggi93afa1d2014-06-03 20:56:32 +0200204 updateOwnerInfo();
Alex Chauff7653d2018-02-01 17:18:08 +0000205 updateLogoutView();
Lucas Dupin4e023812018-04-02 21:19:23 -0700206 updateDark();
Jim Milleredc74ab2012-11-06 21:46:11 -0800207 }
208
Lucas Dupin1a388512018-06-28 11:09:09 -0700209 /**
Lucas Dupinc9d28b72018-10-22 17:59:18 -0700210 * Moves clock, adjusting margins when slice content changes.
Lucas Dupin1a388512018-06-28 11:09:09 -0700211 */
Lucas Dupin3978e6e2018-05-22 18:08:35 -0700212 private void onSliceContentChanged() {
Robert Snoeberger78a79d22019-05-07 16:47:07 -0400213 final boolean hasHeader = mKeyguardSlice.hasHeader();
214 mClockView.setKeyguardShowingHeader(hasHeader);
215 if (mShowingHeader == hasHeader) {
216 return;
217 }
218 mShowingHeader = hasHeader;
Selim Cinekb543f842019-06-12 16:39:43 -0700219 if (mNotificationIcons != null) {
220 // Update top margin since header has appeared/disappeared.
221 MarginLayoutParams params = (MarginLayoutParams) mNotificationIcons.getLayoutParams();
222 params.setMargins(params.leftMargin,
223 hasHeader ? mIconTopMarginWithHeader : mIconTopMargin,
224 params.rightMargin,
225 params.bottomMargin);
226 mNotificationIcons.setLayoutParams(params);
Robert Snoeberger78a79d22019-05-07 16:47:07 -0400227 }
Lucas Dupin6bd86012017-12-05 17:58:57 -0800228 }
229
Jorim Jaggie210cc82014-08-12 23:44:59 +0200230 @Override
Lucas Dupin4e023812018-04-02 21:19:23 -0700231 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
232 super.onLayout(changed, left, top, right, bottom);
Lucas Dupin09952ee2018-06-06 18:19:18 -0700233 layoutOwnerInfo();
Lucas Dupin4e023812018-04-02 21:19:23 -0700234 }
235
236 @Override
237 public void onDensityOrFontScaleChanged() {
Lucas Dupin4e023812018-04-02 21:19:23 -0700238 if (mClockView != null) {
239 mClockView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
240 getResources().getDimensionPixelSize(R.dimen.widget_big_font_size));
241 }
Jorim Jaggiad15b492017-05-30 18:01:49 -0700242 if (mOwnerInfo != null) {
243 mOwnerInfo.setTextSize(TypedValue.COMPLEX_UNIT_PX,
244 getResources().getDimensionPixelSize(R.dimen.widget_label_font_size));
245 }
Robert Snoeberger78a79d22019-05-07 16:47:07 -0400246 loadBottomMargin();
Jorim Jaggie210cc82014-08-12 23:44:59 +0200247 }
248
Lucas Dupin9fedb892018-05-04 17:42:33 -0700249 public void dozeTimeTick() {
250 refreshTime();
251 mKeyguardSlice.refresh();
252 }
253
254 private void refreshTime() {
Lucas Dupinf9583c42018-04-05 22:20:44 -0700255 mClockView.refresh();
Jorim Jaggid09def7512014-09-02 18:36:45 +0200256 }
Jim Miller0c486892013-10-11 16:21:45 -0700257
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500258 private void updateTimeZone(TimeZone timeZone) {
259 mClockView.onTimeZoneChanged(timeZone);
260 }
261
Lucas Dupin08c013e2018-04-26 17:45:14 -0700262 private void refreshFormat() {
Lucas Dupinca46ae92018-04-02 11:05:09 -0700263 Patterns.update(mContext);
Lucas Dupin08c013e2018-04-26 17:45:14 -0700264 mClockView.setFormat12Hour(Patterns.clockView12);
265 mClockView.setFormat24Hour(Patterns.clockView24);
Jim Milleredc74ab2012-11-06 21:46:11 -0800266 }
267
Alex Chauff7653d2018-02-01 17:18:08 +0000268 public int getLogoutButtonHeight() {
Lucas Dupin0cf5e4a2018-05-02 00:33:17 -0700269 if (mLogoutView == null) {
270 return 0;
271 }
Alex Chauff7653d2018-02-01 17:18:08 +0000272 return mLogoutView.getVisibility() == VISIBLE ? mLogoutView.getHeight() : 0;
Adrian Roosc934c432017-01-13 11:44:56 -0800273 }
274
Lucas Dupin987f1932017-05-13 21:02:52 -0700275 public float getClockTextSize() {
276 return mClockView.getTextSize();
277 }
278
Robert Snoeberger69956802019-04-16 16:55:21 -0400279 /**
280 * Returns the preferred Y position of the clock.
281 *
282 * @param totalHeight The height available to position the clock.
283 * @return Y position of clock.
284 */
285 public int getClockPreferredY(int totalHeight) {
286 return mClockView.getPreferredY(totalHeight);
287 }
288
Alex Chauff7653d2018-02-01 17:18:08 +0000289 private void updateLogoutView() {
Lucas Dupin0cf5e4a2018-05-02 00:33:17 -0700290 if (mLogoutView == null) {
291 return;
292 }
Alex Chauff7653d2018-02-01 17:18:08 +0000293 mLogoutView.setVisibility(shouldShowLogout() ? VISIBLE : GONE);
294 // Logout button will stay in language of user 0 if we don't set that manually.
295 mLogoutView.setText(mContext.getResources().getString(
296 com.android.internal.R.string.global_action_logout));
297 }
298
Jorim Jaggi93afa1d2014-06-03 20:56:32 +0200299 private void updateOwnerInfo() {
John Spurlock1e6eb172014-07-13 11:59:50 -0400300 if (mOwnerInfo == null) return;
Lucas Dupin4e023812018-04-02 21:19:23 -0700301 String info = mLockPatternUtils.getDeviceOwnerInfo();
302 if (info == null) {
Andrei Stingaceanu04e245b2015-11-12 12:15:56 +0000303 // Use the current user owner information if enabled.
304 final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled(
305 KeyguardUpdateMonitor.getCurrentUser());
306 if (ownerInfoEnabled) {
307 info = mLockPatternUtils.getOwnerInfo(KeyguardUpdateMonitor.getCurrentUser());
308 }
Jorim Jaggi93afa1d2014-06-03 20:56:32 +0200309 }
Lucas Dupin4e023812018-04-02 21:19:23 -0700310 mOwnerInfo.setText(info);
Lucas Dupin43976f82018-10-22 19:52:59 -0700311 updateDark();
Lucas Dupin4e023812018-04-02 21:19:23 -0700312 }
313
314 @Override
315 protected void onAttachedToWindow() {
316 super.onAttachedToWindow();
317 KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mInfoCallback);
318 Dependency.get(ConfigurationController.class).addCallback(this);
319 }
320
321 @Override
322 protected void onDetachedFromWindow() {
323 super.onDetachedFromWindow();
324 KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mInfoCallback);
325 Dependency.get(ConfigurationController.class).removeCallback(this);
Jorim Jaggi93afa1d2014-06-03 20:56:32 +0200326 }
327
Selim Cinekf99d0002014-06-13 07:36:01 +0200328 @Override
Lucas Dupin08c013e2018-04-26 17:45:14 -0700329 public void onLocaleListChanged() {
330 refreshFormat();
331 }
332
Lucas Dupin43499522019-03-04 16:45:58 -0800333 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
334 pw.println("KeyguardStatusView:");
335 pw.println(" mOwnerInfo: " + (mOwnerInfo == null
336 ? "null" : mOwnerInfo.getVisibility() == VISIBLE));
337 pw.println(" mPulsing: " + mPulsing);
338 pw.println(" mDarkAmount: " + mDarkAmount);
339 pw.println(" mTextColor: " + Integer.toHexString(mTextColor));
340 if (mLogoutView != null) {
341 pw.println(" logout visible: " + (mLogoutView.getVisibility() == VISIBLE));
342 }
343 if (mClockView != null) {
344 mClockView.dump(fd, pw, args);
345 }
346 if (mKeyguardSlice != null) {
347 mKeyguardSlice.dump(fd, pw, args);
348 }
349 }
350
Robert Snoeberger78a79d22019-05-07 16:47:07 -0400351 private void loadBottomMargin() {
Selim Cinekb543f842019-06-12 16:39:43 -0700352 mIconTopMargin = getResources().getDimensionPixelSize(R.dimen.widget_vertical_padding);
353 mIconTopMarginWithHeader = getResources().getDimensionPixelSize(
Robert Snoeberger78a79d22019-05-07 16:47:07 -0400354 R.dimen.widget_vertical_padding_with_header);
355 }
356
John Spurlock385a63d2013-10-30 19:40:48 -0400357 // DateFormat.getBestDateTimePattern is extremely expensive, and refresh is called often.
358 // This is an optimization to ensure we only recompute the patterns when the inputs change.
359 private static final class Patterns {
John Spurlock385a63d2013-10-30 19:40:48 -0400360 static String clockView12;
361 static String clockView24;
362 static String cacheKey;
363
Lucas Dupinca46ae92018-04-02 11:05:09 -0700364 static void update(Context context) {
John Spurlock385a63d2013-10-30 19:40:48 -0400365 final Locale locale = Locale.getDefault();
366 final Resources res = context.getResources();
John Spurlock385a63d2013-10-30 19:40:48 -0400367 final String clockView12Skel = res.getString(R.string.clock_12hr_format);
368 final String clockView24Skel = res.getString(R.string.clock_24hr_format);
Lucas Dupinca46ae92018-04-02 11:05:09 -0700369 final String key = locale.toString() + clockView12Skel + clockView24Skel;
John Spurlock385a63d2013-10-30 19:40:48 -0400370 if (key.equals(cacheKey)) return;
371
John Spurlock385a63d2013-10-30 19:40:48 -0400372 clockView12 = DateFormat.getBestDateTimePattern(locale, clockView12Skel);
373 // CLDR insists on adding an AM/PM indicator even though it wasn't in the skeleton
374 // format. The following code removes the AM/PM indicator if we didn't want it.
375 if (!clockView12Skel.contains("a")) {
376 clockView12 = clockView12.replaceAll("a", "").trim();
377 }
378
379 clockView24 = DateFormat.getBestDateTimePattern(locale, clockView24Skel);
380
Jorim Jaggicc12a9d2014-05-26 01:55:29 +0200381 // Use fancy colon.
382 clockView24 = clockView24.replace(':', '\uee01');
383 clockView12 = clockView12.replace(':', '\uee01');
384
John Spurlock385a63d2013-10-30 19:40:48 -0400385 cacheKey = key;
386 }
387 }
Adrian Roos7907ff22017-01-17 15:44:11 -0800388
Lucas Dupin4272f442018-01-13 22:00:35 -0800389 public void setDarkAmount(float darkAmount) {
Lucas Dupin76d38e72017-05-13 22:04:22 -0700390 if (mDarkAmount == darkAmount) {
Adrian Roos52414e32017-04-28 09:23:19 -0700391 return;
392 }
Lucas Dupin76d38e72017-05-13 22:04:22 -0700393 mDarkAmount = darkAmount;
Robert Snoebergere32efd72018-11-12 08:38:34 -0500394 mClockView.setDarkAmount(darkAmount);
Lucas Dupin4e023812018-04-02 21:19:23 -0700395 updateDark();
Adrian Roos7907ff22017-01-17 15:44:11 -0800396 }
Adrian Roosd83e9992017-03-16 15:17:57 -0700397
Lucas Dupin4e023812018-04-02 21:19:23 -0700398 private void updateDark() {
399 boolean dark = mDarkAmount == 1;
Lucas Dupin0cf5e4a2018-05-02 00:33:17 -0700400 if (mLogoutView != null) {
401 mLogoutView.setAlpha(dark ? 0 : 1);
402 }
Lucas Dupin09952ee2018-06-06 18:19:18 -0700403
Lucas Dupin4e023812018-04-02 21:19:23 -0700404 if (mOwnerInfo != null) {
405 boolean hasText = !TextUtils.isEmpty(mOwnerInfo.getText());
Lucas Dupin09952ee2018-06-06 18:19:18 -0700406 mOwnerInfo.setVisibility(hasText ? VISIBLE : GONE);
407 layoutOwnerInfo();
Lucas Dupin4e023812018-04-02 21:19:23 -0700408 }
409
410 final int blendedTextColor = ColorUtils.blendARGB(mTextColor, Color.WHITE, mDarkAmount);
Lucas Dupin4e023812018-04-02 21:19:23 -0700411 mKeyguardSlice.setDarkAmount(mDarkAmount);
412 mClockView.setTextColor(blendedTextColor);
Lucas Dupin4e023812018-04-02 21:19:23 -0700413 }
414
Lucas Dupin09952ee2018-06-06 18:19:18 -0700415 private void layoutOwnerInfo() {
416 if (mOwnerInfo != null && mOwnerInfo.getVisibility() != GONE) {
417 // Animate owner info during wake-up transition
418 mOwnerInfo.setAlpha(1f - mDarkAmount);
419
420 float ratio = mDarkAmount;
421 // Calculate how much of it we should crop in order to have a smooth transition
422 int collapsed = mOwnerInfo.getTop() - mOwnerInfo.getPaddingTop();
423 int expanded = mOwnerInfo.getBottom() + mOwnerInfo.getPaddingBottom();
424 int toRemove = (int) ((expanded - collapsed) * ratio);
425 setBottom(getMeasuredHeight() - toRemove);
Selim Cinekf6d63f92019-06-12 10:00:47 -0700426 if (mNotificationIcons != null) {
427 // We're using scrolling in order not to overload the translation which is used
428 // when appearing the icons
429 mNotificationIcons.setScrollY(toRemove);
430 }
431 } else if (mNotificationIcons != null){
Selim Cinek8fd0cca2019-06-10 21:01:18 -0700432 mNotificationIcons.setScrollY(0);
Lucas Dupin09952ee2018-06-06 18:19:18 -0700433 }
434 }
435
Lucas Dupin00be88f2019-01-03 17:50:52 -0800436 public void setPulsing(boolean pulsing) {
Lucas Dupin2a6bdfd2018-06-12 17:45:21 -0700437 if (mPulsing == pulsing) {
438 return;
439 }
Adrian Roosd83e9992017-03-16 15:17:57 -0700440 mPulsing = pulsing;
Adrian Roosd83e9992017-03-16 15:17:57 -0700441 }
Alex Chauff7653d2018-02-01 17:18:08 +0000442
443 private boolean shouldShowLogout() {
444 return KeyguardUpdateMonitor.getInstance(mContext).isLogoutEnabled()
445 && KeyguardUpdateMonitor.getCurrentUser() != UserHandle.USER_SYSTEM;
446 }
447
448 private void onLogoutClicked(View view) {
449 int currentUserId = KeyguardUpdateMonitor.getCurrentUser();
450 try {
451 mIActivityManager.switchUser(UserHandle.USER_SYSTEM);
452 mIActivityManager.stopUser(currentUserId, true /*force*/, null);
453 } catch (RemoteException re) {
454 Log.e(TAG, "Failed to logout user", re);
455 }
456 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700457}