From 3954a797739918e7100031ad253e5921b5bee999 Mon Sep 17 00:00:00 2001 From: Peter_Liang Date: Wed, 20 Apr 2022 13:18:56 +0800 Subject: [PATCH 1/6] Prevent cutting the thumb of the LabeledSeekBarPreference from different themes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the attribute “clipChildren” as false to avoid cutting. Bug: 219415822 Test: manual test Change-Id: I0c565896279111e65600d1b41c576106a8de7136 --- res/layout/icon_discrete_slider.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/res/layout/icon_discrete_slider.xml b/res/layout/icon_discrete_slider.xml index b1d960f8dec..47be5efff79 100644 --- a/res/layout/icon_discrete_slider.xml +++ b/res/layout/icon_discrete_slider.xml @@ -19,6 +19,7 @@ android:id="@+id/seekbar_frame" android:layout_width="match_parent" android:layout_height="wrap_content" + android:clipChildren="false" android:background="?android:colorBackground" android:gravity="center_vertical"> From c5551dc974478a9818a04d19ba149ce88182f99e Mon Sep 17 00:00:00 2001 From: Peter_Liang Date: Wed, 20 Apr 2022 16:02:10 +0800 Subject: [PATCH 2/6] Fix that the color of each option and subtext of Display size and text has the color difference. Change the android:selectable from false to true to avoid the title and summary impacted by color style. Fix: 229560847 Test: manual test Change-Id: Iec2ba560538a4f69f79198015bf6a24fb9a7caca --- res/xml/accessibility_text_reading_options.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/xml/accessibility_text_reading_options.xml b/res/xml/accessibility_text_reading_options.xml index ad742c949b4..7fd5ff9a581 100644 --- a/res/xml/accessibility_text_reading_options.xml +++ b/res/xml/accessibility_text_reading_options.xml @@ -27,7 +27,7 @@ Date: Tue, 19 Apr 2022 13:00:52 +0800 Subject: [PATCH 3/6] [Settings] Code refactor for Lifecycle listening This is an abstract class for building a set of callback behavior based on Lifecycle status change. Through extending this class, the implemented methods are invoked only when required. Bug: 229689535 Test: unit test Change-Id: I7534393546f821738a63ebde121a5a88ee03b23b (cherry picked from commit 9a4c66d23ba1631350bcdf5d4bba0d5067e2beff) --- .../helper/LifecycleCallbackAdapter.java | 100 ++++++++++++++++ .../helper/LifecycleCallbackAdapterTest.java | 111 ++++++++++++++++++ 2 files changed, 211 insertions(+) create mode 100644 src/com/android/settings/network/helper/LifecycleCallbackAdapter.java create mode 100644 tests/unit/src/com/android/settings/network/helper/LifecycleCallbackAdapterTest.java diff --git a/src/com/android/settings/network/helper/LifecycleCallbackAdapter.java b/src/com/android/settings/network/helper/LifecycleCallbackAdapter.java new file mode 100644 index 00000000000..548eae572f4 --- /dev/null +++ b/src/com/android/settings/network/helper/LifecycleCallbackAdapter.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2022 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.settings.network.helper; + +import androidx.annotation.MainThread; +import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleEventObserver; +import androidx.lifecycle.LifecycleOwner; + +import java.util.concurrent.atomic.AtomicReference; + +/** + * A {@link androidx.lifecycle.LifecycleObserver} implementation of adapter over callback. + * + * Which including: + * 1. Request to active callback when Lifecycle.State.STARTED + * 2. Request to inactive callback when Lifecycle.State.STOPPED + * 3. Close (no further resume) when Lifecycle.State.DESTROYED + */ +@VisibleForTesting +abstract class LifecycleCallbackAdapter implements LifecycleEventObserver, AutoCloseable { + private static final String TAG = "LifecycleCallbackAdapter"; + private AtomicReference mLifecycle = new AtomicReference(); + + /** + * Constructor + * @param lifecycle {@link Lifecycle} to monitor + */ + @VisibleForTesting + protected LifecycleCallbackAdapter(@NonNull Lifecycle lifecycle) { + mLifecycle.set(lifecycle); + lifecycle.addObserver(this); + } + + /** + * Get {@link Lifecycle} under monitor. + * @return {@link Lifecycle}. Return {@code null} when closed. + */ + @VisibleForTesting + public Lifecycle getLifecycle() { + return mLifecycle.get(); + } + + /** + * Check current callback status. + * @return true when callback is active. + */ + public abstract boolean isCallbackActive(); + + /** + * Change callback status. + * @param isActive true to active callback, otherwise inactive. + */ + public abstract void setCallbackActive(boolean isActive); + + /** + * Implementation of LifecycleEventObserver. + */ + public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) { + if (mLifecycle.get() == null) { + return; + } + + Lifecycle.State state = event.getTargetState(); + boolean expectCallbackActive = state.isAtLeast(Lifecycle.State.STARTED); + if (expectCallbackActive != isCallbackActive()) { + setCallbackActive(expectCallbackActive); + } + if (state == Lifecycle.State.DESTROYED) { + close(); + } + } + + /** + * Implementation of AutoCloseable. + */ + @MainThread + public void close() { + Lifecycle lifecycle = mLifecycle.getAndSet(null); + if (lifecycle != null) { + lifecycle.removeObserver(this); + } + } +} diff --git a/tests/unit/src/com/android/settings/network/helper/LifecycleCallbackAdapterTest.java b/tests/unit/src/com/android/settings/network/helper/LifecycleCallbackAdapterTest.java new file mode 100644 index 00000000000..ddeb3f81bd9 --- /dev/null +++ b/tests/unit/src/com/android/settings/network/helper/LifecycleCallbackAdapterTest.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2022 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.settings.network.helper; + +import static com.google.common.truth.Truth.assertThat; + +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.LifecycleRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class LifecycleCallbackAdapterTest implements LifecycleOwner { + + private final LifecycleRegistry mRegistry = LifecycleRegistry.createUnsafe(this); + + private TestObj mTarget; + + @Before + public void setUp() { + mTarget = new TestObj(getLifecycle()); + } + + public Lifecycle getLifecycle() { + return mRegistry; + } + + @Test + public void lifecycle_get_lifecycleToMonitor() { + assertThat(mTarget.getLifecycle()).isEqualTo(mRegistry); + } + + @Test + public void lifecycle_stateChangeToStart_callbackActive() { + mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE); + + assertThat(mTarget.getCallbackCount()).isEqualTo(0); + assertThat(mTarget.isCallbackActive()).isEqualTo(Boolean.FALSE); + + mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); + + assertThat(mTarget.getCallbackCount()).isEqualTo(1); + assertThat(mTarget.isCallbackActive()).isEqualTo(Boolean.TRUE); + } + + @Test + public void lifecycle_stateChangeToStop_callbackInActive() { + mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE); + mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); + mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP); + + assertThat(mTarget.getCallbackCount()).isEqualTo(2); + assertThat(mTarget.isCallbackActive()).isEqualTo(Boolean.FALSE); + } + + @Test + public void lifecycle_stateChangeToDestroy_noFurtherActive() { + mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE); + mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); + mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP); + mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY); + + assertThat(mTarget.getCallbackCount()).isEqualTo(2); + assertThat(mTarget.isCallbackActive()).isEqualTo(Boolean.FALSE); + + mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE); + mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); + + assertThat(mTarget.getCallbackCount()).isEqualTo(2); + assertThat(mTarget.isCallbackActive()).isEqualTo(Boolean.FALSE); + } + + public static class TestObj extends LifecycleCallbackAdapter { + boolean mIsActive; + int mNumberOfCallback; + + public TestObj(Lifecycle lifecycle) { + super(lifecycle); + } + + public boolean isCallbackActive() { + return mIsActive; + } + + public void setCallbackActive(boolean isActive) { + mIsActive = isActive; + mNumberOfCallback ++; + } + + protected int getCallbackCount() { + return mNumberOfCallback; + } + } +} From 0d47c548d974525a9c0fb8eccc393481a224750d Mon Sep 17 00:00:00 2001 From: menghanli Date: Thu, 21 Apr 2022 16:55:47 +0800 Subject: [PATCH 4/6] Fix Live Caption does not follow caption size if caption is not enabled Root cause: Changing captions style without turning on the preference WHILE Live Caption is running works when it shouldn't. Solution: Turn on the show caption if users change caption size and style by UX suggestion. Bug: 221051127 Test: Manual testing 1. Turning on/off Live Caption and Caption Manager 2. Changing styles when Caption Manager is off Change-Id: Ie6cfb9e0b7325c2e469ac8b6a7d359b843cc173a --- .../accessibility/CaptionAppearanceFragment.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/com/android/settings/accessibility/CaptionAppearanceFragment.java b/src/com/android/settings/accessibility/CaptionAppearanceFragment.java index 13055be0c07..53c1dd005db 100644 --- a/src/com/android/settings/accessibility/CaptionAppearanceFragment.java +++ b/src/com/android/settings/accessibility/CaptionAppearanceFragment.java @@ -16,6 +16,8 @@ package com.android.settings.accessibility; +import static com.android.settings.accessibility.AccessibilityUtil.State.ON; + import android.app.settings.SettingsEnums; import android.content.ContentResolver; import android.content.Context; @@ -400,6 +402,7 @@ public class CaptionAppearanceFragment extends DashboardFragment } refreshPreviewText(); + enableCaptioningManager(); } @Override @@ -409,16 +412,26 @@ public class CaptionAppearanceFragment extends DashboardFragment Settings.Secure.putString( cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE, (String) value); refreshPreviewText(); + enableCaptioningManager(); } else if (mFontSize == preference) { Settings.Secure.putFloat( cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE, Float.parseFloat((String) value)); refreshPreviewText(); + enableCaptioningManager(); } return true; } + private void enableCaptioningManager() { + if (mCaptioningManager.isEnabled()) { + return; + } + Settings.Secure.putInt(getContentResolver(), + Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, ON); + } + @Override public int getHelpResource() { return R.string.help_url_caption; From 7f67e278ca357917d322c97dc2d7b0726e1212d3 Mon Sep 17 00:00:00 2001 From: Peter_Liang Date: Thu, 21 Apr 2022 16:25:34 +0800 Subject: [PATCH 5/6] =?UTF-8?q?Fine-tune=20the=20location=20and=20style=20?= =?UTF-8?q?of=20the=20reset=20button=20in=20the=20=E2=80=9CDisplay=20size?= =?UTF-8?q?=20and=20text=E2=80=9D=20page.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: 222419452 Test: manual test Change-Id: I9099f13c715ce29cce8d52f6ca9cc47a4fa22306 --- .../accessibility_text_reading_reset_button.xml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/res/layout/accessibility_text_reading_reset_button.xml b/res/layout/accessibility_text_reading_reset_button.xml index f3691e1f816..a0bdcbad81d 100644 --- a/res/layout/accessibility_text_reading_reset_button.xml +++ b/res/layout/accessibility_text_reading_reset_button.xml @@ -27,14 +27,11 @@ android:id="@+id/reset_button" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_gravity="center|end" + android:layout_gravity="center_vertical|start" android:paddingVertical="14dp" - android:background="@null" android:drawableStart="@drawable/ic_history" android:drawablePadding="9dp" - android:drawableTint="?android:attr/colorAccent" - android:textColor="?android:attr/colorAccent" - android:textSize="16sp" - android:textAppearance="@android:style/TextAppearance.DeviceDefault.Medium" - android:text="@string/accessibility_text_reading_reset_button_title"/> + android:drawableTint="@color/settingslib_btn_colored_text_material" + android:text="@string/accessibility_text_reading_reset_button_title" + style="@style/ActionPrimaryButton"/> From d44da3b9596f609aa4a7b2fa4c594b24acc0dfb4 Mon Sep 17 00:00:00 2001 From: menghanli Date: Thu, 21 Apr 2022 17:24:37 +0800 Subject: [PATCH 6/6] Fine tune Caption size and style preview height for tablet Root cause: We introduce the material design illustration in Android S. The most of illustration preview height is 300dp, but the SubTitleView preview keep 200dp in the phone and 150dp in tablet. The value is defined in 2017. Solution: Align material design illustration height which looks a lot closer to an actual video, without pushing too much content below the screen. Bug: 227264630 Test: Manual testing Change-Id: I1a9040f50dfb6fb95c1cadbe4e7e4d24ff8ab058 --- res/values-land/dimens.xml | 2 -- res/values-sw600dp-land/dimens.xml | 2 -- res/values/dimens.xml | 2 +- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml index 37e71e2174e..5248da63de4 100755 --- a/res/values-land/dimens.xml +++ b/res/values-land/dimens.xml @@ -18,8 +18,6 @@ 421dip 68dip - 100dp - 46dip diff --git a/res/values-sw600dp-land/dimens.xml b/res/values-sw600dp-land/dimens.xml index 4e4a1d38e97..015a6af2dde 100755 --- a/res/values-sw600dp-land/dimens.xml +++ b/res/values-sw600dp-land/dimens.xml @@ -19,8 +19,6 @@ 72dip 48dip - 150dp - 20dp 24dp diff --git a/res/values/dimens.xml b/res/values/dimens.xml index b67bb22481b..c80e42c74c0 100755 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -49,7 +49,7 @@ 16dp 3dp - 200dp + 300dp 200dp