diff options
author | Danny Lin <danny@kdrag0n.dev> | 2020-11-03 13:17:29 -0800 |
---|---|---|
committer | alk3pInjection <webmaster@raspii.tech> | 2021-09-27 21:17:05 +0800 |
commit | f3354b658fbcc145ef66475404b298ec4c3be5e0 (patch) | |
tree | e8e74fcb2ee20e68fe524a86a9360b65a38babcc | |
parent | 1cfdd307448a54a436c94db4ddc884b0ae157e7a (diff) |
[crdroid][11.0] SystemUI: Restore typographic clock face
This reverts commits 583067c4e4799b0a633d8e861698c8fc2a5c7a6f and
37fe8022174fc809ef4622f7d6c69f9bdff06913.
This clock face still works fine and we can expose it in ThemePicker.
Changes made for forward-porting to Android 11:
- Added SmallClockPosition to manage preferred Y position
- Adjusted resources class imports for res-keyguard merge
- Updated arguments to ColorExtractor#getColors
Change-Id: If75c593e3403962e1a7ffa6fae0734f785d79589
8 files changed, 501 insertions, 0 deletions
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/type_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/type_thumbnail.png Binary files differnew file mode 100644 index 000000000000..2bfd655e37de --- /dev/null +++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/type_thumbnail.png diff --git a/packages/SystemUI/res-keyguard/layout/type_aod_clock.xml b/packages/SystemUI/res-keyguard/layout/type_aod_clock.xml new file mode 100644 index 000000000000..28ff5a253317 --- /dev/null +++ b/packages/SystemUI/res-keyguard/layout/type_aod_clock.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2019 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. + --> +<com.android.keyguard.clock.ClockLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + > + <include layout="@layout/typographic_clock" /> +</com.android.keyguard.clock.ClockLayout> diff --git a/packages/SystemUI/res-keyguard/layout/typographic_clock.xml b/packages/SystemUI/res-keyguard/layout/typographic_clock.xml new file mode 100644 index 000000000000..73bb4b9a0fc9 --- /dev/null +++ b/packages/SystemUI/res-keyguard/layout/typographic_clock.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2019 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. + --> +<com.android.keyguard.clock.TypographicClock + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/type_clock" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingStart="50dp" + android:textAlignment="viewStart" + style="@style/widget_big" + android:textSize="40dp" + /> diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml index 4b6621379b44..91df39056849 100644 --- a/packages/SystemUI/res-keyguard/values/strings.xml +++ b/packages/SystemUI/res-keyguard/values/strings.xml @@ -318,11 +318,113 @@ number">%d</xliff:g> remaining attempt before SIM becomes permanently unusable. number">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. Contact carrier for details.</item> </plurals> + <!-- Time displayed on typographic clock face, which displays the time in words. + Example: + + It's + Four + Twenty + Nine + + This string requires two arguments: the first in the hours of the time and + the second is the minutes of the time. The hours string is obtained from + string-array type_clock_hours below and the minutes string is obtained + from string-array type_clock_minutes below. + + [CHAR LIMIT=8] --> + <plurals name="type_clock_header"> + <item quantity="one"><annotation name="color">It\u2019s</annotation>\n^1\n^2</item> + <item quantity="few"><annotation name="color">It\u2019s</annotation>\n^1\n^2</item> + <item quantity="other"><annotation name="color">It\u2019s</annotation>\n^1\n^2</item> + </plurals> + + <!-- Hour displayed in words on the typographic clock face. [CHAR LIMIT=12] --> + <string-array name="type_clock_hours"> + <item>Twelve</item> + <item>One</item> + <item>Two</item> + <item>Three</item> + <item>Four</item> + <item>Five</item> + <item>Six</item> + <item>Seven</item> + <item>Eight</item> + <item>Nine</item> + <item>Ten</item> + <item>Eleven</item> + </string-array> + + <!-- Minutes displayed in words on the typographic clock face. [CHAR LIMIT=20] --> + <string-array name="type_clock_minutes"> + <item>O\u2019Clock</item> + <item>Oh One</item> + <item>Oh Two</item> + <item>Oh Three</item> + <item>Oh Four</item> + <item>Oh Five</item> + <item>Oh Six</item> + <item>Oh Seven</item> + <item>Oh Eight</item> + <item>Oh Nine</item> + <item>Ten</item> + <item>Eleven</item> + <item>Twelve</item> + <item>Thirteen</item> + <item>Fourteen</item> + <item>Fifteen</item> + <item>Sixteen</item> + <item>Seventeen</item> + <item>Eighteen</item> + <item>Nineteen</item> + <item>Twenty</item> + <item>Twenty\nOne</item> + <item>Twenty\nTwo</item> + <item>Twenty\nThree</item> + <item>Twenty\nFour</item> + <item>Twenty\nFive</item> + <item>Twenty\nSix</item> + <item>Twenty\nSeven</item> + <item>Twenty\nEight</item> + <item>Twenty\nNine</item> + <item>Thirty</item> + <item>Thirty\nOne</item> + <item>Thirty\nTwo</item> + <item>Thirty\nThree</item> + <item>Thirty\nFour</item> + <item>Thirty\nFive</item> + <item>Thirty\nSix</item> + <item>Thirty\nSeven</item> + <item>Thirty\nEight</item> + <item>Thirty\nNine</item> + <item>Forty</item> + <item>Forty\nOne</item> + <item>Forty\nTwo</item> + <item>Forty\nThree</item> + <item>Forty\nFour</item> + <item>Forty\nFive</item> + <item>Forty\nSix</item> + <item>Forty\nSeven</item> + <item>Forty\nEight</item> + <item>Forty\nNine</item> + <item>Fifty</item> + <item>Fifty\nOne</item> + <item>Fifty\nTwo</item> + <item>Fifty\nThree</item> + <item>Fifty\nFour</item> + <item>Fifty\nFive</item> + <item>Fifty\nSix</item> + <item>Fifty\nSeven</item> + <item>Fifty\nEight</item> + <item>Fifty\nNine</item> + </string-array> + <!-- Name of the "Default" clock face, which is the clock face that will be shown by default. [CHAR LIMIT=15]--> <string name="clock_title_default">Default</string> <!-- Name of the "Bubble" clock face, which is an analog clock with hands shaped like large bubbles [CHAR LIMIT=15]--> <string name="clock_title_bubble">Bubble</string> <!-- Name of the "Analog" clock face [CHAR LIMIT=15]--> <string name="clock_title_analog">Analog</string> + <!-- Name of the "Typographic" clock face [CHAR LIMIT=15]--> + <string name="clock_title_type">Type</string> </resources> diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java index d44d89e63e8f..ccb495fcec28 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java @@ -37,6 +37,7 @@ public class ClockLayout extends FrameLayout { * Clock face views. */ private View mAnalogClock; + private View mTypeClock; /** * Pixel shifting amplitudes used to prevent screen burn-in. @@ -62,6 +63,7 @@ public class ClockLayout extends FrameLayout { protected void onFinishInflate() { super.onFinishInflate(); mAnalogClock = findViewById(R.id.analog_clock); + mTypeClock = findViewById(R.id.type_clock); // Get pixel shifting X, Y amplitudes from resources. Resources resources = getResources(); @@ -105,5 +107,11 @@ public class ClockLayout extends FrameLayout { mAnalogClock.setY(Math.max(0f, 0.5f * (getHeight() - mAnalogClock.getHeight())) + ANALOG_CLOCK_SHIFT_FACTOR * offsetY); } + + // Put the typographic clock part way down the screen. + if (mTypeClock != null) { + mTypeClock.setX(offsetX); + mTypeClock.setY(0.2f * getHeight() + offsetY); + } } } diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java index 2200b22b8b27..fd5c99e75a1f 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java @@ -150,6 +150,7 @@ public final class ClockManager { LayoutInflater layoutInflater = injectionInflater.injectable(LayoutInflater.from(context)); addBuiltinClock(() -> new DefaultClockController(res, layoutInflater, colorExtractor)); + addBuiltinClock(() -> new TypeClockController(res, layoutInflater, colorExtractor)); // Store the size of the display for generation of clock preview. DisplayMetrics dm = res.getDisplayMetrics(); diff --git a/packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java new file mode 100644 index 000000000000..890ba1da0911 --- /dev/null +++ b/packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2019 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.clock; + +import android.app.WallpaperManager; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.graphics.Paint.Style; +import android.view.LayoutInflater; +import android.view.View; + +import com.android.internal.colorextraction.ColorExtractor; +import com.android.systemui.R; +import com.android.systemui.colorextraction.SysuiColorExtractor; +import com.android.systemui.plugins.ClockPlugin; + +import java.util.TimeZone; + +/** + * Plugin for a custom Typographic clock face that displays the time in words. + */ +public class TypeClockController implements ClockPlugin { + + /** + * Resources used to get title and thumbnail. + */ + private final Resources mResources; + + /** + * LayoutInflater used to inflate custom clock views. + */ + private final LayoutInflater mLayoutInflater; + + /** + * Extracts accent color from wallpaper. + */ + private final SysuiColorExtractor mColorExtractor; + + /** + * Computes preferred position of clock. + */ + private final SmallClockPosition mClockPosition; + + /** + * Renders preview from clock view. + */ + private final ViewPreviewer mRenderer = new ViewPreviewer(); + + /** + * Custom clock shown on AOD screen and behind stack scroller on lock. + */ + private View mView; + private TypographicClock mTypeClock; + + /** + * Small clock shown on lock screen above stack scroller. + */ + private TypographicClock mLockClock; + + /** + * Controller for transition into dark state. + */ + private CrossFadeDarkController mDarkController; + + /** + * Create a TypeClockController instance. + * + * @param res Resources contains title and thumbnail. + * @param inflater Inflater used to inflate custom clock views. + * @param colorExtractor Extracts accent color from wallpaper. + */ + TypeClockController(Resources res, LayoutInflater inflater, + SysuiColorExtractor colorExtractor) { + mResources = res; + mLayoutInflater = inflater; + mColorExtractor = colorExtractor; + mClockPosition = new SmallClockPosition(res); + } + + private void createViews() { + mView = mLayoutInflater.inflate(R.layout.type_aod_clock, null); + mTypeClock = mView.findViewById(R.id.type_clock); + + // For now, this view is used to hide the default digital clock. + // Need better transition to lock screen. + mLockClock = (TypographicClock) mLayoutInflater.inflate(R.layout.typographic_clock, null); + mLockClock.setVisibility(View.GONE); + + mDarkController = new CrossFadeDarkController(mView, mLockClock); + } + + @Override + public void onDestroyView() { + mView = null; + mTypeClock = null; + mLockClock = null; + mDarkController = null; + } + + @Override + public String getName() { + return "type"; + } + + @Override + public String getTitle() { + return mResources.getString(R.string.clock_title_type); + } + + @Override + public Bitmap getThumbnail() { + return BitmapFactory.decodeResource(mResources, R.drawable.type_thumbnail); + } + + @Override + public Bitmap getPreview(int width, int height) { + + // Use the big clock view for the preview + View view = getBigClockView(); + + // Initialize state of plugin before generating preview. + setDarkAmount(1f); + setTextColor(Color.WHITE); + ColorExtractor.GradientColors colors = mColorExtractor.getColors( + WallpaperManager.FLAG_LOCK); + setColorPalette(colors.supportsDarkText(), colors.getColorPalette()); + onTimeTick(); + + return mRenderer.createPreview(view, width, height); + } + + @Override + public View getView() { + if (mLockClock == null) { + createViews(); + } + return mLockClock; + } + + @Override + public View getBigClockView() { + if (mView == null) { + createViews(); + } + return mView; + } + + @Override + public int getPreferredY(int totalHeight) { + return mClockPosition.getPreferredY(); + } + + @Override + public void setStyle(Style style) {} + + @Override + public void setTextColor(int color) { + mTypeClock.setTextColor(color); + mLockClock.setTextColor(color); + } + + @Override + public void setColorPalette(boolean supportsDarkText, int[] colorPalette) { + if (colorPalette == null || colorPalette.length == 0) { + return; + } + final int color = colorPalette[Math.max(0, colorPalette.length - 5)]; + mTypeClock.setClockColor(color); + mLockClock.setClockColor(color); + } + + @Override + public void onTimeTick() { + mTypeClock.onTimeChanged(); + mLockClock.onTimeChanged(); + } + + @Override + public void setDarkAmount(float darkAmount) { + if (mDarkController != null) { + mDarkController.setDarkAmount(darkAmount); + } + mClockPosition.setDarkAmount(darkAmount); + } + + @Override + public void onTimeZoneChanged(TimeZone timeZone) { + mTypeClock.onTimeZoneChanged(timeZone); + mLockClock.onTimeZoneChanged(timeZone); + } + + @Override + public boolean shouldShowStatusArea() { + return false; + } +} diff --git a/packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java b/packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java new file mode 100644 index 000000000000..c84c598498d0 --- /dev/null +++ b/packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2019 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.clock; + +import android.content.Context; +import android.content.res.Resources; +import android.text.Annotation; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.SpannedString; +import android.text.TextUtils; +import android.text.format.DateFormat; +import android.text.style.ForegroundColorSpan; +import android.util.AttributeSet; +import android.widget.TextView; + +import com.android.systemui.R; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.TimeZone; + +/** + * Clock that presents the time in words. + */ +public class TypographicClock extends TextView { + + private static final String ANNOTATION_COLOR = "color"; + + private final Resources mResources; + private final String[] mHours; + private final String[] mMinutes; + private int mAccentColor; + private final Calendar mTime = Calendar.getInstance(TimeZone.getDefault()); + private String mDescFormat; + private TimeZone mTimeZone; + + public TypographicClock(Context context) { + this(context, null); + } + + public TypographicClock(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public TypographicClock(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + mDescFormat = ((SimpleDateFormat) DateFormat.getTimeFormat(context)).toLocalizedPattern(); + mResources = context.getResources(); + mHours = mResources.getStringArray(R.array.type_clock_hours); + mMinutes = mResources.getStringArray(R.array.type_clock_minutes); + mAccentColor = mResources.getColor(R.color.typeClockAccentColor, null); + } + + /** + * Call when the time changes to update the text of the time. + */ + public void onTimeChanged() { + mTime.setTimeInMillis(System.currentTimeMillis()); + setContentDescription(DateFormat.format(mDescFormat, mTime)); + final int hour = mTime.get(Calendar.HOUR) % 12; + final int minute = mTime.get(Calendar.MINUTE) % 60; + + // Get the quantity based on the hour for languages like Portuguese and Czech. + SpannedString typeTemplate = (SpannedString) mResources.getQuantityText( + R.plurals.type_clock_header, hour); + + // Find the "color" annotation and set the foreground color to the accent color. + Annotation[] annotations = typeTemplate.getSpans(0, typeTemplate.length(), + Annotation.class); + SpannableString spanType = new SpannableString(typeTemplate); + for (int i = 0; i < annotations.length; i++) { + Annotation annotation = annotations[i]; + String key = annotation.getValue(); + if (ANNOTATION_COLOR.equals(key)) { + spanType.setSpan(new ForegroundColorSpan(mAccentColor), + spanType.getSpanStart(annotation), spanType.getSpanEnd(annotation), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } + } + + setText(TextUtils.expandTemplate(spanType, mHours[hour], mMinutes[minute])); + } + + /** + * Call when the time zone has changed to update clock time. + * + * @param timeZone The updated time zone that will be used. + */ + public void onTimeZoneChanged(TimeZone timeZone) { + mTimeZone = timeZone; + mTime.setTimeZone(timeZone); + } + + /** + * Sets the accent color used on the clock face. + */ + public void setClockColor(int color) { + mAccentColor = color; + onTimeChanged(); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + mTime.setTimeZone(mTimeZone != null ? mTimeZone : TimeZone.getDefault()); + onTimeChanged(); + } + + /** + * Overriding hasOverlappingRendering as false to improve performance of crossfading. + */ + @Override + public boolean hasOverlappingRendering() { + return false; + } +} |