Add custom typographic clock face.

Bug: 122301289
Test: Used adb to enable clock face.
Change-Id: I052367c9671697f621cba4ecb7e6b21c0cec784c
This commit is contained in:
Robert Snoeberger
2019-01-17 10:36:02 -05:00
parent 1f2ef22cc2
commit ce8c204eac
7 changed files with 371 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
<?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"
>
<com.android.keyguard.clock.TypographicClock
android:id="@+id/type_clock"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
style="@style/widget_big"
android:textColor="@color/typeClockAccentColor"
android:text="@string/type_clock_header"
android:textSize="40dp"
/>
<TextView
android:id="@+id/hour"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
style="@style/widget_big"
android:textSize="40dp"
/>
<TextView
android:id="@+id/minute"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
style="@style/widget_big"
android:textSize="40dp"
/>
</com.android.keyguard.clock.TypographicClock>
</com.android.keyguard.clock.ClockLayout>

View File

@@ -19,4 +19,6 @@
<color name="bubbleHourHandColor">#C97343</color>
<!-- Default color for minute hand of Bubble clock. -->
<color name="bubbleMinuteHandColor">#F5C983</color>
<!-- Accent color for Typographic clock. -->
<color name="typeClockAccentColor">#F5C983</color>
</resources>

View File

@@ -402,4 +402,87 @@ 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>
<!-- Header for typographic clock face. [CHAR LIMIT=8] -->
<string name="type_clock_header">It\u2019s</string>
<!-- Hour displayed in words on the typographic clock face. [CHAR LIMIT=8] -->
<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=16] -->
<string-array name="type_clock_minutes">
<item>O\u2019Clock</item>
<item>O\u2019One</item>
<item>O\u2019Two</item>
<item>O\u2019Three</item>
<item>O\u2019Four</item>
<item>O\u2019Five</item>
<item>O\u2019Six</item>
<item>O\u2019Seven</item>
<item>O\u2019Eight</item>
<item>O\u2019Nine</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>
</resources>

View File

@@ -20,6 +20,7 @@ import androidx.annotation.VisibleForTesting;
import com.android.keyguard.clock.BubbleClockController;
import com.android.keyguard.clock.StretchAnalogClockController;
import com.android.keyguard.clock.TypeClockController;
import com.android.systemui.Dependency;
import com.android.systemui.plugins.ClockPlugin;
import com.android.systemui.statusbar.StatusBarState;
@@ -153,6 +154,12 @@ public class KeyguardClockSwitch extends RelativeLayout {
Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE,
StretchAnalogClockController.class.getName(),
() -> StretchAnalogClockController.build(mLayoutInflater)))
.withDefault(
new SettingsGattedSupplier(
mContentResolver,
Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE,
TypeClockController.class.getName(),
() -> TypeClockController.build(mLayoutInflater)))
.build();
mContentResolver.registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE),

View File

@@ -36,6 +36,7 @@ public class ClockLayout extends FrameLayout {
*/
private View mDigitalClock;
private View mAnalogClock;
private View mTypeClock;
/**
* Pixel shifting amplitidues used to prevent screen burn-in.
@@ -60,6 +61,7 @@ public class ClockLayout extends FrameLayout {
super.onFinishInflate();
mDigitalClock = findViewById(R.id.digital_clock);
mAnalogClock = findViewById(R.id.analog_clock);
mTypeClock = findViewById(R.id.type_clock);
// Get pixel shifting X, Y amplitudes from resources.
Resources resources = getResources();
@@ -89,5 +91,11 @@ public class ClockLayout extends FrameLayout {
mAnalogClock.setY(Math.max(0f, 0.5f * (getHeight() - mAnalogClock.getHeight()))
+ offsetY);
}
// Put the typographic clock part way down the screen.
if (mTypeClock != null) {
mTypeClock.setX(offsetX);
mTypeClock.setY(0.2f * getHeight() + offsetY);
}
}
}

View File

@@ -0,0 +1,106 @@
/*
* 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.graphics.Paint.Style;
import android.view.LayoutInflater;
import android.view.View;
import com.android.keyguard.R;
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 {
/**
* 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 View mLockClockContainer;
/**
* Controller for transition into dark state.
*/
private CrossFadeDarkController mDarkController;
private TypeClockController() {}
/**
* Create a TypeClockController instance.
*
* @param inflater Inflater used to inflate custom clock views.
*/
public static TypeClockController build(LayoutInflater inflater) {
TypeClockController controller = new TypeClockController();
controller.createViews(inflater);
return controller;
}
private void createViews(LayoutInflater inflater) {
mView = inflater.inflate(R.layout.type_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.
mLockClockContainer = inflater.inflate(R.layout.digital_clock, null);
mLockClockContainer.setVisibility(View.GONE);
}
@Override
public View getView() {
return mLockClockContainer;
}
@Override
public View getBigClockView() {
return mView;
}
@Override
public void setStyle(Style style) {}
@Override
public void setTextColor(int color) {
mTypeClock.setTextColor(color);
}
@Override
public void dozeTimeTick() {
mTypeClock.onTimeChanged();
}
@Override
public void setDarkAmount(float darkAmount) {}
@Override
public void onTimeZoneChanged(TimeZone timeZone) {
mTypeClock.onTimeZoneChanged(timeZone);
}
@Override
public boolean shouldShowStatusArea() {
return false;
}
}

View File

@@ -0,0 +1,110 @@
/*
* 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.format.DateFormat;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.keyguard.R;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
/**
* Clock that presents the time in words.
*/
public class TypographicClock extends LinearLayout {
private final String[] mHours;
private final String[] mMinutes;
private TextView mHeaderText;
private TextView mHourText;
private TextView mMinuteText;
private Calendar mTime;
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);
mTime = Calendar.getInstance();
mDescFormat = ((SimpleDateFormat) DateFormat.getTimeFormat(context)).toLocalizedPattern();
Resources res = context.getResources();
mHours = res.getStringArray(R.array.type_clock_hours);
mMinutes = res.getStringArray(R.array.type_clock_minutes);
}
/**
* 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);
mHourText.setText(mHours[hour % 12]);
final int minute = mTime.get(Calendar.MINUTE);
mMinuteText.setText(mMinutes[minute % 60]);
invalidate();
}
/**
* 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);
}
/**
* Set the color of the text used to display the time.
*
* This is necessary when the wallpaper shown behind the clock on the
* lock screen changes.
*/
public void setTextColor(int color) {
mHourText.setTextColor(color);
mMinuteText.setTextColor(color);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mHeaderText = findViewById(R.id.header);
mHourText = findViewById(R.id.hour);
mMinuteText = findViewById(R.id.minute);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mTime = Calendar.getInstance(mTimeZone != null ? mTimeZone : TimeZone.getDefault());
onTimeChanged();
}
}