diff options
Diffstat (limited to 'TwoPanelSettingsLib')
129 files changed, 4755 insertions, 645 deletions
diff --git a/TwoPanelSettingsLib/Android.bp b/TwoPanelSettingsLib/Android.bp index d7a011e7c..6fd79f091 100644 --- a/TwoPanelSettingsLib/Android.bp +++ b/TwoPanelSettingsLib/Android.bp @@ -48,7 +48,7 @@ android_library { "statslog-tvsettings", ], - min_sdk_version: "21", + min_sdk_version: "29", } // For the test package. diff --git a/TwoPanelSettingsLib/AndroidManifest.xml b/TwoPanelSettingsLib/AndroidManifest.xml index bbacf9d6d..8e2ee152b 100644 --- a/TwoPanelSettingsLib/AndroidManifest.xml +++ b/TwoPanelSettingsLib/AndroidManifest.xml @@ -19,6 +19,6 @@ package="com.android.tv.twopanelsettings"> <uses-sdk - android:minSdkVersion="21" /> + android:minSdkVersion="29" /> </manifest> diff --git a/TwoPanelSettingsLib/lint-baseline.xml b/TwoPanelSettingsLib/lint-baseline.xml index ef635e5c0..6f372c4ac 100644 --- a/TwoPanelSettingsLib/lint-baseline.xml +++ b/TwoPanelSettingsLib/lint-baseline.xml @@ -47,6 +47,50 @@ <issue id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" ctx.getSystemService(SliceManager.class).grantPermissionFromUser(" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/ContextSingleton.java" + line="82" + column="17"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`" + errorLine1=" ctx.getSystemService(SliceManager.class).grantPermissionFromUser(" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/ContextSingleton.java" + line="82" + column="17"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level 28 (current min is 21): `android.app.slice.SliceManager`" + errorLine1=" ctx.getSystemService(SliceManager.class).grantPermissionFromUser(" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/ContextSingleton.java" + line="82" + column="34"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level 28 (current min is 21): `android.app.slice.SliceManager`" + errorLine1=" ctx.getSystemService(SliceManager.class).grantPermissionFromUser(" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/ContextSingleton.java" + line="82" + column="34"/> + </issue> + + <issue + id="NewApi" message="Call requires API level 23 (current min is 21): `android.graphics.drawable.LayerDrawable#setLayerGravity`" errorLine1=" compoundDrawable.setLayerGravity(0, Gravity.CENTER);" errorLine2=" ~~~~~~~~~~~~~~~"> @@ -91,46 +135,46 @@ <issue id="NewApi" - message="Call requires API level 23 (current min is 21): `android.app.Fragment#getContext`" - errorLine1=" .setImageDrawable(image.loadDrawable(getContext()));" - errorLine2=" ~~~~~~~~~~"> + message="Call requires API level 23 (current min is 21): `android.graphics.drawable.Icon#loadDrawable`" + errorLine1=" infoImage.setImageDrawable(image.loadDrawable(getContext()));" + errorLine2=" ~~~~~~~~~~~~"> <location file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/InfoFragment.java" - line="44" - column="58"/> + line="69" + column="46"/> </issue> <issue id="NewApi" - message="Call requires API level 23 (current min is 21): `android.app.Fragment#getContext`" - errorLine1=" .setImageDrawable(image.loadDrawable(getContext()));" - errorLine2=" ~~~~~~~~~~"> + message="Call requires API level 23 (current min is 21): `android.graphics.drawable.Icon#loadDrawable`" + errorLine1=" infoImage.setImageDrawable(image.loadDrawable(getContext()));" + errorLine2=" ~~~~~~~~~~~~"> <location file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/InfoFragment.java" - line="44" - column="58"/> + line="69" + column="46"/> </issue> <issue id="NewApi" message="Call requires API level 23 (current min is 21): `android.graphics.drawable.Icon#loadDrawable`" - errorLine1=" .setImageDrawable(image.loadDrawable(getContext()));" - errorLine2=" ~~~~~~~~~~~~"> + errorLine1=" infoIcon.setImageDrawable(titleIcon.loadDrawable(getContext()));" + errorLine2=" ~~~~~~~~~~~~"> <location file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/InfoFragment.java" - line="44" - column="45"/> + line="72" + column="49"/> </issue> <issue id="NewApi" message="Call requires API level 23 (current min is 21): `android.graphics.drawable.Icon#loadDrawable`" - errorLine1=" .setImageDrawable(image.loadDrawable(getContext()));" - errorLine2=" ~~~~~~~~~~~~"> + errorLine1=" infoIcon.setImageDrawable(titleIcon.loadDrawable(getContext()));" + errorLine2=" ~~~~~~~~~~~~"> <location file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/InfoFragment.java" - line="44" - column="45"/> + line="72" + column="49"/> </issue> <issue @@ -157,144 +201,12 @@ <issue id="NewApi" - message="Call requires API level 23 (current min is 21): `android.app.Fragment#getContext`" - errorLine1=" ContextSingleton.getInstance().grantFullAccess(getContext(), Uri.parse(mUriString));" - errorLine2=" ~~~~~~~~~~"> - <location - file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java" - line="112" - column="56"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 23 (current min is 21): `android.app.Fragment#getContext`" - errorLine1=" ContextSingleton.getInstance().grantFullAccess(getContext(), Uri.parse(mUriString));" - errorLine2=" ~~~~~~~~~~"> - <location - file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java" - line="112" - column="56"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 23 (current min is 21): `android.app.Fragment#getContext`" - errorLine1=" getContext().getContentResolver().registerContentObserver(" - errorLine2=" ~~~~~~~~~~"> - <location - file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java" - line="129" - column="9"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 23 (current min is 21): `android.app.Fragment#getContext`" - errorLine1=" getContext().getContentResolver().registerContentObserver(" - errorLine2=" ~~~~~~~~~~"> - <location - file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java" - line="129" - column="9"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 23 (current min is 21): `android.app.Fragment#getContext`" - errorLine1=" mPreferenceFollowupIntent.send(getContext()," - errorLine2=" ~~~~~~~~~~"> - <location - file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java" - line="164" - column="48"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 23 (current min is 21): `android.app.Fragment#getContext`" - errorLine1=" mPreferenceFollowupIntent.send(getContext()," - errorLine2=" ~~~~~~~~~~"> - <location - file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java" - line="164" - column="48"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 23 (current min is 21): `android.app.Fragment#getContext`" - errorLine1=" getContext().getContentResolver().unregisterContentObserver(mContentObserver);" - errorLine2=" ~~~~~~~~~~"> - <location - file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java" - line="177" - column="9"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 23 (current min is 21): `android.app.Fragment#getContext`" - errorLine1=" getContext().getContentResolver().unregisterContentObserver(mContentObserver);" - errorLine2=" ~~~~~~~~~~"> - <location - file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java" - line="177" - column="9"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 23 (current min is 21): `android.app.Fragment#getContext`" - errorLine1=" .createPreferenceScreen(getContext());" - errorLine2=" ~~~~~~~~~~"> - <location - file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java" - line="184" - column="41"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 23 (current min is 21): `android.app.Fragment#getContext`" - errorLine1=" .createPreferenceScreen(getContext());" - errorLine2=" ~~~~~~~~~~"> - <location - file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java" - line="184" - column="41"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 24 (current min is 21): `android.app.Fragment#startIntentSenderForResult`" - errorLine1=" startIntentSenderForResult(" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java" - line="429" - column="9"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 24 (current min is 21): `android.app.Fragment#startIntentSenderForResult`" - errorLine1=" startIntentSenderForResult(" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java" - line="429" - column="9"/> - </issue> - - <issue - id="NewApi" message="Cast from `Icon` to `Parcelable` requires API level 23 (current min is 21)" errorLine1=" outState.putParcelable(KEY_SCREEN_ICON, mScreenIcon);" errorLine2=" ~~~~~~~~~~~"> <location file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java" - line="454" + line="518" column="49"/> </issue> @@ -305,7 +217,7 @@ errorLine2=" ~~~~~~~~~~~"> <location file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java" - line="454" + line="518" column="49"/> </issue> @@ -316,7 +228,7 @@ errorLine2=" ~~~~~~~~~~~~"> <location file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java" - line="534" + line="599" column="45"/> </issue> @@ -327,40 +239,18 @@ errorLine2=" ~~~~~~~~~~~~"> <location file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java" - line="534" + line="599" column="45"/> </issue> <issue id="NewApi" - message="Call requires API level 23 (current min is 21): `android.app.Fragment#getContext`" - errorLine1=" Toast.makeText(getContext(), errorMessage, Toast.LENGTH_SHORT).show();" - errorLine2=" ~~~~~~~~~~"> - <location - file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java" - line="581" - column="28"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 23 (current min is 21): `android.app.Fragment#getContext`" - errorLine1=" Toast.makeText(getContext(), errorMessage, Toast.LENGTH_SHORT).show();" - errorLine2=" ~~~~~~~~~~"> - <location - file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java" - line="581" - column="28"/> - </issue> - - <issue - id="NewApi" message="Call requires API level 23 (current min is 21): `android.graphics.drawable.Icon#loadDrawable`" errorLine1=" Drawable iconDrawable = icon.loadDrawable(contextThemeWrapper);" errorLine2=" ~~~~~~~~~~~~"> <location file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicePreferencesUtil.java" - line="167" + line="179" column="46"/> </issue> @@ -371,7 +261,7 @@ errorLine2=" ~~~~~~~~~~~~"> <location file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicePreferencesUtil.java" - line="167" + line="179" column="46"/> </issue> @@ -382,7 +272,7 @@ errorLine2=" ~~~~~~"> <location file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicePreferencesUtil.java" - line="196" + line="216" column="72"/> </issue> @@ -393,7 +283,7 @@ errorLine2=" ~~~~~~"> <location file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicePreferencesUtil.java" - line="196" + line="216" column="72"/> </issue> @@ -404,7 +294,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~"> <location file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicePreferencesUtil.java" - line="196" + line="216" column="62"/> </issue> @@ -415,18 +305,62 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~"> <location file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicePreferencesUtil.java" - line="196" + line="216" column="62"/> </issue> <issue id="NewApi" message="Call requires API level 23 (current min is 21): `toIcon`" + errorLine1=" b.putParcelable(EXTRA_PREFERENCE_INFO_TITLE_ICON, infoTitleIcon.toIcon());" + errorLine2=" ~~~~~~"> + <location + file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicePreferencesUtil.java" + line="219" + column="81"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `toIcon`" + errorLine1=" b.putParcelable(EXTRA_PREFERENCE_INFO_TITLE_ICON, infoTitleIcon.toIcon());" + errorLine2=" ~~~~~~"> + <location + file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicePreferencesUtil.java" + line="219" + column="81"/> + </issue> + + <issue + id="NewApi" + message="Cast from `Icon` to `Parcelable` requires API level 23 (current min is 21)" + errorLine1=" b.putParcelable(EXTRA_PREFERENCE_INFO_TITLE_ICON, infoTitleIcon.toIcon());" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicePreferencesUtil.java" + line="219" + column="67"/> + </issue> + + <issue + id="NewApi" + message="Cast from `Icon` to `Parcelable` requires API level 23 (current min is 21)" + errorLine1=" b.putParcelable(EXTRA_PREFERENCE_INFO_TITLE_ICON, infoTitleIcon.toIcon());" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicePreferencesUtil.java" + line="219" + column="67"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 23 (current min is 21): `toIcon`" errorLine1=" return icon.toIcon();" errorLine2=" ~~~~~~"> <location file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicePreferencesUtil.java" - line="405" + line="480" column="29"/> </issue> @@ -437,51 +371,73 @@ errorLine2=" ~~~~~~"> <location file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicePreferencesUtil.java" - line="405" + line="480" column="29"/> </issue> <issue id="NewApi" - message="Call requires API level 24 (current min is 21): `android.app.FragmentTransaction#commitNow`" - errorLine1=" transaction.commitNow();" - errorLine2=" ~~~~~~~~~"> + message="Call requires API level 28 (current min is 21): `android.view.View#setAccessibilityPaneTitle`" + errorLine1=" .setAccessibilityPaneTitle(newA11yTitle);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/TwoPanelSettingsFragment.java" + line="330" + column="22"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 28 (current min is 21): `android.view.View#setAccessibilityPaneTitle`" + errorLine1=" .setAccessibilityPaneTitle(newA11yTitle);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/TwoPanelSettingsFragment.java" - line="257" - column="21"/> + line="330" + column="22"/> </issue> <issue id="NewApi" - message="Call requires API level 24 (current min is 21): `android.app.FragmentTransaction#commitNow`" - errorLine1=" transaction.commitNow();" - errorLine2=" ~~~~~~~~~"> + message="Call requires API level 23 (current min is 21): `android.graphics.drawable.Icon#createWithResource`" + errorLine1=" Icon.createWithResource(getContext(), R.drawable.slice_error_icon));" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> <location file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/TwoPanelSettingsFragment.java" - line="257" - column="21"/> + line="1034" + column="22"/> </issue> <issue id="NewApi" - message="Call requires API level 23 (current min is 21): `android.app.Fragment#getContext`" - errorLine1=" getContext().getContentResolver().acquireContentProviderClient(Uri.parse(uri));" - errorLine2=" ~~~~~~~~~~"> + message="Call requires API level 23 (current min is 21): `android.graphics.drawable.Icon#createWithResource`" + errorLine1=" Icon.createWithResource(getContext(), R.drawable.slice_error_icon));" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> <location file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/TwoPanelSettingsFragment.java" - line="827" + line="1034" + column="22"/> + </issue> + + <issue + id="NewApi" + message="Cast from `Icon` to `Parcelable` requires API level 23 (current min is 21)" + errorLine1=" Icon.createWithResource(getContext(), R.drawable.slice_error_icon));" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/TwoPanelSettingsFragment.java" + line="1034" column="17"/> </issue> <issue id="NewApi" - message="Call requires API level 23 (current min is 21): `android.app.Fragment#getContext`" - errorLine1=" getContext().getContentResolver().acquireContentProviderClient(Uri.parse(uri));" - errorLine2=" ~~~~~~~~~~"> + message="Cast from `Icon` to `Parcelable` requires API level 23 (current min is 21)" + errorLine1=" Icon.createWithResource(getContext(), R.drawable.slice_error_icon));" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/TwoPanelSettingsFragment.java" - line="827" + line="1034" column="17"/> </issue> diff --git a/TwoPanelSettingsLib/res/animator/preference.xml b/TwoPanelSettingsLib/res/animator/preference.xml new file mode 100644 index 000000000..ddfda0017 --- /dev/null +++ b/TwoPanelSettingsLib/res/animator/preference.xml @@ -0,0 +1,98 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + + <item android:state_focused="true" + android:state_pressed="true">> + <set> + <objectAnimator + android:duration="160" + android:propertyName="translationZ" + android:valueTo="6dp" + android:valueType="floatType" + android:interpolator="@android:anim/accelerate_interpolator" /> + + <objectAnimator + android:duration="160" + android:propertyName="scaleX" + android:valueTo="1.025" + android:valueType="floatType" + android:interpolator="@android:anim/accelerate_interpolator" /> + + <objectAnimator + android:duration="160" + android:propertyName="scaleY" + android:valueTo="1.025" + android:valueType="floatType" + android:interpolator="@android:anim/accelerate_interpolator" /> + + </set> + </item> + + <item android:state_focused="true" + android:state_pressed="false"> + <set> + <objectAnimator + android:duration="320" + android:propertyName="translationZ" + android:valueTo="12dp" + android:valueType="floatType" + android:interpolator="@android:anim/accelerate_interpolator" /> + + <objectAnimator + android:duration="320" + android:propertyName="scaleX" + android:valueTo="1.05" + android:valueType="floatType" + android:interpolator="@android:anim/accelerate_interpolator" /> + + <objectAnimator + android:duration="320" + android:propertyName="scaleY" + android:valueTo="1.05" + android:valueType="floatType" + android:interpolator="@android:anim/accelerate_interpolator" /> + </set> + </item> + + <item android:state_focused="false"> + <set> + <objectAnimator + android:duration="320" + android:propertyName="translationZ" + android:valueTo="0dp" + android:valueType="floatType" + android:interpolator="@android:anim/decelerate_interpolator" /> + + <objectAnimator + android:duration="320" + android:propertyName="scaleX" + android:valueTo="1" + android:valueType="floatType" + android:interpolator="@android:anim/decelerate_interpolator" /> + + <objectAnimator + android:duration="320" + android:propertyName="scaleY" + android:valueTo="1" + android:valueType="floatType" + android:interpolator="@android:anim/decelerate_interpolator" /> + </set> + </item> + +</selector>
\ No newline at end of file diff --git a/TwoPanelSettingsLib/res/color/two_panel_preference_icon_color.xml b/TwoPanelSettingsLib/res/color/two_panel_preference_icon_color.xml index e365b6f56..ad1941f29 100644 --- a/TwoPanelSettingsLib/res/color/two_panel_preference_icon_color.xml +++ b/TwoPanelSettingsLib/res/color/two_panel_preference_icon_color.xml @@ -15,7 +15,7 @@ --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:color="#FF0E0E0E" + <item android:color="#FF4285F4" android:state_focused="true"/> <item android:color="#B3E8EAED"/> diff --git a/TwoPanelSettingsLib/res/drawable/compound_icon_background_focused.xml b/TwoPanelSettingsLib/res/drawable/compound_icon_background_focused.xml index 9e501d118..0203a67bb 100644 --- a/TwoPanelSettingsLib/res/drawable/compound_icon_background_focused.xml +++ b/TwoPanelSettingsLib/res/drawable/compound_icon_background_focused.xml @@ -19,7 +19,4 @@ <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="@color/tp_preference_item_icon_focused_background_color"></solid> - <stroke - android:width="1dp" - android:color="@color/tp_preference_item_icon_stroke_color"/> </shape>
\ No newline at end of file diff --git a/TwoPanelSettingsLib/res/drawable/slice_error_icon.xml b/TwoPanelSettingsLib/res/drawable/slice_error_icon.xml new file mode 100644 index 000000000..e80c605e6 --- /dev/null +++ b/TwoPanelSettingsLib/res/drawable/slice_error_icon.xml @@ -0,0 +1,25 @@ +<!-- + ~ Copyright (C) 2020 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 + --> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:pathData="M11,15h2v2h-2zM11,7h2v6h-2zM11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z" + android:fillColor="#ffffff"/> +</vector>
\ No newline at end of file diff --git a/TwoPanelSettingsLib/res/drawable/switch_thumb.xml b/TwoPanelSettingsLib/res/drawable/switch_thumb.xml index fc92dd260..83956d35a 100644 --- a/TwoPanelSettingsLib/res/drawable/switch_thumb.xml +++ b/TwoPanelSettingsLib/res/drawable/switch_thumb.xml @@ -18,8 +18,18 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_checked="true" - android:color="@color/tp_preference_switch_thumb_on"/> + android:state_enabled="true" + android:color="@color/tp_preference_switch_thumb_on_default_color"/> + <item + android:state_checked="true" + android:state_enabled="false" + android:color="@color/tp_preference_switch_thumb_disabled_color"/> + <item + android:state_checked="false" + android:state_enabled="true" + android:color="@color/tp_preference_switch_thumb_off_default_color"/> <item android:state_checked="false" - android:color="@color/tp_preference_switch_thumb_off"/> + android:state_enabled="false" + android:color="@color/tp_preference_switch_thumb_disabled_color"/> </selector>
\ No newline at end of file diff --git a/TwoPanelSettingsLib/res/drawable/switch_track.xml b/TwoPanelSettingsLib/res/drawable/switch_track.xml index 024b75823..5f95bcc47 100644 --- a/TwoPanelSettingsLib/res/drawable/switch_track.xml +++ b/TwoPanelSettingsLib/res/drawable/switch_track.xml @@ -18,8 +18,18 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_checked="true" - android:color="@color/tp_preference_switch_track_on"/> + android:state_enabled="true" + android:color="@color/tp_preference_switch_track_on_default_color"/> + <item + android:state_checked="true" + android:state_enabled="false" + android:color="@color/tp_preference_switch_track_disabled_color"/> + <item + android:state_checked="false" + android:state_enabled="true" + android:color="@color/tp_preference_switch_track_off_default_color"/> <item android:state_checked="false" - android:color="@color/tp_preference_switch_track_off"/> + android:state_enabled="false" + android:color="@color/tp_preference_switch_track_disabled_color"/> </selector>
\ No newline at end of file diff --git a/TwoPanelSettingsLib/res/drawable/two_panel_preference_focused.xml b/TwoPanelSettingsLib/res/drawable/two_panel_preference_focused.xml index e35c5f239..478e816d3 100644 --- a/TwoPanelSettingsLib/res/drawable/two_panel_preference_focused.xml +++ b/TwoPanelSettingsLib/res/drawable/two_panel_preference_focused.xml @@ -4,5 +4,5 @@ <stroke android:width="1dp" android:color="#ffe8eaed"/> - <corners android:radius="2dp"/> + <corners android:radius="8dp"/> </shape> diff --git a/TwoPanelSettingsLib/res/layout/dummy_fragment.xml b/TwoPanelSettingsLib/res/layout/dummy_fragment.xml index ad8c2ae96..2a9b14284 100644 --- a/TwoPanelSettingsLib/res/layout/dummy_fragment.xml +++ b/TwoPanelSettingsLib/res/layout/dummy_fragment.xml @@ -17,5 +17,4 @@ <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/container" android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@color/tp_preference_panel_background_color"/> + android:layout_height="match_parent" /> diff --git a/TwoPanelSettingsLib/res/layout/info_fragment.xml b/TwoPanelSettingsLib/res/layout/info_fragment.xml index abba5479d..34f37451f 100644 --- a/TwoPanelSettingsLib/res/layout/info_fragment.xml +++ b/TwoPanelSettingsLib/res/layout/info_fragment.xml @@ -20,7 +20,6 @@ android:id="@+id/main_frame1" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/tp_preference_panel_background_color" android:transitionGroup="false"> <androidx.cardview.widget.CardView @@ -38,14 +37,66 @@ android:scaleType="centerCrop"/> </androidx.cardview.widget.CardView> - <TextView - android:id="@+id/info_text" - style="?android:attr/titleTextStyle" - android:layout_width="match_parent" + <RelativeLayout + android:layout_width="@dimen/settings_info_fragment_bottom_section_width" android:layout_height="wrap_content" + android:layout_alignParentStart="true" android:layout_alignParentBottom="true" - android:layout_marginBottom="@dimen/settings_info_fragment_text_margin_bottom" - android:paddingEnd="@dimen/settings_info_fragment_text_padding_end" - android:paddingStart="@dimen/settings_info_fragment_text_padding_start"/> + android:focusable="true" + android:importantForAccessibility="yes" + android:layout_marginBottom="@dimen/settings_info_fragment_bottom_section_margin_bottom" + android:paddingEnd="@dimen/settings_info_fragment_bottom_section_padding_end" > + + <ImageView + android:id="@+id/info_title_icon" + android:layout_width="@dimen/settings_info_fragment_title_icon_width" + android:layout_height="@dimen/settings_info_fragment_title_icon_width" + android:layout_alignParentStart="true" + android:layout_alignParentTop="true" + android:focusable="false" + android:importantForAccessibility="no" + android:layout_marginEnd="@dimen/settings_info_fragment_title_icon_margin_end" + android:clickable="false" /> + + <TextView + android:id="@+id/info_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_toEndOf="@id/info_title_icon" + android:layout_alignParentTop="true" + android:layout_alignWithParentIfMissing="true" + android:layout_marginBottom="@dimen/settings_info_fragment_title_margin_bottom" + android:focusable="false" + android:importantForAccessibility="yes" + android:maxLines="2" + android:ellipsize="end" + style="@style/TwoPanelInfoTitleTextStyle"/> + + <TextView + android:id="@+id/info_status" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_toEndOf="@id/info_title" + android:layout_alignParentTop="true" + android:layout_marginStart="@dimen/settings_info_fragment_status_margin_start" + android:focusable="false" + android:importantForAccessibility="yes" + android:visibility="gone" + style="@style/TwoPanelInfoTitleTextStyle"/> + + <TextView + android:id="@+id/info_summary" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_toEndOf="@id/info_title_icon" + android:layout_below="@id/info_title" + android:layout_alignWithParentIfMissing="true" + android:focusable="false" + android:importantForAccessibility="yes" + android:maxLines="12" + android:ellipsize="end" + style="@style/TwoPanelInfoSummaryTextStyle"/> + + </RelativeLayout> </RelativeLayout>
\ No newline at end of file diff --git a/TwoPanelSettingsLib/res/layout/leanback_list_preference_item_single.xml b/TwoPanelSettingsLib/res/layout/leanback_list_preference_item_single.xml new file mode 100644 index 000000000..bbb5ba109 --- /dev/null +++ b/TwoPanelSettingsLib/res/layout/leanback_list_preference_item_single.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="?android:attr/selectableItemBackground" + android:clickable="true" + android:focusable="true" + android:descendantFocusability="blocksDescendants" + android:orientation="horizontal" + android:paddingStart="?android:attr/listPreferredItemPaddingStart" + android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" > + + <RadioButton + android:id="@+id/button" + android:layout_width="wrap_content" + android:layout_height="match_parent" + style="?android:attr/radioButtonStyle" + android:background="@null" + android:focusable="false" + android:clickable="false" + android:layout_marginEnd="@dimen/lb_preference_item_icon_margin_end" + android:layout_gravity="center_vertical" /> + + <LinearLayout android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:duplicateParentState="true" + android:orientation="vertical"> + <Space android:layout_width="0dp" android:layout_height="@dimen/lb_preference_item_text_space_top" /> + <TextView + android:id="@android:id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/lb_preference_item_primary_text_margin_bottom" + android:duplicateParentState="true" + android:textAppearance="?android:attr/textAppearanceListItem"/> + <TextView + android:id="@android:id/summary" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/lb_preference_item_primary_text_margin_bottom" + android:duplicateParentState="true" + android:textAppearance="?android:attr/textAppearanceListItemSecondary" + android:visibility="gone"/> + <Space android:layout_width="0dp" android:layout_height="@dimen/lb_preference_item_text_space_bottom" /> + </LinearLayout> + +</LinearLayout> diff --git a/TwoPanelSettingsLib/res/layout/slice_title_container.xml b/TwoPanelSettingsLib/res/layout/slice_title_container.xml index cbf0ad44d..a01fa081a 100644 --- a/TwoPanelSettingsLib/res/layout/slice_title_container.xml +++ b/TwoPanelSettingsLib/res/layout/slice_title_container.xml @@ -15,38 +15,39 @@ --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginBottom="@dimen/decor_container_margin_bottom" - android:background="?attr/defaultBrandColor" - android:elevation="@dimen/lb_preference_decor_title_container_elevation" - android:transitionGroup="false"> - <TextView - android:id="@+id/decor_title" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:includeFontPadding="false" - android:singleLine="false" - android:maxLines="2" - android:ellipsize="end" - style="?android:attr/titleTextStyle"/> - <TextView - android:id="@+id/decor_subtitle" - android:layout_width="@dimen/decor_subtitle_width" - android:layout_height="wrap_content" - android:layout_marginStart="?android:attr/listPreferredItemPaddingStart" - android:layout_marginEnd="?android:attr/listPreferredItemPaddingEnd" - android:layout_marginTop="@dimen/decor_subtitle_margin_top" - android:layout_below="@id/decor_title" - android:includeFontPadding="false" - android:maxLines="2" - style="@style/TextAppearance.TwoPanelPreference.Subtitle"/> - <ImageView - android:id="@+id/decor_icon" - android:layout_width="@dimen/decor_icon_width" - android:layout_height="@dimen/decor_icon_height" - android:layout_marginEnd="@dimen/decor_icon_margin_start" - android:layout_marginTop="@dimen/decor_icon_margin_top" - android:layout_alignTop="@id/decor_title" - android:layout_alignParentEnd="true"/> -</RelativeLayout>
\ No newline at end of file + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:id="@+id/decor_title_container" + android:layout_marginBottom="@dimen/decor_container_margin_bottom" + android:paddingBottom="@dimen/decor_container_padding_bottom" + android:background="@color/tp_preference_brand_color" + android:elevation="@dimen/lb_preference_decor_title_container_elevation" + android:transitionGroup="false"> + <TextView + android:id="@+id/decor_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:includeFontPadding="true" + android:singleLine="false" + android:maxLines="4" + android:ellipsize="end" + style="?android:attr/titleTextStyle"/> + <TextView + android:id="@+id/decor_subtitle" + android:layout_width="@dimen/decor_subtitle_width" + android:layout_height="wrap_content" + android:layout_marginStart="?android:attr/listPreferredItemPaddingStart" + android:layout_marginEnd="?android:attr/listPreferredItemPaddingEnd" + android:layout_marginTop="@dimen/decor_subtitle_margin_top" + android:layout_below="@id/decor_title" + android:includeFontPadding="true" + style="@style/TextAppearance.TwoPanelPreference.Subtitle"/> + <ImageView + android:id="@+id/decor_icon" + android:layout_width="@dimen/decor_icon_width" + android:layout_height="@dimen/decor_icon_height" + android:layout_marginEnd="@dimen/decor_icon_margin_start" + android:layout_marginTop="@dimen/decor_icon_margin_top" + android:layout_alignTop="@id/decor_title" + android:layout_alignParentEnd="true"/> +</RelativeLayout> diff --git a/TwoPanelSettingsLib/res/layout/two_panel_settings_fragment.xml b/TwoPanelSettingsLib/res/layout/two_panel_settings_fragment.xml index a7aaaa5e9..4fb0392a2 100644 --- a/TwoPanelSettingsLib/res/layout/two_panel_settings_fragment.xml +++ b/TwoPanelSettingsLib/res/layout/two_panel_settings_fragment.xml @@ -69,201 +69,113 @@ android:layout_height="match_parent" /> <FrameLayout - android:id="@+id/frame1_container" + android:id="@+id/frame1" android:background="@color/tp_preference_panel_background_color" android:layout_width="@dimen/tp_settings_preference_pane_width" - android:layout_height="match_parent"> - <FrameLayout - android:id="@+id/frame1" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:paddingStart="@dimen/pane_basic_padding_start" - android:paddingEnd="@dimen/preference_pane_padding_end" /> - <FrameLayout - android:id="@+id/frame1_overlay" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@color/tp_preview_panel_overlay_color" - android:alpha="0" - android:focusable="false"/> + android:layout_height="match_parent" + android:paddingStart="@dimen/pane_basic_padding_start" + android:paddingEnd="@dimen/preference_pane_padding_end" + android:clipChildren="false" + android:clipToPadding="false"> </FrameLayout> <FrameLayout - android:id="@+id/frame2_container" + android:id="@+id/frame2" android:background="@color/tp_preference_panel_background_color" android:layout_width="@dimen/tp_settings_preference_pane_width" - android:layout_height="match_parent"> - <FrameLayout - android:id="@+id/frame2" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:paddingStart="@dimen/pane_basic_padding_start" - android:paddingEnd="@dimen/preference_pane_padding_end" /> - <FrameLayout - android:id="@+id/frame2_overlay" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@color/tp_preview_panel_overlay_color" - android:alpha="0" - android:focusable="false"/> + android:layout_height="match_parent" + android:paddingStart="@dimen/pane_basic_padding_start" + android:paddingEnd="@dimen/preference_pane_padding_end" + android:clipChildren="false" + android:clipToPadding="false"> </FrameLayout> <FrameLayout - android:id="@+id/frame3_container" + android:id="@+id/frame3" + android:background="@color/tp_preference_panel_background_color" android:layout_width="@dimen/tp_settings_preference_pane_width" - android:layout_height="match_parent" > - <FrameLayout - android:id="@+id/frame3" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:paddingStart="@dimen/pane_basic_padding_start" - android:paddingEnd="@dimen/preference_pane_padding_end" /> - <FrameLayout - android:id="@+id/frame3_overlay" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@color/tp_preview_panel_overlay_color" - android:alpha="0" - android:focusable="false"/> + android:layout_height="match_parent" + android:paddingStart="@dimen/pane_basic_padding_start" + android:paddingEnd="@dimen/preference_pane_padding_end" + android:clipChildren="false" + android:clipToPadding="false"> </FrameLayout> <FrameLayout - android:id="@+id/frame4_container" + android:id="@+id/frame4" android:background="@color/tp_preference_panel_background_color" android:layout_width="@dimen/tp_settings_preference_pane_width" - android:layout_height="match_parent"> - <FrameLayout - android:id="@+id/frame4" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:paddingStart="@dimen/pane_basic_padding_start" - android:paddingEnd="@dimen/preference_pane_padding_end" /> - <FrameLayout - android:id="@+id/frame4_overlay" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@color/tp_preview_panel_overlay_color" - android:alpha="0" - android:focusable="false"/> + android:layout_height="match_parent" + android:paddingStart="@dimen/pane_basic_padding_start" + android:paddingEnd="@dimen/preference_pane_padding_end" + android:clipChildren="false" + android:clipToPadding="false"> </FrameLayout> <FrameLayout - android:id="@+id/frame5_container" + android:id="@+id/frame5" android:background="@color/tp_preference_panel_background_color" android:layout_width="@dimen/tp_settings_preference_pane_width" - android:layout_height="match_parent"> - <FrameLayout - android:id="@+id/frame5" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:paddingStart="@dimen/pane_basic_padding_start" - android:paddingEnd="@dimen/preference_pane_padding_end" /> - <FrameLayout - android:id="@+id/frame5_overlay" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@color/tp_preview_panel_overlay_color" - android:alpha="0" - android:focusable="false"/> + android:layout_height="match_parent" + android:paddingStart="@dimen/pane_basic_padding_start" + android:paddingEnd="@dimen/preference_pane_padding_end" + android:clipChildren="false" + android:clipToPadding="false"> </FrameLayout> <FrameLayout - android:id="@+id/frame6_container" + android:id="@+id/frame6" android:background="@color/tp_preference_panel_background_color" android:layout_width="@dimen/tp_settings_preference_pane_width" - android:layout_height="match_parent" > - <FrameLayout - android:id="@+id/frame6" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:paddingStart="@dimen/pane_basic_padding_start" - android:paddingEnd="@dimen/preference_pane_padding_end" /> - <FrameLayout - android:id="@+id/frame6_overlay" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@color/tp_preview_panel_overlay_color" - android:alpha="0" - android:focusable="false"/> + android:layout_height="match_parent" + android:paddingStart="@dimen/pane_basic_padding_start" + android:paddingEnd="@dimen/preference_pane_padding_end" + android:clipChildren="false" + android:clipToPadding="false"> </FrameLayout> <FrameLayout - android:id="@+id/frame7_container" + android:id="@+id/frame7" android:background="@color/tp_preference_panel_background_color" android:layout_width="@dimen/tp_settings_preference_pane_width" - android:layout_height="match_parent" > - <FrameLayout - android:id="@+id/frame7" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:paddingStart="@dimen/pane_basic_padding_start" - android:paddingEnd="@dimen/preference_pane_padding_end" /> - <FrameLayout - android:id="@+id/frame7_overlay" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@color/tp_preview_panel_overlay_color" - android:alpha="0" - android:focusable="false"/> + android:layout_height="match_parent" + android:paddingStart="@dimen/pane_basic_padding_start" + android:paddingEnd="@dimen/preference_pane_padding_end" + android:clipChildren="false" + android:clipToPadding="false"> </FrameLayout> <FrameLayout - android:id="@+id/frame8_container" + android:id="@+id/frame8" android:background="@color/tp_preference_panel_background_color" android:layout_width="@dimen/tp_settings_preference_pane_width" - android:layout_height="match_parent" > - <FrameLayout - android:id="@+id/frame8" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:paddingStart="@dimen/pane_basic_padding_start" - android:paddingEnd="@dimen/preference_pane_padding_end" /> - <FrameLayout - android:id="@+id/frame8_overlay" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@color/tp_preview_panel_overlay_color" - android:alpha="0" - android:focusable="false"/> + android:layout_height="match_parent" + android:paddingStart="@dimen/pane_basic_padding_start" + android:paddingEnd="@dimen/preference_pane_padding_end" + android:clipChildren="false" + android:clipToPadding="false"> </FrameLayout> <FrameLayout - android:id="@+id/frame9_container" + android:id="@+id/frame9" android:background="@color/tp_preference_panel_background_color" android:layout_width="@dimen/tp_settings_preference_pane_width" - android:layout_height="match_parent" > - <FrameLayout - android:id="@+id/frame9" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:paddingStart="@dimen/pane_basic_padding_start" - android:paddingEnd="@dimen/preference_pane_padding_end" /> - <FrameLayout - android:id="@+id/frame9_overlay" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@color/tp_preview_panel_overlay_color" - android:alpha="0" - android:focusable="false"/> + android:layout_height="match_parent" + android:paddingStart="@dimen/pane_basic_padding_start" + android:paddingEnd="@dimen/preference_pane_padding_end" + android:clipChildren="false" + android:clipToPadding="false"> </FrameLayout> <FrameLayout - android:id="@+id/frame10_container" + android:id="@+id/frame10" android:background="@color/tp_preference_panel_background_color" android:layout_width="@dimen/tp_settings_preference_pane_width" - android:layout_height="match_parent" > - <FrameLayout - android:id="@+id/frame10" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:paddingStart="@dimen/pane_basic_padding_start" - android:paddingEnd="@dimen/preference_pane_padding_end" /> - <FrameLayout - android:id="@+id/frame10_overlay" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@color/tp_preview_panel_overlay_color" - android:focusable="false"/> + android:layout_height="match_parent" + android:paddingStart="@dimen/pane_basic_padding_start" + android:paddingEnd="@dimen/preference_pane_padding_end" + android:clipChildren="false" + android:clipToPadding="false"> </FrameLayout> <!-- extra_padding_rtl, the extra paddingStart of preference pane in RTL --> diff --git a/TwoPanelSettingsLib/res/values-af/strings.xml b/TwoPanelSettingsLib/res/values-af/strings.xml new file mode 100644 index 000000000..3fbc8ac4a --- /dev/null +++ b/TwoPanelSettingsLib/res/values-af/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Aan"</string> + <string name="info_status_off" msgid="1947357954040244822">"Af"</string> + <string name="switch_on" msgid="6078857185301284868">"AAN"</string> + <string name="switch_off" msgid="2555309941117626592">"AF"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Skakelaar"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-am/strings.xml b/TwoPanelSettingsLib/res/values-am/strings.xml new file mode 100644 index 000000000..b5f52be2e --- /dev/null +++ b/TwoPanelSettingsLib/res/values-am/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"አብራ"</string> + <string name="info_status_off" msgid="1947357954040244822">"አጥፋ"</string> + <string name="switch_on" msgid="6078857185301284868">"በርቷል"</string> + <string name="switch_off" msgid="2555309941117626592">"ጠፍቷል"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"ማብሪያ/ማጥፊያ"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-ar/strings.xml b/TwoPanelSettingsLib/res/values-ar/strings.xml new file mode 100644 index 000000000..dacaee2df --- /dev/null +++ b/TwoPanelSettingsLib/res/values-ar/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"تفعيل"</string> + <string name="info_status_off" msgid="1947357954040244822">"إيقاف"</string> + <string name="switch_on" msgid="6078857185301284868">"تفعيل"</string> + <string name="switch_off" msgid="2555309941117626592">"إيقاف"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"تبديل"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-as/strings.xml b/TwoPanelSettingsLib/res/values-as/strings.xml new file mode 100644 index 000000000..cf872e3f8 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-as/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"অন আছে"</string> + <string name="info_status_off" msgid="1947357954040244822">"অফ আছে"</string> + <string name="switch_on" msgid="6078857185301284868">"অন আছে"</string> + <string name="switch_off" msgid="2555309941117626592">"অফ আছে"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"সলনি কৰক"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-az/strings.xml b/TwoPanelSettingsLib/res/values-az/strings.xml new file mode 100644 index 000000000..48f965afc --- /dev/null +++ b/TwoPanelSettingsLib/res/values-az/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Aktiv"</string> + <string name="info_status_off" msgid="1947357954040244822">"Deaktiv"</string> + <string name="switch_on" msgid="6078857185301284868">"AKTİV"</string> + <string name="switch_off" msgid="2555309941117626592">"DEAKTİV"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Dəyişdirin"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-b+sr+Latn/strings.xml b/TwoPanelSettingsLib/res/values-b+sr+Latn/strings.xml new file mode 100644 index 000000000..d692eb9d2 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-b+sr+Latn/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Uključeno"</string> + <string name="info_status_off" msgid="1947357954040244822">"Isključeno"</string> + <string name="switch_on" msgid="6078857185301284868">"UKLJUČENO"</string> + <string name="switch_off" msgid="2555309941117626592">"ISKLJUČENO"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Prekidač"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-be/strings.xml b/TwoPanelSettingsLib/res/values-be/strings.xml new file mode 100644 index 000000000..8ffe835ee --- /dev/null +++ b/TwoPanelSettingsLib/res/values-be/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Уключана"</string> + <string name="info_status_off" msgid="1947357954040244822">"Выключана"</string> + <string name="switch_on" msgid="6078857185301284868">"УКЛЮЧАНА"</string> + <string name="switch_off" msgid="2555309941117626592">"ВЫКЛЮЧАНА"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Пераключальнік"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-bg/strings.xml b/TwoPanelSettingsLib/res/values-bg/strings.xml new file mode 100644 index 000000000..86017b317 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-bg/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Вкл."</string> + <string name="info_status_off" msgid="1947357954040244822">"Изкл."</string> + <string name="switch_on" msgid="6078857185301284868">"ВКЛ."</string> + <string name="switch_off" msgid="2555309941117626592">"ИЗКЛ."</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Превключване"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-bn/strings.xml b/TwoPanelSettingsLib/res/values-bn/strings.xml new file mode 100644 index 000000000..d025e34a8 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-bn/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"চালু আছে"</string> + <string name="info_status_off" msgid="1947357954040244822">"বন্ধ আছে"</string> + <string name="switch_on" msgid="6078857185301284868">"চালু করুন"</string> + <string name="switch_off" msgid="2555309941117626592">"বন্ধ করুন"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"পাল্টান"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-bs/strings.xml b/TwoPanelSettingsLib/res/values-bs/strings.xml new file mode 100644 index 000000000..a47172114 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-bs/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Uključeno"</string> + <string name="info_status_off" msgid="1947357954040244822">"Isključeno"</string> + <string name="switch_on" msgid="6078857185301284868">"UKLJUČENO"</string> + <string name="switch_off" msgid="2555309941117626592">"ISKLJUČENO"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Prebacivanje"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-ca/strings.xml b/TwoPanelSettingsLib/res/values-ca/strings.xml new file mode 100644 index 000000000..b0e989edc --- /dev/null +++ b/TwoPanelSettingsLib/res/values-ca/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Activat"</string> + <string name="info_status_off" msgid="1947357954040244822">"Desactivat"</string> + <string name="switch_on" msgid="6078857185301284868">"ACTIVAT"</string> + <string name="switch_off" msgid="2555309941117626592">"DESACTIVAT"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Canvia"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-cs/strings.xml b/TwoPanelSettingsLib/res/values-cs/strings.xml new file mode 100644 index 000000000..2386ca81e --- /dev/null +++ b/TwoPanelSettingsLib/res/values-cs/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Zap"</string> + <string name="info_status_off" msgid="1947357954040244822">"Vyp"</string> + <string name="switch_on" msgid="6078857185301284868">"ZAP"</string> + <string name="switch_off" msgid="2555309941117626592">"VYP"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Přepnout"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-da/strings.xml b/TwoPanelSettingsLib/res/values-da/strings.xml new file mode 100644 index 000000000..2ccb9ba24 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-da/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Til"</string> + <string name="info_status_off" msgid="1947357954040244822">"Fra"</string> + <string name="switch_on" msgid="6078857185301284868">"TIL"</string> + <string name="switch_off" msgid="2555309941117626592">"FRA"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Kontakt"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-de/strings.xml b/TwoPanelSettingsLib/res/values-de/strings.xml new file mode 100644 index 000000000..2b0138bc1 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-de/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"An"</string> + <string name="info_status_off" msgid="1947357954040244822">"Aus"</string> + <string name="switch_on" msgid="6078857185301284868">"AN"</string> + <string name="switch_off" msgid="2555309941117626592">"AUS"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Wechseln"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-el/strings.xml b/TwoPanelSettingsLib/res/values-el/strings.xml new file mode 100644 index 000000000..f84f449fc --- /dev/null +++ b/TwoPanelSettingsLib/res/values-el/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Ενεργή"</string> + <string name="info_status_off" msgid="1947357954040244822">"Ανενεργή"</string> + <string name="switch_on" msgid="6078857185301284868">"ΕΝΕΡΓΗ"</string> + <string name="switch_off" msgid="2555309941117626592">"ΑΝΕΝΕΡΓΗ"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Εναλλαγή"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-en-rAU/strings.xml b/TwoPanelSettingsLib/res/values-en-rAU/strings.xml new file mode 100644 index 000000000..1026c4a1f --- /dev/null +++ b/TwoPanelSettingsLib/res/values-en-rAU/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"On"</string> + <string name="info_status_off" msgid="1947357954040244822">"Off"</string> + <string name="switch_on" msgid="6078857185301284868">"ON"</string> + <string name="switch_off" msgid="2555309941117626592">"OFF"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Switch"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-en-rCA/strings.xml b/TwoPanelSettingsLib/res/values-en-rCA/strings.xml new file mode 100644 index 000000000..1026c4a1f --- /dev/null +++ b/TwoPanelSettingsLib/res/values-en-rCA/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"On"</string> + <string name="info_status_off" msgid="1947357954040244822">"Off"</string> + <string name="switch_on" msgid="6078857185301284868">"ON"</string> + <string name="switch_off" msgid="2555309941117626592">"OFF"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Switch"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-en-rGB/strings.xml b/TwoPanelSettingsLib/res/values-en-rGB/strings.xml new file mode 100644 index 000000000..1026c4a1f --- /dev/null +++ b/TwoPanelSettingsLib/res/values-en-rGB/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"On"</string> + <string name="info_status_off" msgid="1947357954040244822">"Off"</string> + <string name="switch_on" msgid="6078857185301284868">"ON"</string> + <string name="switch_off" msgid="2555309941117626592">"OFF"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Switch"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-en-rIN/strings.xml b/TwoPanelSettingsLib/res/values-en-rIN/strings.xml new file mode 100644 index 000000000..1026c4a1f --- /dev/null +++ b/TwoPanelSettingsLib/res/values-en-rIN/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"On"</string> + <string name="info_status_off" msgid="1947357954040244822">"Off"</string> + <string name="switch_on" msgid="6078857185301284868">"ON"</string> + <string name="switch_off" msgid="2555309941117626592">"OFF"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Switch"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-en-rXC/strings.xml b/TwoPanelSettingsLib/res/values-en-rXC/strings.xml new file mode 100644 index 000000000..05fc98451 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-en-rXC/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"On"</string> + <string name="info_status_off" msgid="1947357954040244822">"Off"</string> + <string name="switch_on" msgid="6078857185301284868">"ON"</string> + <string name="switch_off" msgid="2555309941117626592">"OFF"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Switch"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-es-rUS/strings.xml b/TwoPanelSettingsLib/res/values-es-rUS/strings.xml new file mode 100644 index 000000000..81d30a79a --- /dev/null +++ b/TwoPanelSettingsLib/res/values-es-rUS/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Activado"</string> + <string name="info_status_off" msgid="1947357954040244822">"Desactivado"</string> + <string name="switch_on" msgid="6078857185301284868">"Activado"</string> + <string name="switch_off" msgid="2555309941117626592">"Desactivado"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Interruptor"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-es/strings.xml b/TwoPanelSettingsLib/res/values-es/strings.xml new file mode 100644 index 000000000..492bdca16 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-es/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Activado"</string> + <string name="info_status_off" msgid="1947357954040244822">"Desactivado"</string> + <string name="switch_on" msgid="6078857185301284868">"ACTIVADO"</string> + <string name="switch_off" msgid="2555309941117626592">"DESACTIVADO"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Interruptor"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-et/strings.xml b/TwoPanelSettingsLib/res/values-et/strings.xml new file mode 100644 index 000000000..11408d528 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-et/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Sees"</string> + <string name="info_status_off" msgid="1947357954040244822">"Väljas"</string> + <string name="switch_on" msgid="6078857185301284868">"SEES"</string> + <string name="switch_off" msgid="2555309941117626592">"VÄLJAS"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Vahetamine"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-eu/strings.xml b/TwoPanelSettingsLib/res/values-eu/strings.xml new file mode 100644 index 000000000..89fc8dcaf --- /dev/null +++ b/TwoPanelSettingsLib/res/values-eu/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Aktibatuta"</string> + <string name="info_status_off" msgid="1947357954040244822">"Desaktibatuta"</string> + <string name="switch_on" msgid="6078857185301284868">"AKTIBATUTA"</string> + <string name="switch_off" msgid="2555309941117626592">"DESAKTIBATUTA"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Aldatu"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-fa/strings.xml b/TwoPanelSettingsLib/res/values-fa/strings.xml new file mode 100644 index 000000000..827b3ff73 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-fa/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"روشن"</string> + <string name="info_status_off" msgid="1947357954040244822">"خاموش"</string> + <string name="switch_on" msgid="6078857185301284868">"روشن"</string> + <string name="switch_off" msgid="2555309941117626592">"خاموش"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"عوض کردن"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-fi/strings.xml b/TwoPanelSettingsLib/res/values-fi/strings.xml new file mode 100644 index 000000000..458731492 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-fi/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Päällä"</string> + <string name="info_status_off" msgid="1947357954040244822">"Poissa päältä"</string> + <string name="switch_on" msgid="6078857185301284868">"PÄÄLLÄ"</string> + <string name="switch_off" msgid="2555309941117626592">"POISSA"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Vaihda"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-fr-rCA/strings.xml b/TwoPanelSettingsLib/res/values-fr-rCA/strings.xml new file mode 100644 index 000000000..f064148e4 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-fr-rCA/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Activé"</string> + <string name="info_status_off" msgid="1947357954040244822">"Désactivé"</string> + <string name="switch_on" msgid="6078857185301284868">"ACTIVÉ"</string> + <string name="switch_off" msgid="2555309941117626592">"DÉSACTIVÉ"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Changer"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-fr/strings.xml b/TwoPanelSettingsLib/res/values-fr/strings.xml new file mode 100644 index 000000000..f064148e4 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-fr/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Activé"</string> + <string name="info_status_off" msgid="1947357954040244822">"Désactivé"</string> + <string name="switch_on" msgid="6078857185301284868">"ACTIVÉ"</string> + <string name="switch_off" msgid="2555309941117626592">"DÉSACTIVÉ"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Changer"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-gl/strings.xml b/TwoPanelSettingsLib/res/values-gl/strings.xml new file mode 100644 index 000000000..fdc9de00e --- /dev/null +++ b/TwoPanelSettingsLib/res/values-gl/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Activado"</string> + <string name="info_status_off" msgid="1947357954040244822">"Desactivado"</string> + <string name="switch_on" msgid="6078857185301284868">"SI"</string> + <string name="switch_off" msgid="2555309941117626592">"NON"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Interruptor"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-gu/strings.xml b/TwoPanelSettingsLib/res/values-gu/strings.xml new file mode 100644 index 000000000..1f5e92149 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-gu/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"ચાલુ"</string> + <string name="info_status_off" msgid="1947357954040244822">"બંધ"</string> + <string name="switch_on" msgid="6078857185301284868">"ચાલુ"</string> + <string name="switch_off" msgid="2555309941117626592">"બંધ"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"સ્વિચ"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-hi/strings.xml b/TwoPanelSettingsLib/res/values-hi/strings.xml new file mode 100644 index 000000000..19ed484df --- /dev/null +++ b/TwoPanelSettingsLib/res/values-hi/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"चालू है"</string> + <string name="info_status_off" msgid="1947357954040244822">"बंद है"</string> + <string name="switch_on" msgid="6078857185301284868">"चालू है"</string> + <string name="switch_off" msgid="2555309941117626592">"बंद है"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"स्विच"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-hr/strings.xml b/TwoPanelSettingsLib/res/values-hr/strings.xml new file mode 100644 index 000000000..a47172114 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-hr/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Uključeno"</string> + <string name="info_status_off" msgid="1947357954040244822">"Isključeno"</string> + <string name="switch_on" msgid="6078857185301284868">"UKLJUČENO"</string> + <string name="switch_off" msgid="2555309941117626592">"ISKLJUČENO"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Prebacivanje"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-hu/strings.xml b/TwoPanelSettingsLib/res/values-hu/strings.xml new file mode 100644 index 000000000..9706a3ca0 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-hu/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Be"</string> + <string name="info_status_off" msgid="1947357954040244822">"Ki"</string> + <string name="switch_on" msgid="6078857185301284868">"BE"</string> + <string name="switch_off" msgid="2555309941117626592">"KI"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Váltás"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-hy/strings.xml b/TwoPanelSettingsLib/res/values-hy/strings.xml new file mode 100644 index 000000000..a7e145078 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-hy/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Միացված է"</string> + <string name="info_status_off" msgid="1947357954040244822">"Անջատված է"</string> + <string name="switch_on" msgid="6078857185301284868">"ՄԻԱՑՎԱԾ Է"</string> + <string name="switch_off" msgid="2555309941117626592">"ԱՆՋԱՏՎԱԾ է"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Փոխանջատիչ"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-in/strings.xml b/TwoPanelSettingsLib/res/values-in/strings.xml new file mode 100644 index 000000000..c655f0543 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-in/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Aktif"</string> + <string name="info_status_off" msgid="1947357954040244822">"Nonaktif"</string> + <string name="switch_on" msgid="6078857185301284868">"AKTIF"</string> + <string name="switch_off" msgid="2555309941117626592">"NONAKTIF"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Tombol"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-is/strings.xml b/TwoPanelSettingsLib/res/values-is/strings.xml new file mode 100644 index 000000000..f1e026d8b --- /dev/null +++ b/TwoPanelSettingsLib/res/values-is/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Kveikt"</string> + <string name="info_status_off" msgid="1947357954040244822">"Slökkt"</string> + <string name="switch_on" msgid="6078857185301284868">"KVEIKT"</string> + <string name="switch_off" msgid="2555309941117626592">"SLÖKKT"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Rofi"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-it/strings.xml b/TwoPanelSettingsLib/res/values-it/strings.xml new file mode 100644 index 000000000..c6caca074 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-it/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"On"</string> + <string name="info_status_off" msgid="1947357954040244822">"Off"</string> + <string name="switch_on" msgid="6078857185301284868">"ON"</string> + <string name="switch_off" msgid="2555309941117626592">"OFF"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Cambia"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-iw/strings.xml b/TwoPanelSettingsLib/res/values-iw/strings.xml new file mode 100644 index 000000000..05e5b468d --- /dev/null +++ b/TwoPanelSettingsLib/res/values-iw/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"פועל"</string> + <string name="info_status_off" msgid="1947357954040244822">"כבוי"</string> + <string name="switch_on" msgid="6078857185301284868">"מופעל"</string> + <string name="switch_off" msgid="2555309941117626592">"כבוי"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"החלפה"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-ja/strings.xml b/TwoPanelSettingsLib/res/values-ja/strings.xml new file mode 100644 index 000000000..c94598f63 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-ja/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"ON"</string> + <string name="info_status_off" msgid="1947357954040244822">"OFF"</string> + <string name="switch_on" msgid="6078857185301284868">"ON"</string> + <string name="switch_off" msgid="2555309941117626592">"OFF"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"切り替える"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-ka/strings.xml b/TwoPanelSettingsLib/res/values-ka/strings.xml new file mode 100644 index 000000000..64c93dc77 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-ka/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"ჩართვა"</string> + <string name="info_status_off" msgid="1947357954040244822">"გამორთვა"</string> + <string name="switch_on" msgid="6078857185301284868">"ჩართვა"</string> + <string name="switch_off" msgid="2555309941117626592">"გამორთვა"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"გადართვა"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-kk/strings.xml b/TwoPanelSettingsLib/res/values-kk/strings.xml new file mode 100644 index 000000000..6229795fc --- /dev/null +++ b/TwoPanelSettingsLib/res/values-kk/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Қосулы"</string> + <string name="info_status_off" msgid="1947357954040244822">"Өшірулі"</string> + <string name="switch_on" msgid="6078857185301284868">"ҚОСУЛЫ"</string> + <string name="switch_off" msgid="2555309941117626592">"ӨШІРУЛІ"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Ауысу"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-km/strings.xml b/TwoPanelSettingsLib/res/values-km/strings.xml new file mode 100644 index 000000000..6b7a547ba --- /dev/null +++ b/TwoPanelSettingsLib/res/values-km/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"បើក"</string> + <string name="info_status_off" msgid="1947357954040244822">"បិទ"</string> + <string name="switch_on" msgid="6078857185301284868">"បើក"</string> + <string name="switch_off" msgid="2555309941117626592">"បិទ"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"ប៊ូតុងបិទបើក"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-kn/strings.xml b/TwoPanelSettingsLib/res/values-kn/strings.xml new file mode 100644 index 000000000..0a3961df2 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-kn/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"ಆನ್"</string> + <string name="info_status_off" msgid="1947357954040244822">"ಆಫ್"</string> + <string name="switch_on" msgid="6078857185301284868">"ಆನ್"</string> + <string name="switch_off" msgid="2555309941117626592">"ಆಫ್"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"ಬದಲಿಸಿ"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-ko/strings.xml b/TwoPanelSettingsLib/res/values-ko/strings.xml new file mode 100644 index 000000000..181a6d08f --- /dev/null +++ b/TwoPanelSettingsLib/res/values-ko/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"사용"</string> + <string name="info_status_off" msgid="1947357954040244822">"사용 안함"</string> + <string name="switch_on" msgid="6078857185301284868">"사용"</string> + <string name="switch_off" msgid="2555309941117626592">"사용 안함"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"전환"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-ky/strings.xml b/TwoPanelSettingsLib/res/values-ky/strings.xml new file mode 100644 index 000000000..f393fac45 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-ky/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Күйүк"</string> + <string name="info_status_off" msgid="1947357954040244822">"Өчүк"</string> + <string name="switch_on" msgid="6078857185301284868">"КҮЙҮК"</string> + <string name="switch_off" msgid="2555309941117626592">"ӨЧҮК"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Которгуч"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-lo/strings.xml b/TwoPanelSettingsLib/res/values-lo/strings.xml new file mode 100644 index 000000000..f32476c57 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-lo/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"ເປີດ"</string> + <string name="info_status_off" msgid="1947357954040244822">"ປິດ"</string> + <string name="switch_on" msgid="6078857185301284868">"ເປີດ"</string> + <string name="switch_off" msgid="2555309941117626592">"ປິດ"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"ປຸ່ມກົດ"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-lt/strings.xml b/TwoPanelSettingsLib/res/values-lt/strings.xml new file mode 100644 index 000000000..1e047108f --- /dev/null +++ b/TwoPanelSettingsLib/res/values-lt/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Įjungta"</string> + <string name="info_status_off" msgid="1947357954040244822">"Išjungta"</string> + <string name="switch_on" msgid="6078857185301284868">"ĮJUNGTA"</string> + <string name="switch_off" msgid="2555309941117626592">"IŠJUNGTA"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Perjungti"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-lv/strings.xml b/TwoPanelSettingsLib/res/values-lv/strings.xml new file mode 100644 index 000000000..15b33d492 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-lv/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Ieslēgta"</string> + <string name="info_status_off" msgid="1947357954040244822">"Izslēgta"</string> + <string name="switch_on" msgid="6078857185301284868">"IESLĒGTS"</string> + <string name="switch_off" msgid="2555309941117626592">"IZSLĒGTS"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Pārslēgt"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-mk/strings.xml b/TwoPanelSettingsLib/res/values-mk/strings.xml new file mode 100644 index 000000000..9a980e3ca --- /dev/null +++ b/TwoPanelSettingsLib/res/values-mk/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Вклучено"</string> + <string name="info_status_off" msgid="1947357954040244822">"Исклучено"</string> + <string name="switch_on" msgid="6078857185301284868">"ВКЛУЧЕНО"</string> + <string name="switch_off" msgid="2555309941117626592">"ИСКЛУЧЕНО"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Прекинувач"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-ml/strings.xml b/TwoPanelSettingsLib/res/values-ml/strings.xml new file mode 100644 index 000000000..cabccf505 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-ml/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"ഓണാണ്"</string> + <string name="info_status_off" msgid="1947357954040244822">"ഓഫാണ്"</string> + <string name="switch_on" msgid="6078857185301284868">"ഓൺ"</string> + <string name="switch_off" msgid="2555309941117626592">"ഓഫ്"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"മാറുക"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-mn/strings.xml b/TwoPanelSettingsLib/res/values-mn/strings.xml new file mode 100644 index 000000000..e2ee60e51 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-mn/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Асаалттай"</string> + <string name="info_status_off" msgid="1947357954040244822">"Унтраалттай"</string> + <string name="switch_on" msgid="6078857185301284868">"АСААЛТТАЙ"</string> + <string name="switch_off" msgid="2555309941117626592">"УНТРААЛТТАЙ"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Сэлгэх"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-mr/strings.xml b/TwoPanelSettingsLib/res/values-mr/strings.xml new file mode 100644 index 000000000..8a12bb51e --- /dev/null +++ b/TwoPanelSettingsLib/res/values-mr/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"सुरू करा"</string> + <string name="info_status_off" msgid="1947357954040244822">"बंद करा"</string> + <string name="switch_on" msgid="6078857185301284868">"सुरू"</string> + <string name="switch_off" msgid="2555309941117626592">"बंद"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"स्विच करा"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-ms/strings.xml b/TwoPanelSettingsLib/res/values-ms/strings.xml new file mode 100644 index 000000000..9456fc2fa --- /dev/null +++ b/TwoPanelSettingsLib/res/values-ms/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Hidup"</string> + <string name="info_status_off" msgid="1947357954040244822">"Mati"</string> + <string name="switch_on" msgid="6078857185301284868">"HIDUP"</string> + <string name="switch_off" msgid="2555309941117626592">"MATI"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Tukar"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-my/strings.xml b/TwoPanelSettingsLib/res/values-my/strings.xml new file mode 100644 index 000000000..7803b5cae --- /dev/null +++ b/TwoPanelSettingsLib/res/values-my/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"ဖွင့်ထားသည်"</string> + <string name="info_status_off" msgid="1947357954040244822">"ပိတ်ထားသည်"</string> + <string name="switch_on" msgid="6078857185301284868">"ဖွင့်ထားသည်"</string> + <string name="switch_off" msgid="2555309941117626592">"ပိတ်ထားသည်"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"ပြောင်းရန်"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-nb/strings.xml b/TwoPanelSettingsLib/res/values-nb/strings.xml new file mode 100644 index 000000000..181ee1d84 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-nb/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"På"</string> + <string name="info_status_off" msgid="1947357954040244822">"Av"</string> + <string name="switch_on" msgid="6078857185301284868">"PÅ"</string> + <string name="switch_off" msgid="2555309941117626592">"AV"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Bryter"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-ne/strings.xml b/TwoPanelSettingsLib/res/values-ne/strings.xml new file mode 100644 index 000000000..0284ba145 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-ne/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"अन छ"</string> + <string name="info_status_off" msgid="1947357954040244822">"अफ छ"</string> + <string name="switch_on" msgid="6078857185301284868">"अन छ"</string> + <string name="switch_off" msgid="2555309941117626592">"अफ छ"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"अन/अफ गर्नुहोस्"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-nl/strings.xml b/TwoPanelSettingsLib/res/values-nl/strings.xml new file mode 100644 index 000000000..307f58161 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-nl/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Aan"</string> + <string name="info_status_off" msgid="1947357954040244822">"Uit"</string> + <string name="switch_on" msgid="6078857185301284868">"ON"</string> + <string name="switch_off" msgid="2555309941117626592">"UIT"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Overschakelen"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-or/strings.xml b/TwoPanelSettingsLib/res/values-or/strings.xml new file mode 100644 index 000000000..45e19b03b --- /dev/null +++ b/TwoPanelSettingsLib/res/values-or/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"ଚାଲୁ ଅଛି"</string> + <string name="info_status_off" msgid="1947357954040244822">"ବନ୍ଦ ଅଛି"</string> + <string name="switch_on" msgid="6078857185301284868">"ଚାଲୁ ଅଛି"</string> + <string name="switch_off" msgid="2555309941117626592">"ବନ୍ଦ ଅଛି"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"ସ୍ୱିଚ୍ କରନ୍ତୁ"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-pa/strings.xml b/TwoPanelSettingsLib/res/values-pa/strings.xml new file mode 100644 index 000000000..2138ee9ec --- /dev/null +++ b/TwoPanelSettingsLib/res/values-pa/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"ਚਾਲੂ ਹੈ"</string> + <string name="info_status_off" msgid="1947357954040244822">"ਬੰਦ ਹੈ"</string> + <string name="switch_on" msgid="6078857185301284868">"ਚਾਲੂ"</string> + <string name="switch_off" msgid="2555309941117626592">"ਬੰਦ"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"ਸਵਿੱਚ ਕਰੋ"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-pl/strings.xml b/TwoPanelSettingsLib/res/values-pl/strings.xml new file mode 100644 index 000000000..a353070a4 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-pl/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Włączono"</string> + <string name="info_status_off" msgid="1947357954040244822">"Wyłączono"</string> + <string name="switch_on" msgid="6078857185301284868">"WŁĄCZONO"</string> + <string name="switch_off" msgid="2555309941117626592">"WYŁĄCZONO"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Przełącznik"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-pt-rBR/strings.xml b/TwoPanelSettingsLib/res/values-pt-rBR/strings.xml new file mode 100644 index 000000000..98ab8c120 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-pt-rBR/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Ativado"</string> + <string name="info_status_off" msgid="1947357954040244822">"Desativado"</string> + <string name="switch_on" msgid="6078857185301284868">"ATIVADO"</string> + <string name="switch_off" msgid="2555309941117626592">"DESATIVADO"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Trocar"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-pt-rPT/strings.xml b/TwoPanelSettingsLib/res/values-pt-rPT/strings.xml new file mode 100644 index 000000000..7c973ef09 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-pt-rPT/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Ativado"</string> + <string name="info_status_off" msgid="1947357954040244822">"Desativado"</string> + <string name="switch_on" msgid="6078857185301284868">"ATIVAR"</string> + <string name="switch_off" msgid="2555309941117626592">"DESATIVAR"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Interruptor"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-pt/strings.xml b/TwoPanelSettingsLib/res/values-pt/strings.xml new file mode 100644 index 000000000..98ab8c120 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-pt/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Ativado"</string> + <string name="info_status_off" msgid="1947357954040244822">"Desativado"</string> + <string name="switch_on" msgid="6078857185301284868">"ATIVADO"</string> + <string name="switch_off" msgid="2555309941117626592">"DESATIVADO"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Trocar"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-ro/strings.xml b/TwoPanelSettingsLib/res/values-ro/strings.xml new file mode 100644 index 000000000..a4a0c0684 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-ro/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Activat"</string> + <string name="info_status_off" msgid="1947357954040244822">"Dezactivat"</string> + <string name="switch_on" msgid="6078857185301284868">"ACTIVAT"</string> + <string name="switch_off" msgid="2555309941117626592">"DEZACTIVAT"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Comutați"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-ru/strings.xml b/TwoPanelSettingsLib/res/values-ru/strings.xml new file mode 100644 index 000000000..1bd19f816 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-ru/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Вкл."</string> + <string name="info_status_off" msgid="1947357954040244822">"Откл."</string> + <string name="switch_on" msgid="6078857185301284868">"ВКЛЮЧЕНО"</string> + <string name="switch_off" msgid="2555309941117626592">"ВЫКЛЮЧЕНО"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Переключатель"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-si/strings.xml b/TwoPanelSettingsLib/res/values-si/strings.xml new file mode 100644 index 000000000..f58afc87a --- /dev/null +++ b/TwoPanelSettingsLib/res/values-si/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"ක්රියාත්මකයි"</string> + <string name="info_status_off" msgid="1947357954040244822">"ක්රියාවිරහිතයි"</string> + <string name="switch_on" msgid="6078857185301284868">"ක්රියාත්මකයි"</string> + <string name="switch_off" msgid="2555309941117626592">"ක්රියාවිරහිතයි"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"මාරු කරන්න"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-sk/strings.xml b/TwoPanelSettingsLib/res/values-sk/strings.xml new file mode 100644 index 000000000..8ebd5625a --- /dev/null +++ b/TwoPanelSettingsLib/res/values-sk/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Zapnuté"</string> + <string name="info_status_off" msgid="1947357954040244822">"Vypnuté"</string> + <string name="switch_on" msgid="6078857185301284868">"ZAPNUTÉ"</string> + <string name="switch_off" msgid="2555309941117626592">"VYPNUTÉ"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Prepnúť"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-sl/strings.xml b/TwoPanelSettingsLib/res/values-sl/strings.xml new file mode 100644 index 000000000..ac43b42a5 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-sl/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Vklopljeno"</string> + <string name="info_status_off" msgid="1947357954040244822">"Izklopljeno"</string> + <string name="switch_on" msgid="6078857185301284868">"VKLOPLJENO"</string> + <string name="switch_off" msgid="2555309941117626592">"IZKLOPLJENO"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Preklop"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-sq/strings.xml b/TwoPanelSettingsLib/res/values-sq/strings.xml new file mode 100644 index 000000000..467dd3f8c --- /dev/null +++ b/TwoPanelSettingsLib/res/values-sq/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Aktiv"</string> + <string name="info_status_off" msgid="1947357954040244822">"Joaktiv"</string> + <string name="switch_on" msgid="6078857185301284868">"AKTIV"</string> + <string name="switch_off" msgid="2555309941117626592">"JOAKTIV"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Ndërro"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-sr/strings.xml b/TwoPanelSettingsLib/res/values-sr/strings.xml new file mode 100644 index 000000000..3cd08c137 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-sr/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Укључено"</string> + <string name="info_status_off" msgid="1947357954040244822">"Искључено"</string> + <string name="switch_on" msgid="6078857185301284868">"УКЉУЧЕНО"</string> + <string name="switch_off" msgid="2555309941117626592">"ИСКЉУЧЕНО"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Прекидач"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-sv/strings.xml b/TwoPanelSettingsLib/res/values-sv/strings.xml new file mode 100644 index 000000000..bcff2ee95 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-sv/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"På"</string> + <string name="info_status_off" msgid="1947357954040244822">"Av"</string> + <string name="switch_on" msgid="6078857185301284868">"PÅ"</string> + <string name="switch_off" msgid="2555309941117626592">"AV"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Brytare"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-sw/strings.xml b/TwoPanelSettingsLib/res/values-sw/strings.xml new file mode 100644 index 000000000..5a3262a25 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-sw/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Imewashwa"</string> + <string name="info_status_off" msgid="1947357954040244822">"Imezimwa"</string> + <string name="switch_on" msgid="6078857185301284868">"WASHA"</string> + <string name="switch_off" msgid="2555309941117626592">"ZIMA"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Badilisha"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-ta/strings.xml b/TwoPanelSettingsLib/res/values-ta/strings.xml new file mode 100644 index 000000000..a6c89b425 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-ta/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"ஆனில் உள்ளது"</string> + <string name="info_status_off" msgid="1947357954040244822">"ஆஃபில் உள்ளது"</string> + <string name="switch_on" msgid="6078857185301284868">"ஆன்"</string> + <string name="switch_off" msgid="2555309941117626592">"ஆஃப்"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"ஸ்விட்ச்"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-te/strings.xml b/TwoPanelSettingsLib/res/values-te/strings.xml new file mode 100644 index 000000000..483386e49 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-te/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"ఆన్"</string> + <string name="info_status_off" msgid="1947357954040244822">"ఆఫ్"</string> + <string name="switch_on" msgid="6078857185301284868">"ఆన్"</string> + <string name="switch_off" msgid="2555309941117626592">"ఆఫ్"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"స్విచ్"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-th/strings.xml b/TwoPanelSettingsLib/res/values-th/strings.xml new file mode 100644 index 000000000..d5b17a4c9 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-th/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"เปิด"</string> + <string name="info_status_off" msgid="1947357954040244822">"ปิด"</string> + <string name="switch_on" msgid="6078857185301284868">"เปิด"</string> + <string name="switch_off" msgid="2555309941117626592">"ปิด"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"เปลี่ยน"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-tl/strings.xml b/TwoPanelSettingsLib/res/values-tl/strings.xml new file mode 100644 index 000000000..43ced772d --- /dev/null +++ b/TwoPanelSettingsLib/res/values-tl/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Naka-on"</string> + <string name="info_status_off" msgid="1947357954040244822">"Naka-off"</string> + <string name="switch_on" msgid="6078857185301284868">"NAKA-ON"</string> + <string name="switch_off" msgid="2555309941117626592">"NAKA-OFF"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Lumipat"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-tr/strings.xml b/TwoPanelSettingsLib/res/values-tr/strings.xml new file mode 100644 index 000000000..274737ffc --- /dev/null +++ b/TwoPanelSettingsLib/res/values-tr/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Açık"</string> + <string name="info_status_off" msgid="1947357954040244822">"Kapalı"</string> + <string name="switch_on" msgid="6078857185301284868">"AÇ"</string> + <string name="switch_off" msgid="2555309941117626592">"KAPAT"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Anahtar"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-uk/strings.xml b/TwoPanelSettingsLib/res/values-uk/strings.xml new file mode 100644 index 000000000..186d735a2 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-uk/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Увімкнено"</string> + <string name="info_status_off" msgid="1947357954040244822">"Вимкнено"</string> + <string name="switch_on" msgid="6078857185301284868">"УВІМКНЕНО"</string> + <string name="switch_off" msgid="2555309941117626592">"ВИМКНЕНО"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Перемикач"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-ur/strings.xml b/TwoPanelSettingsLib/res/values-ur/strings.xml new file mode 100644 index 000000000..d32e2dd4d --- /dev/null +++ b/TwoPanelSettingsLib/res/values-ur/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"آن کریں"</string> + <string name="info_status_off" msgid="1947357954040244822">"آف کریں"</string> + <string name="switch_on" msgid="6078857185301284868">"آن"</string> + <string name="switch_off" msgid="2555309941117626592">"آف"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"سوئچ کریں"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-uz/strings.xml b/TwoPanelSettingsLib/res/values-uz/strings.xml new file mode 100644 index 000000000..c0b03a529 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-uz/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Yoniq"</string> + <string name="info_status_off" msgid="1947357954040244822">"Yoqilmagan"</string> + <string name="switch_on" msgid="6078857185301284868">"YONIQ"</string> + <string name="switch_off" msgid="2555309941117626592">"OʻCHIQ"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Almashtirish"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-vi/strings.xml b/TwoPanelSettingsLib/res/values-vi/strings.xml new file mode 100644 index 000000000..a95e9a166 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-vi/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Đang bật"</string> + <string name="info_status_off" msgid="1947357954040244822">"Đang tắt"</string> + <string name="switch_on" msgid="6078857185301284868">"ĐANG BẬT"</string> + <string name="switch_off" msgid="2555309941117626592">"ĐANG TẮT"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Chuyển"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-zh-rCN/strings.xml b/TwoPanelSettingsLib/res/values-zh-rCN/strings.xml new file mode 100644 index 000000000..2b7e410c9 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-zh-rCN/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"开"</string> + <string name="info_status_off" msgid="1947357954040244822">"关"</string> + <string name="switch_on" msgid="6078857185301284868">"开启"</string> + <string name="switch_off" msgid="2555309941117626592">"关闭"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"开关"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-zh-rHK/strings.xml b/TwoPanelSettingsLib/res/values-zh-rHK/strings.xml new file mode 100644 index 000000000..dd7ce796c --- /dev/null +++ b/TwoPanelSettingsLib/res/values-zh-rHK/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"開啟"</string> + <string name="info_status_off" msgid="1947357954040244822">"關閉"</string> + <string name="switch_on" msgid="6078857185301284868">"開咗"</string> + <string name="switch_off" msgid="2555309941117626592">"閂咗"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"切換"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-zh-rTW/strings.xml b/TwoPanelSettingsLib/res/values-zh-rTW/strings.xml new file mode 100644 index 000000000..dba372568 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-zh-rTW/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"開啟"</string> + <string name="info_status_off" msgid="1947357954040244822">"關閉"</string> + <string name="switch_on" msgid="6078857185301284868">"已開啟"</string> + <string name="switch_off" msgid="2555309941117626592">"已關閉"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"切換"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values-zu/strings.xml b/TwoPanelSettingsLib/res/values-zu/strings.xml new file mode 100644 index 000000000..43bd6f3d5 --- /dev/null +++ b/TwoPanelSettingsLib/res/values-zu/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="info_status_on" msgid="8274851391556672594">"Vuliwe"</string> + <string name="info_status_off" msgid="1947357954040244822">"Valiwe"</string> + <string name="switch_on" msgid="6078857185301284868">"VULA"</string> + <string name="switch_off" msgid="2555309941117626592">"VALA"</string> + <string name="switch_talkback_identifier" msgid="3243563960920396436">"Shintsha"</string> +</resources> diff --git a/TwoPanelSettingsLib/res/values/colors.xml b/TwoPanelSettingsLib/res/values/colors.xml index 02135d425..b497fe2b1 100644 --- a/TwoPanelSettingsLib/res/values/colors.xml +++ b/TwoPanelSettingsLib/res/values/colors.xml @@ -15,33 +15,40 @@ --> <resources> - <color name="tp_preview_panel_overlay_color">#99000000</color> - <color name="tp_preference_window_background">#FF0E0E0F</color> + <color name="tp_preference_window_background">@android:color/transparent</color> <color name="tp_preference_brand_color">@android:color/transparent</color> - <color name="tp_fragment_container_background_color">#FF0E0E0F</color> - <color name="tp_preview_panel_background_color">#ff1c1d1f</color> - <color name="tp_preference_panel_background_color">#FF0E0E0F</color> + <color name="tp_fragment_container_background_color">#FF1E232C</color> + <color name="tp_preview_panel_background_color">#FF222730</color> + <color name="tp_preference_panel_background_color">#FF1E232C</color> <color name="tp_preference_item_primary_text_focused_color">#FF0E0E0F</color> - <color name="tp_preference_item_primary_text_disabled_color">#FF5F6368</color> + <color name="tp_preference_item_primary_text_disabled_color">#FF9AA0A6</color> <color name="tp_preference_item_primary_text_default_color">#FFE8EAED</color> <color name="tp_preference_item_secondary_text_focused_color">#990E0E0F</color> - <color name="tp_preference_item_secondary_text_disabled_color">#FF5F6368</color> + <color name="tp_preference_item_secondary_text_disabled_color">#FF9AA0A6</color> <color name="tp_preference_item_secondary_text_default_color">#99E8EAED</color> - <color name="tp_preference_category_text_color">#FF5F6368</color> + <color name="tp_preference_category_text_color">#FF9AA0A6</color> <color name="tp_preference_decor_title_text_color">#FFE8EAED</color> - <color name="tp_preference_item_icon_focused_background_color">#FFE8EAED</color> - <color name="tp_preference_item_icon_default_background_color">#14E8EAED</color> - <color name="tp_preference_item_icon_stroke_color">#4D0E0E0F</color> + <color name="tp_preference_item_icon_focused_background_color">#FFD3E0F5</color> + <color name="tp_preference_item_icon_default_background_color">#FF263041</color> - <color name="tp_preference_switch_thumb_on">#FF4284f4</color> - <color name="tp_preference_switch_thumb_off">#FFF1F1F1</color> - <color name="tp_preference_switch_track_on">#FF4284f4</color> - <color name="tp_preference_switch_track_off">#FF5F6368</color> + <color name="tp_preference_switch_thumb_on_default_color">#FF3B78E7</color> + <color name="tp_preference_switch_thumb_off_default_color">#FFFAFAFA</color> + <color name="tp_preference_switch_track_on_default_color">#FF87ADF1</color> + <color name="tp_preference_switch_track_off_default_color">#FF9CA8BA</color> + + <color name="tp_preference_switch_thumb_disabled_color">#FFBDBDBD</color> + <color name="tp_preference_switch_track_disabled_color">#FFBDC1C6</color> + + <color name="tp_preference_wifi_signal_lock_focused">#5F6368</color> + <color name="tp_preference_wifi_signal_lock_unfocused">#F8F9FA</color> <color name="info_separator">#FF323232</color> + <color name="info_title_text_color">#FFFFFFFF</color> + <color name="info_status_on">#FF5BB974</color> + <color name="info_status_off">#FFEE675C</color> </resources> diff --git a/TwoPanelSettingsLib/res/values/configs.xml b/TwoPanelSettingsLib/res/values/configs.xml new file mode 100644 index 000000000..4cd1a7e7a --- /dev/null +++ b/TwoPanelSettingsLib/res/values/configs.xml @@ -0,0 +1,23 @@ + +<!-- + ~ Copyright (C) 2021 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. + --> + +<resources> + <!-- Whether to check scroll state when creating preview panel fragment --> + <bool name="config_check_scroll_state" translatable="false">false</bool> + <!-- Delay before creating preview panel fragment --> + <integer name="config_preview_panel_create_delay" translatable="false">0</integer> +</resources> diff --git a/TwoPanelSettingsLib/res/values/dimens.xml b/TwoPanelSettingsLib/res/values/dimens.xml index 1ce9442c2..e88231593 100644 --- a/TwoPanelSettingsLib/res/values/dimens.xml +++ b/TwoPanelSettingsLib/res/values/dimens.xml @@ -35,7 +35,8 @@ <dimen name="decor_title_width">258dp</dimen> <dimen name="decor_subtitle_width">270dp</dimen> <dimen name="decor_subtitle_margin_top">4dp</dimen> - <dimen name="decor_container_margin_bottom">14dp</dimen> + <dimen name="decor_container_margin_bottom">9dp</dimen> + <dimen name="decor_container_padding_bottom">5dp</dimen> <dimen name="settings_info_item_icon_margin">10dp</dimen> <dimen name="settings_info_item_icon_margin_top">15dp</dimen> @@ -44,7 +45,17 @@ <dimen name="settings_info_fragment_image_width">200dp</dimen> <dimen name="settings_info_fragment_image_margin_top">50dp</dimen> - <dimen name="settings_info_fragment_text_padding_start">50dp</dimen> - <dimen name="settings_info_fragment_text_padding_end">10dp</dimen> - <dimen name="settings_info_fragment_text_margin_bottom">100dp</dimen> + <dimen name="settings_info_fragment_bottom_section_width">380dp</dimen> + <dimen name="settings_info_fragment_bottom_section_margin_bottom">54dp</dimen> + <dimen name="settings_info_fragment_bottom_section_padding_end">44dp</dimen> + <dimen name="settings_info_fragment_title_icon_width">20dp</dimen> + <dimen name="settings_info_fragment_title_icon_margin_end">16dp</dimen> + <dimen name="settings_info_fragment_status_margin_start">12dp</dimen> + <dimen name="settings_info_fragment_title_padding_start">44dp</dimen> + <dimen name="settings_info_fragment_title_padding_end">58dp</dimen> + <dimen name="settings_info_fragment_title_text_size">16sp</dimen> + <dimen name="settings_info_fragment_title_margin_bottom">12dp</dimen> + <dimen name="settings_info_fragment_title_text_max_width_long">240dp</dimen> + <dimen name="settings_info_fragment_title_text_max_width_short">200dp</dimen> + <dimen name="settings_info_fragment_summary_text_size">12sp</dimen> </resources> diff --git a/TwoPanelSettingsLib/res/values/strings.xml b/TwoPanelSettingsLib/res/values/strings.xml new file mode 100644 index 000000000..5a6d5bb71 --- /dev/null +++ b/TwoPanelSettingsLib/res/values/strings.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2020 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 + --> + +<resources> + <string name="preference_title_text_font" translatable="false">sans-serif</string> + <string name="preference_subtitle_text_font" translatable="false">sans-serif</string> + <string name="preference_category_text_font" translatable="false">sans-serif-medium</string> + <string name="preference_list_item_text_font" translatable="false">sans-serif</string> + <string name="preference_list_item_secondary_text_font" translatable="false">roboto-regular</string> + <!-- Informational text indicating on state of a SwitchPreference toggle [CHAR LIMIT=50] --> + <string name="info_status_on">On</string> + <!-- Informational text indicating off state of a SwitchPreference toggle [CHAR LIMIT=50] --> + <string name="info_status_off">Off</string> + <!-- Talkback description of SwitchPreference toggle state on [CHAR LIMIT=NONE] --> + <string name="switch_on">ON</string> + <!-- Talkback description of SwitchPreference toggle state off [CHAR LIMIT=NONE] --> + <string name="switch_off">OFF</string> + <!-- Talkback description of a SwitchPreference [CHAR LIMIT=NONE] --> + <string name="switch_talkback_identifier">Switch</string> +</resources>
\ No newline at end of file diff --git a/TwoPanelSettingsLib/res/values/styles.xml b/TwoPanelSettingsLib/res/values/styles.xml index 55f638b99..e3a89f248 100644 --- a/TwoPanelSettingsLib/res/values/styles.xml +++ b/TwoPanelSettingsLib/res/values/styles.xml @@ -17,32 +17,32 @@ <resources> <style name="TextAppearance.TwoPanelPreference.Title" parent="android:TextAppearance"> - <item name="android:fontFamily">sans-serif</item> + <item name="android:fontFamily">@string/preference_title_text_font</item> <item name="android:textSize">@dimen/tp_preference_decor_title_text_size</item> <item name="android:textColor">@color/tp_preference_decor_title_text_color</item> </style> <style name="TextAppearance.TwoPanelPreference.Subtitle" parent="android:TextAppearance"> - <item name="android:fontFamily">sans-serif</item> + <item name="android:fontFamily">@string/preference_subtitle_text_font</item> <item name="android:textSize">@dimen/tp_preference_decor_subtitle_text_size</item> <item name="android:alpha">0.6</item> <item name="android:textColor">@color/tp_preference_decor_title_text_color</item> <item name="android:gravity">top</item> </style> <style name="TextAppearance.TwoPanelPreference.Category" parent="android:TextAppearance"> - <item name="android:fontFamily">sans-serif-medium</item> + <item name="android:fontFamily">@string/preference_category_text_font</item> <item name="android:textColor">@color/tp_preference_category_text_color</item> <item name="android:textSize">@dimen/tp_preference_category_text_size</item> <item name="android:textAllCaps">true</item> </style> <style name="TextAppearance.TwoPanelPreference.ListItem" parent="android:TextAppearance"> - <item name="android:fontFamily">sans-serif</item> + <item name="android:fontFamily">@string/preference_list_item_text_font</item> <item name="android:textColor">@color/tp_preference_item_primary_text_color_selector</item> <item name="android:textSize">@dimen/tp_preference_item_primary_text_size</item> </style> <style name="TextAppearance.TwoPanelPreference.ListItem.Secondary" parent="android:TextAppearance"> - <item name="android:fontFamily">roboto-regular</item> + <item name="android:fontFamily">@string/preference_list_item_secondary_text_font</item> <item name="android:textColor">@color/tp_preference_item_secondary_text_color_selector</item> <item name="android:textSize">@dimen/tp_preference_item_secondary_text_size</item> </style> @@ -50,4 +50,16 @@ <style name="TwoPanelPreferenceIconStyle" > <item name="android:duplicateParentState">true</item> </style> + + <style name="TwoPanelInfoTitleTextStyle"> + <item name="android:fontFamily">@string/preference_title_text_font</item> + <item name="android:textSize">@dimen/settings_info_fragment_title_text_size</item> + <item name="android:textColor">@color/info_title_text_color</item> + </style> + + <style name="TwoPanelInfoSummaryTextStyle"> + <item name="android:fontFamily">@string/preference_list_item_secondary_text_font</item> + <item name="android:textSize">@dimen/settings_info_fragment_summary_text_size</item> + <item name="android:textColor">@color/info_title_text_color</item> + </style> </resources>
\ No newline at end of file diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/LeanbackListPreferenceDialogFragmentCompat.java b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/LeanbackListPreferenceDialogFragmentCompat.java new file mode 100644 index 000000000..1f88b7d7e --- /dev/null +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/LeanbackListPreferenceDialogFragmentCompat.java @@ -0,0 +1,350 @@ +/* + * Copyright (C) 2021 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.tv.twopanelsettings; + +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; +import android.util.TypedValue; +import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.widget.Checkable; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.collection.ArraySet; +import androidx.leanback.preference.LeanbackPreferenceDialogFragmentCompat; +import androidx.leanback.widget.VerticalGridView; +import androidx.preference.DialogPreference; +import androidx.preference.ListPreference; +import androidx.preference.MultiSelectListPreference; +import androidx.recyclerview.widget.RecyclerView.Adapter; + +import com.android.tv.twopanelsettings.R; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** A copy-paste from androidx leanback library. Make particular methods to be public so that + * they can be overrode. + */ +public class LeanbackListPreferenceDialogFragmentCompat extends + LeanbackPreferenceDialogFragmentCompat { + private static final String SAVE_STATE_IS_MULTI = + "LeanbackListPreferenceDialogFragment.isMulti"; + private static final String SAVE_STATE_ENTRIES = "LeanbackListPreferenceDialogFragment.entries"; + private static final String SAVE_STATE_ENTRY_VALUES = + "LeanbackListPreferenceDialogFragment.entryValues"; + private static final String SAVE_STATE_TITLE = "LeanbackListPreferenceDialogFragment.title"; + private static final String SAVE_STATE_MESSAGE = "LeanbackListPreferenceDialogFragment.message"; + private static final String SAVE_STATE_INITIAL_SELECTIONS = + "LeanbackListPreferenceDialogFragment.initialSelections"; + private static final String SAVE_STATE_INITIAL_SELECTION = + "LeanbackListPreferenceDialogFragment.initialSelection"; + private boolean mMulti; + private CharSequence[] mEntries; + private CharSequence[] mEntryValues; + private CharSequence mDialogTitle; + private CharSequence mDialogMessage; + Set<String> mInitialSelections; + private String mInitialSelection; + + public LeanbackListPreferenceDialogFragmentCompat() { + } + + public static LeanbackListPreferenceDialogFragmentCompat newInstanceSingle(String key) { + Bundle args = new Bundle(1); + args.putString("key", key); + LeanbackListPreferenceDialogFragmentCompat fragment = + new LeanbackListPreferenceDialogFragmentCompat(); + fragment.setArguments(args); + return fragment; + } + + public static LeanbackListPreferenceDialogFragmentCompat newInstanceMulti(String key) { + Bundle args = new Bundle(1); + args.putString("key", key); + LeanbackListPreferenceDialogFragmentCompat fragment = + new LeanbackListPreferenceDialogFragmentCompat(); + fragment.setArguments(args); + return fragment; + } + + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (savedInstanceState == null) { + DialogPreference preference = this.getPreference(); + this.mDialogTitle = preference.getDialogTitle(); + this.mDialogMessage = preference.getDialogMessage(); + if (preference instanceof ListPreference) { + this.mMulti = false; + this.mEntries = ((ListPreference) preference).getEntries(); + this.mEntryValues = ((ListPreference) preference).getEntryValues(); + this.mInitialSelection = ((ListPreference) preference).getValue(); + } else { + if (!(preference instanceof MultiSelectListPreference)) { + throw new IllegalArgumentException( + "Preference must be a ListPreference or MultiSelectListPreference"); + } + + this.mMulti = true; + this.mEntries = ((MultiSelectListPreference) preference).getEntries(); + this.mEntryValues = ((MultiSelectListPreference) preference).getEntryValues(); + this.mInitialSelections = ((MultiSelectListPreference) preference).getValues(); + } + } else { + this.mDialogTitle = savedInstanceState.getCharSequence( + "LeanbackListPreferenceDialogFragment.title"); + this.mDialogMessage = savedInstanceState.getCharSequence( + "LeanbackListPreferenceDialogFragment.message"); + this.mMulti = savedInstanceState.getBoolean( + "LeanbackListPreferenceDialogFragment.isMulti"); + this.mEntries = savedInstanceState.getCharSequenceArray( + "LeanbackListPreferenceDialogFragment.entries"); + this.mEntryValues = savedInstanceState.getCharSequenceArray( + "LeanbackListPreferenceDialogFragment.entryValues"); + if (this.mMulti) { + String[] initialSelections = savedInstanceState.getStringArray( + "LeanbackListPreferenceDialogFragment.initialSelections"); + this.mInitialSelections = new ArraySet( + initialSelections != null ? initialSelections.length : 0); + if (initialSelections != null) { + Collections.addAll(this.mInitialSelections, initialSelections); + } + } else { + this.mInitialSelection = savedInstanceState.getString( + "LeanbackListPreferenceDialogFragment.initialSelection"); + } + } + + } + + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putCharSequence("LeanbackListPreferenceDialogFragment.title", this.mDialogTitle); + outState.putCharSequence("LeanbackListPreferenceDialogFragment.message", + this.mDialogMessage); + outState.putBoolean("LeanbackListPreferenceDialogFragment.isMulti", this.mMulti); + outState.putCharSequenceArray("LeanbackListPreferenceDialogFragment.entries", + this.mEntries); + outState.putCharSequenceArray("LeanbackListPreferenceDialogFragment.entryValues", + this.mEntryValues); + if (this.mMulti) { + outState.putStringArray("LeanbackListPreferenceDialogFragment.initialSelections", + (String[]) this.mInitialSelections.toArray( + new String[this.mInitialSelections.size()])); + } else { + outState.putString("LeanbackListPreferenceDialogFragment.initialSelection", + this.mInitialSelection); + } + + } + + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + TypedValue tv = new TypedValue(); + this.getActivity().getTheme().resolveAttribute(R.attr.preferenceTheme, tv, true); + int theme = tv.resourceId; + if (theme == 0) { + theme = R.style.PreferenceThemeOverlayLeanback; + } + + Context styledContext = new ContextThemeWrapper(this.getActivity(), theme); + LayoutInflater styledInflater = inflater.cloneInContext(styledContext); + View view = styledInflater.inflate(R.layout.leanback_list_preference_fragment, container, + false); + VerticalGridView verticalGridView = (VerticalGridView) view.findViewById(16908298); + verticalGridView.setWindowAlignment(3); + verticalGridView.setFocusScrollStrategy(0); + verticalGridView.setAdapter(this.onCreateAdapter()); + CharSequence title = this.mDialogTitle; + if (!TextUtils.isEmpty(title)) { + TextView titleView = (TextView) view.findViewById(R.id.decor_title); + titleView.setText(title); + } + + CharSequence message = this.mDialogMessage; + if (!TextUtils.isEmpty(message)) { + TextView messageView = (TextView) view.findViewById(16908299); + messageView.setVisibility(0); + messageView.setText(message); + } + + return view; + } + + public Adapter onCreateAdapter() { + return (Adapter) (this.mMulti ? new LeanbackListPreferenceDialogFragmentCompat.AdapterMulti( + this.mEntries, this.mEntryValues, this.mInitialSelections) + : new LeanbackListPreferenceDialogFragmentCompat.AdapterSingle(this.mEntries, + this.mEntryValues, this.mInitialSelection)); + } + + public static final class ViewHolder extends + androidx.recyclerview.widget.RecyclerView.ViewHolder implements OnClickListener { + private final Checkable mWidgetView; + private final TextView mTitleView; + private final ViewGroup mContainer; + private final LeanbackListPreferenceDialogFragmentCompat.OnItemClickListener mListener; + + public ViewHolder(@NonNull View view, + @NonNull LeanbackListPreferenceDialogFragmentCompat.OnItemClickListener listener) { + super(view); + this.mWidgetView = (Checkable) view.findViewById(R.id.button); + this.mContainer = (ViewGroup) view.findViewById(R.id.container); + this.mTitleView = (TextView) view.findViewById(16908310); + this.mContainer.setOnClickListener(this); + this.mListener = listener; + } + + public Checkable getWidgetView() { + return this.mWidgetView; + } + + public TextView getTitleView() { + return this.mTitleView; + } + + public ViewGroup getContainer() { + return this.mContainer; + } + + public void onClick(View v) { + this.mListener.onItemClick(this); + } + } + + public interface OnItemClickListener { + void onItemClick(LeanbackListPreferenceDialogFragmentCompat.ViewHolder var1); + } + + final class AdapterMulti extends + Adapter<LeanbackListPreferenceDialogFragmentCompat.ViewHolder> implements + LeanbackListPreferenceDialogFragmentCompat.OnItemClickListener { + private final CharSequence[] mEntries; + private final CharSequence[] mEntryValues; + private final Set<String> mSelections; + + AdapterMulti(CharSequence[] entries, CharSequence[] entryValues, + Set<String> initialSelections) { + this.mEntries = entries; + this.mEntryValues = entryValues; + this.mSelections = new HashSet(initialSelections); + } + + public LeanbackListPreferenceDialogFragmentCompat.ViewHolder onCreateViewHolder( + ViewGroup parent, int viewType) { + LayoutInflater inflater = LayoutInflater.from(parent.getContext()); + View view = inflater.inflate(R.layout.leanback_list_preference_item_multi, parent, false); + return new LeanbackListPreferenceDialogFragmentCompat.ViewHolder(view, this); + } + + public void onBindViewHolder(LeanbackListPreferenceDialogFragmentCompat.ViewHolder holder, + int position) { + holder.getWidgetView().setChecked( + this.mSelections.contains(this.mEntryValues[position].toString())); + holder.getTitleView().setText(this.mEntries[position]); + } + + public int getItemCount() { + return this.mEntries.length; + } + + public void onItemClick(LeanbackListPreferenceDialogFragmentCompat.ViewHolder viewHolder) { + int index = viewHolder.getAdapterPosition(); + if (index != -1) { + String entry = this.mEntryValues[index].toString(); + if (this.mSelections.contains(entry)) { + this.mSelections.remove(entry); + } else { + this.mSelections.add(entry); + } + + MultiSelectListPreference multiSelectListPreference = + (MultiSelectListPreference) LeanbackListPreferenceDialogFragmentCompat.this.getPreference(); + if (multiSelectListPreference.callChangeListener(new HashSet(this.mSelections))) { + multiSelectListPreference.setValues(new HashSet(this.mSelections)); + LeanbackListPreferenceDialogFragmentCompat.this.mInitialSelections = + this.mSelections; + } else if (this.mSelections.contains(entry)) { + this.mSelections.remove(entry); + } else { + this.mSelections.add(entry); + } + + this.notifyDataSetChanged(); + } + } + } + + final class AdapterSingle extends + Adapter<LeanbackListPreferenceDialogFragmentCompat.ViewHolder> implements + LeanbackListPreferenceDialogFragmentCompat.OnItemClickListener { + private final CharSequence[] mEntries; + private final CharSequence[] mEntryValues; + private CharSequence mSelectedValue; + + AdapterSingle(CharSequence[] entries, CharSequence[] entryValues, + CharSequence selectedValue) { + this.mEntries = entries; + this.mEntryValues = entryValues; + this.mSelectedValue = selectedValue; + } + + public LeanbackListPreferenceDialogFragmentCompat.ViewHolder onCreateViewHolder( + ViewGroup parent, int viewType) { + LayoutInflater inflater = LayoutInflater.from(parent.getContext()); + View view = inflater.inflate(R.layout.leanback_list_preference_item_single, parent, + false); + return new LeanbackListPreferenceDialogFragmentCompat.ViewHolder(view, this); + } + + public void onBindViewHolder(LeanbackListPreferenceDialogFragmentCompat.ViewHolder holder, + int position) { + holder.getWidgetView().setChecked( + this.mEntryValues[position].equals(this.mSelectedValue)); + holder.getTitleView().setText(this.mEntries[position]); + } + + public int getItemCount() { + return this.mEntries.length; + } + + public void onItemClick(LeanbackListPreferenceDialogFragmentCompat.ViewHolder viewHolder) { + int index = viewHolder.getAdapterPosition(); + if (index != -1) { + CharSequence entry = this.mEntryValues[index]; + ListPreference preference = + (ListPreference) LeanbackListPreferenceDialogFragmentCompat.this.getPreference(); + if (index >= 0) { + String value = this.mEntryValues[index].toString(); + if (preference.callChangeListener(value)) { + preference.setValue(value); + this.mSelectedValue = entry; + } + } + + LeanbackListPreferenceDialogFragmentCompat.this.getFragmentManager().popBackStack(); + this.notifyDataSetChanged(); + } + } + } +} diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/SettingsPreferenceFragmentBase.java b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/SettingsPreferenceFragmentBase.java index 4e4b7dc59..2e68f3663 100644 --- a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/SettingsPreferenceFragmentBase.java +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/SettingsPreferenceFragmentBase.java @@ -16,13 +16,13 @@ package com.android.tv.twopanelsettings; -import androidx.leanback.preference.LeanbackPreferenceFragment; +import androidx.leanback.preference.LeanbackPreferenceFragmentCompat; /** * Child preference fragment should extend this class to make two panel settings functionality work, * otherwise preview panel would not show up. */ -public abstract class SettingsPreferenceFragmentBase extends LeanbackPreferenceFragment { +public abstract class SettingsPreferenceFragmentBase extends LeanbackPreferenceFragmentCompat { @Override public void onResume() { super.onResume(); diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/SummaryListPreference.java b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/SummaryListPreference.java new file mode 100644 index 000000000..ea8c1c3cc --- /dev/null +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/SummaryListPreference.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 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.tv.twopanelsettings; + +import android.content.Context; +import android.util.AttributeSet; + +import androidx.preference.ListPreference; + +/** + * A ListPreference that optionally displays a summary (aka subtitle) for + * each of its options. + */ +public class SummaryListPreference extends ListPreference { + + private CharSequence[] mSummaries; + + public SummaryListPreference(Context context, AttributeSet attrs) { + super(context, attrs, 0, 0); + } + + public SummaryListPreference(Context context) { + super(context, null); + } + + public void setSummaries(CharSequence[] summaries) { + this.mSummaries = summaries; + } + + public CharSequence[] getSummaries() { + return mSummaries; + } +}; diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/TwoPanelListPreferenceDialogFragment.java b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/TwoPanelListPreferenceDialogFragment.java index 8937fdd50..a165083d2 100644 --- a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/TwoPanelListPreferenceDialogFragment.java +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/TwoPanelListPreferenceDialogFragment.java @@ -16,31 +16,38 @@ package com.android.tv.twopanelsettings; +import android.animation.AnimatorInflater; import android.os.Bundle; +import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.TextView; -import androidx.leanback.preference.LeanbackListPreferenceDialogFragment; import androidx.preference.DialogPreference; import androidx.preference.ListPreference; import androidx.preference.MultiSelectListPreference; import androidx.recyclerview.widget.RecyclerView; + /** A workaround for pi-tv-dev to fix the issue that ListPreference is not correctly handled by two * panel lib. When moving to Q, we should fix this problem in androidx(b/139085296). */ -public class TwoPanelListPreferenceDialogFragment extends LeanbackListPreferenceDialogFragment { +public class TwoPanelListPreferenceDialogFragment extends + LeanbackListPreferenceDialogFragmentCompat { private static final String SAVE_STATE_IS_MULTI = "LeanbackListPreferenceDialogFragment.isMulti"; private static final String SAVE_STATE_ENTRIES = "LeanbackListPreferenceDialogFragment.entries"; private static final String SAVE_STATE_ENTRY_VALUES = "LeanbackListPreferenceDialogFragment.entryValues"; + private static final String SAVE_STATE_SUMMARIES = + "LeanbackListPreferenceDialogFragment.summaries"; private static final String SAVE_STATE_INITIAL_SELECTION = "LeanbackListPreferenceDialogFragment.initialSelection"; private boolean mMultiCopy; private CharSequence[] mEntriesCopy; private CharSequence[] mEntryValuesCopy; + private CharSequence[] mSummariesCopy; private String mInitialSelectionCopy; /** Provide a ListPreferenceDialogFragment which satisfy the use of two panel lib **/ @@ -64,6 +71,9 @@ public class TwoPanelListPreferenceDialogFragment extends LeanbackListPreference mMultiCopy = false; mEntriesCopy = ((ListPreference) preference).getEntries(); mEntryValuesCopy = ((ListPreference) preference).getEntryValues(); + if (preference instanceof SummaryListPreference) { + mSummariesCopy = ((SummaryListPreference) preference).getSummaries(); + } mInitialSelectionCopy = ((ListPreference) preference).getValue(); } else if (preference instanceof MultiSelectListPreference) { mMultiCopy = true; @@ -75,6 +85,7 @@ public class TwoPanelListPreferenceDialogFragment extends LeanbackListPreference mMultiCopy = savedInstanceState.getBoolean(SAVE_STATE_IS_MULTI); mEntriesCopy = savedInstanceState.getCharSequenceArray(SAVE_STATE_ENTRIES); mEntryValuesCopy = savedInstanceState.getCharSequenceArray(SAVE_STATE_ENTRY_VALUES); + mSummariesCopy = savedInstanceState.getCharSequenceArray(SAVE_STATE_SUMMARIES); if (!mMultiCopy) { mInitialSelectionCopy = savedInstanceState.getString(SAVE_STATE_INITIAL_SELECTION); } @@ -82,23 +93,49 @@ public class TwoPanelListPreferenceDialogFragment extends LeanbackListPreference } @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (view != null) { + removeAnimationClipping(view); + ViewGroup mainFrame = view.findViewById(R.id.main_frame); + if (mainFrame != null) { + mainFrame.setOutlineProvider(null); + } + } + } + + protected void removeAnimationClipping(View v) { + if (v instanceof ViewGroup) { + ((ViewGroup) v).setClipChildren(false); + ((ViewGroup) v).setClipToPadding(false); + for (int index = 0; index < ((ViewGroup) v).getChildCount(); index++) { + View child = ((ViewGroup) v).getChildAt(index); + removeAnimationClipping(child); + } + } + } + + @Override public RecyclerView.Adapter onCreateAdapter() { if (!mMultiCopy) { - return new TwoPanelAdapterSingle(mEntriesCopy, mEntryValuesCopy, mInitialSelectionCopy); + return new TwoPanelAdapterSingle(mEntriesCopy, mEntryValuesCopy, mSummariesCopy, + mInitialSelectionCopy); } return super.onCreateAdapter(); } private class TwoPanelAdapterSingle extends RecyclerView.Adapter<ViewHolder> - implements ViewHolder.OnItemClickListener { + implements OnItemClickListener { private final CharSequence[] mEntries; private final CharSequence[] mEntryValues; + private final CharSequence[] mSummaries; private CharSequence mSelectedValue; TwoPanelAdapterSingle(CharSequence[] entries, CharSequence[] entryValues, - CharSequence selectedValue) { + CharSequence[] summaries, CharSequence selectedValue) { mEntries = entries; mEntryValues = entryValues; + mSummaries = summaries; mSelectedValue = selectedValue; } @@ -114,6 +151,18 @@ public class TwoPanelListPreferenceDialogFragment extends LeanbackListPreference public void onBindViewHolder(ViewHolder holder, int position) { holder.getWidgetView().setChecked(mEntryValues[position].equals(mSelectedValue)); holder.getTitleView().setText(mEntries[position]); + holder.itemView.setStateListAnimator(AnimatorInflater.loadStateListAnimator( + getContext(), R.animator.preference)); + TextView summaryView = (TextView) holder.getContainer() + .findViewById(android.R.id.summary); + if (summaryView != null) { + if (mSummaries != null && !TextUtils.isEmpty(mSummaries[position])) { + summaryView.setText(mSummaries[position]); + summaryView.setVisibility(View.VISIBLE); + } else { + summaryView.setVisibility(View.GONE); + } + } } @Override diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/TwoPanelSettingsFragment.java b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/TwoPanelSettingsFragment.java index 3c0ef15e6..bb300388d 100644 --- a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/TwoPanelSettingsFragment.java +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/TwoPanelSettingsFragment.java @@ -16,13 +16,26 @@ package com.android.tv.twopanelsettings; +import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_PREFERENCE_INFO_SUMMARY; +import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_PREFERENCE_INFO_TEXT; +import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_PREFERENCE_INFO_TITLE_ICON; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.animation.ArgbEvaluator; import android.animation.ObjectAnimator; -import android.app.Fragment; -import android.app.FragmentTransaction; +import android.content.BroadcastReceiver; import android.content.ContentProviderClient; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.graphics.drawable.Icon; +import android.media.AudioManager; import android.net.Uri; import android.os.Bundle; import android.os.Handler; +import android.provider.Settings; import android.text.TextUtils; import android.transition.Fade; import android.util.Log; @@ -32,38 +45,47 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.widget.HorizontalScrollView; +import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.leanback.preference.LeanbackListPreferenceDialogFragment; -import androidx.leanback.preference.LeanbackPreferenceFragment; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentTransaction; +import androidx.leanback.app.GuidedStepSupportFragment; +import androidx.leanback.preference.LeanbackListPreferenceDialogFragmentCompat; +import androidx.leanback.preference.LeanbackPreferenceFragmentCompat; import androidx.leanback.widget.OnChildViewHolderSelectedListener; import androidx.leanback.widget.VerticalGridView; import androidx.preference.ListPreference; import androidx.preference.MultiSelectListPreference; import androidx.preference.Preference; -import androidx.preference.PreferenceFragment; +import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceGroupAdapter; import androidx.preference.PreferenceViewHolder; import androidx.recyclerview.widget.RecyclerView; +import com.android.tv.twopanelsettings.slices.CustomContentDescriptionPreference; +import com.android.tv.twopanelsettings.slices.HasCustomContentDescription; import com.android.tv.twopanelsettings.slices.HasSliceUri; import com.android.tv.twopanelsettings.slices.InfoFragment; +import com.android.tv.twopanelsettings.slices.SliceFragment; import com.android.tv.twopanelsettings.slices.SlicePreference; +import com.android.tv.twopanelsettings.slices.SliceSwitchPreference; import com.android.tv.twopanelsettings.slices.SlicesConstants; +import com.android.tv.twopanelsettings.slices.SliceSeekbarPreference; import java.util.Set; /** - * This fragment provides containers for displaying two {@link LeanbackPreferenceFragment}. + * This fragment provides containers for displaying two {@link LeanbackPreferenceFragmentCompat}. * The preference fragment on the left works as a main panel on which the user can operate. * The preference fragment on the right works as a preview panel for displaying the preview * information. */ public abstract class TwoPanelSettingsFragment extends Fragment implements - PreferenceFragment.OnPreferenceStartFragmentCallback, - PreferenceFragment.OnPreferenceStartScreenCallback, - PreferenceFragment.OnPreferenceDisplayDialogCallback { + PreferenceFragmentCompat.OnPreferenceStartFragmentCallback, + PreferenceFragmentCompat.OnPreferenceStartScreenCallback, + PreferenceFragmentCompat.OnPreferenceDisplayDialogCallback { private static final String TAG = "TwoPanelSettingsFragment"; private static final boolean DEBUG = false; private static final String PREVIEW_FRAGMENT_TAG = @@ -75,12 +97,13 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements private static final int[] frameResIds = {R.id.frame1, R.id.frame2, R.id.frame3, R.id.frame4, R.id.frame5, R.id.frame6, R.id.frame7, R.id.frame8, R.id.frame9, R.id.frame10}; - private static final int[] frameResOverlayIds = - {R.id.frame1_overlay, R.id.frame2_overlay, R.id.frame3_overlay, R.id.frame4_overlay, - R.id.frame5_overlay, R.id.frame6_overlay, R.id.frame7_overlay, R.id.frame8_overlay, - R.id.frame9_overlay, R.id.frame10_overlay}; + private static final long PANEL_ANIMATION_MS = 400; private static final long PANEL_ANIMATION_DELAY_MS = 200; + private static final long PREVIEW_PANEL_DEFAULT_DELAY_MS = 0; + private static final long CHECK_IDLE_STATE_MS = 100; + private long mPreviewPanelCreationDelay = 0; + private static final float PREVIEW_PANEL_ALPHA = 0.6f; private int mMaxScrollX; private final RootViewOnKeyListener mRootViewOnKeyListener = new RootViewOnKeyListener(); @@ -88,20 +111,42 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements private HorizontalScrollView mScrollView; private Handler mHandler; private boolean mIsNavigatingBack; + private boolean mCheckVerticalGridViewScrollState; + private Preference mFocusedPreference; + private boolean mIsWaitingForUpdatingPreview = false; + private AudioManager mAudioManager; + + private static final String DELAY_MS = "delay_ms"; + private static final String CHECK_SCROLL_STATE = "check_scroll_state"; + + /** An broadcast receiver to help OEM test best delay for preview panel fragment creation. */ + private BroadcastReceiver mPreviewPanelDelayReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + long delay = intent.getLongExtra(DELAY_MS, PREVIEW_PANEL_DEFAULT_DELAY_MS); + boolean checkScrollState = intent.getBooleanExtra(CHECK_SCROLL_STATE, false); + Log.d(TAG, "New delay for creating preview panel fragment " + delay + + " check scroll state " + checkScrollState); + mPreviewPanelCreationDelay = delay; + mCheckVerticalGridViewScrollState = checkScrollState; + } + }; - private OnChildViewHolderSelectedListener mOnChildViewHolderSelectedListener = + private final OnChildViewHolderSelectedListener mOnChildViewHolderSelectedListener = new OnChildViewHolderSelectedListener() { @Override public void onChildViewHolderSelected(RecyclerView parent, RecyclerView.ViewHolder child, int position, int subposition) { - if (child == null) { + if (parent == null || child == null) { return; } int adapterPosition = child.getAdapterPosition(); PreferenceGroupAdapter preferenceGroupAdapter = (PreferenceGroupAdapter) parent.getAdapter(); - Preference preference = preferenceGroupAdapter.getItem(adapterPosition); - onPreferenceFocused(preference); + if (preferenceGroupAdapter != null) { + Preference preference = preferenceGroupAdapter.getItem(adapterPosition); + onPreferenceFocused(preference); + } } @Override @@ -110,15 +155,28 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements } }; - private OnGlobalLayoutListener mOnGlobalLayoutListener = new OnGlobalLayoutListener() { + private final OnGlobalLayoutListener mOnGlobalLayoutListener = new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { - getView().getViewTreeObserver().removeOnGlobalLayoutListener(mOnGlobalLayoutListener); - moveToPanel(mPrefPanelIdx, false); + if (getView() != null && getView().getViewTreeObserver() != null) { + getView().getViewTreeObserver().removeOnGlobalLayoutListener( + mOnGlobalLayoutListener); + moveToPanel(mPrefPanelIdx, false); + } } }; @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mCheckVerticalGridViewScrollState = getContext().getResources() + .getBoolean(R.bool.config_check_scroll_state); + mPreviewPanelCreationDelay = getContext().getResources() + .getInteger(R.integer.config_preview_panel_create_delay); + mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE); + } + + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final View v = inflater.inflate(R.layout.two_panel_settings_fragment, container, false); @@ -150,17 +208,29 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements /** Extend this method to provide the initial screen **/ public abstract void onPreferenceStartInitialScreen(); - private boolean shouldDisplay(String fragment) { + private boolean isPreferenceFragment(String fragment) { try { - return LeanbackPreferenceFragment.class.isAssignableFrom(Class.forName(fragment)) - || InfoFragment.class.isAssignableFrom(Class.forName(fragment)); + return LeanbackPreferenceFragmentCompat.class.isAssignableFrom(Class.forName(fragment)); } catch (ClassNotFoundException e) { - throw new RuntimeException("Fragment class not found.", e); + Log.e(TAG, "Fragment class not found " + e); + return false; + } + } + + private boolean isInfoFragment(String fragment) { + try { + return InfoFragment.class.isAssignableFrom(Class.forName(fragment)); + } catch (ClassNotFoundException e) { + Log.e(TAG, "Fragment class not found " + e); + return false; } } @Override - public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) { + public boolean onPreferenceStartFragment(PreferenceFragmentCompat caller, Preference pref) { + if (pref == null) { + return false; + } if (DEBUG) { Log.d(TAG, "onPreferenceStartFragment " + pref.getTitle()); } @@ -171,7 +241,9 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements frameResIds[mPrefPanelIdx + 1]); if (preview != null && !(preview instanceof DummyFragment)) { if (!(preview instanceof InfoFragment)) { - navigateToPreviewFragment(); + if (!mIsWaitingForUpdatingPreview) { + navigateToPreviewFragment(); + } } } else { // If there is no corresponding slice provider, thus the corresponding fragment is not @@ -179,8 +251,15 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements if (pref instanceof SlicePreference) { return false; } - startImmersiveFragment(Fragment.instantiate(getActivity(), pref.getFragment(), - pref.getExtras())); + try { + Fragment immersiveFragment = Fragment.instantiate(getActivity(), pref.getFragment(), + pref.getExtras()); + startImmersiveFragment(immersiveFragment); + } catch (Exception e) { + Log.e(TAG, "error trying to instantiate fragment " + e); + // return true so it won't be handled by onPreferenceTreeClick in PreferenceFragment + return true; + } } return true; } @@ -213,6 +292,11 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements } initialPreviewFragment.setExitTransition(null); + if (previewFragment.getView() != null) { + previewFragment.getView().setImportantForAccessibility( + View.IMPORTANT_FOR_ACCESSIBILITY_YES); + } + mPrefPanelIdx++; Fragment fragment = getChildFragmentManager().findFragmentById(frameResIds[mPrefPanelIdx]); @@ -227,12 +311,50 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements removeFragmentAndAddToBackStack(mPrefPanelIdx - 1); } + private boolean isA11yOn() { + return Settings.Secure.getInt( + getActivity().getContentResolver(), + Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1; + } + + private void updateAccessibilityTitle(Fragment fragment) { + CharSequence newA11yTitle = ""; + if (fragment instanceof SliceFragment) { + newA11yTitle = ((SliceFragment) fragment).getScreenTitle(); + } else if (fragment instanceof LeanbackPreferenceFragmentCompat) { + newA11yTitle = ((LeanbackPreferenceFragmentCompat) fragment).getPreferenceScreen() + .getTitle(); + } else if (fragment instanceof GuidedStepSupportFragment) { + if (fragment.getView() != null) { + View titleView = fragment.getView().findViewById(R.id.guidance_title); + if (titleView instanceof TextView) { + newA11yTitle = ((TextView) titleView).getText(); + } + } + } + + if (!TextUtils.isEmpty(newA11yTitle)) { + if (DEBUG) { + Log.d(TAG, "changing a11y title to: " + newA11yTitle); + } + + // Set both window title and pane title to avoid messy announcements when coming from + // other activities. (window title is announced on activity change) + getActivity().getWindow().setTitle(newA11yTitle); + if (getView() != null + && getView().findViewById(R.id.two_panel_fragment_container) != null) { + getView().findViewById(R.id.two_panel_fragment_container) + .setAccessibilityPaneTitle(newA11yTitle); + } + } + } + private void addOrRemovePreferenceFocusedListener(Fragment fragment, boolean isAddingListener) { - if (fragment == null || !(fragment instanceof LeanbackPreferenceFragment)) { + if (!(fragment instanceof LeanbackPreferenceFragmentCompat)) { return; } - LeanbackPreferenceFragment leanbackPreferenceFragment = - (LeanbackPreferenceFragment) fragment; + LeanbackPreferenceFragmentCompat leanbackPreferenceFragment = + (LeanbackPreferenceFragmentCompat) fragment; VerticalGridView listView = (VerticalGridView) leanbackPreferenceFragment.getListView(); if (listView != null) { if (isAddingListener) { @@ -269,7 +391,11 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements } @Override - public boolean onPreferenceDisplayDialog(@NonNull PreferenceFragment caller, Preference pref) { + public boolean onPreferenceDisplayDialog( + @NonNull PreferenceFragmentCompat caller, Preference pref) { + if (pref == null) { + return false; + } if (DEBUG) { Log.d(TAG, "PreferenceDisplayDialog"); } @@ -324,9 +450,19 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements public interface SliceFragmentCallback { /** Triggered when preference is focused **/ void onPreferenceFocused(Preference preference); + + /** Triggered when Seekbar preference is changed **/ + void onSeekbarPreferenceChanged(SliceSeekbarPreference preference, int addValue); } - private boolean onPreferenceFocused(Preference pref) { + protected void onPreferenceFocused(Preference pref) { + onPreferenceFocusedImpl(pref, false); + } + + private void onPreferenceFocusedImpl(Preference pref, boolean forceRefresh) { + if (pref == null) { + return; + } if (DEBUG) { Log.d(TAG, "onPreferenceFocused " + pref.getTitle()); } @@ -335,7 +471,46 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements if (prefFragment instanceof SliceFragmentCallback) { ((SliceFragmentCallback) prefFragment).onPreferenceFocused(pref); } + mFocusedPreference = pref; + if (mCheckVerticalGridViewScrollState || mPreviewPanelCreationDelay > 0) { + mIsWaitingForUpdatingPreview = true; + VerticalGridView listView = (VerticalGridView) + ((LeanbackPreferenceFragmentCompat) prefFragment).getListView(); + mHandler.postDelayed(new PostShowPreviewRunnable( + listView, pref, forceRefresh), mPreviewPanelCreationDelay); + } else { + handleFragmentTransactionWhenFocused(pref, forceRefresh); + } + } + + private final class PostShowPreviewRunnable implements Runnable { + private final VerticalGridView mListView; + private final Preference mPref; + private final boolean mForceFresh; + + PostShowPreviewRunnable(VerticalGridView listView, Preference pref, boolean forceFresh) { + this.mListView = listView; + this.mPref = pref; + this.mForceFresh = forceFresh; + } + + @Override + public void run() { + if (mPref == mFocusedPreference) { + if (mListView.getScrollState() != RecyclerView.SCROLL_STATE_IDLE) { + mHandler.postDelayed(this, CHECK_IDLE_STATE_MS); + } else { + handleFragmentTransactionWhenFocused(mPref, mForceFresh); + mIsWaitingForUpdatingPreview = false; + } + } + } + } + + private void handleFragmentTransactionWhenFocused(Preference pref, boolean forceRefresh) { Fragment previewFragment = null; + final Fragment prefFragment = + getChildFragmentManager().findFragmentById(frameResIds[mPrefPanelIdx]); try { previewFragment = onCreatePreviewFragment(prefFragment, pref); } catch (Exception e) { @@ -343,22 +518,24 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements } if (previewFragment == null) { previewFragment = new DummyFragment(); - } else { - previewFragment.setTargetFragment(prefFragment, 0); } - final Fragment existingPreviewFragment = - getChildFragmentManager().findFragmentById(frameResIds[mPrefPanelIdx + 1]); + getChildFragmentManager().findFragmentById( + frameResIds[mPrefPanelIdx + 1]); if (existingPreviewFragment != null && existingPreviewFragment.getClass().equals(previewFragment.getClass()) && equalArguments(existingPreviewFragment.getArguments(), previewFragment.getArguments())) { - if (isRTL() && mScrollView.getScrollX() == 0 && mPrefPanelIdx == 0) { + if (isRTL() && mScrollView.getScrollX() == 0 && mPrefPanelIdx == 0 + && getView() != null && getView().getViewTreeObserver() != null) { // For RTL we need to reclaim focus to the correct scroll position if a pref // launches a new activity because the horizontal scroll goes back to 0. - getView().getViewTreeObserver().addOnGlobalLayoutListener(mOnGlobalLayoutListener); + getView().getViewTreeObserver().addOnGlobalLayoutListener( + mOnGlobalLayoutListener); + } + if (!forceRefresh) { + return; } - return true; } // If the existing preview fragment is recreated when the activity is recreated, the @@ -370,13 +547,26 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements previewFragment.setEnterTransition(new Fade()); previewFragment.setExitTransition(null); - final FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); - transaction.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out); + final FragmentTransaction transaction = + getChildFragmentManager().beginTransaction(); + transaction.setCustomAnimations(android.R.animator.fade_in, + android.R.animator.fade_out); transaction.replace(frameResIds[mPrefPanelIdx + 1], previewFragment); transaction.commit(); // Some fragments may steal focus on creation. Reclaim focus on main fragment. - getView().getViewTreeObserver().addOnGlobalLayoutListener(mOnGlobalLayoutListener); + if (getView() != null && getView().getViewTreeObserver() != null) { + getView().getViewTreeObserver().addOnGlobalLayoutListener( + mOnGlobalLayoutListener); + } + } + + private boolean onSeekbarPreferenceChanged(SliceSeekbarPreference pref, int addValue) { + final Fragment prefFragment = + getChildFragmentManager().findFragmentById(frameResIds[mPrefPanelIdx]); + if (prefFragment instanceof SliceFragmentCallback) { + ((SliceFragmentCallback) prefFragment).onSeekbarPreferenceChanged(pref, addValue); + } return true; } @@ -390,6 +580,9 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements Log.d(TAG, "onResume"); } super.onResume(); + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction("com.android.tv.settings.PREVIEW_DELAY"); + getContext().registerReceiver(mPreviewPanelDelayReceiver, intentFilter); // Trap back button presses final TwoPanelSettingsRootView rootView = (TwoPanelSettingsRootView) getView(); if (rootView != null) { @@ -403,6 +596,7 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements Log.d(TAG, "onPause"); } super.onPause(); + getContext().unregisterReceiver(mPreviewPanelDelayReceiver); final TwoPanelSettingsRootView rootView = (TwoPanelSettingsRootView) getView(); if (rootView != null) { rootView.setOnBackKeyListener(null); @@ -426,6 +620,10 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements .remove(target) .addToBackStack(null) .commit(); + mHandler.post(() -> { + updateAccessibilityTitle(fragment); + }); + } public static class DummyFragment extends Fragment { @@ -473,7 +671,7 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements * panel. * * @param forward means whether the component arrives at main panel when users are - * navigating forwards (deeper into the TvSettings tree). + * navigating forwards (deeper into the TvSettings tree). */ void onArriveAtMainPanel(boolean forward); } @@ -484,6 +682,22 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements public boolean onKey(View v, int keyCode, KeyEvent event) { Fragment prefFragment = getChildFragmentManager().findFragmentById(frameResIds[mPrefPanelIdx]); + + if (event.getAction() == KeyEvent.ACTION_DOWN + && (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT + || keyCode == KeyEvent.KEYCODE_DPAD_LEFT)) { + Preference preference = getChosenPreference(prefFragment); + if ((preference instanceof SliceSeekbarPreference)) { + SliceSeekbarPreference sbPref = (SliceSeekbarPreference) preference; + if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) { + onSeekbarPreferenceChanged(sbPref, 1); + } else { + onSeekbarPreferenceChanged(sbPref, -1); + } + return true; + } + } + if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK) { return back(true); } @@ -509,11 +723,17 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements } else { Fragment previewFragment = getChildFragmentManager() .findFragmentById(frameResIds[mPrefPanelIdx + 1]); - if (!(previewFragment instanceof InfoFragment)) { + if (!(previewFragment instanceof InfoFragment) + && !mIsWaitingForUpdatingPreview) { + mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_RIGHT); + navigateToPreviewFragment(); } } - return true; + // TODO(b/163432209): improve NavigationCallback and be more specific here. + // Do not consume the KeyEvent for NavigationCallback classes such as date & time + // picker. + return !(prefFragment instanceof NavigationCallback); } return false; } @@ -528,16 +748,12 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements } // This is for the case when a preference has preview but once user navigate to // see the preview, settings actually launch an intent to start external activity. - if (preference.getIntent() != null && !TextUtils.isEmpty(preference.getFragment())) { + if (preference.getIntent() != null && !TextUtils.isEmpty(preference.getFragment())) { return true; } - if (preference instanceof SlicePreference + return preference instanceof SlicePreference && ((SlicePreference) preference).getSliceAction() != null - && ((SlicePreference) preference).getUri() != null) { - return true; - } - - return false; + && ((SlicePreference) preference).getUri() != null; } private boolean back(boolean isKeyBackPressed) { @@ -565,6 +781,21 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements return true; } + // When a11y is on, we allow InfoFragments to take focus without scrolling panels. So if + // the user presses back button in this state, we should not scroll our panels back, or exit + // Settings activity, but rather reinstate the focus to be on the main panel. + Fragment preview = + getChildFragmentManager().findFragmentById(frameResIds[mPrefPanelIdx + 1]); + if (isA11yOn() && preview instanceof InfoFragment && preview.getView() != null + && preview.getView().hasFocus()) { + View mainPanelView = getChildFragmentManager() + .findFragmentById(frameResIds[mPrefPanelIdx]).getView(); + if (mainPanelView != null) { + mainPanelView.requestFocus(); + return true; + } + } + if (mPrefPanelIdx < 1) { // Disallow the user to use "dpad left" to finish activity in the first screen if (isKeyBackPressed) { @@ -582,6 +813,11 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements mPrefPanelIdx--; mHandler.postDelayed(() -> { + if (isKeyBackPressed) { + mAudioManager.playSoundEffect(AudioManager.FX_BACK); + } else { + mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_LEFT); + } moveToPanel(mPrefPanelIdx, true); }, PANEL_ANIMATION_DELAY_MS); @@ -646,13 +882,24 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements int distanceToScrollToRight; int panelWidth = getResources().getDimensionPixelSize( R.dimen.tp_settings_preference_pane_width); - View scrollToPanelOverlay = getView().findViewById(frameResOverlayIds[index]); - View previewPanelOverlay = getView().findViewById(frameResOverlayIds[index + 1]); + View scrollToPanel = getView().findViewById(frameResIds[index]); + View previewPanel = getView().findViewById(frameResIds[index + 1]); + if (scrollToPanel == null || previewPanel == null) { + return; + } + View scrollToPanelHead = scrollToPanel.findViewById(R.id.decor_title_container); + View previewPanelHead = previewPanel.findViewById(R.id.decor_title_container); boolean scrollsToPreview = isRTL() ? mScrollView.getScrollX() >= mMaxScrollX - panelWidth * index : mScrollView.getScrollX() <= panelWidth * index; - boolean hasPreviewFragment = fragmentToBecomePreviewPanel != null - && !(fragmentToBecomePreviewPanel instanceof DummyFragment); + + boolean setAlphaForPreview = fragmentToBecomePreviewPanel != null + && !(fragmentToBecomePreviewPanel instanceof DummyFragment) + && !(fragmentToBecomePreviewPanel instanceof InfoFragment); + int previewPanelColor = getResources().getColor( + R.color.tp_preview_panel_background_color); + int mainPanelColor = getResources().getColor( + R.color.tp_preference_panel_background_color); if (smoothScroll) { int animationEnd = isRTL() ? mMaxScrollX - panelWidth * index : panelWidth * index; distanceToScrollToRight = animationEnd - mScrollView.getScrollX(); @@ -661,39 +908,99 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements mScrollView.getScrollX(), animationEnd); slideAnim.setAutoCancel(true); slideAnim.setDuration(PANEL_ANIMATION_MS); + slideAnim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); + if (isA11yOn() && fragmentToBecomeMainPanel != null + && fragmentToBecomeMainPanel.getView() != null) { + fragmentToBecomeMainPanel.getView().requestFocus(); + } + } + }); slideAnim.start(); // Color animation if (scrollsToPreview) { - previewPanelOverlay.setAlpha(hasPreviewFragment ? 1f : 0f); - ObjectAnimator colorAnim = ObjectAnimator.ofFloat(scrollToPanelOverlay, "alpha", - scrollToPanelOverlay.getAlpha(), 0f); - colorAnim.setAutoCancel(true); - colorAnim.setDuration(PANEL_ANIMATION_MS); - colorAnim.start(); + previewPanel.setAlpha(setAlphaForPreview ? PREVIEW_PANEL_ALPHA : 1f); + previewPanel.setBackgroundColor(previewPanelColor); + if (previewPanelHead != null) { + previewPanelHead.setBackgroundColor(previewPanelColor); + } + ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(scrollToPanel, "alpha", + scrollToPanel.getAlpha(), 1f); + ObjectAnimator backgroundColorAnim = ObjectAnimator.ofObject(scrollToPanel, + "backgroundColor", + new ArgbEvaluator(), previewPanelColor, mainPanelColor); + alphaAnim.setAutoCancel(true); + backgroundColorAnim.setAutoCancel(true); + AnimatorSet animatorSet = new AnimatorSet(); + if (scrollToPanelHead != null) { + ObjectAnimator backgroundColorAnimForHead = ObjectAnimator.ofObject( + scrollToPanelHead, + "backgroundColor", + new ArgbEvaluator(), previewPanelColor, mainPanelColor); + backgroundColorAnimForHead.setAutoCancel(true); + animatorSet.playTogether(alphaAnim, backgroundColorAnim, + backgroundColorAnimForHead); + } else { + animatorSet.playTogether(alphaAnim, backgroundColorAnim); + } + animatorSet.setDuration(PANEL_ANIMATION_MS); + animatorSet.start(); } else { - scrollToPanelOverlay.setAlpha(0f); - ObjectAnimator colorAnim = ObjectAnimator.ofFloat(previewPanelOverlay, "alpha", - previewPanelOverlay.getAlpha(), hasPreviewFragment ? 1f : 0f); - colorAnim.setAutoCancel(true); - colorAnim.setDuration(PANEL_ANIMATION_MS); - colorAnim.start(); + scrollToPanel.setAlpha(1f); + scrollToPanel.setBackgroundColor(mainPanelColor); + if (scrollToPanelHead != null) { + scrollToPanelHead.setBackgroundColor(mainPanelColor); + } + ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(previewPanel, "alpha", + previewPanel.getAlpha(), setAlphaForPreview ? PREVIEW_PANEL_ALPHA : 1f); + ObjectAnimator backgroundColorAnim = ObjectAnimator.ofObject(previewPanel, + "backgroundColor", + new ArgbEvaluator(), mainPanelColor, previewPanelColor); + alphaAnim.setAutoCancel(true); + backgroundColorAnim.setAutoCancel(true); + AnimatorSet animatorSet = new AnimatorSet(); + if (previewPanelHead != null) { + ObjectAnimator backgroundColorAnimForHead = ObjectAnimator.ofObject( + previewPanelHead, + "backgroundColor", + new ArgbEvaluator(), mainPanelColor, previewPanelColor); + backgroundColorAnimForHead.setAutoCancel(true); + animatorSet.playTogether(alphaAnim, backgroundColorAnim, + backgroundColorAnimForHead); + } else { + animatorSet.playTogether(alphaAnim, backgroundColorAnim); + } + animatorSet.setDuration(PANEL_ANIMATION_MS); + animatorSet.start(); } } else { int scrollToX = isRTL() ? mMaxScrollX - panelWidth * index : panelWidth * index; distanceToScrollToRight = scrollToX - mScrollView.getScrollX(); mScrollView.scrollTo(scrollToX, 0); - scrollToPanelOverlay.setAlpha(0f); - previewPanelOverlay.setAlpha(hasPreviewFragment ? 1f : 0f); + previewPanel.setAlpha(setAlphaForPreview ? PREVIEW_PANEL_ALPHA : 1f); + previewPanel.setBackgroundColor(previewPanelColor); + if (previewPanelHead != null) { + previewPanelHead.setBackgroundColor(previewPanelColor); + } + scrollToPanel.setAlpha(1f); + scrollToPanel.setBackgroundColor(mainPanelColor); + if (scrollToPanelHead != null) { + scrollToPanelHead.setBackgroundColor(mainPanelColor); + } } if (fragmentToBecomeMainPanel != null && fragmentToBecomeMainPanel.getView() != null) { - fragmentToBecomeMainPanel.getView().requestFocus(); + if (!isA11yOn()) { + fragmentToBecomeMainPanel.getView().requestFocus(); + } for (int resId : frameResIds) { Fragment f = getChildFragmentManager().findFragmentById(resId); if (f != null) { View view = f.getView(); if (view != null) { view.setImportantForAccessibility( - f == fragmentToBecomeMainPanel + f == fragmentToBecomeMainPanel || f instanceof InfoFragment ? View.IMPORTANT_FOR_ACCESSIBILITY_YES : View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS); } @@ -708,17 +1015,18 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements .onArriveAtMainPanel(isRTL()); } // distanceToScrollToRight being 0 means no actual panel sliding; thus noop. } + updateAccessibilityTitle(fragmentToBecomeMainPanel); } }); } private Fragment getInitialPreviewFragment(Fragment fragment) { - if (!(fragment instanceof LeanbackPreferenceFragment)) { + if (!(fragment instanceof LeanbackPreferenceFragmentCompat)) { return null; } - LeanbackPreferenceFragment leanbackPreferenceFragment = - (LeanbackPreferenceFragment) fragment; + LeanbackPreferenceFragmentCompat leanbackPreferenceFragment = + (LeanbackPreferenceFragmentCompat) fragment; if (leanbackPreferenceFragment.getListView() == null) { return null; } @@ -727,6 +1035,9 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements int position = listView.getSelectedPosition(); PreferenceGroupAdapter adapter = (PreferenceGroupAdapter) (leanbackPreferenceFragment.getListView().getAdapter()); + if (adapter == null) { + return null; + } Preference chosenPreference = adapter.getItem(position); // Find the first focusable preference if cannot find the selected preference if (chosenPreference == null || (listView.findViewHolderForPosition(position) != null @@ -752,6 +1063,7 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements /** * Refocus the current selected preference. When a preference is selected and its InfoFragment * slice data changes. We need to call this method to make sure InfoFragment updates in time. + * This is also helpful in refreshing preview of ListPreference. */ public void refocusPreference(Fragment fragment) { if (!isFragmentInTheMainPanel(fragment)) { @@ -759,23 +1071,115 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements } Preference chosenPreference = getChosenPreference(fragment); try { - if (chosenPreference != null && chosenPreference.getFragment() != null - && InfoFragment.class.isAssignableFrom( - Class.forName(chosenPreference.getFragment()))) { - onPreferenceFocused(chosenPreference); + if (chosenPreference != null) { + if (chosenPreference.getFragment() != null + && InfoFragment.class.isAssignableFrom( + Class.forName(chosenPreference.getFragment()))) { + updateInfoFragmentStatus(fragment); + } + if (chosenPreference instanceof ListPreference) { + refocusPreferenceForceRefresh(chosenPreference); + } } } catch (ClassNotFoundException e) { e.printStackTrace(); } } - private static Preference getChosenPreference(Fragment fragment) { - if (!(fragment instanceof LeanbackPreferenceFragment)) { + /** Force refresh preview panel. */ + public void refocusPreferenceForceRefresh(Preference chosenPreference) { + onPreferenceFocusedImpl(chosenPreference, true); + } + + /** Show error message in preview panel **/ + public void showErrorMessage(String errorMessage, Fragment fragment) { + Fragment prefFragment = + getChildFragmentManager().findFragmentById(frameResIds[mPrefPanelIdx]); + if (fragment == prefFragment) { + // If user has already navigated to the preview screen, main panel screen should be + // updated to new InFoFragment. Create a fake preference to work around this case. + Preference preference = new Preference(getContext()); + updatePreferenceWithErrorMessage(preference, errorMessage, getContext()); + Fragment newPrefFragment = onCreatePreviewFragment(null, preference); + final FragmentTransaction transaction = + getChildFragmentManager().beginTransaction(); + transaction.setCustomAnimations(android.R.animator.fade_in, + android.R.animator.fade_out); + transaction.replace(frameResIds[mPrefPanelIdx], newPrefFragment); + transaction.commit(); + } else { + Preference preference = getChosenPreference(prefFragment); + if (preference != null) { + if (isA11yOn()) { + appendErrorToContentDescription(prefFragment, errorMessage); + } + updatePreferenceWithErrorMessage(preference, errorMessage, getContext()); + onPreferenceFocused(preference); + } + } + } + + private static void updatePreferenceWithErrorMessage( + Preference preference, String errorMessage, Context context) { + preference.setFragment(InfoFragment.class.getCanonicalName()); + Bundle b = preference.getExtras(); + b.putParcelable(EXTRA_PREFERENCE_INFO_TITLE_ICON, + Icon.createWithResource(context, R.drawable.slice_error_icon)); + b.putCharSequence(EXTRA_PREFERENCE_INFO_TEXT, + context.getString(R.string.status_unavailable)); + b.putCharSequence(EXTRA_PREFERENCE_INFO_SUMMARY, errorMessage); + } + + private void appendErrorToContentDescription(Fragment fragment, String errorMessage) { + Preference preference = getChosenPreference(fragment); + + String errorMessageContentDescription = ""; + if (preference.getTitle() != null) { + errorMessageContentDescription += preference.getTitle().toString(); + } + + errorMessageContentDescription += + HasCustomContentDescription.CONTENT_DESCRIPTION_SEPARATOR + + getString(R.string.status_unavailable) + + HasCustomContentDescription.CONTENT_DESCRIPTION_SEPARATOR + errorMessage; + + if (preference instanceof SlicePreference) { + ((SlicePreference) preference).setContentDescription(errorMessageContentDescription); + } else if (preference instanceof SliceSwitchPreference) { + ((SliceSwitchPreference) preference) + .setContentDescription(errorMessageContentDescription); + } else if (preference instanceof CustomContentDescriptionPreference) { + ((CustomContentDescriptionPreference) preference) + .setContentDescription(errorMessageContentDescription); + } + + LeanbackPreferenceFragmentCompat leanbackPreferenceFragment = + (LeanbackPreferenceFragmentCompat) fragment; + if (leanbackPreferenceFragment.getListView() != null + && leanbackPreferenceFragment.getListView().getAdapter() != null) { + leanbackPreferenceFragment.getListView().getAdapter().notifyDataSetChanged(); + } + } + + private void updateInfoFragmentStatus(Fragment fragment) { + if (!isFragmentInTheMainPanel(fragment)) { + return; + } + final Fragment existingPreviewFragment = + getChildFragmentManager().findFragmentById(frameResIds[mPrefPanelIdx + 1]); + if (existingPreviewFragment instanceof InfoFragment) { + ((InfoFragment) existingPreviewFragment).updateInfoFragment(); + } + } + + /** Get the current chosen preference. */ + public static Preference getChosenPreference(Fragment fragment) { + if (!(fragment instanceof LeanbackPreferenceFragmentCompat)) { return null; } - LeanbackPreferenceFragment leanbackPreferenceFragment = - (LeanbackPreferenceFragment) fragment; + LeanbackPreferenceFragmentCompat leanbackPreferenceFragment = + (LeanbackPreferenceFragmentCompat) fragment; if (leanbackPreferenceFragment.getListView() == null) { return null; } @@ -784,17 +1188,21 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements int position = listView.getSelectedPosition(); PreferenceGroupAdapter adapter = (PreferenceGroupAdapter) (leanbackPreferenceFragment.getListView().getAdapter()); - Preference chosenPreference = adapter.getItem(position); - return chosenPreference; + return adapter != null ? adapter.getItem(position) : null; } /** Creates preview preference fragment. */ public Fragment onCreatePreviewFragment(Fragment caller, Preference preference) { + if (preference == null) { + return null; + } if (preference.getFragment() != null) { - if (!shouldDisplay(preference.getFragment())) { + if (!isInfoFragment(preference.getFragment()) + && !isPreferenceFragment(preference.getFragment())) { return null; } - if (preference instanceof HasSliceUri) { + if (isPreferenceFragment(preference.getFragment()) + && preference instanceof HasSliceUri) { HasSliceUri slicePref = (HasSliceUri) preference; if (slicePref.getUri() == null || !isUriValid(slicePref.getUri())) { return null; @@ -810,7 +1218,8 @@ public abstract class TwoPanelSettingsFragment extends Fragment implements if (preference instanceof ListPreference) { f = TwoPanelListPreferenceDialogFragment.newInstanceSingle(preference.getKey()); } else if (preference instanceof MultiSelectListPreference) { - f = LeanbackListPreferenceDialogFragment.newInstanceMulti(preference.getKey()); + f = LeanbackListPreferenceDialogFragmentCompat.newInstanceMulti( + preference.getKey()); } if (f != null && caller != null) { f.setTargetFragment(caller, 0); diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/Android.bp b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/Android.bp new file mode 100644 index 000000000..3a91d7472 --- /dev/null +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/Android.bp @@ -0,0 +1,23 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +android_library { + name: "TvSliceLib", + + srcs: ["builders/*.java", "SlicesConstants.java"], + + static_libs: [ + "androidx.slice_slice-builders", + "androidx.slice_slice-core", + "androidx.slice_slice-view", + ], + + sdk_version: "system_current", + min_sdk_version: "21", + + apex_available: [ + "//apex_available:platform", + "com.android.permission", + ], +} diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/AndroidManifest.xml b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/AndroidManifest.xml new file mode 100644 index 000000000..5bad5a306 --- /dev/null +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/AndroidManifest.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2018 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.tv.twopanelsettings.slices"> + + <uses-sdk + android:minSdkVersion="21" /> + +</manifest> diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/ContextSingleton.java b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/ContextSingleton.java index 5af059838..62fc17bab 100644 --- a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/ContextSingleton.java +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/ContextSingleton.java @@ -71,4 +71,17 @@ public class ContextSingleton { mGivenFullSliceAccess = true; } } + + /** + * Grant full access to specific package. + */ + public void grantFullAccess(Context ctx, String uri, String packageName) { + if (!mGivenFullSliceAccess) { + // Uri cannot be null here as SliceManagerService calls notifyChange(uri, null) in + // grantPermissionFromUser. + ctx.getSystemService(SliceManager.class).grantPermissionFromUser( + Uri.parse(uri), packageName, true); + mGivenFullSliceAccess = true; + } + } } diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/CustomContentDescriptionPreference.java b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/CustomContentDescriptionPreference.java new file mode 100644 index 000000000..61ebe56ef --- /dev/null +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/CustomContentDescriptionPreference.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2020 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.tv.twopanelsettings.slices; + +import android.content.Context; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.View; + +import androidx.preference.PreferenceViewHolder; + +import com.android.settingslib.RestrictedPreference; + +/** + * Preference that allows external classes to set its view's content description for accessibility + * purposes. + */ +public class CustomContentDescriptionPreference extends RestrictedPreference implements + HasCustomContentDescription { + + private String mContentDescription; + + public CustomContentDescriptionPreference(Context context) { + super(context); + } + + public CustomContentDescriptionPreference(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + public void onBindViewHolder(PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + if (!TextUtils.isEmpty(mContentDescription)) { + holder.itemView.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE); + holder.itemView.setContentDescription(mContentDescription); + } + } + + /** + * Sets the accessibility content description that will be read to the TalkBack users when they + * focus on this preference. + */ + public void setContentDescription(String contentDescription) { + this.mContentDescription = contentDescription; + } + + public String getContentDescription() { + return mContentDescription; + } +} diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/CustomContentDescriptionUtil.java b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/CustomContentDescriptionUtil.java new file mode 100644 index 000000000..c778e0a5c --- /dev/null +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/CustomContentDescriptionUtil.java @@ -0,0 +1,53 @@ +/* + * 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.tv.twopanelsettings.slices; + +import static com.android.tv.twopanelsettings.slices.HasCustomContentDescription.CONTENT_DESCRIPTION_SEPARATOR; + +import android.content.Context; + +import com.android.tv.twopanelsettings.R; + +/** + * Generate fallback content descriptions for when custom content descriptions are not specified. + */ +public final class CustomContentDescriptionUtil { + + /** + * Generate fallback content description for Switch Preferences + * @param context + * @param contentDescription to generate first portion of full content description + * @param isChecked is the toggle state of SwitchPreference + * @return the full content description for switch preferences + */ + public static String getFullSwitchContentDescription( + Context context, String contentDescription, Boolean isChecked) { + StringBuilder switchContentDescription = new StringBuilder(); + switchContentDescription.append(contentDescription); + switchContentDescription.append(CONTENT_DESCRIPTION_SEPARATOR); + if (isChecked) { + switchContentDescription.append(context.getString(R.string.switch_on)); + switchContentDescription.append(CONTENT_DESCRIPTION_SEPARATOR); + } else { + switchContentDescription.append(context.getString(R.string.switch_off)); + switchContentDescription.append(CONTENT_DESCRIPTION_SEPARATOR); + } + switchContentDescription + .append(context.getString(R.string.switch_talkback_identifier)); + return switchContentDescription.toString(); + } +} diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/EmbeddedSlicePreference.java b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/EmbeddedSlicePreference.java index 63477f068..c58adbe09 100644 --- a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/EmbeddedSlicePreference.java +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/EmbeddedSlicePreference.java @@ -62,7 +62,8 @@ public class EmbeddedSlicePreference extends SlicePreference { setTitle(mHelper.mNewPref.getTitle()); setSummary(mHelper.mNewPref.getSummary()); setIcon(mHelper.mNewPref.getIcon()); - if (mHelper.mNewPref instanceof HasSliceAction) { + if (mHelper.mNewPref instanceof HasSliceAction + && ((HasSliceAction) mHelper.mNewPref).getSliceAction() != null) { setIntent(((HasSliceAction) mHelper.mNewPref).getSliceAction().getAction().getIntent()); } } diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/EmbeddedSlicePreferenceHelper.java b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/EmbeddedSlicePreferenceHelper.java index 6a1466ad3..52d2649cb 100644 --- a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/EmbeddedSlicePreferenceHelper.java +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/EmbeddedSlicePreferenceHelper.java @@ -86,8 +86,13 @@ public class EmbeddedSlicePreferenceHelper implements Observer<Slice> { return; } SliceItem embeddedItem = SlicePreferencesUtil.getEmbeddedItem(items); + // TODO(b/174691340): Refactor this class and integrate the functionality to TsPreference. + // TODO: Redesign TvSettings project structure so class in twopanelsettings lib can access + // FlavorUtils + // For now, put true or false here does not affect anything as the only related preference + // is not displayed to user anymore. mNewPref = SlicePreferencesUtil.getPreference(embeddedItem, - (ContextThemeWrapper) mContext, null); + (ContextThemeWrapper) mContext, null, false); if (mNewPref == null) { updateVisibility(false); return; diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/HasCustomContentDescription.java b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/HasCustomContentDescription.java new file mode 100644 index 000000000..8753150be --- /dev/null +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/HasCustomContentDescription.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2020 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.tv.twopanelsettings.slices; + +/** + * Preference that allows external classes to set its view's content description for accessibility. + */ +public interface HasCustomContentDescription { + String CONTENT_DESCRIPTION_SEPARATOR = ", "; + + /** Set the content description for talkback */ + void setContentDescription(String contentDescription); + + /** Return the content description. */ + String getContentDescription(); +} diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/InfoFragment.java b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/InfoFragment.java index 3bc1a08f3..12a7e4f6b 100644 --- a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/InfoFragment.java +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/InfoFragment.java @@ -17,7 +17,7 @@ package com.android.tv.twopanelsettings.slices; -import android.app.Fragment; +import android.content.res.Resources; import android.graphics.drawable.Icon; import android.os.Bundle; import android.view.LayoutInflater; @@ -26,26 +26,86 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; +import androidx.fragment.app.Fragment; + import com.android.tv.twopanelsettings.R; /** * Fragment to display informational image and description text for slice. */ public class InfoFragment extends Fragment { + public static final String EXTRA_INFO_HAS_STATUS = "extra_info_has_status"; @Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.info_fragment, container, false); + updateInfo(view); + return view; + } + + /** Update the infos in InfoFragment **/ + public void updateInfoFragment() { + updateInfo(getView()); + } + + private void updateInfo(View view) { Icon image = getArguments().getParcelable(SlicesConstants.EXTRA_PREFERENCE_INFO_IMAGE); - String text = getArguments().getString(SlicesConstants.EXTRA_PREFERENCE_INFO_TEXT); + Icon titleIcon = getArguments().getParcelable( + SlicesConstants.EXTRA_PREFERENCE_INFO_TITLE_ICON); + String title = getArguments().getString(SlicesConstants.EXTRA_PREFERENCE_INFO_TEXT); + String summary = getArguments().getString(SlicesConstants.EXTRA_PREFERENCE_INFO_SUMMARY); + boolean hasStatus = getArguments().getBoolean(EXTRA_INFO_HAS_STATUS); + boolean status = getArguments().getBoolean(SlicesConstants.EXTRA_PREFERENCE_INFO_STATUS); + + Resources res = getResources(); + ImageView infoImage = view.findViewById(R.id.info_image); + ImageView infoIcon = view.findViewById(R.id.info_title_icon); + TextView infoTitle = view.findViewById(R.id.info_title); + TextView infoStatus = view.findViewById(R.id.info_status); + TextView infoSummary = view.findViewById(R.id.info_summary); + if (image != null) { - ((ImageView) view.findViewById(R.id.info_image)) - .setImageDrawable(image.loadDrawable(getContext())); + infoImage.setImageDrawable(image.loadDrawable(getContext())); } - if (text != null) { - ((TextView) view.findViewById(R.id.info_text)).setText(text); + if (titleIcon != null) { + infoIcon.setImageDrawable(titleIcon.loadDrawable(getContext())); + infoIcon.setVisibility(View.VISIBLE); + } else { + infoIcon.setVisibility(View.GONE); + } + if (title != null) { + infoTitle.setText(title); + infoTitle.setVisibility(View.VISIBLE); + if (hasStatus) { + infoStatus.setVisibility(View.VISIBLE); + if (infoIcon.getVisibility() == View.VISIBLE) { + infoTitle.setMaxWidth( + res.getDimensionPixelSize( + R.dimen.settings_info_fragment_title_text_max_width_short)); + } else { + infoTitle.setMaxWidth( + res.getDimensionPixelSize( + R.dimen.settings_info_fragment_title_text_max_width_long)); + } + if (status) { + infoStatus.setTextColor(getResources().getColor(R.color.info_status_on)); + infoStatus.setText(getString(R.string.info_status_on)); + } else { + infoStatus.setTextColor(getResources().getColor(R.color.info_status_off)); + infoStatus.setText(getString(R.string.info_status_off)); + } + } else { + infoStatus.setVisibility(View.GONE); + // Reset maxWidth to allow the TextView to utilize the full width of its container. + infoTitle.setMaxWidth(Integer.MAX_VALUE); + } + } else { + infoTitle.setVisibility(View.GONE); + infoStatus.setVisibility(View.GONE); + } + if (summary != null) { + infoSummary.setText(summary); } - return view; } } diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SettingsPreferenceFragment.java b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SettingsPreferenceFragment.java index 2a344b20f..58ceda8fb 100644 --- a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SettingsPreferenceFragment.java +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SettingsPreferenceFragment.java @@ -25,6 +25,7 @@ import static androidx.lifecycle.Lifecycle.Event.ON_STOP; import static com.android.tv.twopanelsettings.slices.InstrumentationUtils.logPageFocused; +import android.animation.AnimatorInflater; import android.app.tvsettings.TvSettingsEnums; import android.content.Context; import android.os.Bundle; @@ -33,16 +34,17 @@ import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; +import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.CallSuper; import androidx.annotation.NonNull; import androidx.lifecycle.LifecycleOwner; +import androidx.preference.PreferenceGroupAdapter; import androidx.preference.PreferenceScreen; +import androidx.preference.PreferenceViewHolder; +import androidx.recyclerview.widget.RecyclerView; -import com.android.settingslib.core.instrumentation.Instrumentable; -import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; -import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.tv.twopanelsettings.R; import com.android.tv.twopanelsettings.SettingsPreferenceFragmentBase; @@ -52,23 +54,18 @@ import com.android.tv.twopanelsettings.TwoPanelSettingsFragment; * A copy of SettingsPreferenceFragment in Settings. */ public abstract class SettingsPreferenceFragment extends SettingsPreferenceFragmentBase - implements LifecycleOwner, Instrumentable, + implements LifecycleOwner, TwoPanelSettingsFragment.PreviewableComponentCallback { private final Lifecycle mLifecycle = new Lifecycle(this); - private final VisibilityLoggerMixin mVisibilityLoggerMixin; - protected MetricsFeatureProvider mMetricsFeatureProvider; + // Rename getLifecycle() to getSettingsLifecycle() as androidx Fragment has already implemented + // getLifecycle(), overriding here would cause unexpected crash in framework. @NonNull - public Lifecycle getLifecycle() { + public Lifecycle getSettingsLifecycle() { return mLifecycle; } public SettingsPreferenceFragment() { - mMetricsFeatureProvider = new MetricsFeatureProvider(); - // Mixin that logs visibility change for activity. - mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory(), - mMetricsFeatureProvider); - getLifecycle().addObserver(mVisibilityLoggerMixin); } @CallSuper @@ -103,13 +100,28 @@ public abstract class SettingsPreferenceFragment extends SettingsPreferenceFragm // it is RTL. if (titleView != null && getResources().getConfiguration().getLayoutDirection() - == View.LAYOUT_DIRECTION_RTL) { + == View.LAYOUT_DIRECTION_RTL) { titleView.setGravity(Gravity.RIGHT); } } } @Override + protected RecyclerView.Adapter onCreateAdapter(PreferenceScreen preferenceScreen) { + return new PreferenceGroupAdapter(preferenceScreen) { + @Override + @NonNull + public PreferenceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, + int viewType) { + PreferenceViewHolder vh = super.onCreateViewHolder(parent, viewType); + vh.itemView.setStateListAnimator(AnimatorInflater.loadStateListAnimator( + getContext(), R.animator.preference)); + return vh; + } + }; + } + + @Override public void setPreferenceScreen(PreferenceScreen preferenceScreen) { mLifecycle.setPreferenceScreen(preferenceScreen); super.setPreferenceScreen(preferenceScreen); @@ -132,7 +144,6 @@ public abstract class SettingsPreferenceFragment extends SettingsPreferenceFragm @CallSuper @Override public void onResume() { - mVisibilityLoggerMixin.setSourceMetricsCategory(getActivity()); super.onResume(); mLifecycle.handleLifecycleEvent(ON_RESUME); } diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java index 2cdf1d900..7b42ddc69 100644 --- a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceFragment.java @@ -16,20 +16,23 @@ package com.android.tv.twopanelsettings.slices; +import static android.app.slice.Slice.EXTRA_SLIDER_VALUE; import static android.app.slice.Slice.EXTRA_TOGGLE_STATE; import static android.app.slice.Slice.HINT_PARTIAL; import static com.android.tv.twopanelsettings.slices.InstrumentationUtils.logEntrySelected; import static com.android.tv.twopanelsettings.slices.InstrumentationUtils.logToggleInteracted; +import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_PREFERENCE_INFO_STATUS; import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_PREFERENCE_KEY; import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_SLICE_FOLLOWUP; +import android.app.Activity; import android.app.PendingIntent; import android.app.PendingIntent.CanceledException; import android.app.tvsettings.TvSettingsEnums; +import android.content.ContentProviderClient; import android.content.Intent; import android.content.IntentSender; -import android.content.IntentSender.SendIntentException; import android.database.ContentObserver; import android.graphics.drawable.Icon; import android.net.Uri; @@ -46,8 +49,12 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; -import android.widget.Toast; +import androidx.activity.result.ActivityResult; +import androidx.activity.result.ActivityResultCallback; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.IntentSenderRequest; +import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.lifecycle.Observer; @@ -59,7 +66,6 @@ import androidx.slice.SliceItem; import androidx.slice.widget.ListContent; import androidx.slice.widget.SliceContent; -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.tv.twopanelsettings.R; import com.android.tv.twopanelsettings.TwoPanelSettingsFragment; import com.android.tv.twopanelsettings.TwoPanelSettingsFragment.SliceFragmentCallback; @@ -98,7 +104,22 @@ public class SliceFragment extends SettingsPreferenceFragment implements Observe private Intent mFollowupPendingIntentExtras; private Intent mFollowupPendingIntentExtrasCopy; private String mLastFocusedPreferenceKey; - private ContentObserver mContentObserver = new ContentObserver(new Handler()) { + private boolean mIsMainPanelReady = true; + + private final Handler mHandler = new Handler(); + private final ActivityResultLauncher<IntentSenderRequest> mActivityResultLauncher = + registerForActivityResult(new ActivityResultContracts.StartIntentSenderForResult(), + new ActivityResultCallback<ActivityResult>() { + @Override + public void onActivityResult(ActivityResult result) { + Intent data = result.getData(); + mFollowupPendingIntentExtras = data; + mFollowupPendingIntentExtrasCopy = data == null ? null : new Intent( + data); + mFollowupPendingIntentResultCode = result.getResultCode(); + } + }); + private final ContentObserver mContentObserver = new ContentObserver(new Handler()) { @Override public void onChange(boolean selfChange, Uri uri) { handleUri(uri); @@ -106,6 +127,11 @@ public class SliceFragment extends SettingsPreferenceFragment implements Observe } }; + /** Callback for one panel settings fragment **/ + public interface OnePanelSliceFragmentContainer { + void navigateBack(); + } + @Override public void onCreate(Bundle savedInstanceState) { mUriString = getArguments().getString(SlicesConstants.TAG_TARGET_URI); @@ -190,15 +216,22 @@ public class SliceFragment extends SettingsPreferenceFragment implements Observe } - @Override - public int getMetricsCategory() { - return MetricsEvent.VIEW_UNKNOWN; + private boolean isUriValid(String uri) { + if (uri == null) { + return false; + } + ContentProviderClient client = + getContext().getContentResolver().acquireContentProviderClient(Uri.parse(uri)); + if (client != null) { + client.close(); + return true; + } else { + return false; + } } private void update() { - // TODO: Remove ListContent mListContent = new ListContent(mSlice); - // TODO: Compare and update the existing preferences instead of rebuilding the screen. PreferenceScreen preferenceScreen = getPreferenceManager().getPreferenceScreen(); @@ -211,6 +244,24 @@ public class SliceFragment extends SettingsPreferenceFragment implements Observe return; } + SliceItem redirectSliceItem = SlicePreferencesUtil.getRedirectSlice(items); + String redirectSlice = null; + if (redirectSliceItem != null) { + Data data = SlicePreferencesUtil.extract(redirectSliceItem); + CharSequence title = SlicePreferencesUtil.getText(data.mTitleItem); + if (!TextUtils.isEmpty(title)) { + redirectSlice = title.toString(); + } + } + if (isUriValid(redirectSlice)) { + getSliceLiveData().removeObserver(this); + getContext().getContentResolver().unregisterContentObserver(mContentObserver); + mUriString = redirectSlice; + getSliceLiveData().observeForever(this); + getContext().getContentResolver().registerContentObserver( + SlicePreferencesUtil.getStatusPath(mUriString), false, mContentObserver); + } + SliceItem screenTitleItem = SlicePreferencesUtil.getScreenTitleItem(items); if (screenTitleItem == null) { setTitle(mScreenTitle); @@ -245,13 +296,17 @@ public class SliceFragment extends SettingsPreferenceFragment implements Observe List<Preference> newPrefs = new ArrayList<>(); for (SliceContent contentItem : items) { SliceItem item = contentItem.getSliceItem(); - Preference preference = SlicePreferencesUtil.getPreference(item, mContextThemeWrapper, - getClass().getCanonicalName()); - if (preference != null) { - newPrefs.add(preference); + if (SlicesConstants.TYPE_PREFERENCE.equals(item.getSubType()) + || SlicesConstants.TYPE_PREFERENCE_CATEGORY.equals(item.getSubType())) { + Preference preference = + SlicePreferencesUtil.getPreference( + item, mContextThemeWrapper, getClass().getCanonicalName(), + getParentFragment() instanceof TwoPanelSettingsFragment); + if (preference != null) { + newPrefs.add(preference); + } } } - updatePreferenceScreen(preferenceScreen, newPrefs); if (defaultFocusedKey != null) { scrollToPreference(defaultFocusedKey.toString()); @@ -262,6 +317,7 @@ public class SliceFragment extends SettingsPreferenceFragment implements Observe if (getParentFragment() instanceof TwoPanelSettingsFragment) { ((TwoPanelSettingsFragment) getParentFragment()).refocusPreference(this); } + mIsMainPanelReady = true; } @@ -272,16 +328,31 @@ public class SliceFragment extends SettingsPreferenceFragment implements Observe if (parentFragment.isFragmentInTheMainPanel(this)) { parentFragment.navigateBack(); } + } else if (getCallbackFragment() instanceof OnePanelSliceFragmentContainer) { + ((OnePanelSliceFragmentContainer) getCallbackFragment()).navigateBack(); } } private void forward() { - if (getCallbackFragment() instanceof TwoPanelSettingsFragment) { - TwoPanelSettingsFragment parentFragment = - (TwoPanelSettingsFragment) getCallbackFragment(); - if (parentFragment.isFragmentInTheMainPanel(this)) { - parentFragment.navigateToPreviewFragment(); + if (mIsMainPanelReady) { + if (getCallbackFragment() instanceof TwoPanelSettingsFragment) { + TwoPanelSettingsFragment parentFragment = + (TwoPanelSettingsFragment) getCallbackFragment(); + Preference chosenPreference = TwoPanelSettingsFragment.getChosenPreference(this); + if (chosenPreference == null && mLastFocusedPreferenceKey != null) { + chosenPreference = findPreference(mLastFocusedPreferenceKey); + } + if (chosenPreference != null && chosenPreference instanceof HasSliceUri + && ((HasSliceUri) chosenPreference).getUri() != null) { + chosenPreference.setFragment(SliceFragment.class.getCanonicalName()); + parentFragment.refocusPreferenceForceRefresh(chosenPreference); + } + if (parentFragment.isFragmentInTheMainPanel(this)) { + parentFragment.navigateToPreviewFragment(); + } } + } else { + mHandler.post(() -> forward()); } } @@ -293,7 +364,7 @@ public class SliceFragment extends SettingsPreferenceFragment implements Observe while (index < screen.getPreferenceCount()) { boolean needToRemoveCurrentPref = true; Preference oldPref = screen.getPreference(index); - if (oldPref.getKey() != null) { + if (oldPref != null && oldPref.getKey() != null) { for (Preference newPref : newPrefs) { if (newPref.getKey() != null && newPref.getKey().equals(oldPref.getKey())) { needToRemoveCurrentPref = false; @@ -353,6 +424,18 @@ public class SliceFragment extends SettingsPreferenceFragment implements Observe screen.addPreference(newPref); } } + removeAnimationClipping(getView()); + } + + protected void removeAnimationClipping(View v) { + if (v instanceof ViewGroup) { + ((ViewGroup) v).setClipChildren(false); + ((ViewGroup) v).setClipToPadding(false); + for (int index = 0; index < ((ViewGroup) v).getChildCount(); index++) { + View child = ((ViewGroup) v).getChildAt(index); + removeAnimationClipping(child); + } + } } @Override @@ -361,87 +444,88 @@ public class SliceFragment extends SettingsPreferenceFragment implements Observe } @Override + public void onSeekbarPreferenceChanged(SliceSeekbarPreference preference, int addValue) { + int curValue = preference.getValue(); + if((addValue > 0 && curValue < preference.getMax()) || + (addValue < 0 && curValue > preference.getMin())) { + preference.setValue(curValue + addValue); + + try { + Intent fillInIntent = + new Intent() + .putExtra(EXTRA_SLIDER_VALUE, preference.getValue()) + .putExtra(EXTRA_PREFERENCE_KEY, preference.getKey()); + firePendingIntent((HasSliceAction) preference, fillInIntent); + } catch (Exception e) { + Log.e(TAG, "PendingIntent for slice cannot be sent", e); + } + } + } + + @Override public boolean onPreferenceTreeClick(Preference preference) { if (preference instanceof SliceRadioPreference) { SliceRadioPreference radioPref = (SliceRadioPreference) preference; if (!radioPref.isChecked()) { radioPref.setChecked(true); - return true; + if (TextUtils.isEmpty(radioPref.getUri())) { + return true; + } } logEntrySelected(getPreferenceActionId(preference)); Intent fillInIntent = new Intent().putExtra(EXTRA_PREFERENCE_KEY, preference.getKey()); - try { - boolean result = firePendingIntent(radioPref, fillInIntent); - radioPref.clearOtherRadioPreferences(getPreferenceScreen()); - if (result) { - return true; - } - } catch (SendIntentException e) { - Log.e(TAG, "PendingIntent for slice cannot be sent", e); + + boolean result = firePendingIntent(radioPref, fillInIntent); + radioPref.clearOtherRadioPreferences(getPreferenceScreen()); + if (result) { + return true; } } else if (preference instanceof TwoStatePreference && preference instanceof HasSliceAction) { - // TODO - Show loading indicator here? - try { - boolean isChecked = ((TwoStatePreference) preference).isChecked(); - logToggleInteracted(getPreferenceActionId(preference), isChecked); - Intent fillInIntent = - new Intent() - .putExtra(EXTRA_TOGGLE_STATE, isChecked) - .putExtra(EXTRA_PREFERENCE_KEY, preference.getKey()); - if (firePendingIntent((HasSliceAction) preference, fillInIntent)) { - return true; - } - } catch (SendIntentException e) { - ((TwoStatePreference) preference).setChecked( - !((TwoStatePreference) preference).isChecked()); - Log.e(TAG, "PendingIntent for slice cannot be sent", e); + boolean isChecked = ((TwoStatePreference) preference).isChecked(); + preference.getExtras().putBoolean(EXTRA_PREFERENCE_INFO_STATUS, isChecked); + if (getParentFragment() instanceof TwoPanelSettingsFragment) { + ((TwoPanelSettingsFragment) getParentFragment()).refocusPreference(this); + } + logToggleInteracted(getPreferenceActionId(preference), isChecked); + Intent fillInIntent = + new Intent() + .putExtra(EXTRA_TOGGLE_STATE, isChecked) + .putExtra(EXTRA_PREFERENCE_KEY, preference.getKey()); + if (firePendingIntent((HasSliceAction) preference, fillInIntent)) { + return true; } return true; } else if (preference instanceof SlicePreference) { - try { - // In this case, we may intentionally ignore this entry selection to avoid double - // logging as the action should result in a PAGE_FOCUSED event being logged. - if (getPreferenceActionId(preference) != TvSettingsEnums.ENTRY_DEFAULT) { - logEntrySelected(getPreferenceActionId(preference)); - } - Intent fillInIntent = - new Intent().putExtra(EXTRA_PREFERENCE_KEY, preference.getKey()); - if (firePendingIntent((HasSliceAction) preference, fillInIntent)) { - return true; - } - - } catch (SendIntentException e) { - Log.e(TAG, "PendingIntent for slice cannot be sent", e); + // In this case, we may intentionally ignore this entry selection to avoid double + // logging as the action should result in a PAGE_FOCUSED event being logged. + if (getPreferenceActionId(preference) != TvSettingsEnums.ENTRY_DEFAULT) { + logEntrySelected(getPreferenceActionId(preference)); + } + Intent fillInIntent = + new Intent().putExtra(EXTRA_PREFERENCE_KEY, preference.getKey()); + if (firePendingIntent((HasSliceAction) preference, fillInIntent)) { + return true; } } return super.onPreferenceTreeClick(preference); } - private boolean firePendingIntent(HasSliceAction preference, Intent fillInIntent) - throws SendIntentException { + private boolean firePendingIntent(@NonNull HasSliceAction preference, Intent fillInIntent) { if (preference.getSliceAction() == null) { return false; } IntentSender intentSender = preference.getSliceAction().getAction().getIntentSender(); - startIntentSenderForResult( - intentSender, SLICE_REQUEST_CODE, fillInIntent, 0, 0, 0, null); + mActivityResultLauncher.launch( + new IntentSenderRequest.Builder(intentSender).setFillInIntent( + fillInIntent).build()); if (preference.getFollowupSliceAction() != null) { mPreferenceFollowupIntent = preference.getFollowupSliceAction().getAction(); } - return true; - } - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == 0) { - return; - } - mFollowupPendingIntentExtras = data; - mFollowupPendingIntentExtrasCopy = data == null ? null : new Intent(data); - mFollowupPendingIntentResultCode = resultCode; + return true; } @Override @@ -485,11 +569,13 @@ public class SliceFragment extends SettingsPreferenceFragment implements Observe } else { hideProgressBar(); } + mIsMainPanelReady = false; update(); } private void showProgressBar() { - View progressBar = getView().findViewById(R.id.progress_bar); + View view = this.getView(); + View progressBar = view == null ? null : getView().findViewById(R.id.progress_bar); if (progressBar != null) { progressBar.bringToFront(); progressBar.setVisibility(View.VISIBLE); @@ -497,7 +583,8 @@ public class SliceFragment extends SettingsPreferenceFragment implements Observe } private void hideProgressBar() { - View progressBar = getView().findViewById(R.id.progress_bar); + View view = this.getView(); + View progressBar = view == null ? null : getView().findViewById(R.id.progress_bar); if (progressBar != null) { progressBar.setVisibility(View.GONE); } @@ -530,10 +617,13 @@ public class SliceFragment extends SettingsPreferenceFragment implements Observe ImageView decorIcon = view == null ? null : (ImageView) view.findViewById(R.id.decor_icon); if (decorIcon != null && icon != null) { TextView decorTitle = view.findViewById(R.id.decor_title); - decorTitle.setMaxWidth(getResources().getDimensionPixelSize(R.dimen.decor_title_width)); + if (decorTitle != null) { + decorTitle.setMaxWidth( + getResources().getDimensionPixelSize(R.dimen.decor_title_width)); + } decorIcon.setImageDrawable(icon.loadDrawable(mContextThemeWrapper)); decorIcon.setVisibility(View.VISIBLE); - } else { + } else if (decorIcon != null) { decorIcon.setVisibility(View.GONE); } mScreenIcon = icon; @@ -550,9 +640,16 @@ public class SliceFragment extends SettingsPreferenceFragment implements Observe view.removeView(view.findViewById(R.id.decor_title_container)); view.addView(newTitleContainer, 0); + if (newTitleContainer != null) { + newTitleContainer.setOutlineProvider(null); + newTitleContainer.setBackgroundResource(R.color.tp_preference_panel_background_color); + } + final View newContainer = themedInflater.inflate(R.layout.slice_progress_bar, container, false); - ((ViewGroup) newContainer).addView(view); + if (newContainer != null) { + ((ViewGroup) newContainer).addView(view); + } return newContainer; } @@ -573,12 +670,25 @@ public class SliceFragment extends SettingsPreferenceFragment implements Observe forward(); } else if (direction.equals(SlicesConstants.BACKWARD)) { back(); + } else if (direction.equals(SlicesConstants.EXIT)) { + finish(); } } String errorMessage = uri.getQueryParameter(SlicesConstants.PARAMETER_ERROR); if (errorMessage != null) { - Toast.makeText(getContext(), errorMessage, Toast.LENGTH_SHORT).show(); + showErrorMessage(errorMessage); + } + } + + private void finish() { + getActivity().setResult(Activity.RESULT_OK); + getActivity().finish(); + } + + private void showErrorMessage(String errorMessage) { + if (getCallbackFragment() instanceof TwoPanelSettingsFragment) { + ((TwoPanelSettingsFragment) getCallbackFragment()).showErrorMessage(errorMessage, this); } } @@ -591,8 +701,17 @@ public class SliceFragment extends SettingsPreferenceFragment implements Observe return TvSettingsEnums.ENTRY_DEFAULT; } + public CharSequence getScreenTitle() { + return mScreenTitle; + } + @Override protected int getPageId() { return mCurrentPageId != 0 ? mCurrentPageId : TvSettingsEnums.PAGE_SLICE_DEFAULT; } + + @Deprecated + public int getMetricsCategory() { + return 0; + } } diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicePreference.java b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicePreference.java index 95079f0c2..e25bb3260 100644 --- a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicePreference.java +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicePreference.java @@ -17,10 +17,13 @@ package com.android.tv.twopanelsettings.slices; import android.content.Context; import android.content.res.TypedArray; +import android.text.TextUtils; import android.util.AttributeSet; +import android.view.View; import androidx.annotation.Nullable; import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; import androidx.slice.core.SliceActionImpl; import com.android.tv.twopanelsettings.R; @@ -28,14 +31,17 @@ import com.android.tv.twopanelsettings.R; /** * A preference that represents a slice provided by another app. */ -public class SlicePreference extends Preference implements HasSliceAction, HasSliceUri { +public class SlicePreference extends Preference implements HasSliceAction, HasSliceUri, + HasCustomContentDescription { private static final String TAG = "SlicePreference"; + private static final String SEPARATOR = ","; private String mUri; private int mActionId; private SliceActionImpl mAction; private SliceActionImpl mFollowUpAction; + private String mContentDescription; public SlicePreference(Context context) { super(context); @@ -47,6 +53,15 @@ public class SlicePreference extends Preference implements HasSliceAction, HasSl init(attrs); } + @Override + public void onBindViewHolder(PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + if (!TextUtils.isEmpty(mContentDescription)) { + holder.itemView.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE); + holder.itemView.setContentDescription(mContentDescription); + } + } + private void init(@Nullable AttributeSet attrs) { if (attrs != null) { initStyleAttributes(attrs); @@ -101,4 +116,16 @@ public class SlicePreference extends Preference implements HasSliceAction, HasSl public SliceActionImpl getSliceAction() { return mAction; } + + /** + * Sets the accessibility content description that will be read to the TalkBack users when they + * select this preference. + */ + public void setContentDescription(String contentDescription) { + this.mContentDescription = contentDescription; + } + + public String getContentDescription() { + return mContentDescription; + } } diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicePreferencesUtil.java b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicePreferencesUtil.java index ec2cd0854..db95ee0c8 100644 --- a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicePreferencesUtil.java +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicePreferencesUtil.java @@ -19,6 +19,7 @@ package com.android.tv.twopanelsettings.slices; import static android.app.slice.Slice.HINT_PARTIAL; import static android.app.slice.Slice.HINT_SUMMARY; import static android.app.slice.Slice.HINT_TITLE; +import static android.app.slice.Slice.SUBTYPE_CONTENT_DESCRIPTION; import static android.app.slice.SliceItem.FORMAT_ACTION; import static android.app.slice.SliceItem.FORMAT_IMAGE; import static android.app.slice.SliceItem.FORMAT_INT; @@ -26,13 +27,19 @@ import static android.app.slice.SliceItem.FORMAT_LONG; import static android.app.slice.SliceItem.FORMAT_SLICE; import static android.app.slice.SliceItem.FORMAT_TEXT; +import static com.android.tv.twopanelsettings.slices.HasCustomContentDescription.CONTENT_DESCRIPTION_SEPARATOR; import static com.android.tv.twopanelsettings.slices.SlicesConstants.CHECKMARK; import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_ACTION_ID; +import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_ADD_INFO_STATUS; import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_PAGE_ID; import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_PREFERENCE_INFO_IMAGE; +import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_PREFERENCE_INFO_STATUS; +import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_PREFERENCE_INFO_SUMMARY; import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_PREFERENCE_INFO_TEXT; +import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_PREFERENCE_INFO_TITLE_ICON; import static com.android.tv.twopanelsettings.slices.SlicesConstants.RADIO; import static com.android.tv.twopanelsettings.slices.SlicesConstants.SWITCH; +import static com.android.tv.twopanelsettings.slices.SlicesConstants.SEEKBAR; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; @@ -63,7 +70,7 @@ import java.util.List; public final class SlicePreferencesUtil { static Preference getPreference(SliceItem item, ContextThemeWrapper contextThemeWrapper, - String className) { + String className, boolean isTwoPanel) { Preference preference = null; if (item == null) { return null; @@ -112,6 +119,13 @@ public final class SlicePreferencesUtil { getRadioGroup(item).toString()); } break; + case SEEKBAR : + int min = SlicePreferencesUtil.getSeekbarMin(item); + int max = SlicePreferencesUtil.getSeekbarMax(item); + int value = SlicePreferencesUtil.getSeekbarValue(item); + preference = new SliceSeekbarPreference( + contextThemeWrapper, action, min, max, value); + break; } if (preference instanceof HasSliceAction) { ((HasSliceAction) preference).setActionId(getActionId(item)); @@ -128,7 +142,13 @@ public final class SlicePreferencesUtil { CharSequence uri = getText(data.mTargetSliceItem); if (uri == null || TextUtils.isEmpty(uri)) { if (preference == null) { - preference = new Preference(contextThemeWrapper); + // if contains info text + if (getInfoSummary(item) != null) { + preference = new CustomContentDescriptionPreference( + contextThemeWrapper); + } else { + preference = new Preference(contextThemeWrapper); + } } } else { if (preference == null) { @@ -165,7 +185,7 @@ public final class SlicePreferencesUtil { boolean isIconNeedToBeProcessed = SlicePreferencesUtil.isIconNeedsToBeProcessed(item); Drawable iconDrawable = icon.loadDrawable(contextThemeWrapper); - if (isIconNeedToBeProcessed) { + if (isIconNeedToBeProcessed && isTwoPanel) { preference.setIcon(IconUtil.getCompoundIcon(contextThemeWrapper, iconDrawable)); } else { preference.setIcon(iconDrawable); @@ -188,17 +208,58 @@ public final class SlicePreferencesUtil { preference.setSummary(getText(data.mSummaryItem)); } } + // Set preview info image and text CharSequence infoText = getInfoText(item); + CharSequence infoSummary = getInfoSummary(item); + boolean addInfoStatus = addInfoStatus(item); IconCompat infoImage = getInfoImage(item); + IconCompat infoTitleIcon = getInfoTitleIcon(item); Bundle b = preference.getExtras(); + String fallbackInfoContentDescription = ""; + if (preference.getTitle() != null) { + fallbackInfoContentDescription += preference.getTitle().toString(); + } if (infoImage != null) { b.putParcelable(EXTRA_PREFERENCE_INFO_IMAGE, infoImage.toIcon()); } + if (infoTitleIcon != null) { + b.putParcelable(EXTRA_PREFERENCE_INFO_TITLE_ICON, infoTitleIcon.toIcon()); + } if (infoText != null) { + if (preference instanceof SliceSwitchPreference && addInfoStatus) { + b.putBoolean(InfoFragment.EXTRA_INFO_HAS_STATUS, true); + b.putBoolean(EXTRA_PREFERENCE_INFO_STATUS, + ((SliceSwitchPreference) preference).isChecked()); + } else { + b.putBoolean(InfoFragment.EXTRA_INFO_HAS_STATUS, false); + } b.putCharSequence(EXTRA_PREFERENCE_INFO_TEXT, infoText); + if (preference.getTitle() != null + && !preference.getTitle().equals(infoText.toString())) { + fallbackInfoContentDescription += + CONTENT_DESCRIPTION_SEPARATOR + infoText.toString(); + } + + } + if (infoSummary != null) { + b.putCharSequence(EXTRA_PREFERENCE_INFO_SUMMARY, infoSummary); + fallbackInfoContentDescription += + CONTENT_DESCRIPTION_SEPARATOR + infoSummary.toString(); } - if (infoImage != null || infoText != null) { + if (infoText != null || infoSummary != null) { + if (preference instanceof SlicePreference) { + ((SlicePreference) preference).setContentDescription( + getInfoContentDescription(item, fallbackInfoContentDescription)); + } else if (preference instanceof SliceSwitchPreference) { + ((SliceSwitchPreference) preference).setContentDescription( + getInfoContentDescription(item, fallbackInfoContentDescription)); + } else if (preference instanceof CustomContentDescriptionPreference) { + ((CustomContentDescriptionPreference) preference).setContentDescription( + getInfoContentDescription(item, fallbackInfoContentDescription)); + } + } + if (infoImage != null || infoText != null || infoSummary != null) { preference.setFragment(InfoFragment.class.getCanonicalName()); } } @@ -318,6 +379,17 @@ public final class SlicePreferencesUtil { return null; } + static SliceItem getRedirectSlice(List<SliceContent> sliceItems) { + for (SliceContent contentItem : sliceItems) { + SliceItem item = contentItem.getSliceItem(); + if (item.getSubType() != null + && item.getSubType().equals(SlicesConstants.TYPE_REDIRECTED_SLICE_URI)) { + return item; + } + } + return null; + } + static SliceItem getFocusedPreferenceItem(List<SliceContent> sliceItems) { for (SliceContent contentItem : sliceItems) { SliceItem item = contentItem.getSliceItem(); @@ -362,6 +434,39 @@ public final class SlicePreferencesUtil { return -1; } + private static int getSeekbarMin(SliceItem sliceItem) { + List<SliceItem> items = sliceItem.getSlice().getItems(); + for (SliceItem item : items) { + if (item.getSubType() != null + && item.getSubType().equals(SlicesConstants.SUBTYPE_SEEKBAR_MIN)) { + return item.getInt(); + } + } + return -1; + } + + private static int getSeekbarMax(SliceItem sliceItem) { + List<SliceItem> items = sliceItem.getSlice().getItems(); + for (SliceItem item : items) { + if (item.getSubType() != null + && item.getSubType().equals(SlicesConstants.SUBTYPE_SEEKBAR_MAX)) { + return item.getInt(); + } + } + return -1; + } + + private static int getSeekbarValue(SliceItem sliceItem) { + List<SliceItem> items = sliceItem.getSlice().getItems(); + for (SliceItem item : items) { + if (item.getSubType() != null + && item.getSubType().equals(SlicesConstants.SUBTYPE_SEEKBAR_VALUE)) { + return item.getInt(); + } + } + return -1; + } + private static boolean enabled(SliceItem sliceItem) { List<SliceItem> items = sliceItem.getSlice().getItems(); for (SliceItem item : items) { @@ -384,6 +489,17 @@ public final class SlicePreferencesUtil { return true; } + private static boolean addInfoStatus(SliceItem sliceItem) { + List<SliceItem> items = sliceItem.getSlice().getItems(); + for (SliceItem item : items) { + if (item.getSubType() != null + && item.getSubType().equals(EXTRA_ADD_INFO_STATUS)) { + return item.getInt() == 1; + } + } + return true; + } + /** * Get the text from the SliceItem. */ @@ -394,7 +510,7 @@ public final class SlicePreferencesUtil { return item.getText(); } - /** Get the icon from the SlicItem if available */ + /** Get the icon from the SliceItem if available */ static Icon getIcon(SliceItem startItem) { if (startItem != null && startItem.getSlice() != null && startItem.getSlice().getItems() != null @@ -430,8 +546,34 @@ public final class SlicePreferencesUtil { return target != null ? target.getText() : null; } + private static CharSequence getInfoSummary(SliceItem item) { + SliceItem target = SliceQuery.findSubtype(item, FORMAT_TEXT, EXTRA_PREFERENCE_INFO_SUMMARY); + return target != null ? target.getText() : null; + } + private static IconCompat getInfoImage(SliceItem item) { SliceItem target = SliceQuery.findSubtype(item, FORMAT_IMAGE, EXTRA_PREFERENCE_INFO_IMAGE); return target != null ? target.getIcon() : null; } + + private static IconCompat getInfoTitleIcon(SliceItem item) { + SliceItem target = SliceQuery.findSubtype( + item, FORMAT_IMAGE, EXTRA_PREFERENCE_INFO_TITLE_ICON); + return target != null ? target.getIcon() : null; + } + + /** + * Get the content description from SliceItem if available + */ + private static String getInfoContentDescription( + SliceItem sliceItem, String contentDescription) { + List<SliceItem> items = sliceItem.getSlice().getItems(); + for (SliceItem item : items) { + if (item.getSubType() != null + && item.getSubType().equals(SUBTYPE_CONTENT_DESCRIPTION)) { + return item.getText().toString(); + } + } + return contentDescription; + } } diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceSeekbarPreference.java b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceSeekbarPreference.java new file mode 100644 index 000000000..b7e281470 --- /dev/null +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceSeekbarPreference.java @@ -0,0 +1,74 @@ +package com.android.tv.twopanelsettings.slices; + +import android.content.Context; +import android.util.AttributeSet; + +import androidx.preference.SeekBarPreference; +import androidx.slice.core.SliceActionImpl; + +/** + * Slices version of SeekBarPreference. + */ +public class SliceSeekbarPreference extends SeekBarPreference implements HasSliceAction { + private int mActionId; + protected SliceActionImpl mAction; + private SliceActionImpl mFollowupSliceAction; + + public SliceSeekbarPreference(Context context, SliceActionImpl action, int min, int max, + int value) { + super(context); + mAction = action; + update(min, max, value); + } + + public SliceSeekbarPreference(Context context, AttributeSet attrs, SliceActionImpl action, + int min, int max, int value) { + super(context, attrs); + mAction = action; + update(min, max, value); + } + + @Override + public int getActionId() { + return mActionId; + } + + @Override + public void setActionId(int actionId) { + mActionId = actionId; + } + + public SliceSeekbarPreference(Context context) { + super(context); + } + + public SliceSeekbarPreference(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + public SliceActionImpl getSliceAction() { + return mAction; + } + + @Override + public void setSliceAction(SliceActionImpl sliceAction) { + mAction = sliceAction; + } + + @Override + public SliceActionImpl getFollowupSliceAction() { + return mFollowupSliceAction; + } + + @Override + public void setFollowupSliceAction(SliceActionImpl sliceAction) { + mFollowupSliceAction = sliceAction; + } + + private void update(int min, int max, int value) { + this.setMin(min); + this.setMax(max); + this.setValue(value); + } +} diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceSwitchPreference.java b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceSwitchPreference.java index 96eb70b93..d6678106a 100644 --- a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceSwitchPreference.java +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SliceSwitchPreference.java @@ -17,18 +17,24 @@ package com.android.tv.twopanelsettings.slices; import android.content.Context; +import android.text.TextUtils; import android.util.AttributeSet; +import android.view.View; +import androidx.preference.PreferenceViewHolder; import androidx.preference.SwitchPreference; import androidx.slice.core.SliceActionImpl; /** * Slices version of SwitchPreference. */ -public class SliceSwitchPreference extends SwitchPreference implements HasSliceAction { +public class SliceSwitchPreference extends SwitchPreference implements HasSliceAction, + HasCustomContentDescription { + private int mActionId; protected SliceActionImpl mAction; private SliceActionImpl mFollowupSliceAction; + private String mContentDescription; public SliceSwitchPreference(Context context, SliceActionImpl action) { super(context); @@ -43,6 +49,17 @@ public class SliceSwitchPreference extends SwitchPreference implements HasSliceA } @Override + public void onBindViewHolder(PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + if (!TextUtils.isEmpty(mContentDescription)) { + holder.itemView.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE); + holder.itemView.setContentDescription( + CustomContentDescriptionUtil.getFullSwitchContentDescription( + getContext(), mContentDescription, this.isChecked())); + } + } + + @Override public int getActionId() { return mActionId; } @@ -83,4 +100,17 @@ public class SliceSwitchPreference extends SwitchPreference implements HasSliceA private void update() { this.setChecked(mAction.isChecked()); } + + /** + * Sets the accessibility content description that will be read to the TalkBack users when they + * focus on this preference. + */ + public void setContentDescription(String contentDescription) { + this.mContentDescription = contentDescription; + } + + public String getContentDescription() { + return this.mContentDescription; + } + } diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicesConstants.java b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicesConstants.java index f2fa0c724..c545f03bb 100644 --- a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicesConstants.java +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/SlicesConstants.java @@ -30,6 +30,7 @@ public final class SlicesConstants { public static final String TYPE_PREFERENCE_SCREEN_TITLE = "TYPE_PREFERENCE_SCREEN_TITLE"; public static final String TYPE_PREFERENCE_EMBEDDED = "TYPE_PREFERENCE_EMBEDDED"; public static final String TYPE_FOCUSED_PREFERENCE = "TYPE_FOCUSED_PREFERENCE"; + public static final String TYPE_REDIRECTED_SLICE_URI = "TYPE_REDIRECTED_SLICE_URI"; public static final String TAG_TARGET_URI = "TAG_TARGET_URI"; public static final String TAG_SCREEN_TITLE = "TAG_SCREEN_TITLE"; public static final String TAG_KEY = "TAG_KEY"; @@ -42,23 +43,33 @@ public final class SlicesConstants { public static final String SUBTYPE_IS_ENABLED = "SUBTYPE_IS_ENABLED"; public static final String SUBTYPE_IS_SELECTABLE = "SUBTYPE_IS_SELECTABLE"; public static final String SUBTYPE_INFO_PREFERENCE = "SUBTYPE_INFO_PREFERENCE"; + public static final String SUBTYPE_SEEKBAR_MIN = "SUBTYPE_SEEKBAR_MIN"; + public static final String SUBTYPE_SEEKBAR_MAX = "SUBTYPE_SEEKBAR_MAX"; + public static final String SUBTYPE_SEEKBAR_VALUE = "SUBTYPE_SEEKBAR_VALUE"; public static final String PATH_STATUS = "status"; public static final String PARAMETER_DIRECTION = "direction"; public static final String FORWARD = "forward"; public static final String BACKWARD = "back"; + public static final String EXIT = "exit"; public static final String PARAMETER_ERROR = "error"; public static final String PARAMETER_URI = "uri"; public static final String EXTRA_PREFERENCE_KEY = "extra_preference_key"; public static final String EXTRA_PREFERENCE_INFO_TEXT= "extra_preference_info_text"; public static final String EXTRA_PREFERENCE_INFO_IMAGE = "extra_preference_info_image"; + public static final String EXTRA_PREFERENCE_INFO_TITLE_ICON = + "extra_preference_info_title_icon"; + public static final String EXTRA_PREFERENCE_INFO_SUMMARY = "extra_preference_info_summary"; + public static final String EXTRA_PREFERENCE_INFO_STATUS = "extra_preference_info_status"; + public static final String EXTRA_ADD_INFO_STATUS = "extra_preference_add_info_status"; public static final String EXTRA_ACTION_ID = "extra_action_id"; public static final String EXTRA_PAGE_ID = "extra_page_id"; public static final String EXTRA_SLICE_FOLLOWUP = "extra_slice_followup"; public static final int SWITCH = 0; public static final int CHECKMARK = 1; public static final int RADIO = 2; + public static final int SEEKBAR = 3; - @IntDef({SWITCH, CHECKMARK, RADIO}) + @IntDef({SWITCH, CHECKMARK, RADIO, SEEKBAR}) @Retention(RetentionPolicy.SOURCE) public @interface BUTTONSTYLE {} } diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/builders/PreferenceSliceBuilder.java b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/builders/PreferenceSliceBuilder.java index 3cd6f11c0..249432966 100644 --- a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/builders/PreferenceSliceBuilder.java +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/builders/PreferenceSliceBuilder.java @@ -20,6 +20,7 @@ import static com.android.tv.twopanelsettings.slices.SlicesConstants.BUTTONSTYLE import static com.android.tv.twopanelsettings.slices.SlicesConstants.CHECKMARK; import static com.android.tv.twopanelsettings.slices.SlicesConstants.RADIO; import static com.android.tv.twopanelsettings.slices.SlicesConstants.SWITCH; +import static com.android.tv.twopanelsettings.slices.SlicesConstants.SEEKBAR; import android.app.PendingIntent; import android.content.Context; @@ -177,6 +178,17 @@ public class PreferenceSliceBuilder extends TemplateSliceBuilder { return this; } + + /** + * Set the redirected slice uri. Settings would render the slice from the redirected slice uri. + * @param redirectedSliceUri the redirected slice uri. + */ + @NonNull + public PreferenceSliceBuilder setRedirectedSliceUri(@NonNull CharSequence redirectedSliceUri) { + mImpl.setRedirectedSliceUri(redirectedSliceUri); + return this; + } + public static class RowBuilder { private final Uri mUri; @@ -195,8 +207,10 @@ public class PreferenceSliceBuilder extends TemplateSliceBuilder { private CharSequence mSubtitle; private boolean mSubtitleLoading; private CharSequence mContentDescription; - private CharSequence mInfoText; + private CharSequence mInfoTitle; + private CharSequence mInfoSummary; private IconCompat mInfoImage; + private IconCompat mInfoTitleIcon; private int mLayoutDirection = -1; private List<Object> mEndItems = new ArrayList<>(); private List<Integer> mEndTypes = new ArrayList<>(); @@ -207,9 +221,14 @@ public class PreferenceSliceBuilder extends TemplateSliceBuilder { private CharSequence mKey; private boolean mIconNeedsToBeProcessed; private @BUTTONSTYLE int mButtonStyle; + private int mSeekbarMin; + private int mSeekbarMax; + private int mSeekbarValue; private CharSequence mRadioGroup; private boolean mEnabled; private boolean mSelectable; + private boolean mAddInfoStatus; + private CharSequence mRedirectSliceUri; public static final int TYPE_ICON = 1; public static final int TYPE_ACTION = 2; @@ -327,7 +346,7 @@ public class PreferenceSliceBuilder extends TemplateSliceBuilder { } /** - * Sets the information image for the preference builder. + * Set the information image for the preference builder. * The image would be displayed at the top of preview screen. */ @NonNull @@ -337,12 +356,56 @@ public class PreferenceSliceBuilder extends TemplateSliceBuilder { } /** - * Sets the information text for the preference builder. - * The image would be displayed at the top of preview screen. + * Set the information title icon for the preference builder. + * The icon will be displayed to the left of description text title */ @NonNull + public RowBuilder setInfoTitleIcon(@NonNull IconCompat icon) { + mInfoTitleIcon = icon; + return this; + } + + /** + * Set the information text for the preference builder. + */ + @Deprecated + @NonNull public RowBuilder setInfoText(CharSequence text) { - mInfoText = text; + mInfoTitle = text; + return this; + } + + /** + * Set the information text title for the preference builder. + * + * It is strongly recommended to also invoke setContentDescription() for a11y + * purposes. Please see setContentDescription() for more details. + */ + @NonNull + public RowBuilder setInfoTitle(CharSequence text) { + mInfoTitle = text; + return this; + } + + /** + * Set the information text summary for the preference builder. + * + * It is strongly recommended to also invoke setContentDescription() for a11y + * purposes. Please see setContentDescription() for more details. + */ + @NonNull + public RowBuilder setInfoSummary(CharSequence text) { + mInfoSummary = text; + return this; + } + + /** + * Set whether need to add info status. If set true, info status would be automatically + * generated based upon the on/off status of the switch. + */ + @NonNull + public RowBuilder setAddInfoStatus(boolean addInfoStatus) { + mAddInfoStatus = addInfoStatus; return this; } @@ -405,7 +468,7 @@ public class PreferenceSliceBuilder extends TemplateSliceBuilder { return this; } - /** + /** * Sets the title for the row builder. A title should fit on a single line and is ellipsized * if too long. */ @@ -575,6 +638,16 @@ public class PreferenceSliceBuilder extends TemplateSliceBuilder { return addEndItem(switchAction); } + public PreferenceSliceBuilder.RowBuilder addSeekBar( + PendingIntent pendingIntent, int min, int max, int value) { + SliceAction seekbarAction = new SliceAction(pendingIntent, "", false); + mButtonStyle = SEEKBAR; + mSeekbarMin = min; + mSeekbarMax = max; + mSeekbarValue = value; + return addEndItem(seekbarAction); + } + /** * Adds an action to the end items of the row builder. A mixture of icons and actions is not * permitted. If an icon has already been added, this will throw {@link @@ -609,6 +682,14 @@ public class PreferenceSliceBuilder extends TemplateSliceBuilder { /** * Sets the content description for the row. + * + * Although TvSettings will try to construct the content description to its best extent + * if it's not set, it is strongly recommended to invoke this method with info items + * folded in the content description for the Roy for a11y purposes, as the info items + * may be unfocusable when talkback is on. + * + * By default, this method will assign the full info item title and summary to the + * content description if one is not specified. */ @NonNull public RowBuilder setContentDescription(@NonNull CharSequence description) { @@ -725,6 +806,27 @@ public class PreferenceSliceBuilder extends TemplateSliceBuilder { } /** + * + */ + public int getSeekbarMin() { + return mSeekbarMin; + } + + /** + * + */ + public int getSeekbarMax() { + return mSeekbarMax; + } + + /** + * + */ + public int getSeekbarValue() { + return mSeekbarValue; + } + + /** * Get the target slice uri. */ public CharSequence getTargetSliceUri() { @@ -764,6 +866,10 @@ public class PreferenceSliceBuilder extends TemplateSliceBuilder { return mSelectable; } + public boolean addInfoStatus() { + return mAddInfoStatus; + } + public boolean isTitleItemLoading() { return mTitleItemLoading; } @@ -792,6 +898,10 @@ public class PreferenceSliceBuilder extends TemplateSliceBuilder { return mPageId; } + public CharSequence getRedirectSliceUri() { + return mRedirectSliceUri; + } + public CharSequence getTitle() { return mTitle; } @@ -817,13 +927,25 @@ public class PreferenceSliceBuilder extends TemplateSliceBuilder { } public CharSequence getInfoText() { - return mInfoText; + return mInfoTitle; + } + + public CharSequence getInfoTitle() { + return mInfoTitle; + } + + public CharSequence getInfoSummary() { + return mInfoSummary; } public IconCompat getInfoImage() { return mInfoImage; } + public IconCompat getInfoTitleIcon() { + return mInfoTitleIcon; + } + public List<Object> getEndItems() { return mEndItems; } diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/builders/PreferenceSliceBuilderImpl.java b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/builders/PreferenceSliceBuilderImpl.java index 0cb6b21bb..0246cff88 100644 --- a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/builders/PreferenceSliceBuilderImpl.java +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/builders/PreferenceSliceBuilderImpl.java @@ -40,9 +40,12 @@ import static androidx.slice.core.SliceHints.SUBTYPE_MILLIS; import static com.android.tv.twopanelsettings.slices.SlicesConstants.BUTTONSTYLE; import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_ACTION_ID; +import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_ADD_INFO_STATUS; import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_PAGE_ID; import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_PREFERENCE_INFO_IMAGE; +import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_PREFERENCE_INFO_SUMMARY; import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_PREFERENCE_INFO_TEXT; +import static com.android.tv.twopanelsettings.slices.SlicesConstants.EXTRA_PREFERENCE_INFO_TITLE_ICON; import android.net.Uri; @@ -77,6 +80,7 @@ public class PreferenceSliceBuilderImpl extends TemplateBuilderImpl { public static final String TYPE_FOCUSED_PREFERENCE = "TYPE_FOCUSED_PREFERENCE"; public static final String TYPE_PREFERENCE_EMBEDDED = "TYPE_PREFERENCE_EMBEDDED"; public static final String TYPE_PREFERENCE_RADIO = "TYPE_PREFERENCE_RADIO"; + public static final String TYPE_REDIRECTED_SLICE_URI = "TYPE_REDIRECTED_SLICE_URI"; public static final String TAG_TARGET_URI = "TAG_TARGET_URI"; public static final String TAG_KEY = "TAG_KEY"; public static final String TAG_RADIO_GROUP = "TAG_RADIO_GROUP"; @@ -88,6 +92,9 @@ public class PreferenceSliceBuilderImpl extends TemplateBuilderImpl { public static final String SUBTYPE_IS_ENABLED = "SUBTYPE_IS_ENABLED"; public static final String SUBTYPE_IS_SELECTABLE = "SUBTYPE_IS_SELECTABLE"; public static final String SUBTYPE_INFO_PREFERENCE = "SUBTYPE_INFO_PREFERENCE"; + public static final String SUBTYPE_SEEKBAR_MIN = "SUBTYPE_SEEKBAR_MIN"; + public static final String SUBTYPE_SEEKBAR_MAX = "SUBTYPE_SEEKBAR_MAX"; + public static final String SUBTYPE_SEEKBAR_VALUE = "SUBTYPE_SEEKBAR_VALUE"; /** * @@ -157,6 +164,15 @@ public class PreferenceSliceBuilderImpl extends TemplateBuilderImpl { public void setEmbeddedPreference(@NonNull RowBuilder builder) { addRow(builder, TYPE_PREFERENCE_EMBEDDED); } + + /** + * Set the redirected slice uri. + * @param redirectedSliceUri the new redirected slice uri + */ + public void setRedirectedSliceUri(CharSequence redirectedSliceUri) { + addRow(new RowBuilder().setTitle(redirectedSliceUri), TYPE_REDIRECTED_SLICE_URI); + } + /** * Add a row to list builder. */ @@ -229,11 +245,17 @@ public class PreferenceSliceBuilderImpl extends TemplateBuilderImpl { private SliceItem mKeyItem; private SliceItem mIconNeedsToBeProcessedItem; private SliceItem mButtonStyleItem; + private SliceItem mSeekbarMinItem; + private SliceItem mSeekbarMaxItem; + private SliceItem mSeekbarValueItem; private SliceItem mIsEnabledItem; private SliceItem mIsSelectableItem; + private SliceItem mIsAddingInfoStatusItem; private SliceItem mRadioGroupItem; private SliceItem mInfoTextItem; private SliceItem mInfoImageItem; + private SliceItem mInfoTitleIconItem; + private SliceItem mInfoSummaryItem; /** * @@ -305,12 +327,25 @@ public class PreferenceSliceBuilderImpl extends TemplateBuilderImpl { if (builder.getInfoText() != null) { setInfoText(builder.getInfoText()); } + if (builder.getInfoTitle() != null) { + setInfoTitle(builder.getInfoTitle()); + } + if (builder.getInfoSummary() != null) { + setInfoSummary(builder.getInfoSummary()); + } + if (builder.getInfoTitleIcon() != null) { + setInfoTitleIcon(builder.getInfoTitleIcon()); + } if (builder.getInfoImage() != null) { setInfoImage(builder.getInfoImage()); } setButtonStyle(builder.getButtonStyle()); + setSeekbarMin(builder.getSeekbarMin()); + setSeekbarMax(builder.getSeekbarMax()); + setSeekbarValue(builder.getSeekbarValue()); setEnabled(builder.isEnabled()); setSelectable(builder.isSelectable()); + setAddInfoStatus(builder.addInfoStatus()); List<Object> endItems = builder.getEndItems(); List<Integer> endTypes = builder.getEndTypes(); List<Boolean> endLoads = builder.getEndLoads(); @@ -451,6 +486,30 @@ public class PreferenceSliceBuilderImpl extends TemplateBuilderImpl { } /** + * Set minimum value of the seekbar. + */ + public void setSeekbarMin(int value) { + mSeekbarMinItem = new SliceItem( + value, FORMAT_INT, SUBTYPE_SEEKBAR_MIN, new String[]{}); + } + + /** + * Set maximum value of the seekbar. + */ + public void setSeekbarMax(int value) { + mSeekbarMaxItem = new SliceItem( + value, FORMAT_INT, SUBTYPE_SEEKBAR_MAX, new String[]{}); + } + + /** + * Set progress value of the seekbar. + */ + public void setSeekbarValue(int value) { + mSeekbarValueItem = new SliceItem( + value, FORMAT_INT, SUBTYPE_SEEKBAR_VALUE, new String[]{}); + } + + /** * */ public void setRadioGroup(CharSequence radioGroup) { @@ -471,13 +530,17 @@ public class PreferenceSliceBuilderImpl extends TemplateBuilderImpl { selectable ? 1 : 0, FORMAT_INT, SUBTYPE_IS_SELECTABLE, new String[]{}); } + public void setAddInfoStatus(boolean addInfoStatus) { + mIsAddingInfoStatusItem = new SliceItem( + addInfoStatus ? 1 : 0, FORMAT_INT, EXTRA_ADD_INFO_STATUS, new String[]{}); + } + public void setKey(CharSequence key) { mKeyItem = new SliceItem(key, FORMAT_TEXT, TAG_KEY, new String[] {HINT_KEYWORDS}); } public void setInfoText(CharSequence infoText) { - mInfoTextItem = new SliceItem( - infoText, FORMAT_TEXT, EXTRA_PREFERENCE_INFO_TEXT, new String[]{}); + setInfoTitle(infoText); } public void setInfoImage(IconCompat infoImage) { @@ -485,6 +548,21 @@ public class PreferenceSliceBuilderImpl extends TemplateBuilderImpl { infoImage, FORMAT_IMAGE, EXTRA_PREFERENCE_INFO_IMAGE, new String[]{}); } + public void setInfoTitleIcon(IconCompat infoImage) { + mInfoTitleIconItem = new SliceItem( + infoImage, FORMAT_IMAGE, EXTRA_PREFERENCE_INFO_TITLE_ICON, new String[]{}); + } + + public void setInfoTitle(CharSequence infoTitle) { + mInfoTextItem = new SliceItem( + infoTitle, FORMAT_TEXT, EXTRA_PREFERENCE_INFO_TEXT, new String[]{}); + } + + public void setInfoSummary(CharSequence infoSummary) { + mInfoSummaryItem = new SliceItem( + infoSummary, FORMAT_TEXT, EXTRA_PREFERENCE_INFO_SUMMARY, new String[]{}); + } + /** * */ @@ -604,6 +682,24 @@ public class PreferenceSliceBuilderImpl extends TemplateBuilderImpl { if (mPageIdItem != null) { b.addItem(mPageIdItem); } + if (mInfoTitleIconItem != null) { + b.addItem(mInfoTitleIconItem); + } + if (mInfoSummaryItem != null) { + b.addItem(mInfoSummaryItem); + } + if (mIsAddingInfoStatusItem != null) { + b.addItem(mIsAddingInfoStatusItem); + } + if (mSeekbarMinItem != null) { + b.addItem(mSeekbarMinItem); + } + if (mSeekbarMaxItem != null) { + b.addItem(mSeekbarMaxItem); + } + if (mSeekbarValueItem != null) { + b.addItem(mSeekbarValueItem); + } for (int i = 0; i < mEndItems.size(); i++) { Slice item = mEndItems.get(i); b.addSubSlice(item); diff --git a/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/lint-baseline.xml b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/lint-baseline.xml new file mode 100644 index 000000000..1535a4da7 --- /dev/null +++ b/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/lint-baseline.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0"> + + <issue + id="NewApi" + message="Call requires API level 26 (current min is 21): `setTtl`" + errorLine1=" mImpl.setTtl(ttl);" + errorLine2=" ~~~~~~"> + <location + file="packages/apps/TvSettings/TwoPanelSettingsLib/src/com/android/tv/twopanelsettings/slices/builders/PreferenceSliceBuilder.java" + line="111" + column="15"/> + </issue> + +</issues> |
