diff options
14 files changed, 343 insertions, 101 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index acac6718c9be..2f8651416057 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -5778,6 +5778,14 @@ public final class Settings { "touch_exploration_granted_accessibility_services"; /** + * Uri of the slice that's presented on the keyguard. + * Defaults to a slice with the date and next alarm. + * + * @hide + */ + public static final String KEYGUARD_SLICE_URI = "keyguard_slice_uri"; + + /** * Whether to speak passwords while in accessibility mode. * * @deprecated The speaking of passwords is controlled by individual accessibility services. diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index eef9866d7691..fc8650086cd8 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -525,7 +525,8 @@ public class SettingsBackupTest { Settings.Secure.VOICE_INTERACTION_SERVICE, Settings.Secure.VOICE_RECOGNITION_SERVICE, Settings.Secure.INSTANT_APPS_ENABLED, - Settings.Secure.BACKUP_MANAGER_CONSTANTS); + Settings.Secure.BACKUP_MANAGER_CONSTANTS, + Settings.Secure.KEYGUARD_SLICE_URI); @Test public void systemSettingsBackedUpOrBlacklisted() { diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk index 2c5eb27abe3d..73fcdd7aa90d 100644 --- a/packages/SystemUI/Android.mk +++ b/packages/SystemUI/Android.mk @@ -39,7 +39,12 @@ LOCAL_STATIC_ANDROID_LIBRARIES := \ android-support-v7-mediarouter \ android-support-v7-palette \ android-support-v14-preference \ - android-support-v17-leanback + android-support-v17-leanback \ + android-slices-core \ + android-slices-view \ + android-slices-builders \ + apptoolkit-arch-core-runtime \ + apptoolkit-lifecycle-extensions \ LOCAL_STATIC_JAVA_LIBRARIES := \ SystemUI-tags \ diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml index 020cfeeaa194..b154d46f162c 100644 --- a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml +++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml @@ -24,31 +24,20 @@ android:layout_marginEnd="16dp" android:layout_width="wrap_content" android:layout_height="wrap_content" - 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" + android:layout_marginBottom="@dimen/widget_vertical_padding" + android:theme="@style/TextAppearance.Keyguard" /> - <TextView android:id="@+id/text" + <LinearLayout android:id="@+id/row" android:layout_width="match_parent" android:layout_height="wrap_content" - android:singleLine="true" + android:orientation="horizontal" 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/res-keyguard/layout/keyguard_status_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml index 138733e646ce..c97cfc4bb835 100644 --- a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml +++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml @@ -34,6 +34,7 @@ android:orientation="vertical"> <RelativeLayout android:id="@+id/keyguard_clock_container" + android:animateLayoutChanges="true" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal|top"> @@ -59,14 +60,23 @@ android:layout_toEndOf="@id/clock_view" android:visibility="invisible" android:src="@drawable/ic_aod_charging_24dp" - android:contentDescription="@string/accessibility_ambient_display_charging" - /> + android:contentDescription="@string/accessibility_ambient_display_charging" /> + <View + android:id="@+id/clock_separator" + android:layout_width="16dp" + android:layout_height="1dp" + android:layout_marginTop="10dp" + android:layout_below="@id/clock_view" + android:background="#f00" + android:layout_centerHorizontal="true" /> <include layout="@layout/keyguard_status_area" android:id="@+id/keyguard_status_area" + android:layout_marginTop="10dp" + android:layout_marginBottom="@dimen/widget_vertical_padding" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_below="@id/clock_view" /> + android:layout_below="@id/clock_separator" /> </RelativeLayout> <TextView @@ -83,6 +93,5 @@ android:letterSpacing="0.05" android:ellipsize="marquee" android:singleLine="true" /> - </LinearLayout> </com.android.keyguard.KeyguardStatusView> diff --git a/packages/SystemUI/res-keyguard/values-h560dp/dimens.xml b/packages/SystemUI/res-keyguard/values-h560dp/dimens.xml index 1b6fa4cf4892..3fb86d03a167 100644 --- a/packages/SystemUI/res-keyguard/values-h560dp/dimens.xml +++ b/packages/SystemUI/res-keyguard/values-h560dp/dimens.xml @@ -16,5 +16,5 @@ --> <resources> - <dimen name="widget_big_font_size">72dp</dimen> + <dimen name="widget_big_font_size">64dp</dimen> </resources>
\ No newline at end of file diff --git a/packages/SystemUI/res-keyguard/values-h650dp/dimens.xml b/packages/SystemUI/res-keyguard/values-h650dp/dimens.xml index 1b6fa4cf4892..3fb86d03a167 100644 --- a/packages/SystemUI/res-keyguard/values-h650dp/dimens.xml +++ b/packages/SystemUI/res-keyguard/values-h650dp/dimens.xml @@ -16,5 +16,5 @@ --> <resources> - <dimen name="widget_big_font_size">72dp</dimen> + <dimen name="widget_big_font_size">64dp</dimen> </resources>
\ No newline at end of file diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml index bcac07295cce..463af61c16f1 100644 --- a/packages/SystemUI/res-keyguard/values/dimens.xml +++ b/packages/SystemUI/res-keyguard/values/dimens.xml @@ -42,9 +42,22 @@ <dimen name="eca_overlap">-10dip</dimen> <!-- Default clock parameters --> - <dimen name="bottom_text_spacing_digital">-1dp</dimen> - <dimen name="widget_label_font_size">14sp</dimen> - <dimen name="widget_big_font_size">72dp</dimen> + <dimen name="bottom_text_spacing_digital">-10dp</dimen> + <!-- Slice header --> + <dimen name="widget_title_font_size">28sp</dimen> + <!-- Slice subtitle --> + <dimen name="widget_label_font_size">16sp</dimen> + <!-- Clock without header --> + <dimen name="widget_big_font_size">64dp</dimen> + <!-- Clock with header --> + <dimen name="widget_small_font_size">22dp</dimen> + <!-- Dash between clock and header --> + <dimen name="widget_vertical_padding">16dp</dimen> + <!-- Subtitle paddings --> + <dimen name="widget_separator_thickness">2dp</dimen> + <dimen name="widget_horizontal_padding">8dp</dimen> + <dimen name="widget_icon_size">16dp</dimen> + <dimen name="widget_icon_padding">4dp</dimen> <!-- The y translation to apply at the start in appear animations. --> <dimen name="appear_y_translation_start">32dp</dimen> diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml index 826e3ea1f7e5..d50bab533856 100644 --- a/packages/SystemUI/res-keyguard/values/styles.xml +++ b/packages/SystemUI/res-keyguard/values/styles.xml @@ -78,4 +78,18 @@ <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_dark</item> </style> + <style name="TextAppearance.Keyguard" parent="Theme.SystemUI"> + <item name="android:textSize">@dimen/widget_title_font_size</item> + <item name="android:gravity">center</item> + <item name="android:ellipsize">end</item> + <item name="android:maxLines">2</item> + </style> + + <style name="TextAppearance.Keyguard.Secondary"> + <item name="android:layout_width">wrap_content</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:textSize">@dimen/widget_label_font_size</item> + <item name="android:singleLine">true</item> + </style> + </resources> diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java index cb3d59c4dff6..b9bf80de304b 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java @@ -17,38 +17,56 @@ 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.arch.lifecycle.LiveData; +import android.arch.lifecycle.Observer; import android.content.Context; -import android.database.ContentObserver; +import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.drawable.Drawable; import android.net.Uri; -import android.os.Handler; +import android.provider.Settings; import android.util.AttributeSet; +import android.util.Log; +import android.view.View; +import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; import com.android.internal.graphics.ColorUtils; +import com.android.settingslib.Utils; +import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.keyguard.KeyguardSliceProvider; +import com.android.systemui.tuner.TunerService; -import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.function.Consumer; + +import androidx.app.slice.Slice; +import androidx.app.slice.SliceItem; +import androidx.app.slice.core.SliceQuery; +import androidx.app.slice.widget.SliceLiveData; /** * View visible under the clock on the lock screen and AoD. */ -public class KeyguardSliceView extends LinearLayout { +public class KeyguardSliceView extends LinearLayout implements View.OnClickListener, + Observer<Slice>, TunerService.Tunable { - private final Uri mKeyguardSliceUri; + private static final String TAG = "KeyguardSliceView"; + private final HashMap<View, PendingIntent> mClickActions; + private Uri mKeyguardSliceUri; private TextView mTitle; - private TextView mText; - private Slice mSlice; - private PendingIntent mSliceAction; + private LinearLayout mRow; private int mTextColor; private float mDarkAmount = 0; - private final ContentObserver mObserver; + private LiveData<Slice> mLiveData; + private int mIconSize; + private Consumer<Boolean> mListener; + private boolean mHasHeader; public KeyguardSliceView(Context context) { this(context, null, 0); @@ -60,16 +78,20 @@ public class KeyguardSliceView extends LinearLayout { public KeyguardSliceView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - mObserver = new KeyguardSliceObserver(new Handler()); - mKeyguardSliceUri = Uri.parse(KeyguardSliceProvider.KEYGUARD_SLICE_URI);; + + TunerService tunerService = Dependency.get(TunerService.class); + tunerService.addTunable(this, Settings.Secure.KEYGUARD_SLICE_URI); + + mClickActions = new HashMap<>(); } @Override protected void onFinishInflate() { super.onFinishInflate(); mTitle = findViewById(R.id.title); - mText = findViewById(R.id.text); - mTextColor = mTitle.getCurrentTextColor(); + mRow = findViewById(R.id.row); + mTextColor = Utils.getColorAttr(mContext, R.attr.wallpaperTextColor); + mIconSize = (int) mContext.getResources().getDimension(R.dimen.widget_icon_size); } @Override @@ -77,57 +99,103 @@ public class KeyguardSliceView extends LinearLayout { super.onAttachedToWindow(); // Set initial content - showSlice(Slice.bindSlice(getContext().getContentResolver(), mKeyguardSliceUri, - Collections.emptyList())); + showSlice(Slice.bindSlice(getContext(), mKeyguardSliceUri)); // Make sure we always have the most current slice - getContext().getContentResolver().registerContentObserver(mKeyguardSliceUri, - false /* notifyDescendants */, mObserver); + mLiveData.observeForever(this); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); - getContext().getContentResolver().unregisterContentObserver(mObserver); + mLiveData.removeObserver(this); } private void showSlice(Slice slice) { - // Items will be wrapped into an action when they have tap targets. - SliceItem actionSlice = SliceQuery.find(slice, SliceItem.FORMAT_ACTION); - if (actionSlice != null) { - mSlice = actionSlice.getSlice(); - mSliceAction = actionSlice.getAction(); - } else { - mSlice = slice; - mSliceAction = null; - } - if (mSlice == null) { - setVisibility(GONE); - return; - } + // Main area + SliceItem mainItem = SliceQuery.find(slice, android.app.slice.SliceItem.FORMAT_SLICE, + null /* hints */, new String[]{android.app.slice.Slice.HINT_LIST_ITEM}); + mHasHeader = mainItem != null; - SliceItem title = SliceQuery.find(mSlice, SliceItem.FORMAT_TEXT, Slice.HINT_TITLE, null); - if (title == null) { + List<SliceItem> subItems = SliceQuery.findAll(slice, + android.app.slice.SliceItem.FORMAT_SLICE, + new String[]{android.app.slice.Slice.HINT_LIST_ITEM}, + null /* nonHints */); + + if (!mHasHeader) { mTitle.setVisibility(GONE); } else { mTitle.setVisibility(VISIBLE); - mTitle.setText(title.getText()); + SliceItem mainTitle = SliceQuery.find(mainItem.getSlice(), + android.app.slice.SliceItem.FORMAT_TEXT, + new String[]{android.app.slice.Slice.HINT_TITLE}, + null /* nonHints */); + mTitle.setText(mainTitle.getText()); } - SliceItem text = SliceQuery.find(mSlice, SliceItem.FORMAT_TEXT, null, Slice.HINT_TITLE); - if (text == null) { - mText.setVisibility(GONE); - } else { - mText.setVisibility(VISIBLE); - mText.setText(text.getText()); + mClickActions.clear(); + final int subItemsCount = subItems.size(); + + for (int i = 0; i < subItemsCount; i++) { + SliceItem item = subItems.get(i); + final Uri itemTag = item.getSlice().getUri(); + // Try to reuse the view if already exists in the layout + KeyguardSliceButton button = mRow.findViewWithTag(itemTag); + if (button == null) { + button = new KeyguardSliceButton(mContext); + button.setTextColor(mTextColor); + button.setTag(itemTag); + } else { + mRow.removeView(button); + } + button.setHasDivider(i < subItemsCount - 1); + mRow.addView(button, i); + + PendingIntent pendingIntent; + try { + pendingIntent = item.getAction(); + } catch (RuntimeException e) { + Log.w(TAG, "Cannot retrieve action from keyguard slice", e); + pendingIntent = null; + } + mClickActions.put(button, pendingIntent); + + SliceItem title = SliceQuery.find(item.getSlice(), + android.app.slice.SliceItem.FORMAT_TEXT, + new String[]{android.app.slice.Slice.HINT_TITLE}, + null /* nonHints */); + button.setText(title.getText()); + + Drawable iconDrawable = null; + SliceItem icon = SliceQuery.find(item.getSlice(), + android.app.slice.SliceItem.FORMAT_IMAGE); + if (icon != null) { + iconDrawable = icon.getIcon().loadDrawable(mContext); + final int width = (int) (iconDrawable.getIntrinsicWidth() + / (float) iconDrawable.getIntrinsicHeight() * mIconSize); + iconDrawable.setBounds(0, 0, Math.max(width, 1), mIconSize); + } + button.setCompoundDrawablesRelative(iconDrawable, null, null, null); + button.setOnClickListener(this); + } + + // Removing old views + for (int i = 0; i < mRow.getChildCount(); i++) { + View child = mRow.getChildAt(i); + if (!mClickActions.containsKey(child)) { + mRow.removeView(child); + i--; + } } - final int visibility = title == null && text == null ? GONE : VISIBLE; + final int visibility = mHasHeader || subItemsCount > 0 ? VISIBLE : GONE; if (visibility != getVisibility()) { setVisibility(visibility); } + + mListener.accept(mHasHeader); } public void setDark(float darkAmount) { @@ -135,30 +203,113 @@ public class KeyguardSliceView extends LinearLayout { 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); + int childCount = mRow.getChildCount(); + for (int i = 0; i < childCount; i++) { + View v = mRow.getChildAt(i); + if (v instanceof Button) { + ((Button) v).setTextColor(blendedColor); + } + } + } + + @Override + public void onClick(View v) { + final PendingIntent action = mClickActions.get(v); + if (action != null) { + try { + action.send(); + } catch (PendingIntent.CanceledException e) { + Log.i(TAG, "Pending intent cancelled, nothing to launch", e); + } + } } - private class KeyguardSliceObserver extends ContentObserver { - KeyguardSliceObserver(Handler handler) { - super(handler); + public void setListener(Consumer<Boolean> listener) { + mListener = listener; + } + + public boolean hasHeader() { + return mHasHeader; + } + + /** + * LiveData observer lifecycle. + * @param slice the new slice content. + */ + @Override + public void onChanged(Slice slice) { + showSlice(slice); + } + + @Override + public void onTuningChanged(String key, String newValue) { + setupUri(newValue); + } + + public void setupUri(String uriString) { + if (uriString == null) { + uriString = KeyguardSliceProvider.KEYGUARD_SLICE_URI; + } + + boolean wasObserving = false; + if (mLiveData != null && mLiveData.hasActiveObservers()) { + wasObserving = true; + mLiveData.removeObserver(this); + } + + mKeyguardSliceUri = Uri.parse(uriString); + mLiveData = SliceLiveData.fromUri(mContext, mKeyguardSliceUri); + + if (wasObserving) { + mLiveData.observeForever(this); + showSlice(Slice.bindSlice(getContext(), mKeyguardSliceUri)); + } + } + + /** + * Representation of an item that appears under the clock on main keyguard message. + * Shows optional separator. + */ + private class KeyguardSliceButton extends Button { + + private final Paint mPaint; + private boolean mHasDivider; + + public KeyguardSliceButton(Context context) { + super(context, null /* attrs */, + com.android.keyguard.R.style.TextAppearance_Keyguard_Secondary); + mPaint = new Paint(); + mPaint.setStyle(Paint.Style.STROKE); + float dividerWidth = context.getResources() + .getDimension(R.dimen.widget_separator_thickness); + mPaint.setStrokeWidth(dividerWidth); + int horizontalPadding = (int) context.getResources() + .getDimension(R.dimen.widget_horizontal_padding); + setPadding(horizontalPadding, 0, horizontalPadding, 0); + setCompoundDrawablePadding((int) context.getResources() + .getDimension(R.dimen.widget_icon_padding)); + } + + public void setHasDivider(boolean hasDivider) { + mHasDivider = hasDivider; } @Override - public void onChange(boolean selfChange) { - this.onChange(selfChange, null); + public void setTextColor(int color) { + super.setTextColor(color); + mPaint.setColor(color); } @Override - public void onChange(boolean selfChange, Uri uri) { - showSlice(Slice.bindSlice(getContext().getContentResolver(), mKeyguardSliceUri, - Collections.emptyList())); + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + if (mHasDivider) { + final int lineX = getLayoutDirection() == LAYOUT_DIRECTION_RTL ? 0 : getWidth(); + canvas.drawLine(lineX, 0, lineX, getHeight(), mPaint); + } } } } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java index 78cf2b9bf1ed..4abf88602947 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java @@ -28,6 +28,7 @@ import android.os.UserHandle; import android.support.v4.graphics.ColorUtils; import android.text.TextUtils; import android.text.format.DateFormat; +import android.util.ArraySet; import android.util.AttributeSet; import android.util.Log; import android.util.Slog; @@ -38,11 +39,11 @@ import android.widget.GridLayout; import android.widget.TextClock; 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.google.android.collect.Sets; + import java.util.Locale; public class KeyguardStatusView extends GridLayout { @@ -52,8 +53,11 @@ public class KeyguardStatusView extends GridLayout { private final LockPatternUtils mLockPatternUtils; private final AlarmManager mAlarmManager; + private final float mSmallClockScale; + private final float mWidgetPadding; private TextClock mClockView; + private View mClockSeparator; private TextView mOwnerInfo; private ViewGroup mClockContainer; private ChargingView mBatteryDoze; @@ -61,7 +65,7 @@ public class KeyguardStatusView extends GridLayout { private Runnable mPendingMarqueeStart; private Handler mHandler; - private View[] mVisibleInDoze; + private ArraySet<View> mVisibleInDoze; private boolean mPulsing; private float mDarkAmount = 0; private int mTextColor; @@ -112,6 +116,9 @@ public class KeyguardStatusView extends GridLayout { mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); mLockPatternUtils = new LockPatternUtils(getContext()); mHandler = new Handler(Looper.myLooper()); + mSmallClockScale = getResources().getDimension(R.dimen.widget_small_font_size) + / getResources().getDimension(R.dimen.widget_big_font_size); + mWidgetPadding = getResources().getDimension(R.dimen.widget_vertical_padding); } private void setEnableMarquee(boolean enabled) { @@ -150,9 +157,14 @@ public class KeyguardStatusView extends GridLayout { mOwnerInfo = findViewById(R.id.owner_info); mBatteryDoze = findViewById(R.id.battery_doze); mKeyguardSlice = findViewById(R.id.keyguard_status_area); - mVisibleInDoze = new View[]{mBatteryDoze, mClockView, mKeyguardSlice}; + mClockSeparator = findViewById(R.id.clock_separator); + mVisibleInDoze = Sets.newArraySet(mBatteryDoze, mClockView, mKeyguardSlice, + mClockSeparator); mTextColor = mClockView.getCurrentTextColor(); + mKeyguardSlice.setListener(this::onSliceContentChanged); + onSliceContentChanged(mKeyguardSlice.hasHeader()); + boolean shouldMarquee = KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive(); setEnableMarquee(shouldMarquee); refresh(); @@ -163,6 +175,22 @@ public class KeyguardStatusView extends GridLayout { mClockView.setElegantTextHeight(false); } + private void onSliceContentChanged(boolean hasHeader) { + final float clockScale = hasHeader ? mSmallClockScale : 1; + float translation = (mClockView.getHeight() - (mClockView.getHeight() * clockScale)) / 2f; + if (hasHeader) { + translation -= mWidgetPadding; + } + mClockView.setTranslationY(translation); + mClockView.setScaleX(clockScale); + mClockView.setScaleY(clockScale); + final float batteryTranslation = + -(mClockView.getWidth() - (mClockView.getWidth() * clockScale)) / 2; + mBatteryDoze.setTranslationX(batteryTranslation); + mBatteryDoze.setTranslationY(translation); + mClockSeparator.setVisibility(hasHeader ? VISIBLE : GONE); + } + @Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); @@ -303,7 +331,7 @@ public class KeyguardStatusView extends GridLayout { final int N = mClockContainer.getChildCount(); for (int i = 0; i < N; i++) { View child = mClockContainer.getChildAt(i); - if (ArrayUtils.contains(mVisibleInDoze, child)) { + if (mVisibleInDoze.contains(child)) { continue; } child.setAlpha(dark ? 0 : 1); @@ -312,10 +340,12 @@ public class KeyguardStatusView extends GridLayout { mOwnerInfo.setAlpha(dark ? 0 : 1); } + final int blendedTextColor = ColorUtils.blendARGB(mTextColor, Color.WHITE, darkAmount); updateDozeVisibleViews(); mBatteryDoze.setDark(dark); mKeyguardSlice.setDark(darkAmount); - mClockView.setTextColor(ColorUtils.blendARGB(mTextColor, Color.WHITE, darkAmount)); + mClockView.setTextColor(blendedTextColor); + mClockSeparator.setBackgroundColor(blendedTextColor); } 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 index 6ddc76b595b2..2b09903a524d 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java @@ -24,8 +24,6 @@ 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; @@ -33,15 +31,22 @@ import com.android.systemui.R; import java.util.Date; import java.util.Locale; +import androidx.app.slice.Slice; +import androidx.app.slice.SliceProvider; +import androidx.app.slice.builders.ListBuilder; +import androidx.app.slice.builders.ListBuilder.RowBuilder; + /** * 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"; + public static final String KEYGUARD_DATE_URI = "content://com.android.systemui.keyguard/date"; private final Date mCurrentTime = new Date(); protected final Uri mSliceUri; + protected final Uri mDateUri; private final Handler mHandler; private String mDatePattern; private DateFormat mDateFormat; @@ -80,23 +85,31 @@ public class KeyguardSliceProvider extends SliceProvider { KeyguardSliceProvider(Handler handler) { mHandler = handler; mSliceUri = Uri.parse(KEYGUARD_SLICE_URI); + mDateUri = Uri.parse(KEYGUARD_DATE_URI); } + + @Override public Slice onBindSlice(Uri sliceUri) { - return new Slice.Builder(sliceUri).addText(mLastText, null, Slice.HINT_TITLE).build(); + return new ListBuilder(mSliceUri) + .addRow(new RowBuilder(mDateUri).setTitle(mLastText)).build(); } @Override - public boolean onCreate() { - + public boolean onCreateSliceProvider() { mDatePattern = getContext().getString(R.string.system_ui_date_pattern); - registerClockUpdate(false /* everyMinute */); updateClock(); return true; } + /** + * Registers a broadcast receiver for clock updates, include date, time zone and manually + * changing the date/time via the settings app. + * + * @param everyMinute {@code true} if you also want updates every minute. + */ protected void registerClockUpdate(boolean everyMinute) { if (mRegistered) { if (mRegisteredEveryMinute == everyMinute) { diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk index 9d44895dbe8d..066cfe5862ef 100644 --- a/packages/SystemUI/tests/Android.mk +++ b/packages/SystemUI/tests/Android.mk @@ -46,7 +46,12 @@ LOCAL_STATIC_ANDROID_LIBRARIES := \ android-support-v7-mediarouter \ android-support-v7-palette \ android-support-v14-preference \ - android-support-v17-leanback + android-support-v17-leanback \ + android-slices-core \ + android-slices-view \ + android-slices-builders \ + apptoolkit-arch-core-runtime \ + apptoolkit-lifecycle-extensions \ LOCAL_STATIC_JAVA_LIBRARIES := \ metrics-helper-lib \ diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java index 4eae3426f815..be28569ef629 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java @@ -16,11 +16,10 @@ package com.android.systemui.keyguard; -import android.app.slice.Slice; -import android.app.slice.SliceItem; -import android.app.slice.SliceQuery; +import androidx.app.slice.Slice; import android.content.Intent; import android.net.Uri; +import android.os.Debug; import android.os.Handler; import android.support.test.filters.SmallTest; import android.testing.AndroidTestingRunner; @@ -34,6 +33,9 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import androidx.app.slice.SliceItem; +import androidx.app.slice.core.SliceQuery; + @SmallTest @RunWith(AndroidTestingRunner.class) @RunWithLooper(setAsMainLooper = true) @@ -63,7 +65,8 @@ public class KeyguardSliceProviderTest extends SysuiTestCase { @Test public void returnsValidSlice() { Slice slice = mProvider.onBindSlice(Uri.parse(KeyguardSliceProvider.KEYGUARD_SLICE_URI)); - SliceItem text = SliceQuery.find(slice, SliceItem.FORMAT_TEXT, Slice.HINT_TITLE, + SliceItem text = SliceQuery.find(slice, android.app.slice.SliceItem.FORMAT_TEXT, + android.app.slice.Slice.HINT_TITLE, null /* nonHints */); Assert.assertNotNull("Slice must provide a title.", text); } @@ -78,9 +81,10 @@ public class KeyguardSliceProviderTest extends SysuiTestCase { @Test public void updatesClock() { + mProvider.mUpdateClockInvokations = 0; mProvider.mIntentReceiver.onReceive(getContext(), new Intent(Intent.ACTION_TIME_TICK)); TestableLooper.get(this).processAllMessages(); - Assert.assertEquals("Clock should have been updated.", 2 /* expected */, + Assert.assertEquals("Clock should have been updated.", 1 /* expected */, mProvider.mUpdateClockInvokations); } |