diff options
8 files changed, 475 insertions, 68 deletions
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 82aa803ef0ca..f7e0b46ca265 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -328,6 +328,7 @@ applications that come with the platform <privapp-permissions package="com.android.systemui"> <permission name="android.permission.BATTERY_STATS"/> <permission name="android.permission.BIND_APPWIDGET"/> + <permission name="android.permission.BIND_SLICE" /> <permission name="android.permission.BLUETOOTH_PRIVILEGED"/> <permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/> <permission name="android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST"/> diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 7b8d0db9739e..29ecac0080ee 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -120,6 +120,7 @@ <uses-permission android:name="android.permission.TRUST_LISTENER" /> <uses-permission android:name="android.permission.USE_FINGERPRINT" /> <uses-permission android:name="android.permission.RESET_FINGERPRINT_LOCKOUT" /> + <uses-permission android:name="android.permission.BIND_SLICE" /> <!-- Needed for WallpaperManager.clear in ImageWallpaper.updateWallpaperLocked --> <uses-permission android:name="android.permission.SET_WALLPAPER"/> @@ -222,7 +223,7 @@ --> <service android:name="SystemUIService" android:exported="true" - /> + /> <!-- Recents depends on every user having their own SystemUI process, so on user switch, ensure that the process is created by starting this service. @@ -568,6 +569,11 @@ android:resource="@xml/fileprovider" /> </provider> + <provider android:name=".keyguard.KeyguardSliceProvider" + android:authorities="com.android.systemui.keyguard" + android:exported="true"> + </provider> + <receiver android:name=".statusbar.KeyboardShortcutsReceiver"> <intent-filter> diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml index 56fb73faf868..020cfeeaa194 100644 --- a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml +++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml @@ -18,34 +18,37 @@ --> <!-- This is a view that shows general status information in Keyguard. --> -<LinearLayout +<com.android.keyguard.KeyguardSliceView xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:androidprv="http://schemas.android.com/apk/res-auto" - android:layout_width="match_parent" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:layout_width="wrap_content" android:layout_height="wrap_content" - android:orientation="horizontal" - android:gravity="center"> - <com.android.systemui.statusbar.policy.DateView - android:id="@+id/date_view" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textColor="?attr/wallpaperTextColor" - style="@style/widget_label" - android:letterSpacing="0.05" - android:gravity="center" - /> - <TextView android:id="@+id/alarm_status" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:drawablePadding="6dp" - android:drawableStart="@drawable/ic_access_alarms_big" - android:drawableTint="?attr/wallpaperTextColorSecondary" - android:drawableTintMode="src_in" - android:textColor="?attr/wallpaperTextColorSecondary" - android:letterSpacing="0.05" - style="@style/widget_label" - android:layout_marginStart="6dp" - android:gravity="center" - android:visibility="gone" - /> -</LinearLayout> + android:layout_marginTop="@dimen/date_owner_info_margin" + android:layout_gravity="center_horizontal" + android:paddingTop="4dp" + android:clipToPadding="false" + android:orientation="vertical" + android:layout_centerHorizontal="true"> + <TextView android:id="@+id/title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:singleLine="true" + android:ellipsize="end" + android:fadingEdge="horizontal" + android:gravity="center" + android:textSize="22sp" + android:textColor="?attr/wallpaperTextColor" + /> + <TextView android:id="@+id/text" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:singleLine="true" + android:gravity="center" + android:visibility="gone" + android:textSize="16sp" + android:textColor="?attr/wallpaperTextColor" + android:layout_marginTop="4dp" + android:ellipsize="end" + /> +</com.android.keyguard.KeyguardSliceView>
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java new file mode 100644 index 000000000000..c18f9b61c044 --- /dev/null +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.keyguard; + +import android.app.PendingIntent; +import android.app.slice.Slice; +import android.app.slice.SliceItem; +import android.app.slice.SliceQuery; +import android.content.Context; +import android.database.ContentObserver; +import android.graphics.Color; +import android.net.Uri; +import android.os.Handler; +import android.util.AttributeSet; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.android.internal.graphics.ColorUtils; +import com.android.systemui.R; +import com.android.systemui.keyguard.KeyguardSliceProvider; + +/** + * View visible under the clock on the lock screen and AoD. + */ +public class KeyguardSliceView extends LinearLayout { + + private final Uri mKeyguardSliceUri; + private TextView mTitle; + private TextView mText; + private Slice mSlice; + private PendingIntent mSliceAction; + private int mTextColor; + private float mDarkAmount = 0; + + private final ContentObserver mObserver; + + public KeyguardSliceView(Context context) { + this(context, null, 0); + } + + public KeyguardSliceView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public KeyguardSliceView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + mObserver = new KeyguardSliceObserver(new Handler()); + mKeyguardSliceUri = Uri.parse(KeyguardSliceProvider.KEYGUARD_SLICE_URI);; + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mTitle = findViewById(R.id.title); + mText = findViewById(R.id.text); + mTextColor = mTitle.getCurrentTextColor(); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + + // Set initial content + showSlice(Slice.bindSlice(getContext().getContentResolver(), mKeyguardSliceUri)); + + // Make sure we always have the most current slice + getContext().getContentResolver().registerContentObserver(mKeyguardSliceUri, + false /* notifyDescendants */, mObserver); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + + getContext().getContentResolver().unregisterContentObserver(mObserver); + } + + private void showSlice(Slice slice) { + // Items will be wrapped into an action when they have tap targets. + SliceItem actionSlice = SliceQuery.find(slice, SliceItem.TYPE_ACTION); + if (actionSlice != null) { + mSlice = actionSlice.getSlice(); + mSliceAction = actionSlice.getAction(); + } else { + mSlice = slice; + mSliceAction = null; + } + + if (mSlice == null) { + setVisibility(GONE); + return; + } + + SliceItem title = SliceQuery.find(mSlice, SliceItem.TYPE_TEXT, Slice.HINT_TITLE, null); + if (title == null) { + mTitle.setVisibility(GONE); + } else { + mTitle.setVisibility(VISIBLE); + mTitle.setText(title.getText()); + } + + SliceItem text = SliceQuery.find(mSlice, SliceItem.TYPE_TEXT, null, Slice.HINT_TITLE); + if (text == null) { + mText.setVisibility(GONE); + } else { + mText.setVisibility(VISIBLE); + mText.setText(text.getText()); + } + + final int visibility = title == null && text == null ? GONE : VISIBLE; + if (visibility != getVisibility()) { + setVisibility(visibility); + } + } + + public void setDark(float darkAmount) { + mDarkAmount = darkAmount; + updateTextColors(); + } + + public void setTextColor(int textColor) { + mTextColor = textColor; + } + + private void updateTextColors() { + final int blendedColor = ColorUtils.blendARGB(mTextColor, Color.WHITE, mDarkAmount); + mTitle.setTextColor(blendedColor); + mText.setTextColor(blendedColor); + } + + private class KeyguardSliceObserver extends ContentObserver { + KeyguardSliceObserver(Handler handler) { + super(handler); + } + + @Override + public void onChange(boolean selfChange) { + this.onChange(selfChange, null); + } + + @Override + public void onChange(boolean selfChange, Uri uri) { + showSlice(Slice.bindSlice(getContext().getContentResolver(), mKeyguardSliceUri)); + } + } +} diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java index bc2a59df42a6..78cf2b9bf1ed 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java @@ -19,11 +19,9 @@ package com.android.keyguard; import android.app.ActivityManager; import android.app.AlarmManager; import android.content.Context; -import android.content.res.ColorStateList; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Color; -import android.graphics.PorterDuff; import android.os.Handler; import android.os.Looper; import android.os.UserHandle; @@ -42,8 +40,8 @@ import android.widget.TextView; import com.android.internal.util.ArrayUtils; import com.android.internal.widget.LockPatternUtils; +import com.android.settingslib.Utils; import com.android.systemui.ChargingView; -import com.android.systemui.statusbar.policy.DateView; import java.util.Locale; @@ -55,13 +53,11 @@ public class KeyguardStatusView extends GridLayout { private final LockPatternUtils mLockPatternUtils; private final AlarmManager mAlarmManager; - private TextView mAlarmStatusView; - private DateView mDateView; private TextClock mClockView; private TextView mOwnerInfo; private ViewGroup mClockContainer; private ChargingView mBatteryDoze; - private View mKeyguardStatusArea; + private KeyguardSliceView mKeyguardSlice; private Runnable mPendingMarqueeStart; private Handler mHandler; @@ -69,8 +65,6 @@ public class KeyguardStatusView extends GridLayout { private boolean mPulsing; private float mDarkAmount = 0; private int mTextColor; - private int mDateTextColor; - private int mAlarmTextColor; private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() { @@ -141,7 +135,6 @@ public class KeyguardStatusView extends GridLayout { private void setEnableMarqueeImpl(boolean enabled) { if (DEBUG) Log.v(TAG, (enabled ? "Enable" : "Disable") + " transport text marquee"); - if (mAlarmStatusView != null) mAlarmStatusView.setSelected(enabled); if (mOwnerInfo != null) mOwnerInfo.setSelected(enabled); } @@ -149,8 +142,6 @@ public class KeyguardStatusView extends GridLayout { protected void onFinishInflate() { super.onFinishInflate(); mClockContainer = findViewById(R.id.keyguard_clock_container); - mAlarmStatusView = findViewById(R.id.alarm_status); - mDateView = findViewById(R.id.date_view); mClockView = findViewById(R.id.clock_view); mClockView.setShowCurrentUserTime(true); if (KeyguardClockAccessibilityDelegate.isNeeded(mContext)) { @@ -158,11 +149,9 @@ public class KeyguardStatusView extends GridLayout { } mOwnerInfo = findViewById(R.id.owner_info); mBatteryDoze = findViewById(R.id.battery_doze); - mKeyguardStatusArea = findViewById(R.id.keyguard_status_area); - mVisibleInDoze = new View[]{mBatteryDoze, mClockView, mKeyguardStatusArea}; + mKeyguardSlice = findViewById(R.id.keyguard_status_area); + mVisibleInDoze = new View[]{mBatteryDoze, mClockView, mKeyguardSlice}; mTextColor = mClockView.getCurrentTextColor(); - mDateTextColor = mDateView.getCurrentTextColor(); - mAlarmTextColor = mAlarmStatusView.getCurrentTextColor(); boolean shouldMarquee = KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive(); setEnableMarquee(shouldMarquee); @@ -184,8 +173,6 @@ public class KeyguardStatusView extends GridLayout { layoutParams.bottomMargin = getResources().getDimensionPixelSize( R.dimen.bottom_text_spacing_digital); mClockView.setLayoutParams(layoutParams); - mDateView.setTextSize(TypedValue.COMPLEX_UNIT_PX, - getResources().getDimensionPixelSize(R.dimen.widget_label_font_size)); if (mOwnerInfo != null) { mOwnerInfo.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.widget_label_font_size)); @@ -193,8 +180,6 @@ public class KeyguardStatusView extends GridLayout { } public void refreshTime() { - mDateView.setDatePattern(Patterns.dateViewSkel); - mClockView.setFormat12Hour(Patterns.clockView12); mClockView.setFormat24Hour(Patterns.clockView24); } @@ -205,23 +190,11 @@ public class KeyguardStatusView extends GridLayout { Patterns.update(mContext, nextAlarm != null); refreshTime(); - refreshAlarmStatus(nextAlarm); - } - - void refreshAlarmStatus(AlarmManager.AlarmClockInfo nextAlarm) { - if (nextAlarm != null) { - String alarm = formatNextAlarm(mContext, nextAlarm); - mAlarmStatusView.setText(alarm); - mAlarmStatusView.setContentDescription( - getResources().getString(R.string.keyguard_accessibility_next_alarm, alarm)); - mAlarmStatusView.setVisibility(View.VISIBLE); - } else { - mAlarmStatusView.setVisibility(View.GONE); - } } public int getClockBottom() { - return mKeyguardStatusArea.getBottom(); + return mKeyguardSlice.getVisibility() == VISIBLE ? mKeyguardSlice.getBottom() + : mClockView.getBottom(); } public float getClockTextSize() { @@ -341,11 +314,8 @@ public class KeyguardStatusView extends GridLayout { updateDozeVisibleViews(); mBatteryDoze.setDark(dark); + mKeyguardSlice.setDark(darkAmount); mClockView.setTextColor(ColorUtils.blendARGB(mTextColor, Color.WHITE, darkAmount)); - mDateView.setTextColor(ColorUtils.blendARGB(mDateTextColor, Color.WHITE, darkAmount)); - int blendedAlarmColor = ColorUtils.blendARGB(mAlarmTextColor, Color.WHITE, darkAmount); - mAlarmStatusView.setTextColor(blendedAlarmColor); - mAlarmStatusView.setCompoundDrawableTintList(ColorStateList.valueOf(blendedAlarmColor)); } public void setPulsing(boolean pulsing) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java new file mode 100644 index 000000000000..03018f7d8778 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.systemui.keyguard; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.icu.text.DateFormat; +import android.icu.text.DisplayContext; +import android.net.Uri; +import android.os.Handler; +import android.app.slice.Slice; +import android.app.slice.SliceProvider; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.systemui.R; + +import java.util.Date; +import java.util.Locale; + +/** + * Simple Slice provider that shows the current date. + */ +public class KeyguardSliceProvider extends SliceProvider { + + public static final String KEYGUARD_SLICE_URI = "content://com.android.systemui.keyguard/main"; + + private final Date mCurrentTime = new Date(); + protected final Uri mSliceUri; + private final Handler mHandler; + private String mDatePattern; + private DateFormat mDateFormat; + private String mLastText; + private boolean mRegistered; + private boolean mRegisteredEveryMinute; + + /** + * Receiver responsible for time ticking and updating the date format. + */ + @VisibleForTesting + final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (Intent.ACTION_TIME_TICK.equals(action) + || Intent.ACTION_DATE_CHANGED.equals(action) + || Intent.ACTION_TIME_CHANGED.equals(action) + || Intent.ACTION_TIMEZONE_CHANGED.equals(action) + || Intent.ACTION_LOCALE_CHANGED.equals(action)) { + if (Intent.ACTION_LOCALE_CHANGED.equals(action) + || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) { + // need to get a fresh date format + mHandler.post(KeyguardSliceProvider.this::cleanDateFormat); + } + mHandler.post(KeyguardSliceProvider.this::updateClock); + } + } + }; + + public KeyguardSliceProvider() { + this(new Handler()); + } + + @VisibleForTesting + KeyguardSliceProvider(Handler handler) { + mHandler = handler; + mSliceUri = Uri.parse(KEYGUARD_SLICE_URI); + } + + @Override + public Slice onBindSlice(Uri sliceUri) { + return new Slice.Builder(sliceUri).addText(mLastText, Slice.HINT_TITLE).build(); + } + + @Override + public boolean onCreate() { + + mDatePattern = getContext().getString(R.string.system_ui_date_pattern); + + registerClockUpdate(false /* everyMinute */); + updateClock(); + return true; + } + + protected void registerClockUpdate(boolean everyMinute) { + if (mRegistered) { + if (mRegisteredEveryMinute == everyMinute) { + return; + } else { + unregisterClockUpdate(); + } + } + + IntentFilter filter = new IntentFilter(); + if (everyMinute) { + filter.addAction(Intent.ACTION_TIME_TICK); + } + filter.addAction(Intent.ACTION_DATE_CHANGED); + filter.addAction(Intent.ACTION_TIME_CHANGED); + filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); + filter.addAction(Intent.ACTION_LOCALE_CHANGED); + getContext().registerReceiver(mIntentReceiver, filter, null /* permission*/, + null /* scheduler */); + mRegistered = true; + mRegisteredEveryMinute = everyMinute; + } + + protected void unregisterClockUpdate() { + if (!mRegistered) { + return; + } + getContext().unregisterReceiver(mIntentReceiver); + mRegistered = false; + } + + @VisibleForTesting + boolean isRegistered() { + return mRegistered; + } + + protected void updateClock() { + final String text = getFormattedDate(); + if (!text.equals(mLastText)) { + mLastText = text; + getContext().getContentResolver().notifyChange(mSliceUri, null /* observer */); + } + } + + protected String getFormattedDate() { + if (mDateFormat == null) { + final Locale l = Locale.getDefault(); + DateFormat format = DateFormat.getInstanceForSkeleton(mDatePattern, l); + format.setContext(DisplayContext.CAPITALIZATION_FOR_STANDALONE); + mDateFormat = format; + } + mCurrentTime.setTime(System.currentTimeMillis()); + return mDateFormat.format(mCurrentTime); + } + + @VisibleForTesting + void cleanDateFormat() { + mDateFormat = null; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 55308928f9e7..7261db1428fd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -7113,7 +7113,7 @@ public class StatusBar extends SystemUI implements DemoMode, mAllowLockscreenRemoteInput = allowLockscreenRemoteInput; } - private void updateLockscreenNotificationSetting() { + protected void updateLockscreenNotificationSetting() { final boolean show = Settings.Secure.getIntForUser(mContext.getContentResolver(), Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1, diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java new file mode 100644 index 000000000000..4437aaca521d --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.systemui.keyguard; + +import android.app.slice.Slice; +import android.app.slice.SliceItem; +import android.app.slice.SliceQuery; +import android.content.Intent; +import android.net.Uri; +import android.os.Handler; +import android.support.test.filters.SmallTest; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.testing.TestableLooper.RunWithLooper; + +import com.android.systemui.SysuiTestCase; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +@RunWithLooper(setAsMainLooper = true) +public class KeyguardSliceProviderTest extends SysuiTestCase { + + private TestableKeyguardSliceProvider mProvider; + + @Before + public void setup() { + mProvider = new TestableKeyguardSliceProvider(); + mProvider.attachInfo(getContext(), null); + } + + @Test + public void registersClockUpdate() { + Assert.assertTrue("registerClockUpdate should have been called during initialization.", + mProvider.isRegistered()); + } + + @Test + public void unregisterClockUpdate() { + mProvider.unregisterClockUpdate(); + Assert.assertFalse("Clock updates should have been unregistered.", + mProvider.isRegistered()); + } + + @Test + public void returnsValidSlice() { + Slice slice = mProvider.onBindSlice(Uri.parse(KeyguardSliceProvider.KEYGUARD_SLICE_URI)); + SliceItem text = SliceQuery.find(slice, SliceItem.TYPE_TEXT, Slice.HINT_TITLE, + null /* nonHints */); + Assert.assertNotNull("Slice must provide a title.", text); + } + + @Test + public void cleansDateFormat() { + mProvider.mIntentReceiver.onReceive(getContext(), new Intent(Intent.ACTION_TIMEZONE_CHANGED)); + TestableLooper.get(this).processAllMessages(); + Assert.assertEquals("Date format should have been cleaned.", 1 /* expected */, + mProvider.mCleanDateFormatInvokations); + } + + @Test + public void updatesClock() { + mProvider.mIntentReceiver.onReceive(getContext(), new Intent(Intent.ACTION_TIME_TICK)); + TestableLooper.get(this).processAllMessages(); + Assert.assertEquals("Clock should have been updated.", 2 /* expected */, + mProvider.mUpdateClockInvokations); + } + + private class TestableKeyguardSliceProvider extends KeyguardSliceProvider { + int mCleanDateFormatInvokations; + int mUpdateClockInvokations; + + TestableKeyguardSliceProvider() { + super(new Handler(TestableLooper.get(KeyguardSliceProviderTest.this).getLooper())); + } + + @Override + void cleanDateFormat() { + super.cleanDateFormat(); + mCleanDateFormatInvokations++; + } + + @Override + protected void updateClock() { + super.updateClock(); + mUpdateClockInvokations++; + } + } + +} |