blob: 03018f7d8778b6c8d31a1a650d1e8987dd23a401 [file] [log] [blame]
Lucas Dupin957e50c2017-10-10 11:23:27 -07001/*
2 * Copyright (C) 2017 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
17package com.android.systemui.keyguard;
18
19import android.content.BroadcastReceiver;
20import android.content.Context;
21import android.content.Intent;
22import android.content.IntentFilter;
23import android.icu.text.DateFormat;
24import android.icu.text.DisplayContext;
25import android.net.Uri;
26import android.os.Handler;
27import android.app.slice.Slice;
28import android.app.slice.SliceProvider;
29
30import com.android.internal.annotations.VisibleForTesting;
31import com.android.systemui.R;
32
33import java.util.Date;
34import java.util.Locale;
35
36/**
37 * Simple Slice provider that shows the current date.
38 */
39public class KeyguardSliceProvider extends SliceProvider {
40
41 public static final String KEYGUARD_SLICE_URI = "content://com.android.systemui.keyguard/main";
42
43 private final Date mCurrentTime = new Date();
44 protected final Uri mSliceUri;
45 private final Handler mHandler;
46 private String mDatePattern;
47 private DateFormat mDateFormat;
48 private String mLastText;
49 private boolean mRegistered;
50 private boolean mRegisteredEveryMinute;
51
52 /**
53 * Receiver responsible for time ticking and updating the date format.
54 */
55 @VisibleForTesting
56 final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
57 @Override
58 public void onReceive(Context context, Intent intent) {
59 final String action = intent.getAction();
60 if (Intent.ACTION_TIME_TICK.equals(action)
61 || Intent.ACTION_DATE_CHANGED.equals(action)
62 || Intent.ACTION_TIME_CHANGED.equals(action)
63 || Intent.ACTION_TIMEZONE_CHANGED.equals(action)
64 || Intent.ACTION_LOCALE_CHANGED.equals(action)) {
65 if (Intent.ACTION_LOCALE_CHANGED.equals(action)
66 || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
67 // need to get a fresh date format
68 mHandler.post(KeyguardSliceProvider.this::cleanDateFormat);
69 }
70 mHandler.post(KeyguardSliceProvider.this::updateClock);
71 }
72 }
73 };
74
75 public KeyguardSliceProvider() {
76 this(new Handler());
77 }
78
79 @VisibleForTesting
80 KeyguardSliceProvider(Handler handler) {
81 mHandler = handler;
82 mSliceUri = Uri.parse(KEYGUARD_SLICE_URI);
83 }
84
85 @Override
86 public Slice onBindSlice(Uri sliceUri) {
87 return new Slice.Builder(sliceUri).addText(mLastText, Slice.HINT_TITLE).build();
88 }
89
90 @Override
91 public boolean onCreate() {
92
93 mDatePattern = getContext().getString(R.string.system_ui_date_pattern);
94
95 registerClockUpdate(false /* everyMinute */);
96 updateClock();
97 return true;
98 }
99
100 protected void registerClockUpdate(boolean everyMinute) {
101 if (mRegistered) {
102 if (mRegisteredEveryMinute == everyMinute) {
103 return;
104 } else {
105 unregisterClockUpdate();
106 }
107 }
108
109 IntentFilter filter = new IntentFilter();
110 if (everyMinute) {
111 filter.addAction(Intent.ACTION_TIME_TICK);
112 }
113 filter.addAction(Intent.ACTION_DATE_CHANGED);
114 filter.addAction(Intent.ACTION_TIME_CHANGED);
115 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
116 filter.addAction(Intent.ACTION_LOCALE_CHANGED);
117 getContext().registerReceiver(mIntentReceiver, filter, null /* permission*/,
118 null /* scheduler */);
119 mRegistered = true;
120 mRegisteredEveryMinute = everyMinute;
121 }
122
123 protected void unregisterClockUpdate() {
124 if (!mRegistered) {
125 return;
126 }
127 getContext().unregisterReceiver(mIntentReceiver);
128 mRegistered = false;
129 }
130
131 @VisibleForTesting
132 boolean isRegistered() {
133 return mRegistered;
134 }
135
136 protected void updateClock() {
137 final String text = getFormattedDate();
138 if (!text.equals(mLastText)) {
139 mLastText = text;
140 getContext().getContentResolver().notifyChange(mSliceUri, null /* observer */);
141 }
142 }
143
144 protected String getFormattedDate() {
145 if (mDateFormat == null) {
146 final Locale l = Locale.getDefault();
147 DateFormat format = DateFormat.getInstanceForSkeleton(mDatePattern, l);
148 format.setContext(DisplayContext.CAPITALIZATION_FOR_STANDALONE);
149 mDateFormat = format;
150 }
151 mCurrentTime.setTime(System.currentTimeMillis());
152 return mDateFormat.format(mCurrentTime);
153 }
154
155 @VisibleForTesting
156 void cleanDateFormat() {
157 mDateFormat = null;
158 }
159}