Merge "Change LayoutPreference resource path in robo test"
diff --git a/Android.mk b/Android.mk
index 04749bf..7eb9b6a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -30,6 +30,8 @@
androidx.preference_preference \
androidx.recyclerview_recyclerview \
com.google.android.material_material \
+ setupcompat \
+ setupdesign
LOCAL_JAVA_LIBRARIES := \
telephony-common \
@@ -53,7 +55,6 @@
LOCAL_JACK_FLAGS := --multi-dex native
endif
-include frameworks/opt/setupwizard/library/common-gingerbread.mk
include frameworks/base/packages/SettingsLib/common.mk
include frameworks/base/packages/SettingsLib/search/common.mk
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 7807f0e..caca444 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -3054,6 +3054,14 @@
</intent-filter>
</activity>
+ <activity
+ android:name=".wifi.dpp.WifiDppEnrolleeActivity">
+ <intent-filter>
+ <action android:name="android.settings.WIFI_DPP_ENROLLEE_QR_CODE_SCANNER"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ </intent-filter>
+ </activity>
+
<activity android:name=".homepage.contextualcards.ContextualCardFeedbackDialog"
android:theme="@android:style/Theme.DeviceDefault.Light.Dialog.Alert" />
<!-- This is the longest AndroidManifest.xml ever. -->
diff --git a/res/layout-land/choose_lock_pattern.xml b/res/layout-land/choose_lock_pattern.xml
index 4d6f798..25230cb 100644
--- a/res/layout-land/choose_lock_pattern.xml
+++ b/res/layout-land/choose_lock_pattern.xml
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
@@ -164,7 +164,7 @@
</LinearLayout>
<!-- right side: lock pattern -->
- <com.android.setupwizardlib.view.FillContentLayout
+ <com.google.android.setupdesign.view.FillContentLayout
style="@style/LockPatternContainerStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
@@ -177,8 +177,8 @@
android:layout_gravity="center"
android:background="@color/lock_pattern_background" />
- </com.android.setupwizardlib.view.FillContentLayout>
+ </com.google.android.setupdesign.view.FillContentLayout>
</com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout-land/confirm_lock_pattern_normal.xml b/res/layout-land/confirm_lock_pattern_normal.xml
index 158d343..23e5d66 100644
--- a/res/layout-land/confirm_lock_pattern_normal.xml
+++ b/res/layout-land/confirm_lock_pattern_normal.xml
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
@@ -89,7 +89,7 @@
</ScrollView>
- <com.android.setupwizardlib.view.FillContentLayout
+ <com.google.android.setupdesign.view.FillContentLayout
style="@style/LockPatternContainerStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
@@ -102,7 +102,7 @@
android:layout_gravity="center"
android:background="@color/lock_pattern_background" />
- </com.android.setupwizardlib.view.FillContentLayout>
+ </com.google.android.setupdesign.view.FillContentLayout>
</com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout-land/fingerprint_enroll_enrolling.xml b/res/layout-land/fingerprint_enroll_enrolling.xml
index 8b902f1..eb32602 100644
--- a/res/layout-land/fingerprint_enroll_enrolling.xml
+++ b/res/layout-land/fingerprint_enroll_enrolling.xml
@@ -15,7 +15,7 @@
~ limitations under the License
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
@@ -108,7 +108,7 @@
android:gravity="center"
android:orientation="vertical">
- <com.android.setupwizardlib.view.FillContentLayout
+ <com.google.android.setupdesign.view.FillContentLayout
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginVertical="24dp"
@@ -120,7 +120,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center" />
- </com.android.setupwizardlib.view.FillContentLayout>
+ </com.google.android.setupdesign.view.FillContentLayout>
<TextView
style="@style/TextAppearance.FingerprintErrorText"
@@ -139,4 +139,4 @@
</LinearLayout>
</ScrollView>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout-land/fingerprint_enroll_find_sensor.xml b/res/layout-land/fingerprint_enroll_find_sensor.xml
index 8712ad7..e6a2e66 100644
--- a/res/layout-land/fingerprint_enroll_find_sensor.xml
+++ b/res/layout-land/fingerprint_enroll_find_sensor.xml
@@ -15,7 +15,7 @@
~ limitations under the License
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
@@ -112,4 +112,4 @@
</LinearLayout>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout-land/fingerprint_enroll_finish.xml b/res/layout-land/fingerprint_enroll_finish.xml
index 04ed540..1187c20 100644
--- a/res/layout-land/fingerprint_enroll_finish.xml
+++ b/res/layout-land/fingerprint_enroll_finish.xml
@@ -15,7 +15,7 @@
~ limitations under the License
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
@@ -75,7 +75,7 @@
android:layout_height="0dp"
android:layout_weight="1" />
- <com.android.setupwizardlib.view.ButtonBarLayout
+ <com.google.android.setupdesign.view.ButtonBarLayout
style="@style/SuwGlifButtonBar.Stackable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -103,11 +103,11 @@
android:layout_height="wrap_content"
android:text="@string/security_settings_fingerprint_enroll_done" />
- </com.android.setupwizardlib.view.ButtonBarLayout>
+ </com.google.android.setupdesign.view.ButtonBarLayout>
</LinearLayout>
- <com.android.setupwizardlib.view.FillContentLayout
+ <com.google.android.setupdesign.view.FillContentLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent">
@@ -120,8 +120,8 @@
android:contentDescription="@android:string/fingerprint_icon_content_description"
android:src="@drawable/fingerprint_enroll_finish" />
- </com.android.setupwizardlib.view.FillContentLayout>
+ </com.google.android.setupdesign.view.FillContentLayout>
</LinearLayout>
</ScrollView>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout/choose_lock_password.xml b/res/layout/choose_lock_password.xml
index cea3e12..1962ee0 100644
--- a/res/layout/choose_lock_password.xml
+++ b/res/layout/choose_lock_password.xml
@@ -14,14 +14,14 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="@drawable/ic_lock"
android:importantForAutofill="noExcludeDescendants"
- settings:suwFooter="@layout/choose_lock_password_footer"
+ settings:sucFooter="@layout/choose_lock_password_footer"
settings:suwHeaderText="@string/lockpassword_choose_your_screen_lock_header">
<LinearLayout
@@ -79,4 +79,4 @@
</LinearLayout>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout/choose_lock_pattern_common.xml b/res/layout/choose_lock_pattern_common.xml
index 77dd12d..df7fd8c 100644
--- a/res/layout/choose_lock_pattern_common.xml
+++ b/res/layout/choose_lock_pattern_common.xml
@@ -16,14 +16,14 @@
-->
<!-- Used in phone portrait and tablet, as referenced in alias.xml. -->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="@drawable/ic_lock"
android:layout="@layout/suw_glif_blank_template"
- settings:suwFooter="@layout/choose_lock_pattern_common_footer"
+ settings:sucFooter="@layout/choose_lock_pattern_common_footer"
settings:suwHeaderText="@string/lockpassword_choose_your_screen_lock_header">
<com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient
@@ -85,7 +85,7 @@
android:paddingHorizontal="?attr/suwMarginSides"
android:textSize="12sp" />
- <com.android.setupwizardlib.view.FillContentLayout
+ <com.google.android.setupdesign.view.FillContentLayout
style="@style/LockPatternContainerStyle"
android:layout_width="wrap_content"
android:layout_height="0dp"
@@ -97,7 +97,7 @@
android:layout_height="match_parent"
android:layout_gravity="center" />
- </com.android.setupwizardlib.view.FillContentLayout>
+ </com.google.android.setupdesign.view.FillContentLayout>
</LinearLayout>
@@ -119,4 +119,4 @@
</com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout/choose_lock_pattern_common_footer.xml b/res/layout/choose_lock_pattern_common_footer.xml
index deea8f0..b0397ea 100644
--- a/res/layout/choose_lock_pattern_common_footer.xml
+++ b/res/layout/choose_lock_pattern_common_footer.xml
@@ -16,7 +16,7 @@
-->
<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
-<com.android.setupwizardlib.view.ButtonBarLayout
+<com.google.android.setupdesign.view.ButtonBarLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SuwGlifButtonBar.Stackable"
android:layout_width="match_parent"
@@ -49,4 +49,4 @@
android:layout_height="wrap_content"
android:text="@string/lockpattern_tutorial_continue_label" />
-</com.android.setupwizardlib.view.ButtonBarLayout>
+</com.google.android.setupdesign.view.ButtonBarLayout>
diff --git a/res/layout/confirm_lock_password_normal.xml b/res/layout/confirm_lock_password_normal.xml
index 0b516ca..4b92a4a 100644
--- a/res/layout/confirm_lock_password_normal.xml
+++ b/res/layout/confirm_lock_password_normal.xml
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
@@ -82,4 +82,4 @@
android:text="@string/cancel" />
</com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient>
-</com.android.setupwizardlib.GlifLayout>
\ No newline at end of file
+</com.google.android.setupdesign.GlifLayout>
\ No newline at end of file
diff --git a/res/layout/confirm_lock_pattern_normal_base.xml b/res/layout/confirm_lock_pattern_normal_base.xml
index bfabf99..14798df 100644
--- a/res/layout/confirm_lock_pattern_normal_base.xml
+++ b/res/layout/confirm_lock_pattern_normal_base.xml
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
@@ -65,7 +65,7 @@
android:paddingLeft="0dp"
android:paddingRight="0dp">
- <com.android.setupwizardlib.view.FillContentLayout
+ <com.google.android.setupdesign.view.FillContentLayout
style="@style/LockPatternContainerStyle"
android:layout_width="wrap_content"
android:layout_height="0dp"
@@ -77,7 +77,7 @@
android:layout_height="match_parent"
android:layout_gravity="center" />
- </com.android.setupwizardlib.view.FillContentLayout>
+ </com.google.android.setupdesign.view.FillContentLayout>
<TextView
style="@style/TextAppearance.ConfirmDeviceCredentialsErrorText"
@@ -104,4 +104,4 @@
</com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout/enable_accessibility_service_dialog_content.xml b/res/layout/enable_accessibility_service_dialog_content.xml
index f212eb1..e16dc65 100644
--- a/res/layout/enable_accessibility_service_dialog_content.xml
+++ b/res/layout/enable_accessibility_service_dialog_content.xml
@@ -38,20 +38,13 @@
android:textAppearance="?android:attr/textAppearanceMedium"/>
<TextView
- android:id="@+id/capabilities_header"
+ android:id="@+id/accessibility_service_warning"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dip"
android:textAlignment="viewStart"
android:textAppearance="?android:attr/textAppearanceMedium"/>
- <LinearLayout
- android:id="@+id/capabilities"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:padding="10dip"/>
-
</LinearLayout>
</ScrollView>
diff --git a/res/layout/encryption_interstitial.xml b/res/layout/encryption_interstitial.xml
index f827e37..ff56a7c 100644
--- a/res/layout/encryption_interstitial.xml
+++ b/res/layout/encryption_interstitial.xml
@@ -15,13 +15,13 @@
limitations under the License.
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="@drawable/ic_lock"
- app:suwFooter="@layout/encryption_interstitial_footer">
+ app:sucFooter="@layout/encryption_interstitial_footer">
<LinearLayout
style="@style/SuwContentFrame"
@@ -39,4 +39,4 @@
</LinearLayout>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout/face_enroll_enrolling.xml b/res/layout/face_enroll_enrolling.xml
index 2208cc2..e596ff9 100644
--- a/res/layout/face_enroll_enrolling.xml
+++ b/res/layout/face_enroll_enrolling.xml
@@ -15,14 +15,14 @@
~ limitations under the License.
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="?attr/face_layout_theme"
- app:suwFooter="@layout/face_enroll_enrolling_footer">
+ app:sucFooter="@layout/face_enroll_enrolling_footer">
<LinearLayout
style="@style/SuwContentFrame"
@@ -71,4 +71,4 @@
</LinearLayout>
-</com.android.setupwizardlib.GlifLayout>
\ No newline at end of file
+</com.google.android.setupdesign.GlifLayout>
\ No newline at end of file
diff --git a/res/layout/face_enroll_finish.xml b/res/layout/face_enroll_finish.xml
index 9966497..6b3e6ab 100644
--- a/res/layout/face_enroll_finish.xml
+++ b/res/layout/face_enroll_finish.xml
@@ -15,14 +15,14 @@
~ limitations under the License
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/setup_wizard_layout"
style="?attr/face_layout_theme"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:suwFooter="@layout/face_enroll_finish_footer">
+ app:sucFooter="@layout/face_enroll_finish_footer">
<LinearLayout
style="@style/SuwContentFrame"
@@ -39,7 +39,7 @@
android:gravity="center"
android:orientation="vertical">
- <com.android.setupwizardlib.view.FillContentLayout
+ <com.google.android.setupdesign.view.FillContentLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
@@ -51,10 +51,10 @@
android:contentDescription="@null"
android:src="@drawable/face_enroll_introduction" />
- </com.android.setupwizardlib.view.FillContentLayout>
+ </com.google.android.setupdesign.view.FillContentLayout>
</LinearLayout>
</LinearLayout>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout/face_enroll_finish_footer.xml b/res/layout/face_enroll_finish_footer.xml
index 06d2639..b33cde7 100644
--- a/res/layout/face_enroll_finish_footer.xml
+++ b/res/layout/face_enroll_finish_footer.xml
@@ -16,7 +16,7 @@
-->
<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
-<com.android.setupwizardlib.view.ButtonBarLayout
+<com.google.android.setupdesign.view.ButtonBarLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SuwGlifButtonBar.Stackable"
android:layout_width="match_parent"
@@ -34,4 +34,4 @@
android:layout_height="wrap_content"
android:text="@string/security_settings_face_enroll_done" />
-</com.android.setupwizardlib.view.ButtonBarLayout>
+</com.google.android.setupdesign.view.ButtonBarLayout>
diff --git a/res/layout/face_enroll_introduction.xml b/res/layout/face_enroll_introduction.xml
index a56bca5..7a5c172 100644
--- a/res/layout/face_enroll_introduction.xml
+++ b/res/layout/face_enroll_introduction.xml
@@ -15,14 +15,14 @@
~ limitations under the License
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
style="?attr/face_layout_theme"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:suwFooter="@layout/face_enroll_introduction_footer">
+ app:sucFooter="@layout/face_enroll_introduction_footer">
<LinearLayout
style="@style/SuwContentFrame"
@@ -32,20 +32,20 @@
android:clipToPadding="false"
android:orientation="vertical">
- <com.android.setupwizardlib.view.RichTextView
+ <com.google.android.setupdesign.view.RichTextView
android:id="@+id/description_text"
style="@style/SuwDescription.Glif"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/security_settings_face_enroll_introduction_message" />
- <com.android.setupwizardlib.view.RichTextView
+ <com.google.android.setupdesign.view.RichTextView
android:id="@+id/error_text"
style="@style/SuwDescription.Glif"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
- <com.android.setupwizardlib.view.FillContentLayout
+ <com.google.android.setupdesign.view.FillContentLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
@@ -57,8 +57,8 @@
android:contentDescription="@null"
android:src="@drawable/face_enroll_introduction" />
- </com.android.setupwizardlib.view.FillContentLayout>
+ </com.google.android.setupdesign.view.FillContentLayout>
</LinearLayout>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout/face_enroll_introduction_footer.xml b/res/layout/face_enroll_introduction_footer.xml
index 0fcc13b..d73a8ed 100644
--- a/res/layout/face_enroll_introduction_footer.xml
+++ b/res/layout/face_enroll_introduction_footer.xml
@@ -16,7 +16,7 @@
-->
<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
-<com.android.setupwizardlib.view.ButtonBarLayout
+<com.google.android.setupdesign.view.ButtonBarLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SuwGlifButtonBar.Stackable"
android:layout_width="match_parent"
@@ -41,4 +41,4 @@
android:layout_height="wrap_content"
android:text="@string/suw_next_button_label" />
-</com.android.setupwizardlib.view.ButtonBarLayout>
+</com.google.android.setupdesign.view.ButtonBarLayout>
diff --git a/res/layout/fingerprint_enroll_enrolling_base.xml b/res/layout/fingerprint_enroll_enrolling_base.xml
index 00a452c..5a2b60f 100644
--- a/res/layout/fingerprint_enroll_enrolling_base.xml
+++ b/res/layout/fingerprint_enroll_enrolling_base.xml
@@ -15,14 +15,14 @@
~ limitations under the License
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="?attr/fingerprint_layout_theme"
- app:suwFooter="@layout/fingerprint_enroll_enrolling_base_footer">
+ app:sucFooter="@layout/fingerprint_enroll_enrolling_base_footer">
<LinearLayout
style="@style/SuwContentFrame"
@@ -64,7 +64,7 @@
android:gravity="center"
android:orientation="vertical">
- <com.android.setupwizardlib.view.FillContentLayout
+ <com.google.android.setupdesign.view.FillContentLayout
android:layout_width="@dimen/fingerprint_progress_bar_max_size"
android:layout_height="@dimen/fingerprint_progress_bar_max_size"
android:paddingTop="0dp"
@@ -75,7 +75,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center" />
- </com.android.setupwizardlib.view.FillContentLayout>
+ </com.google.android.setupdesign.view.FillContentLayout>
<TextView
style="@style/TextAppearance.FingerprintErrorText"
@@ -91,4 +91,4 @@
</LinearLayout>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout/fingerprint_enroll_find_sensor_base.xml b/res/layout/fingerprint_enroll_find_sensor_base.xml
index ea518a7..18941a2 100644
--- a/res/layout/fingerprint_enroll_find_sensor_base.xml
+++ b/res/layout/fingerprint_enroll_find_sensor_base.xml
@@ -15,14 +15,14 @@
~ limitations under the License
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/setup_wizard_layout"
style="?attr/fingerprint_layout_theme"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:suwFooter="@layout/fingerprint_enroll_find_sensor_base_footer">
+ app:sucFooter="@layout/fingerprint_enroll_find_sensor_base_footer">
<LinearLayout
android:layout_width="match_parent"
@@ -59,4 +59,4 @@
android:layout_gravity="center_horizontal"/>
</LinearLayout>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout/fingerprint_enroll_finish_base.xml b/res/layout/fingerprint_enroll_finish_base.xml
index 819bf4e..5224dab 100644
--- a/res/layout/fingerprint_enroll_finish_base.xml
+++ b/res/layout/fingerprint_enroll_finish_base.xml
@@ -15,14 +15,14 @@
~ limitations under the License
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/setup_wizard_layout"
style="?attr/fingerprint_layout_theme"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:suwFooter="@layout/fingerprint_enroll_finish_base_footer">
+ app:sucFooter="@layout/fingerprint_enroll_finish_base_footer">
<LinearLayout
style="@style/SuwContentFrame"
@@ -48,7 +48,7 @@
android:gravity="center"
android:orientation="vertical">
- <com.android.setupwizardlib.view.FillContentLayout
+ <com.google.android.setupdesign.view.FillContentLayout
android:layout_width="@dimen/fingerprint_progress_bar_max_size"
android:layout_height="@dimen/fingerprint_progress_bar_max_size"
android:layout_marginVertical="24dp"
@@ -64,7 +64,7 @@
android:padding="7dp"
android:contentDescription="@android:string/fingerprint_icon_content_description"
android:src="@drawable/fingerprint_enroll_finish" />
- </com.android.setupwizardlib.view.FillContentLayout>
+ </com.google.android.setupdesign.view.FillContentLayout>
<!-- Added to align elements with fingerprint_enroll_enrolling_base -->
<TextView
@@ -78,4 +78,4 @@
</LinearLayout>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout/fingerprint_enroll_finish_base_footer.xml b/res/layout/fingerprint_enroll_finish_base_footer.xml
index 4c257fa..91164bd 100644
--- a/res/layout/fingerprint_enroll_finish_base_footer.xml
+++ b/res/layout/fingerprint_enroll_finish_base_footer.xml
@@ -16,7 +16,7 @@
-->
<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
-<com.android.setupwizardlib.view.ButtonBarLayout
+<com.google.android.setupdesign.view.ButtonBarLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SuwGlifButtonBar.Stackable"
android:layout_width="match_parent"
@@ -41,4 +41,4 @@
android:layout_height="wrap_content"
android:text="@string/security_settings_fingerprint_enroll_done" />
-</com.android.setupwizardlib.view.ButtonBarLayout>
+</com.google.android.setupdesign.view.ButtonBarLayout>
diff --git a/res/layout/fingerprint_enroll_introduction.xml b/res/layout/fingerprint_enroll_introduction.xml
index 4228f42..701d94a 100644
--- a/res/layout/fingerprint_enroll_introduction.xml
+++ b/res/layout/fingerprint_enroll_introduction.xml
@@ -15,14 +15,14 @@
limitations under the License
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
style="?attr/fingerprint_layout_theme"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:suwFooter="@layout/fingerprint_enroll_introduction_footer">
+ app:sucFooter="@layout/fingerprint_enroll_introduction_footer">
<LinearLayout
style="@style/SuwContentFrame"
@@ -32,20 +32,20 @@
android:clipToPadding="false"
android:orientation="vertical">
- <com.android.setupwizardlib.view.RichTextView
+ <com.google.android.setupdesign.view.RichTextView
android:id="@+id/description_text"
style="@style/SuwDescription.Glif"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/security_settings_fingerprint_enroll_introduction_message" />
- <com.android.setupwizardlib.view.RichTextView
+ <com.google.android.setupdesign.view.RichTextView
android:id="@+id/error_text"
style="@style/SuwDescription.Glif"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
- <com.android.setupwizardlib.view.FillContentLayout
+ <com.google.android.setupdesign.view.FillContentLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
@@ -57,8 +57,8 @@
android:contentDescription="@null"
android:src="@drawable/fingerprint_enroll_introduction" />
- </com.android.setupwizardlib.view.FillContentLayout>
+ </com.google.android.setupdesign.view.FillContentLayout>
</LinearLayout>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout/fingerprint_enroll_introduction_footer.xml b/res/layout/fingerprint_enroll_introduction_footer.xml
index b2d6973..1298d82 100644
--- a/res/layout/fingerprint_enroll_introduction_footer.xml
+++ b/res/layout/fingerprint_enroll_introduction_footer.xml
@@ -16,7 +16,7 @@
-->
<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
-<com.android.setupwizardlib.view.ButtonBarLayout
+<com.google.android.setupdesign.view.ButtonBarLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SuwGlifButtonBar.Stackable"
android:layout_width="match_parent"
@@ -41,4 +41,4 @@
android:layout_height="wrap_content"
android:text="@string/suw_next_button_label" />
-</com.android.setupwizardlib.view.ButtonBarLayout>
+</com.google.android.setupdesign.view.ButtonBarLayout>
diff --git a/res/layout/master_clear.xml b/res/layout/master_clear.xml
index 8d4d623..83b02ff 100644
--- a/res/layout/master_clear.xml
+++ b/res/layout/master_clear.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/setup_wizard_layout"
@@ -135,4 +135,4 @@
android:layout_height="wrap_content"/>
</LinearLayout>
</ScrollView>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout/master_clear_confirm.xml b/res/layout/master_clear_confirm.xml
index d513dbb..2acdfce 100644
--- a/res/layout/master_clear_confirm.xml
+++ b/res/layout/master_clear_confirm.xml
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
@@ -37,4 +37,4 @@
android:layout_height="wrap_content"
android:text="@string/master_clear_final_desc"/>
</LinearLayout>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout/redaction_interstitial.xml b/res/layout/redaction_interstitial.xml
index 939ff92..929ac07 100644
--- a/res/layout/redaction_interstitial.xml
+++ b/res/layout/redaction_interstitial.xml
@@ -15,14 +15,14 @@
limitations under the License
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="@drawable/ic_suggested_notifications"
- settings:suwFooter="@layout/redaction_interstitial_footer"
+ settings:sucFooter="@layout/redaction_interstitial_footer"
settings:suwHeaderText="@string/lock_screen_notifications_interstitial_title">
<LinearLayout
@@ -78,4 +78,4 @@
</LinearLayout>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout/setup_preference.xml b/res/layout/setup_preference.xml
index 298bc9a..314bb0e 100644
--- a/res/layout/setup_preference.xml
+++ b/res/layout/setup_preference.xml
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<com.android.setupwizardlib.GlifPreferenceLayout
+<com.google.android.setupdesign.GlifPreferenceLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/list_container"
android:layout_width="match_parent"
diff --git a/res/layout/storage_wizard_generic.xml b/res/layout/storage_wizard_generic.xml
index fe4c052..77aff9c 100644
--- a/res/layout/storage_wizard_generic.xml
+++ b/res/layout/storage_wizard_generic.xml
@@ -14,13 +14,13 @@
limitations under the License.
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:suwFooter="@layout/storage_wizard_footer">
+ app:sucFooter="@layout/storage_wizard_footer">
<LinearLayout
style="@style/SuwContentFrame"
@@ -44,4 +44,4 @@
</LinearLayout>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout/storage_wizard_init.xml b/res/layout/storage_wizard_init.xml
index 4905de6..3b7a5de 100644
--- a/res/layout/storage_wizard_init.xml
+++ b/res/layout/storage_wizard_init.xml
@@ -14,13 +14,13 @@
limitations under the License.
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:suwFooter="@layout/storage_wizard_footer">
+ app:sucFooter="@layout/storage_wizard_footer">
<LinearLayout
style="@style/SuwContentFrame"
@@ -136,4 +136,4 @@
</LinearLayout>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout/storage_wizard_progress.xml b/res/layout/storage_wizard_progress.xml
index 0b38475..e1d685b 100644
--- a/res/layout/storage_wizard_progress.xml
+++ b/res/layout/storage_wizard_progress.xml
@@ -14,13 +14,13 @@
limitations under the License.
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:suwFooter="@layout/storage_wizard_footer">
+ app:sucFooter="@layout/storage_wizard_footer">
<LinearLayout
style="@style/SuwContentFrame"
@@ -59,4 +59,4 @@
</LinearLayout>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout/storage_wizard_ready.xml b/res/layout/storage_wizard_ready.xml
index a9e4ddf..e947758 100644
--- a/res/layout/storage_wizard_ready.xml
+++ b/res/layout/storage_wizard_ready.xml
@@ -14,13 +14,13 @@
limitations under the License.
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:suwFooter="@layout/storage_wizard_footer">
+ app:sucFooter="@layout/storage_wizard_footer">
<LinearLayout
style="@style/SuwContentFrame"
@@ -38,4 +38,4 @@
</LinearLayout>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout/wifi_button_preference_widget.xml b/res/layout/wifi_button_preference_widget.xml
new file mode 100644
index 0000000..55078c2
--- /dev/null
+++ b/res/layout/wifi_button_preference_widget.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+
+<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/button_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:background="@null"
+ android:visibility="gone"
+ android:contentDescription="@string/wifi_add_network" />
diff --git a/res/layout/wifi_dialog.xml b/res/layout/wifi_dialog.xml
index bb2946d..2a395b6 100644
--- a/res/layout/wifi_dialog.xml
+++ b/res/layout/wifi_dialog.xml
@@ -50,13 +50,28 @@
android:text="@string/wifi_ssid"
android:textDirection="locale" />
- <EditText android:id="@+id/ssid"
+ <RelativeLayout
android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+ <EditText android:id="@+id/ssid"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/wifi_item_edit_content"
+ android:hint="@string/wifi_ssid_hint"
+ android:singleLine="true"
+ android:inputType="textNoSuggestions" />
+ <ImageButton
+ android:id="@+id/ssid_scanner_button"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- style="@style/wifi_item_edit_content"
- android:hint="@string/wifi_ssid_hint"
- android:singleLine="true"
- android:inputType="textNoSuggestions" />
+ android:layout_alignParentRight="true"
+ android:layout_centerVertical="true"
+ android:layout_margin="5dp"
+ android:background="@null"
+ android:src="@drawable/ic_qrcode_24dp"
+ android:visibility="gone"
+ android:contentDescription="@string/wifi_add_network" />
+ </RelativeLayout>
<LinearLayout android:id="@+id/ssid_too_long_warning"
android:layout_width="match_parent"
@@ -270,12 +285,28 @@
style="@style/wifi_item_label"
android:text="@string/wifi_password" />
- <EditText android:id="@+id/password"
- android:layout_width="match_parent"
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+ <EditText android:id="@+id/password"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/wifi_item_edit_content"
+ android:singleLine="true"
+ android:password="true" />
+
+ <ImageButton
+ android:id="@+id/password_scanner_button"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- style="@style/wifi_item_edit_content"
- android:singleLine="true"
- android:password="true" />
+ android:layout_alignParentRight="true"
+ android:layout_centerVertical="true"
+ android:layout_margin="5dp"
+ android:background="@null"
+ android:src="@drawable/ic_qrcode_24dp"
+ android:visibility="gone"
+ android:contentDescription="@string/wifi_add_network" />
+ </RelativeLayout>
</LinearLayout>
<LinearLayout android:id="@+id/show_password_layout"
diff --git a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
index ab38ac1..0beacff 100644
--- a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
+++ b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
@@ -44,8 +44,5 @@
android:layout_height="wrap_content"
android:layout_gravity="center"/>
- <include layout="@layout/wifi_dpp_fragment_footer"
- android:gravity="center|bottom"/>
-
</LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index bdc0081..6aacb0a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2056,6 +2056,14 @@
<string name="wifi_dpp_add_device_to_network">Add a device to this network</string>
<!-- Hint for the user to center another device's QR code in the below camera window [CHAR LIMIT=120] -->
<string name="wifi_dpp_center_qr_code">Center the device\u2019s QR code below to add device to \u201c<xliff:g id="ssid" example="OfficeWifi">%1$s</xliff:g>\u201d</string>
+ <!-- Title for the fragment to scan QR code [CHAR LIMIT=50] -->
+ <string name="wifi_dpp_scan_qr_code">Scan QR code</string>
+ <!-- Hint for the user to center another device's QR code in the below camera window [CHAR LIMIT=NONE] -->
+ <string name="wifi_dpp_scan_qr_code_join_network">Join \u201c<xliff:g id="ssid" example="OfficeWifi">%1$s</xliff:g>\u201d by scanning a QR code</string>
+ <!-- Title for the fragment to share Wi-Fi [CHAR LIMIT=50] -->
+ <string name="wifi_dpp_share_wifi">Share Wi\u2011Fi</string>
+ <!-- Hint for the user to use another device to scan QR code on screen to join Wi-Fi [CHAR LIMIT=NONE] -->
+ <string name="wifi_dpp_scan_qr_code_with_another_device">Scan this QR code with another device to join \u201c<xliff:g id="ssid" example="OfficeWifi">%1$s</xliff:g>\u201d</string>
<!-- Label for the check box to share a network with other users on the same device -->
<string name="wifi_shared">Share with other device users</string>
<!-- Hint for unchanged fields -->
@@ -4830,11 +4838,12 @@
example="TalkBack">%1$s</xliff:g> affects data encryption, you need to confirm your password.
</string>
- <!-- Title for the capability of an accessibility service to receive events and keys. -->
- <string name="capability_title_receiveAccessibilityEvents">Observe your actions</string>
- <!-- Description for the capability of an accessibility service to receive events and keys. -->
- <string name="capability_desc_receiveAccessibilityEvents">Receive notifications when you\u2019re
- interacting with an app.</string>
+ <!-- Warning that explains that accessibility services have a lot of access to user data [CHAR LIMIT=NONE] -->
+ <string name="accessibility_service_warning"><xliff:g id="service"
+ example="TalkBack">%1$s</xliff:g> is requesting full control of this device. The service
+ can read the screen and act on behalf of users with accessibility needs.
+ This level of control is not appropriate for most apps.
+ </string>
<!-- Title for a warning about disabling an accessibility service. [CHAR LIMIT=NONE] -->
<string name="disable_service_title">Stop <xliff:g id="service" example="TalkBack">%1$s</xliff:g>?</string>
@@ -5421,11 +5430,23 @@
<!-- Battery saver: Label for preference to indicate there is no battery saver schedule [CHAR_LIMIT=40] -->
<string name="battery_saver_auto_no_schedule">No schedule</string>
+ <!-- Battery saver: Label for preference to indicate there is a routine based schedule [CHAR_LIMIT=40] -->
+ <string name="battery_saver_auto_routine">Based on your routine</string>
+
+ <!-- Battery saver: Label for preference to indicate there is a percentage based schedule [CHAR_LIMIT=40] -->
+ <string name="battery_saver_auto_percentage">Based on percentage</string>
+
+ <!-- Battery saver: Summary for preference to describe what is meant by a routine based schedule [CHAR_LIMIT=NONE] -->
+ <string name="battery_saver_auto_routine_summary">Battery Saver turns on if your battery is likely to run out before your next typical charge</string>
+
+ <!-- Battery saver: Label for seekbar to change battery saver threshold [CHAR_LIMIT=40] -->
+ <string name="battery_saver_auto_percentage_summary">Will turn on at <xliff:g id="percent" example="52%">%1$s</xliff:g></string>
+
<!-- Battery saver: Title for battery saver schedule screen [CHAR_LIMIT=40] -->
<string name="battery_saver_schedule_settings_title">Set a schedule</string>
<!-- Battery saver: Label for seekbar to change battery saver threshold [CHAR_LIMIT=40] -->
- <string name="battery_saver_seekbar_title">At <xliff:g id="percent">%1$s</xliff:g></string>
+ <string name="battery_saver_seekbar_title"><xliff:g id="percent">%1$s</xliff:g></string>
<!-- Battery saver: Placeholder label for seekbar to change battery saver threshold [CHAR_LIMIT=40] -->
<string name="battery_saver_seekbar_title_placeholder">Turn on</string>
@@ -7141,6 +7162,9 @@
<!-- Do not disturb: Delete text button presented in a dialog to confirm the user would like to delete the selected DND rules. [CHAR LIMIT=30] -->
<string name="zen_mode_schedule_delete">Delete</string>
+ <!-- Do not disturb: Edit label for button that allows user to edit the dnd schedule name. [CHAR LIMIT=30] -->
+ <string name="zen_mode_rule_name_edit">Edit</string>
+
<!-- Do not disturb: Title for the zen mode automatic rules page in settings. [CHAR LIMIT=30] -->
<string name="zen_mode_automation_settings_page_title">Schedules</string>
@@ -7911,7 +7935,7 @@
<item quantity="other"><xliff:g id="num_people" example="3">%d</xliff:g> others</item>
</plurals>
- <!-- [CHAR LIMIT=20] Zen mode settings: Messages option -->
+ <!-- [CHAR LIMIT=40] Zen mode settings: Messages option -->
<string name="zen_mode_messages">Allow text messages</string>
<!-- Do not disturb settings, messages, events and reminders footer [CHAR LIMIT=NONE]-->
@@ -8388,6 +8412,12 @@
<!-- Title for Default Phone app settings [CHAR LIMIT=30] -->
<string name="default_phone_title">Phone app</string>
+ <!--
+ ~ STOPSHIP(b/110557011): Remove once the new UI is ready.
+ -->
+ <!-- Title for Roles settings [CHAR LIMIT=30] -->
+ <string name="roles_title">Roles</string>
+
<!-- Label of default app for current setting [CHAR LIMIT=40] -->
<string name="default_app">(Default)</string>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 1e24770..9a05bfc 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -198,6 +198,7 @@
<item name="android:windowLightStatusBar">true</item>
<item name="android:navigationBarDividerColor">@*android:color/ripple_material_light</item>
<item name="android:navigationBarColor">@android:color/white</item>
+ <item name="android:windowBackground">@android:color/white</item>
<item name="android:windowLightNavigationBar">true</item>
</style>
diff --git a/res/xml/app_default_settings.xml b/res/xml/app_default_settings.xml
index a993aa1..c26c069 100644
--- a/res/xml/app_default_settings.xml
+++ b/res/xml/app_default_settings.xml
@@ -79,6 +79,14 @@
android:fragment="com.android.settings.applications.managedomainurls.ManageDomainUrls"
settings:keywords="@string/keywords_default_links"/>
+ <!--
+ ~ STOPSHIP(b/110557011): Remove once the new UI is ready.
+ -->
+ <Preference
+ android:key="roles"
+ android:title="@string/roles_title"
+ settings:controller="com.android.settings.applications.defaultapps.RolesPreferenceController" />
+
<com.android.settings.widget.WorkOnlyCategory
android:key="work_app_defaults"
android:title="@string/default_for_work">
diff --git a/res/xml/battery_saver_settings.xml b/res/xml/battery_saver_settings.xml
index eb4954f..a086018 100644
--- a/res/xml/battery_saver_settings.xml
+++ b/res/xml/battery_saver_settings.xml
@@ -20,6 +20,12 @@
android:title="@string/battery_saver"
android:key="battery_saver_page">
+ <Preference
+ android:key="battery_saver_schedule"
+ android:fragment="com.android.settings.fuelgauge.batterysaver.BatterySaverScheduleSettings"
+ android:title="@string/battery_saver_schedule_settings_title"
+ settings:controller="com.android.settings.fuelgauge.batterysaver.BatterySaverSchedulePreferenceController"/>
+
<!-- Turn on automatically -->
<SwitchPreference
android:key="auto_battery_saver"
diff --git a/res/xml/zen_mode_event_rule_settings.xml b/res/xml/zen_mode_event_rule_settings.xml
index c871fe1..a70b46c 100644
--- a/res/xml/zen_mode_event_rule_settings.xml
+++ b/res/xml/zen_mode_event_rule_settings.xml
@@ -17,12 +17,17 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="zen_mode_event_rule_settings"
android:title="@string/zen_mode_automatic_rule_settings_page_title">
<com.android.settingslib.widget.LayoutPreference
android:key="pref_app_header"
- android:layout="@layout/settings_entity_header" />
+ android:layout="@layout/settings_entity_header"
+ settings:allowDividerBelow="true" />
+
+ <com.android.settingslib.widget.ActionButtonsPreference
+ android:key="zen_action_buttons" />
<com.android.settingslib.widget.LayoutPreference
android:key="zen_automatic_rule_switch"
diff --git a/res/xml/zen_mode_schedule_rule_settings.xml b/res/xml/zen_mode_schedule_rule_settings.xml
index c257d87..7de10b3 100644
--- a/res/xml/zen_mode_schedule_rule_settings.xml
+++ b/res/xml/zen_mode_schedule_rule_settings.xml
@@ -17,12 +17,17 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="zen_mode_schedule_rule_settings"
android:title="@string/zen_mode_automatic_rule_settings_page_title">
<com.android.settingslib.widget.LayoutPreference
android:key="pref_app_header"
- android:layout="@layout/settings_entity_header" />
+ android:layout="@layout/settings_entity_header"
+ settings:allowDividerBelow="true"/>
+
+ <com.android.settingslib.widget.ActionButtonsPreference
+ android:key="zen_action_buttons"/>
<com.android.settingslib.widget.LayoutPreference
android:key="zen_automatic_rule_switch"
diff --git a/src/com/android/settings/EncryptionInterstitial.java b/src/com/android/settings/EncryptionInterstitial.java
index caef988..8cae26b 100644
--- a/src/com/android/settings/EncryptionInterstitial.java
+++ b/src/com/android/settings/EncryptionInterstitial.java
@@ -39,7 +39,8 @@
import com.android.settings.core.InstrumentedFragment;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.password.ChooseLockSettingsHelper;
-import com.android.setupwizardlib.GlifLayout;
+
+import com.google.android.setupdesign.GlifLayout;
import java.util.List;
diff --git a/src/com/android/settings/MasterClear.java b/src/com/android/settings/MasterClear.java
index 307bbc1..8e745a3 100644
--- a/src/com/android/settings/MasterClear.java
+++ b/src/com/android/settings/MasterClear.java
@@ -64,8 +64,9 @@
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.password.ConfirmLockPattern;
import com.android.settingslib.RestrictedLockUtilsInternal;
-import com.android.setupwizardlib.TemplateLayout;
-import com.android.setupwizardlib.template.ButtonFooterMixin;
+
+import com.google.android.setupcompat.TemplateLayout;
+import com.google.android.setupdesign.template.ButtonFooterMixin;
import java.util.List;
diff --git a/src/com/android/settings/MasterClearConfirm.java b/src/com/android/settings/MasterClearConfirm.java
index 8ebb710..ffbb2aa 100644
--- a/src/com/android/settings/MasterClearConfirm.java
+++ b/src/com/android/settings/MasterClearConfirm.java
@@ -43,8 +43,9 @@
import com.android.settings.core.InstrumentedFragment;
import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper;
import com.android.settingslib.RestrictedLockUtilsInternal;
-import com.android.setupwizardlib.TemplateLayout;
-import com.android.setupwizardlib.template.ButtonFooterMixin;
+
+import com.google.android.setupcompat.TemplateLayout;
+import com.google.android.setupdesign.template.ButtonFooterMixin;
/**
* Confirm and execute a reset of the device to a clean "just out of the box"
diff --git a/src/com/android/settings/SetupWizardUtils.java b/src/com/android/settings/SetupWizardUtils.java
index 27cdb69..0dbb2dc 100644
--- a/src/com/android/settings/SetupWizardUtils.java
+++ b/src/com/android/settings/SetupWizardUtils.java
@@ -21,7 +21,9 @@
import androidx.annotation.VisibleForTesting;
-import com.android.setupwizardlib.util.WizardManagerHelper;
+import com.google.android.setupcompat.util.WizardManagerHelper;
+import com.google.android.setupdesign.util.ThemeHelper;
+
public class SetupWizardUtils {
@@ -35,17 +37,17 @@
}
if (theme != null) {
switch (theme) {
- case WizardManagerHelper.THEME_GLIF_V3_LIGHT:
+ case ThemeHelper.THEME_GLIF_V3_LIGHT:
return R.style.GlifV3Theme_Light;
- case WizardManagerHelper.THEME_GLIF_V3:
+ case ThemeHelper.THEME_GLIF_V3:
return R.style.GlifV3Theme;
- case WizardManagerHelper.THEME_GLIF_V2_LIGHT:
+ case ThemeHelper.THEME_GLIF_V2_LIGHT:
return R.style.GlifV2Theme_Light;
- case WizardManagerHelper.THEME_GLIF_V2:
+ case ThemeHelper.THEME_GLIF_V2:
return R.style.GlifV2Theme;
- case WizardManagerHelper.THEME_GLIF_LIGHT:
+ case ThemeHelper.THEME_GLIF_LIGHT:
return R.style.GlifTheme_Light;
- case WizardManagerHelper.THEME_GLIF:
+ case ThemeHelper.THEME_GLIF:
return R.style.GlifTheme;
}
}
diff --git a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
index 6360d42..e0f1747 100644
--- a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
+++ b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
@@ -43,8 +43,8 @@
import java.util.Locale;
/**
- * Utility class for creating the dialog that asks users for explicit permission to grant
- * all of the requested capabilities to an accessibility service before the service is enabled
+ * Utility class for creating the dialog that asks users for explicit permission for an
+ * accessibility service to access user data before the service is enabled
*/
public class AccessibilityServiceWarning {
public static Dialog createCapabilitiesDialog(Activity parentActivity,
@@ -117,60 +117,9 @@
encryptionWarningView.setVisibility(View.GONE);
}
- TextView capabilitiesHeaderView = (TextView) content.findViewById(
- R.id.capabilities_header);
- capabilitiesHeaderView.setText(context.getString(R.string.capabilities_list_title,
- getServiceName(context, info)));
-
- LinearLayout capabilitiesView = (LinearLayout) content.findViewById(R.id.capabilities);
-
- // This capability is implicit for all services.
- View capabilityView = inflater.inflate(
- com.android.internal.R.layout.app_permission_item_old, null);
-
- ImageView imageView = (ImageView) capabilityView.findViewById(
- com.android.internal.R.id.perm_icon);
- imageView.setImageDrawable(context.getDrawable(
- com.android.internal.R.drawable.ic_text_dot));
-
- TextView labelView = (TextView) capabilityView.findViewById(
- com.android.internal.R.id.permission_group);
- labelView.setText(context.getString(
- R.string.capability_title_receiveAccessibilityEvents));
-
- TextView descriptionView = (TextView) capabilityView.findViewById(
- com.android.internal.R.id.permission_list);
- descriptionView.setText(
- context.getString(R.string.capability_desc_receiveAccessibilityEvents));
-
- List<AccessibilityServiceInfo.CapabilityInfo> capabilities =
- info.getCapabilityInfos(context);
-
- capabilitiesView.addView(capabilityView);
-
- // Service-specific capabilities.
- final int capabilityCount = capabilities.size();
- for (int i = 0; i < capabilityCount; i++) {
- AccessibilityServiceInfo.CapabilityInfo capability = capabilities.get(i);
-
- capabilityView = inflater.inflate(
- com.android.internal.R.layout.app_permission_item_old, null);
-
- imageView = (ImageView) capabilityView.findViewById(
- com.android.internal.R.id.perm_icon);
- imageView.setImageDrawable(context.getDrawable(
- com.android.internal.R.drawable.ic_text_dot));
-
- labelView = (TextView) capabilityView.findViewById(
- com.android.internal.R.id.permission_group);
- labelView.setText(context.getString(capability.titleResId));
-
- descriptionView = (TextView) capabilityView.findViewById(
- com.android.internal.R.id.permission_list);
- descriptionView.setText(context.getString(capability.descResId));
-
- capabilitiesView.addView(capabilityView);
- }
+ TextView serviceWarningTextView = content.findViewById(R.id.accessibility_service_warning);
+ serviceWarningTextView.setText(context.getString(R.string.accessibility_service_warning,
+ getServiceName(context, info)));
return content;
}
diff --git a/src/com/android/settings/applications/defaultapps/RolesPreferenceController.java b/src/com/android/settings/applications/defaultapps/RolesPreferenceController.java
new file mode 100644
index 0000000..59166dd
--- /dev/null
+++ b/src/com/android/settings/applications/defaultapps/RolesPreferenceController.java
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+package com.android.settings.applications.defaultapps;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.provider.Settings;
+import android.text.TextUtils;
+
+import androidx.preference.Preference;
+
+import com.android.settings.core.BasePreferenceController;
+
+/**
+ * STOPSHIP(b/110557011): Remove once the new UI is ready.
+ */
+public class RolesPreferenceController extends BasePreferenceController {
+
+ private Intent mIntent;
+
+ public RolesPreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
+
+ PackageManager packageManager = context.getPackageManager();
+ String packageName = packageManager.getPermissionControllerPackageName();
+ if (packageName != null) {
+ mIntent = new Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS)
+ .setPackage(packageName);
+ }
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return mIntent != null ? AVAILABLE_UNSEARCHABLE : UNSUPPORTED_ON_DEVICE;
+ }
+
+ @Override
+ public boolean handlePreferenceTreeClick(Preference preference) {
+ if (TextUtils.equals(preference.getKey(), mPreferenceKey)) {
+ if (mIntent != null) {
+ mContext.startActivity(mIntent);
+ }
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/com/android/settings/biometrics/BiometricEnrollBase.java b/src/com/android/settings/biometrics/BiometricEnrollBase.java
index f5a1b5e..0aa8936 100644
--- a/src/com/android/settings/biometrics/BiometricEnrollBase.java
+++ b/src/com/android/settings/biometrics/BiometricEnrollBase.java
@@ -32,7 +32,8 @@
import com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling;
import com.android.settings.core.InstrumentedActivity;
import com.android.settings.password.ChooseLockSettingsHelper;
-import com.android.setupwizardlib.GlifLayout;
+
+import com.google.android.setupdesign.GlifLayout;
/**
* Base activity for all biometric enrollment steps.
diff --git a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java
index beefb39..2424eb1 100644
--- a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java
@@ -28,7 +28,8 @@
import com.android.settings.R;
import com.android.settings.password.ChooseLockGeneric;
import com.android.settings.password.ChooseLockSettingsHelper;
-import com.android.setupwizardlib.span.LinkSpan;
+
+import com.google.android.setupdesign.span.LinkSpan;
/**
* Abstract base class for the intro onboarding activity for biometric enrollment.
diff --git a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
index 748f874..c4a9c4f 100644
--- a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
@@ -29,7 +29,8 @@
import com.android.settings.biometrics.BiometricEnrollIntroduction;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settingslib.RestrictedLockUtilsInternal;
-import com.android.setupwizardlib.span.LinkSpan;
+
+import com.google.android.setupdesign.span.LinkSpan;
public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
diff --git a/src/com/android/settings/biometrics/face/FaceEnrollSidecar.java b/src/com/android/settings/biometrics/face/FaceEnrollSidecar.java
index 7b445e5..2433fcb 100644
--- a/src/com/android/settings/biometrics/face/FaceEnrollSidecar.java
+++ b/src/com/android/settings/biometrics/face/FaceEnrollSidecar.java
@@ -43,8 +43,9 @@
if (mUserId != UserHandle.USER_NULL) {
mFaceManager.setActiveUser(mUserId);
}
+ // TODO: Send the list of disabled features
mFaceManager.enroll(mToken, mEnrollmentCancel,
- 0 /* flags */, mUserId, mEnrollmentCallback);
+ mEnrollmentCallback, new int[0] /* disabledFeatures */);
}
private FaceManager.EnrollmentCallback mEnrollmentCallback
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceController.java
index 9c4f964..2e32bf3 100644
--- a/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceController.java
+++ b/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceController.java
@@ -48,7 +48,6 @@
public void setToken(byte[] token) {
mToken = token;
- mPreference.setChecked(mFaceManager.getRequireAttention(mToken));
}
/**
@@ -64,18 +63,13 @@
public boolean isChecked() {
if (!FaceSettings.isAvailable(mContext)) {
return true;
- } else if (mToken == null) {
- // The token will be null when the controller is first created, since CC has not been
- // completed by the user. Once it's completed, FaceSettings will use setToken which
- // will retrieve the correct value from FaceService
- return true;
}
- return mFaceManager.getRequireAttention(mToken);
+ return mFaceManager.getFeature(FaceManager.FEATURE_REQUIRE_ATTENTION);
}
@Override
public boolean setChecked(boolean isChecked) {
- mFaceManager.setRequireAttention(isChecked, mToken);
+ mFaceManager.setFeature(FaceManager.FEATURE_REQUIRE_ATTENTION, isChecked, mToken);
return true;
}
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java
index 241545d..8821ce5 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java
@@ -32,7 +32,8 @@
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settingslib.HelpUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
-import com.android.setupwizardlib.span.LinkSpan;
+
+import com.google.android.setupdesign.span.LinkSpan;
public class FingerprintEnrollIntroduction extends BiometricEnrollIntroduction {
diff --git a/src/com/android/settings/deviceinfo/StorageWizardBase.java b/src/com/android/settings/deviceinfo/StorageWizardBase.java
index ef0e46b..50c908a 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardBase.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardBase.java
@@ -44,7 +44,8 @@
import com.android.settings.R;
import com.android.settingslib.Utils;
-import com.android.setupwizardlib.GlifLayout;
+
+import com.google.android.setupdesign.GlifLayout;
import java.text.NumberFormat;
import java.util.List;
diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSchedulePreferenceController.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSchedulePreferenceController.java
new file mode 100644
index 0000000..cc6aa00
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSchedulePreferenceController.java
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ *
+ */
+package com.android.settings.fuelgauge.batterysaver;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.os.PowerManager;
+import android.provider.Settings;
+import android.provider.Settings.Global;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.core.BasePreferenceController;
+
+public class BatterySaverSchedulePreferenceController extends BasePreferenceController {
+
+ @VisibleForTesting
+ Preference mBatterySaverSchedulePreference;
+ public static final String KEY_BATTERY_SAVER_SCHEDULE = "battery_saver_schedule";
+
+
+ public BatterySaverSchedulePreferenceController(Context context) {
+ super(context, KEY_BATTERY_SAVER_SCHEDULE);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_BATTERY_SAVER_SCHEDULE;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mBatterySaverSchedulePreference = screen.findPreference(KEY_BATTERY_SAVER_SCHEDULE);
+ }
+
+ @Override
+ public CharSequence getSummary() {
+ final ContentResolver resolver = mContext.getContentResolver();
+ final int mode = Settings.Global.getInt(resolver, Global.AUTOMATIC_POWER_SAVER_MODE,
+ PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+ if (mode == PowerManager.POWER_SAVER_MODE_PERCENTAGE) {
+ final int threshold =
+ Settings.Global.getInt(resolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
+ if (threshold <= 0) {
+ return mContext.getText(R.string.battery_saver_auto_no_schedule);
+ } else {
+ return mContext.getString(R.string.battery_saver_auto_percentage_summary,
+ Utils.formatPercentage(threshold));
+ }
+ } else {
+ return mContext.getText(R.string.battery_saver_auto_routine);
+ }
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+}
diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSettings.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSettings.java
new file mode 100644
index 0000000..fad9f31
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSettings.java
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+
+package com.android.settings.fuelgauge.batterysaver;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+import androidx.preference.PreferenceScreen;
+import com.android.settings.widget.RadioButtonPickerFragment;
+import com.android.settings.R;
+import com.android.settings.widget.RadioButtonPreference;
+import com.android.settings.widget.SeekBarPreference;
+import com.android.settingslib.widget.CandidateInfo;
+import com.google.common.collect.Lists;
+import java.util.List;
+
+public class BatterySaverScheduleSettings extends RadioButtonPickerFragment {
+
+ private static final String KEY_NO_SCHEDULE = "key_battery_saver_no_schedule";
+ private static final String KEY_ROUTINE = "key_battery_saver_routine";
+ private static final String KEY_PERCENTAGE = "key_battery_saver_percentage";
+ public static final int MAX_SEEKBAR_VALUE = 15;
+ public static final int MIN_SEEKBAR_VALUE = 1;
+ public static final String KEY_BATTERY_SAVER_SEEK_BAR = "battery_saver_seek_bar";
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.battery_saver_schedule_settings;
+ }
+
+ @Override
+ protected List<? extends CandidateInfo> getCandidates() {
+ Context context = getContext();
+ List<CandidateInfo> candidates = Lists.newArrayList();
+ candidates.add(new BatterySaverScheduleCandidateInfo(
+ context.getText(R.string.battery_saver_auto_no_schedule),
+ /* summary */ null,
+ KEY_NO_SCHEDULE,
+ /* enabled */ true));
+ candidates.add(new BatterySaverScheduleCandidateInfo(
+ context.getText(R.string.battery_saver_auto_routine),
+ context.getText(R.string.battery_saver_auto_routine_summary),
+ KEY_ROUTINE,
+ /* enabled */ true));
+ candidates.add(new BatterySaverScheduleCandidateInfo(
+ context.getText(R.string.battery_saver_auto_percentage),
+ /* summary */ null,
+ KEY_PERCENTAGE,
+ /* enabled */ true));
+
+ return candidates;
+ }
+
+ @Override
+ public void bindPreferenceExtra(RadioButtonPreference pref, String key, CandidateInfo info,
+ String defaultKey, String systemDefaultKey) {
+ final BatterySaverScheduleCandidateInfo candidateInfo =
+ (BatterySaverScheduleCandidateInfo) info;
+ final CharSequence summary = candidateInfo.getSummary();
+ if (summary != null) {
+ pref.setSummary(summary);
+ pref.setAppendixVisibility(View.GONE);
+ }
+ }
+
+ @Override
+ protected void addStaticPreferences(PreferenceScreen screen) {
+ SeekBarPreference seekbar = new SeekBarPreference(getContext());
+ seekbar.setMax(MAX_SEEKBAR_VALUE);
+ seekbar.setMin(MIN_SEEKBAR_VALUE);
+ seekbar.setTitle(R.string.battery_saver_seekbar_title_placeholder);
+ seekbar.setKey(KEY_BATTERY_SAVER_SEEK_BAR);
+ screen.addPreference(seekbar);
+ }
+
+ @Override
+ protected String getDefaultKey() {
+ return null;
+ }
+
+ @Override
+ protected boolean setDefaultKey(String key) {
+ return false;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return 0;
+ }
+
+ static class BatterySaverScheduleCandidateInfo extends CandidateInfo {
+
+ private final CharSequence mLabel;
+ private final CharSequence mSummary;
+ private final String mKey;
+
+ BatterySaverScheduleCandidateInfo(CharSequence label, CharSequence summary, String key,
+ boolean enabled) {
+ super(enabled);
+ mLabel = label;
+ mKey = key;
+ mSummary = summary;
+ }
+
+ @Override
+ public CharSequence loadLabel() {
+ return mLabel;
+ }
+
+ @Override
+ public Drawable loadIcon() {
+ return null;
+ }
+
+ @Override
+ public String getKey() {
+ return mKey;
+ }
+
+ public CharSequence getSummary() {
+ return mSummary;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSlice.java b/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSlice.java
index 403178c..41c2757 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSlice.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/BatteryFixSlice.java
@@ -18,11 +18,14 @@
import static android.content.Context.MODE_PRIVATE;
+import static com.android.settings.slices.CustomSliceRegistry.BATTERY_FIX_SLICE_URI;
+
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
+import android.util.Log;
import androidx.annotation.VisibleForTesting;
import androidx.annotation.WorkerThread;
@@ -36,13 +39,11 @@
import com.android.internal.os.BatteryStatsHelper;
import com.android.settings.R;
import com.android.settings.SubSettings;
-import com.android.settings.Utils;
import com.android.settings.fuelgauge.BatteryStatsHelperLoader;
import com.android.settings.fuelgauge.PowerUsageSummary;
import com.android.settings.fuelgauge.batterytip.BatteryTipLoader;
import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController;
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
-import com.android.settings.slices.CustomSliceRegistry;
import com.android.settings.slices.CustomSliceable;
import com.android.settings.slices.SliceBackgroundWorker;
import com.android.settings.slices.SliceBuilderUtils;
@@ -67,59 +68,44 @@
@Override
public Uri getUri() {
- return CustomSliceRegistry.BATTERY_FIX_SLICE_URI;
+ return BATTERY_FIX_SLICE_URI;
}
@Override
public Slice getSlice() {
- IconCompat icon;
- SliceAction primaryAction;
- Slice slice = null;
+ final ListBuilder sliceBuilder =
+ new ListBuilder(mContext, BATTERY_FIX_SLICE_URI, ListBuilder.INFINITY)
+ .setAccentColor(-1);
// TipType.SUMMARY is battery good
if (readBatteryTipAvailabilityCache(mContext) == BatteryTip.TipType.SUMMARY) {
- return null;
+ return buildBatteryGoodSlice(sliceBuilder, true);
}
final List<BatteryTip> batteryTips = SliceBackgroundWorker.getInstance(mContext,
this).getResults();
- if (batteryTips != null) {
- for (BatteryTip batteryTip : batteryTips) {
- if (batteryTip.getState() != BatteryTip.StateType.INVISIBLE) {
- icon = IconCompat.createWithResource(mContext, batteryTip.getIconId());
- primaryAction = SliceAction.createDeeplink(getPrimaryAction(),
- icon,
- ListBuilder.ICON_IMAGE,
- batteryTip.getTitle(mContext));
- slice = new ListBuilder(mContext, CustomSliceRegistry.BATTERY_FIX_SLICE_URI,
- ListBuilder.INFINITY)
- .setAccentColor(Utils.getColorAccentDefaultColor(mContext))
- .addRow(new RowBuilder()
- .setTitle(batteryTip.getTitle(mContext))
- .setSubtitle(batteryTip.getSummary(mContext))
- .setPrimaryAction(primaryAction)
- .addEndItem(icon, ListBuilder.ICON_IMAGE))
- .build();
- break;
- }
- }
- } else {
- icon = IconCompat.createWithResource(mContext,
- R.drawable.ic_battery_status_good_24dp);
- final String title = mContext.getString(R.string.power_usage_summary_title);
- primaryAction = SliceAction.createDeeplink(getPrimaryAction(), icon,
- ListBuilder.ICON_IMAGE, title);
- slice = new ListBuilder(mContext, CustomSliceRegistry.BATTERY_FIX_SLICE_URI,
- ListBuilder.INFINITY)
- .setAccentColor(Utils.getColorAccentDefaultColor(mContext))
- .addRow(new RowBuilder()
- .setTitle(title)
- .setPrimaryAction(primaryAction)
- .addEndItem(icon, ListBuilder.ICON_IMAGE))
- .build();
+ if (batteryTips == null) {
+ // Because we need wait slice background worker return data
+ return buildBatteryGoodSlice(sliceBuilder, false);
}
- return slice;
+
+ for (BatteryTip batteryTip : batteryTips) {
+ if (batteryTip.getState() != BatteryTip.StateType.INVISIBLE) {
+ final IconCompat icon = IconCompat.createWithResource(mContext, batteryTip.getIconId());
+ final SliceAction primaryAction = SliceAction.createDeeplink(getPrimaryAction(),
+ icon,
+ ListBuilder.ICON_IMAGE,
+ batteryTip.getTitle(mContext));
+ sliceBuilder.addRow(new RowBuilder()
+ .setTitle(batteryTip.getTitle(mContext))
+ .setSubtitle(batteryTip.getSummary(mContext))
+ .setPrimaryAction(primaryAction)
+ .addEndItem(icon, ListBuilder.ICON_IMAGE));
+ break;
+ }
+ }
+ return sliceBuilder.build();
}
@Override
@@ -151,6 +137,20 @@
return PendingIntent.getActivity(mContext, 0 /* requestCode */, intent, 0 /* flags */);
}
+ private Slice buildBatteryGoodSlice(ListBuilder sliceBuilder, boolean isError) {
+ final IconCompat icon = IconCompat.createWithResource(mContext,
+ R.drawable.ic_battery_status_good_24dp);
+ final String title = mContext.getString(R.string.power_usage_summary_title);
+ final SliceAction primaryAction = SliceAction.createDeeplink(getPrimaryAction(), icon,
+ ListBuilder.ICON_IMAGE, title);
+ sliceBuilder.addRow(new RowBuilder()
+ .setTitle(title)
+ .setPrimaryAction(primaryAction)
+ .addEndItem(icon, ListBuilder.ICON_IMAGE))
+ .setIsError(isError);
+ return sliceBuilder.build();
+ }
+
// TODO(b/114807643): we should find a better way to get current battery tip type quickly
// Now we save battery tip type to shared preference when battery level changes
public static void updateBatteryTipAvailabilityCache(Context context) {
diff --git a/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java b/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java
index c2db773..5fa3954 100644
--- a/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java
+++ b/src/com/android/settings/notification/ZenAutomaticRuleHeaderPreferenceController.java
@@ -76,14 +76,6 @@
mController = EntityHeaderController
.newInstance(mFragment.getActivity(), mFragment,
pref.findViewById(R.id.entity_header));
-
- mController.setEditListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- ZenRuleNameDialog.show(mFragment, mRule.getName(), null,
- new RuleNameChangeListener());
- }
- });
}
pref = mController.setIcon(getIcon())
@@ -123,20 +115,4 @@
mRule = rule;
mId = id;
}
-
- public class RuleNameChangeListener implements ZenRuleNameDialog.PositiveClickListener {
- public RuleNameChangeListener() {}
-
- @Override
- public void onOk(String ruleName, Fragment parent) {
- if (TextUtils.equals(ruleName, mRule.getName())) {
- return;
- }
- mMetricsFeatureProvider.action(mContext,
- MetricsProto.MetricsEvent.ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK);
- mRule.setName(ruleName);
- mRule.setModified(true);
- mBackend.updateZenRule(mId, mRule);
- }
- }
}
diff --git a/src/com/android/settings/notification/ZenModeAutomationSettings.java b/src/com/android/settings/notification/ZenModeAutomationSettings.java
index c559a28..d6a7d72 100644
--- a/src/com/android/settings/notification/ZenModeAutomationSettings.java
+++ b/src/com/android/settings/notification/ZenModeAutomationSettings.java
@@ -20,6 +20,7 @@
import android.app.AutomaticZenRule;
import android.content.Context;
import android.content.DialogInterface;
+import android.os.Bundle;
import android.provider.SearchIndexableResource;
import android.service.notification.ConditionProviderService;
import android.view.Menu;
@@ -44,12 +45,23 @@
@SearchIndexable
public class ZenModeAutomationSettings extends ZenModeSettingsBase {
+ public static final String DELETE = "DELETE_RULE";
protected final ManagedServiceSettings.Config CONFIG = getConditionProviderConfig();
private CharSequence[] mDeleteDialogRuleNames;
private String[] mDeleteDialogRuleIds;
private boolean[] mDeleteDialogChecked;
@Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ Bundle bundle = getArguments();
+ if (bundle != null && bundle.containsKey(DELETE)) {
+ mBackend.removeZenRule(bundle.getString(DELETE));
+ bundle.remove(DELETE);
+ }
+ }
+
+ @Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
ZenServiceListing serviceListing = new ZenServiceListing(getContext(), CONFIG);
serviceListing.reloadApprovedServices();
diff --git a/src/com/android/settings/notification/ZenModeEventRuleSettings.java b/src/com/android/settings/notification/ZenModeEventRuleSettings.java
index c11a672..ee3ed1c 100644
--- a/src/com/android/settings/notification/ZenModeEventRuleSettings.java
+++ b/src/com/android/settings/notification/ZenModeEventRuleSettings.java
@@ -27,6 +27,11 @@
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeConfig.EventInfo;
+import androidx.preference.DropDownPreference;
+import androidx.preference.Preference;
+import androidx.preference.Preference.OnPreferenceChangeListener;
+import androidx.preference.PreferenceScreen;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
@@ -38,11 +43,6 @@
import java.util.List;
import java.util.Objects;
-import androidx.preference.DropDownPreference;
-import androidx.preference.Preference;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-import androidx.preference.PreferenceScreen;
-
public class ZenModeEventRuleSettings extends ZenModeRuleSettingsBase {
private static final String KEY_CALENDAR = "calendar";
private static final String KEY_REPLY = "reply";
@@ -85,9 +85,12 @@
List<AbstractPreferenceController> controllers = new ArrayList<>();
mHeader = new ZenAutomaticRuleHeaderPreferenceController(context, this,
getSettingsLifecycle());
+ mActionButtons = new ZenRuleButtonsPreferenceController(context, this,
+ getSettingsLifecycle());
mSwitch = new ZenAutomaticRuleSwitchPreferenceController(context, this,
getSettingsLifecycle());
controllers.add(mHeader);
+ controllers.add(mActionButtons);
controllers.add(mSwitch);
return controllers;
}
@@ -107,8 +110,16 @@
mEvent.calendarId = calendar.calendarId;
}
}
- mCalendar.setEntries(entries.toArray(new CharSequence[entries.size()]));
- mCalendar.setEntryValues(values.toArray(new CharSequence[values.size()]));
+
+ CharSequence[] entriesArr = entries.toArray(new CharSequence[entries.size()]);
+ CharSequence[] valuesArr = values.toArray(new CharSequence[values.size()]);
+ if (!Objects.equals(mCalendar.getEntries(), entriesArr)) {
+ mCalendar.setEntries(entriesArr);
+ }
+
+ if (!Objects.equals(mCalendar.getEntryValues(), valuesArr)) {
+ mCalendar.setEntryValues(valuesArr);
+ }
}
@Override
@@ -159,8 +170,12 @@
@Override
protected void updateControlsInternal() {
- mCalendar.setValue(key(mEvent));
- mReply.setValue(Integer.toString(mEvent.reply));
+ if (!Objects.equals(mCalendar.getValue(), key(mEvent))) {
+ mCalendar.setValue(key(mEvent));
+ }
+ if (!Objects.equals(mReply.getValue(), Integer.toString(mEvent.reply))) {
+ mReply.setValue(Integer.toString(mEvent.reply));
+ }
}
@Override
@@ -233,7 +248,7 @@
private static String key(int userId, Long calendarId, String displayName) {
return EventInfo.resolveUserId(userId) + ":" + (calendarId == null ? "" : calendarId)
- + ":" + displayName;
+ + ":" + (displayName == null ? "" : displayName);
}
private static final Comparator<CalendarInfo> CALENDAR_NAME = new Comparator<CalendarInfo>() {
diff --git a/src/com/android/settings/notification/ZenModeRuleSettingsBase.java b/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
index 11b8084..e573884 100644
--- a/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
+++ b/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
@@ -43,6 +43,7 @@
protected String mId;
protected ZenAutomaticRuleHeaderPreferenceController mHeader;
+ protected ZenRuleButtonsPreferenceController mActionButtons;
protected ZenAutomaticRuleSwitchPreferenceController mSwitch;
abstract protected void onCreateInternal();
@@ -104,6 +105,10 @@
mHeader.onResume(mRule, mId);
mHeader.displayPreference(screen);
updatePreference(mHeader);
+
+ mActionButtons.onResume(mRule, mId);
+ mActionButtons.displayPreference(screen);
+ updatePreference(mActionButtons);
}
private void updatePreference(AbstractPreferenceController controller) {
@@ -147,7 +152,8 @@
private void toastAndFinish() {
Toast.makeText(mContext, R.string.zen_mode_rule_not_found_text, Toast.LENGTH_SHORT)
- .show();
+ .show();
+
getActivity().finish();
}
diff --git a/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java b/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
index 0b2e1bc..8aa993f 100644
--- a/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
+++ b/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
@@ -199,10 +199,12 @@
List<AbstractPreferenceController> controllers = new ArrayList<>();
mHeader = new ZenAutomaticRuleHeaderPreferenceController(context, this,
getSettingsLifecycle());
+ mActionButtons = new ZenRuleButtonsPreferenceController(context, this,
+ getSettingsLifecycle());
mSwitch = new ZenAutomaticRuleSwitchPreferenceController(context, this,
getSettingsLifecycle());
-
controllers.add(mHeader);
+ controllers.add(mActionButtons);
controllers.add(mSwitch);
return controllers;
}
diff --git a/src/com/android/settings/notification/ZenModeSettingsBase.java b/src/com/android/settings/notification/ZenModeSettingsBase.java
index 2aecae4..b9a14ee 100644
--- a/src/com/android/settings/notification/ZenModeSettingsBase.java
+++ b/src/com/android/settings/notification/ZenModeSettingsBase.java
@@ -52,9 +52,14 @@
}
@Override
- public void onCreate(Bundle icicle) {
- mContext = getActivity();
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ mContext = context;
mBackend = ZenModeBackend.getInstance(mContext);
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
super.onCreate(icicle);
updateZenMode(false /*fireChanged*/);
}
diff --git a/src/com/android/settings/notification/ZenRuleButtonsPreferenceController.java b/src/com/android/settings/notification/ZenRuleButtonsPreferenceController.java
new file mode 100644
index 0000000..1d43f6d
--- /dev/null
+++ b/src/com/android/settings/notification/ZenRuleButtonsPreferenceController.java
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+
+package com.android.settings.notification;
+
+import android.app.AutomaticZenRule;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+
+import androidx.fragment.app.Fragment;
+import androidx.preference.PreferenceFragmentCompat;
+import androidx.preference.PreferenceScreen;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.ActionButtonsPreference;
+
+public class ZenRuleButtonsPreferenceController extends AbstractZenModePreferenceController
+ implements PreferenceControllerMixin {
+ public static final String KEY = "zen_action_buttons";
+
+ private AutomaticZenRule mRule;
+ private String mId;
+ private PreferenceFragmentCompat mFragment;
+ private ActionButtonsPreference mButtonsPref;
+
+
+ public ZenRuleButtonsPreferenceController(Context context, PreferenceFragmentCompat fragment,
+ Lifecycle lc) {
+ super(context, KEY, lc);
+ mFragment = fragment;
+ }
+
+
+ @Override
+ public boolean isAvailable() {
+ return mRule != null;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ if (isAvailable()) {
+ mButtonsPref = ((ActionButtonsPreference) screen.findPreference(KEY))
+ .setButton1Text(R.string.zen_mode_rule_name_edit)
+ .setButton1Icon(R.drawable.ic_mode_edit)
+ .setButton1OnClickListener(new EditRuleNameClickListener())
+ .setButton2Text(R.string.zen_mode_delete_rule_button)
+ .setButton2Icon(R.drawable.ic_settings_delete)
+ .setButton2OnClickListener(new DeleteRuleClickListener());
+ }
+ }
+
+ public class EditRuleNameClickListener implements View.OnClickListener {
+ public EditRuleNameClickListener() {}
+
+ @Override
+ public void onClick(View v) {
+ ZenRuleNameDialog.show(mFragment, mRule.getName(), null,
+ new ZenRuleNameDialog.PositiveClickListener() {
+ @Override
+ public void onOk(String ruleName, Fragment parent) {
+ if (TextUtils.equals(ruleName, mRule.getName())) {
+ return;
+ }
+ mMetricsFeatureProvider.action(mContext,
+ MetricsProto.MetricsEvent.ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK);
+ mRule.setName(ruleName);
+ mRule.setModified(true);
+ mBackend.updateZenRule(mId, mRule);
+ }
+ });
+ }
+ }
+
+ public class DeleteRuleClickListener implements View.OnClickListener {
+ public DeleteRuleClickListener() {}
+
+ @Override
+ public void onClick(View v) {
+ ZenDeleteRuleDialog.show(mFragment, mRule.getName(), mId,
+ new ZenDeleteRuleDialog.PositiveClickListener() {
+ @Override
+ public void onOk(String id) {
+ Bundle bundle = new Bundle();
+ bundle.putString(ZenModeAutomationSettings.DELETE, id);
+ mMetricsFeatureProvider.action(mContext,
+ MetricsProto.MetricsEvent.ACTION_ZEN_DELETE_RULE_OK);
+ new SubSettingLauncher(mContext)
+ .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
+ .setDestination(ZenModeAutomationSettings.class.getName())
+ .setSourceMetricsCategory(MetricsProto.MetricsEvent
+ .NOTIFICATION_ZEN_MODE_AUTOMATION)
+ .setArguments(bundle)
+ .launch();
+ }
+ });
+ }
+ }
+
+ protected void onResume(AutomaticZenRule rule, String id) {
+ mRule = rule;
+ mId = id;
+ }
+}
diff --git a/src/com/android/settings/password/ChooseLockPassword.java b/src/com/android/settings/password/ChooseLockPassword.java
index 1ef95da..32d4edf 100644
--- a/src/com/android/settings/password/ChooseLockPassword.java
+++ b/src/com/android/settings/password/ChooseLockPassword.java
@@ -68,7 +68,8 @@
import com.android.settings.core.InstrumentedFragment;
import com.android.settings.notification.RedactionInterstitial;
import com.android.settings.widget.ImeAwareEditText;
-import com.android.setupwizardlib.GlifLayout;
+
+import com.google.android.setupdesign.GlifLayout;
import java.util.ArrayList;
import java.util.List;
diff --git a/src/com/android/settings/password/ChooseLockPattern.java b/src/com/android/settings/password/ChooseLockPattern.java
index 0d06ed8..1c9e3ff 100644
--- a/src/com/android/settings/password/ChooseLockPattern.java
+++ b/src/com/android/settings/password/ChooseLockPattern.java
@@ -48,9 +48,9 @@
import com.android.settings.Utils;
import com.android.settings.core.InstrumentedFragment;
import com.android.settings.notification.RedactionInterstitial;
-import com.android.setupwizardlib.GlifLayout;
import com.google.android.collect.Lists;
+import com.google.android.setupdesign.GlifLayout;
import java.util.ArrayList;
import java.util.Collections;
diff --git a/src/com/android/settings/password/ChooseLockSettingsHelper.java b/src/com/android/settings/password/ChooseLockSettingsHelper.java
index 938dec4..1c9191a 100644
--- a/src/com/android/settings/password/ChooseLockSettingsHelper.java
+++ b/src/com/android/settings/password/ChooseLockSettingsHelper.java
@@ -31,7 +31,8 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.SettingsActivity;
import com.android.settings.Utils;
-import com.android.setupwizardlib.util.WizardManagerHelper;
+
+import com.google.android.setupcompat.util.WizardManagerHelper;
public final class ChooseLockSettingsHelper {
diff --git a/src/com/android/settings/password/ChooseLockTypeDialogFragment.java b/src/com/android/settings/password/ChooseLockTypeDialogFragment.java
index 10c73c5..191f827 100644
--- a/src/com/android/settings/password/ChooseLockTypeDialogFragment.java
+++ b/src/com/android/settings/password/ChooseLockTypeDialogFragment.java
@@ -39,7 +39,8 @@
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment;
-import com.android.setupwizardlib.util.WizardManagerHelper;
+
+import com.google.android.setupcompat.util.WizardManagerHelper;
import java.util.List;
diff --git a/src/com/android/settings/password/SetupChooseLockGeneric.java b/src/com/android/settings/password/SetupChooseLockGeneric.java
index 7600104..8cd40d5 100644
--- a/src/com/android/settings/password/SetupChooseLockGeneric.java
+++ b/src/com/android/settings/password/SetupChooseLockGeneric.java
@@ -38,7 +38,8 @@
import com.android.settings.SetupWizardUtils;
import com.android.settings.biometrics.fingerprint.SetupFingerprintEnrollFindSensor;
import com.android.settings.utils.SettingsDividerItemDecoration;
-import com.android.setupwizardlib.GlifPreferenceLayout;
+
+import com.google.android.setupdesign.GlifPreferenceLayout;
/**
* Setup Wizard's version of ChooseLockGeneric screen. It inherits the logic and basic structure
diff --git a/src/com/android/settings/utils/SettingsDividerItemDecoration.java b/src/com/android/settings/utils/SettingsDividerItemDecoration.java
index 85cd961..3d9e901 100644
--- a/src/com/android/settings/utils/SettingsDividerItemDecoration.java
+++ b/src/com/android/settings/utils/SettingsDividerItemDecoration.java
@@ -21,7 +21,7 @@
import androidx.preference.PreferenceViewHolder;
import androidx.recyclerview.widget.RecyclerView;
-import com.android.setupwizardlib.DividerItemDecoration;
+import com.google.android.setupdesign.DividerItemDecoration;
public class SettingsDividerItemDecoration extends DividerItemDecoration {
diff --git a/src/com/android/settings/widget/RadioButtonPreference.java b/src/com/android/settings/widget/RadioButtonPreference.java
index ed7f905..512fe4e 100644
--- a/src/com/android/settings/widget/RadioButtonPreference.java
+++ b/src/com/android/settings/widget/RadioButtonPreference.java
@@ -44,6 +44,8 @@
}
private OnClickListener mListener = null;
+ private View appendix;
+ private int appendixVisibility = -1;
public RadioButtonPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
@@ -81,6 +83,10 @@
if (summaryContainer != null) {
summaryContainer.setVisibility(
TextUtils.isEmpty(getSummary()) ? View.GONE : View.VISIBLE);
+ appendix = view.findViewById(R.id.appendix);
+ if (appendix != null && appendixVisibility != -1) {
+ appendix.setVisibility(appendixVisibility);
+ }
}
TextView title = (TextView) view.findViewById(android.R.id.title);
@@ -89,4 +95,11 @@
title.setMaxLines(3);
}
}
+
+ public void setAppendixVisibility(int visibility) {
+ if (appendix != null) {
+ appendix.setVisibility(visibility);
+ }
+ appendixVisibility = visibility;
+ }
}
diff --git a/src/com/android/settings/wifi/AddNetworkFragment.java b/src/com/android/settings/wifi/AddNetworkFragment.java
index 814b358..72d878b 100644
--- a/src/com/android/settings/wifi/AddNetworkFragment.java
+++ b/src/com/android/settings/wifi/AddNetworkFragment.java
@@ -23,12 +23,14 @@
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
+import android.widget.ImageButton;
import androidx.annotation.VisibleForTesting;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.core.InstrumentedFragment;
+import com.android.settings.wifi.dpp.WifiDppUtils;
public class AddNetworkFragment extends InstrumentedFragment implements WifiConfigUiBase,
View.OnClickListener {
@@ -64,6 +66,18 @@
mCancelBtn.setOnClickListener(this);
mUIController = new WifiConfigController(this, rootView, null, getMode());
+ if (WifiDppUtils.isSharingNetworkEnabled(getContext())) {
+ final ImageButton scannerButton = rootView.findViewById(R.id.ssid_scanner_button);
+ if (scannerButton != null) {
+ scannerButton.setVisibility(View.VISIBLE);
+ scannerButton.setOnClickListener((View v) -> {
+ // Launch QR code scanner to join a network.
+ getContext().startActivity(
+ WifiDppUtils.getConfiguratorQRCodeScannerIntent(/* ssid */ null));
+ });
+ }
+ }
+
return rootView;
}
diff --git a/src/com/android/settings/wifi/ButtonPreference.java b/src/com/android/settings/wifi/ButtonPreference.java
new file mode 100644
index 0000000..62e8caf
--- /dev/null
+++ b/src/com/android/settings/wifi/ButtonPreference.java
@@ -0,0 +1,123 @@
+/*
+ * 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
+ */
+
+package com.android.settings.wifi;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageButton;
+
+import com.android.settings.R;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.annotation.DrawableRes;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+
+/**
+ * This preference provides one button layout with Settings style.
+ * It looks like below
+ *
+ * --------------------------------------------------------------
+ * | icon | title | button |
+ * --------------------------------------------------------------
+ *
+ * User can set icon / click listener for button.
+ * By default, the button is invisible.
+ */
+public class ButtonPreference extends Preference {
+
+ private static final String TAG = "ButtonPreference";
+
+ private ImageButton mImageButton;
+ private Drawable mButtonIcon;
+ private View.OnClickListener mClickListener;
+
+ // Used for dummy pref.
+ public ButtonPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setWidgetLayoutResource(R.layout.wifi_button_preference_widget);
+ mImageButton = null;
+ mButtonIcon = null;
+ mClickListener = null;
+ }
+
+ public ButtonPreference(Context context) {
+ this(context, /* attrs */ null);
+ }
+
+ @Override
+ public void onBindViewHolder(final PreferenceViewHolder view) {
+ super.onBindViewHolder(view);
+ initButton(view);
+ }
+
+ @Override
+ public void setOrder(int order) {
+ super.setOrder(order);
+ setButtonVisibility();
+ }
+
+ @VisibleForTesting
+ protected void initButton(final PreferenceViewHolder view) {
+ if (mImageButton == null) {
+ mImageButton = (ImageButton) view.findViewById(R.id.button_icon);
+ }
+ if (mImageButton != null) {
+ mImageButton.setImageDrawable(mButtonIcon);
+ mImageButton.setOnClickListener(mClickListener);
+ }
+ setButtonVisibility();
+ }
+
+ private void setButtonVisibility() {
+ if(mImageButton != null) {
+ mImageButton.setVisibility(mButtonIcon == null ? View.GONE : View.VISIBLE);
+ }
+ }
+
+ /**
+ * Sets the drawable to be displayed in button.
+ */
+ public ButtonPreference setButtonIcon(@DrawableRes int iconResId) {
+ if (iconResId == 0) {
+ return this;
+ }
+
+ try {
+ mButtonIcon = getContext().getDrawable(iconResId);
+ notifyChanged();
+ } catch (Resources.NotFoundException exception) {
+ Log.e(TAG, "Resource does not exist: " + iconResId);
+ }
+ return this;
+ }
+
+ /**
+ * Register a callback to be invoked when button is clicked.
+ */
+ public ButtonPreference setButtonOnClickListener(View.OnClickListener listener) {
+ if (listener != mClickListener) {
+ mClickListener = listener;
+ notifyChanged();
+ }
+ return this;
+ }
+}
diff --git a/src/com/android/settings/wifi/WifiDialog.java b/src/com/android/settings/wifi/WifiDialog.java
index 2b8fb2d..0e2ca60 100644
--- a/src/com/android/settings/wifi/WifiDialog.java
+++ b/src/com/android/settings/wifi/WifiDialog.java
@@ -21,10 +21,13 @@
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
+import android.widget.ImageButton;
import androidx.appcompat.app.AlertDialog;
import com.android.settings.R;
+import com.android.settings.wifi.dpp.WifiDppUtils;
+
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.wifi.AccessPoint;
@@ -77,7 +80,18 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
- mView = getLayoutInflater().inflate(R.layout.wifi_dialog, null);
+ mView = getLayoutInflater().inflate(R.layout.wifi_dialog, /* root */ null);
+ if (WifiDppUtils.isSharingNetworkEnabled(getContext())) {
+ final ImageButton scannerButton = mView.findViewById(R.id.password_scanner_button);
+ if (scannerButton != null) {
+ scannerButton.setVisibility(View.VISIBLE);
+ scannerButton.setOnClickListener((View v) -> {
+ // Launch QR code scanner to join a network.
+ getContext().startActivity(
+ WifiDppUtils.getConfiguratorQRCodeScannerIntent(/* ssid */ null));
+ });
+ }
+ }
setView(mView);
mController = new WifiConfigController(this, mView, mAccessPoint, mMode);
super.onCreate(savedInstanceState);
diff --git a/src/com/android/settings/wifi/WifiDialogActivity.java b/src/com/android/settings/wifi/WifiDialogActivity.java
index e3a03ad..9ef6a39 100644
--- a/src/com/android/settings/wifi/WifiDialogActivity.java
+++ b/src/com/android/settings/wifi/WifiDialogActivity.java
@@ -30,7 +30,8 @@
import com.android.settings.SetupWizardUtils;
import com.android.settingslib.wifi.AccessPoint;
-import com.android.setupwizardlib.util.WizardManagerHelper;
+
+import com.google.android.setupcompat.util.WizardManagerHelper;
public class WifiDialogActivity extends Activity implements WifiDialog.WifiDialogListener,
DialogInterface.OnDismissListener {
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 1c9a5e1..54de28d 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -66,6 +66,7 @@
import com.android.settings.widget.SummaryUpdater.OnSummaryChangeListener;
import com.android.settings.widget.SwitchBarController;
import com.android.settings.wifi.details.WifiNetworkDetailsFragment;
+import com.android.settings.wifi.dpp.WifiDppUtils;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.search.SearchIndexable;
@@ -175,7 +176,7 @@
private PreferenceCategory mConnectedAccessPointPreferenceCategory;
private PreferenceCategory mAccessPointsPreferenceCategory;
- private Preference mAddPreference;
+ private ButtonPreference mAddPreference;
@VisibleForTesting
Preference mConfigureWifiSettingsPreference;
@VisibleForTesting
@@ -235,9 +236,17 @@
mSavedNetworksPreference = findPreference(PREF_KEY_SAVED_NETWORKS);
Context prefContext = getPrefContext();
- mAddPreference = new Preference(prefContext);
+ mAddPreference = new ButtonPreference(prefContext);
mAddPreference.setIcon(R.drawable.ic_menu_add);
mAddPreference.setTitle(R.string.wifi_add_network);
+ if (WifiDppUtils.isSharingNetworkEnabled(getContext())) {
+ mAddPreference.setButtonIcon(R.drawable.ic_qrcode_24dp);
+ mAddPreference.setButtonOnClickListener((View v) -> {
+ // Launch QR code scanner to join a network.
+ getContext().startActivity(
+ WifiDppUtils.getConfiguratorQRCodeScannerIntent(/* ssid */ null));
+ });
+ }
mStatusMessagePreference = (LinkablePreference) findPreference(PREF_KEY_STATUS_MESSAGE);
mUserBadgeCache = new AccessPointPreference.UserBadgeCache(getPackageManager());
diff --git a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
index d81c19b..e4ae292 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
@@ -31,8 +31,26 @@
import com.android.settings.core.InstrumentedActivity;
import com.android.settings.R;
+/**
+ * To provision "other" device with specified Wi-Fi network.
+ *
+ * Uses different intents to specify different provisioning ways.
+ *
+ * For intent action {@code ACTION_CONFIGURATOR_QR_CODE_SCANNER} and
+ * {@code android.settings.WIFI_DPP_CONFIGURATOR_QR_CODE_GENERATOR}, specify the Wi-Fi network to be
+ * provisioned in:
+ *
+ * {@code WifiDppUtils.EXTRA_WIFI_SECURITY}
+ * {@code WifiDppUtils.EXTRA_WIFI_SSID}
+ * {@code WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY}
+ * {@code WifiDppUtils.EXTRA_WIFI_HIDDEN_SSID}
+ *
+ * For intent action {@code ACTION_CONFIGURATOR_CHOOSE_SAVED_WIFI_NETWORK}, specify Wi-Fi (DPP)
+ * QR code in {@code WifiDppUtils.EXTRA_QR_CODE}
+ */
public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
- WifiNetworkConfig.Retriever {
+ WifiNetworkConfig.Retriever,
+ WifiDppQrCodeGeneratorFragment.OnQrCodeGeneratorFragmentAddButtonClickedListener {
private static final String TAG = "WifiDppConfiguratorActivity";
public static final String ACTION_CONFIGURATOR_QR_CODE_SCANNER =
@@ -43,7 +61,6 @@
"android.settings.WIFI_DPP_CONFIGURATOR_CHOOSE_SAVED_WIFI_NETWORK";
private FragmentManager mFragmentManager;
- private FragmentTransaction mFragmentTransaction;
/** The Wi-Fi network which will be configured */
private WifiNetworkConfig mWifiNetworkConfig;
@@ -57,12 +74,20 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+
setContentView(R.layout.wifi_dpp_activity);
-
mFragmentManager = getSupportFragmentManager();
- mFragmentTransaction = getSupportFragmentManager().beginTransaction();
- Intent intent = getIntent();
+ handleIntent(getIntent());
+
+ ActionBar actionBar = getActionBar();
+ if (actionBar != null) {
+ actionBar.setElevation(0);
+ actionBar.setDisplayShowTitleEnabled(false);
+ }
+ }
+
+ private void handleIntent(Intent intent) {
boolean cancelActivity = false;
WifiNetworkConfig config;
switch (intent.getAction()) {
@@ -72,7 +97,7 @@
cancelActivity = true;
} else {
mWifiNetworkConfig = config;
- addQrCodeScannerFragment(/* addToBackStack= */ false);
+ showQrCodeScannerFragment(/* addToBackStack= */ false);
}
break;
case ACTION_CONFIGURATOR_QR_CODE_GENERATOR:
@@ -81,11 +106,11 @@
cancelActivity = true;
} else {
mWifiNetworkConfig = config;
- addQrCodeGeneratorFragment();
+ showQrCodeGeneratorFragment();
}
break;
case ACTION_CONFIGURATOR_CHOOSE_SAVED_WIFI_NETWORK:
- addChooseSavedWifiNetworkFragment(/* addToBackStack */ false);
+ showChooseSavedWifiNetworkFragment(/* addToBackStack */ false);
break;
default:
cancelActivity = true;
@@ -98,45 +123,55 @@
}
}
- private void addQrCodeScannerFragment(boolean addToBackStack) {
- WifiDppQrCodeScannerFragment fragment = new WifiDppQrCodeScannerFragment();
- mFragmentTransaction.add(R.id.fragment_container, fragment);
- if (addToBackStack) {
- mFragmentTransaction.addToBackStack(/* name */ null);
+ private void showQrCodeScannerFragment(boolean addToBackStack) {
+ // Avoid to replace the same fragment during configuration change
+ if (mFragmentManager.findFragmentByTag(WifiDppUtils.TAG_FRAGMENT_QR_CODE_SCANNER) != null) {
+ return;
}
- mFragmentTransaction.commit();
+
+ WifiDppQrCodeScannerFragment fragment = new WifiDppQrCodeScannerFragment();
+ FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
+
+ fragmentTransaction.replace(R.id.fragment_container, fragment,
+ WifiDppUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
+ if (addToBackStack) {
+ fragmentTransaction.addToBackStack(/* name */ null);
+ }
+ fragmentTransaction.commit();
}
- private void addQrCodeGeneratorFragment() {
+ private void showQrCodeGeneratorFragment() {
+ // Avoid to replace the same fragment during configuration change
+ if (mFragmentManager.findFragmentByTag(
+ WifiDppUtils.TAG_FRAGMENT_QR_CODE_GENERATOR) != null) {
+ return;
+ }
+
WifiDppQrCodeGeneratorFragment fragment = new WifiDppQrCodeGeneratorFragment();
- mFragmentTransaction.add(R.id.fragment_container, fragment);
- mFragmentTransaction.commit();
+ FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
+
+ fragmentTransaction.replace(R.id.fragment_container, fragment,
+ WifiDppUtils.TAG_FRAGMENT_QR_CODE_GENERATOR);
+ fragmentTransaction.commit();
}
- private void addChooseSavedWifiNetworkFragment(boolean addToBackStack) {
- ActionBar action = getActionBar();
- if (action != null) {
- action.hide();
+ private void showChooseSavedWifiNetworkFragment(boolean addToBackStack) {
+ // Avoid to replace the same fragment during configuration change
+ if (mFragmentManager.findFragmentByTag(
+ WifiDppUtils.TAG_FRAGMENT_CHOOSE_SAVED_WIFI_NETWORK) != null) {
+ return;
}
WifiDppChooseSavedWifiNetworkFragment fragment =
new WifiDppChooseSavedWifiNetworkFragment();
- mFragmentTransaction.add(R.id.fragment_container, fragment);
+ FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
+
+ fragmentTransaction.replace(R.id.fragment_container, fragment,
+ WifiDppUtils.TAG_FRAGMENT_CHOOSE_SAVED_WIFI_NETWORK);
if (addToBackStack) {
- mFragmentTransaction.addToBackStack(/* name */ null);
+ fragmentTransaction.addToBackStack(/* name */ null);
}
- mFragmentTransaction.commit();
- }
-
- @Override
- protected void onStop() {
- Fragment fragment = mFragmentManager.findFragmentById(R.id.fragment_container);
- if (fragment != null) {
- // Remove it to prevent stacking multiple fragments after screen rotated.
- mFragmentManager.beginTransaction().remove(fragment).commit();
- }
-
- super.onStop();
+ fragmentTransaction.commit();
}
@Override
@@ -153,4 +188,22 @@
return true;
}
}
+
+ @Override
+ public boolean onNavigateUp(){
+ Fragment fragment = mFragmentManager.findFragmentById(R.id.fragment_container);
+ if (fragment instanceof WifiDppQrCodeGeneratorFragment) {
+ setResult(Activity.RESULT_CANCELED);
+ finish();
+ return true;
+ } else if (fragment instanceof WifiDppQrCodeScannerFragment) {
+ mFragmentManager.popBackStackImmediate();
+ }
+
+ return false;
+ }
+
+ @Override public void onQrCodeGeneratorFragmentAddButtonClicked() {
+ showQrCodeScannerFragment(/* addToBackStack */ true);
+ }
}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivity.java b/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivity.java
new file mode 100644
index 0000000..7c58fd5
--- /dev/null
+++ b/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivity.java
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+package com.android.settings.wifi.dpp;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+
+import com.android.internal.logging.nano.MetricsProto;
+
+import com.android.settings.core.InstrumentedActivity;
+import com.android.settings.R;
+
+/**
+ * To provision "this" device with specified Wi-Fi network.
+ *
+ * To use intent action {@code ACTION_ENROLLEE_QR_CODE_SCANNER}, specify the SSID string of the
+ * Wi-Fi network to be provisioned in {@code WifiDppUtils.EXTRA_QR_CODE}.
+ */
+public class WifiDppEnrolleeActivity extends InstrumentedActivity {
+ private static final String TAG = "WifiDppEnrolleeActivity";
+
+ public static final String ACTION_ENROLLEE_QR_CODE_SCANNER =
+ "android.settings.WIFI_DPP_ENROLLEE_QR_CODE_SCANNER";
+
+ private FragmentManager mFragmentManager;
+
+ @Override
+ public int getMetricsCategory() {
+ //TODO:Should we use a new metrics category for Wi-Fi DPP?
+ return MetricsProto.MetricsEvent.WIFI_NETWORK_DETAILS;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.wifi_dpp_activity);
+ mFragmentManager = getSupportFragmentManager();
+
+ handleIntent(getIntent());
+
+ ActionBar actionBar = getActionBar();
+ if (actionBar != null) {
+ actionBar.setElevation(0);
+ actionBar.setDisplayShowTitleEnabled(false);
+ }
+ }
+
+ private void handleIntent(Intent intent) {
+ switch (intent.getAction()) {
+ case ACTION_ENROLLEE_QR_CODE_SCANNER:
+ String ssid = intent.getStringExtra(WifiDppUtils.EXTRA_WIFI_SSID);
+ showQrCodeScannerFragment(/* addToBackStack */ false, ssid);
+ break;
+ default:
+ Log.e(TAG, "Launch with an invalid action");
+ setResult(Activity.RESULT_CANCELED);
+ finish();
+ }
+ }
+
+ private void showQrCodeScannerFragment(boolean addToBackStack, String ssid) {
+ // Avoid to replace the same fragment during configuration change
+ if (mFragmentManager.findFragmentByTag(WifiDppUtils.TAG_FRAGMENT_QR_CODE_SCANNER) != null) {
+ return;
+ }
+
+ WifiDppQrCodeScannerFragment fragment = new WifiDppQrCodeScannerFragment(ssid);
+ FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
+
+ fragmentTransaction.replace(R.id.fragment_container, fragment,
+ WifiDppUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
+ if (addToBackStack) {
+ fragmentTransaction.addToBackStack(/* name */ null);
+ }
+ fragmentTransaction.commit();
+ }
+
+ @Override
+ public boolean onNavigateUp(){
+ setResult(Activity.RESULT_CANCELED);
+ finish();
+ return true;
+ }
+}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeBaseFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeBaseFragment.java
index c86fc98..cddd55c 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeBaseFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeBaseFragment.java
@@ -34,6 +34,10 @@
import com.android.settings.R;
/**
+ * TODO: Should refine code to only initiate UI component in each child fragment.
+ */
+
+/**
* There are below 4 fragments for Wi-Fi DPP UI flow, to reduce redundant code of UI components,
* this parent fragment instantiates all UI components and provides setting APIs for them.
*
@@ -58,11 +62,9 @@
private ImageView mWifiApPictureView; //optional, for WifiDppAddDeviceFragment
private TextView mChooseDifferentNetwork;//optional, for WifiDppAddDeviceFragment
- private Button mButtonLeft; //optional, for WifiDppQrCodeScannerFragment,
- // WifiDppChooseSavedWifiNetworkFragment,
+ private Button mButtonLeft; //optional, for WifiDppChooseSavedWifiNetworkFragment,
// WifiDppAddDeviceFragment
- private Button mButtonRight; //optional, for WifiDppQrCodeScannerFragment,
- // WifiDppChooseSavedWifiNetworkFragment,
+ private Button mButtonRight; //optional, for WifiDppChooseSavedWifiNetworkFragment,
// WifiDppAddDeviceFragment
abstract protected int getLayout();
@@ -122,8 +124,7 @@
}
/**
- * optional, for WifiDppQrCodeScannerFragment,
- * WifiDppChooseSavedWifiNetworkFragment,
+ * optional, for WifiDppChooseSavedWifiNetworkFragment,
* WifiDppAddDeviceFragment
*/
protected void setLeftButtonText(String text) {
@@ -133,8 +134,7 @@
}
/**
- * optional, for WifiDppQrCodeScannerFragment,
- * WifiDppChooseSavedWifiNetworkFragment,
+ * optional, for WifiDppChooseSavedWifiNetworkFragment,
* WifiDppAddDeviceFragment
*/
protected void setRightButtonText(String text) {
@@ -144,8 +144,7 @@
}
/**
- * optional, for WifiDppQrCodeScannerFragment,
- * WifiDppChooseSavedWifiNetworkFragment,
+ * optional, for WifiDppChooseSavedWifiNetworkFragment,
* WifiDppAddDeviceFragment
*/
protected void hideLeftButton() {
@@ -155,8 +154,7 @@
}
/**
- * optional, for WifiDppQrCodeScannerFragment,
- * WifiDppChooseSavedWifiNetworkFragment,
+ * optional, for WifiDppChooseSavedWifiNetworkFragment,
* WifiDppAddDeviceFragment
*/
protected void hideRightButton() {
@@ -166,8 +164,7 @@
}
/**
- * optional, for WifiDppQrCodeScannerFragment,
- * WifiDppChooseSavedWifiNetworkFragment,
+ * optional, for WifiDppChooseSavedWifiNetworkFragment,
* WifiDppAddDeviceFragment
*/
protected void setLeftButtonOnClickListener(View.OnClickListener listener) {
@@ -177,8 +174,7 @@
}
/**
- * optional, for WifiDppQrCodeScannerFragment,
- * WifiDppChooseSavedWifiNetworkFragment,
+ * optional, for WifiDppChooseSavedWifiNetworkFragment,
* WifiDppAddDeviceFragment
*/
protected void setRightButtonOnClickListener(View.OnClickListener listener) {
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
index 9935bf2..b064253 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
@@ -16,7 +16,12 @@
package com.android.settings.wifi.dpp;
+import android.app.ActionBar;
+import android.content.Context;
import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
import com.android.settings.R;
@@ -30,8 +35,64 @@
return R.layout.wifi_dpp_qrcode_generator_fragment;
}
+ // Container Activity must implement this interface
+ public interface OnQrCodeGeneratorFragmentAddButtonClickedListener {
+ public void onQrCodeGeneratorFragmentAddButtonClicked();
+ }
+ OnQrCodeGeneratorFragmentAddButtonClickedListener mListener;
+
@Override
- public void onActivityCreated (Bundle savedInstanceState) {
+ public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
+
+ WifiNetworkConfig wifiNetworkConfig = ((WifiNetworkConfig.Retriever) getActivity())
+ .getWifiNetworkConfig();
+ if (!WifiNetworkConfig.isValidConfig(wifiNetworkConfig)) {
+ throw new IllegalArgumentException("Invalid Wi-Fi network for configuring");
+ }
+ setTitle(getString(R.string.wifi_dpp_share_wifi));
+ setDescription(getString(R.string.wifi_dpp_scan_qr_code_with_another_device,
+ wifiNetworkConfig.getSsid()));
+
+ setHasOptionsMenu(true);
+ ActionBar actionBar = getActivity().getActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.show();
+ }
+ }
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+
+ mListener = (OnQrCodeGeneratorFragmentAddButtonClickedListener) context;
+ }
+
+ @Override
+ public void onDetach() {
+ mListener = null;
+
+ super.onDetach();
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ MenuItem item = menu.add(0, Menu.FIRST, 0, R.string.next_label);
+ item.setIcon(R.drawable.ic_menu_add);
+ item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+
+ super.onCreateOptionsMenu(menu, inflater);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem menuItem) {
+ switch (menuItem.getItemId()) {
+ case Menu.FIRST:
+ mListener.onQrCodeGeneratorFragmentAddButtonClicked();
+ return true;
+ default:
+ return super.onOptionsItemSelected(menuItem);
+ }
}
}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
index 70dade5..5689c56 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
@@ -17,12 +17,15 @@
package com.android.settings.wifi.dpp;
import android.annotation.Nullable;
+import android.app.ActionBar;
import android.app.Activity;
+import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Bundle;
-import android.text.TextUtils;
import android.util.Size;
+import android.view.Menu;
+import android.view.MenuInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
@@ -38,32 +41,60 @@
private SurfaceView mSurfaceView;
private QrDecorateView mDecorateView;
+ /** true if the fragment working for configurator, false enrollee*/
+ private final boolean mConfiguratorMode;
+
+ /** The SSID of the Wi-Fi network which the user specify to enroll */
+ private String mSsid;
+
@Override
protected int getLayout() {
return R.layout.wifi_dpp_qrcode_scanner_fragment;
}
+ /**
+ * Configurator container activity of the fragment should create instance with this constructor.
+ */
+ public WifiDppQrCodeScannerFragment() {
+ super();
+
+ mConfiguratorMode = true;
+ }
+
+ /**
+ * Enrollee container activity of the fragment should create instance with this constructor and
+ * specify the SSID string of the WI-Fi network to be provisioned.
+ */
+ public WifiDppQrCodeScannerFragment(String ssid) {
+ super();
+
+ mConfiguratorMode = false;
+ mSsid = ssid;
+ }
+
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- setTitle(getString(R.string.wifi_dpp_add_device_to_network));
+ if (mConfiguratorMode) {
+ setTitle(getString(R.string.wifi_dpp_add_device_to_network));
- WifiNetworkConfig wifiNetworkConfig = ((WifiNetworkConfig.Retriever) getActivity())
+ WifiNetworkConfig wifiNetworkConfig = ((WifiNetworkConfig.Retriever) getActivity())
.getWifiNetworkConfig();
- if (!WifiNetworkConfig.isValidConfig(wifiNetworkConfig)) {
- throw new IllegalArgumentException("Invalid Wi-Fi network for configuring");
+ if (!WifiNetworkConfig.isValidConfig(wifiNetworkConfig)) {
+ throw new IllegalArgumentException("Invalid Wi-Fi network for configuring");
+ }
+ setDescription(getString(R.string.wifi_dpp_center_qr_code, wifiNetworkConfig.getSsid()));
+ } else {
+ setTitle(getString(R.string.wifi_dpp_scan_qr_code));
+ setDescription(getString(R.string.wifi_dpp_scan_qr_code_join_network, mSsid));
}
- setDescription(getString(R.string.wifi_dpp_center_qr_code, wifiNetworkConfig.getSsid()));
- hideRightButton();
-
- setLeftButtonText(getString(android.R.string.cancel));
-
- setLeftButtonOnClickListener((view) -> {
- getActivity().setResult(Activity.RESULT_CANCELED);
- getActivity().finish();
- });
+ ActionBar actionBar = getActivity().getActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.show();
+ }
}
@Override
@@ -79,6 +110,21 @@
}
@Override
+ public void onDestroyView() {
+ SurfaceHolder surfaceHolder = mSurfaceView.getHolder();
+ surfaceHolder.removeCallback(this);
+
+ super.onDestroyView();
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ menu.removeItem(Menu.FIRST);
+
+ super.onCreateOptionsMenu(menu, inflater);
+ }
+
+ @Override
public void surfaceCreated(final SurfaceHolder holder) {
initCamera(holder);
}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppUtils.java b/src/com/android/settings/wifi/dpp/WifiDppUtils.java
index 70ef3a8..dc0ff84 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppUtils.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppUtils.java
@@ -16,12 +16,36 @@
package com.android.settings.wifi.dpp;
+import android.content.Context;
import android.content.Intent;
+import android.text.TextUtils;
+import android.util.FeatureFlagUtils;
/**
* Here are the items shared by both WifiDppConfiguratorActivity & WifiDppEnrolleeActivity
*/
public class WifiDppUtils {
+ /**
+ * The fragment tag specified to FragmentManager for container activities to manage fragments.
+ */
+ public static final String TAG_FRAGMENT_QR_CODE_SCANNER = "qr_code_scanner_fragment";
+
+ /**
+ * @see #TAG_FRAGMENT_QR_CODE_SCANNER
+ */
+ public static final String TAG_FRAGMENT_QR_CODE_GENERATOR = "qr_code_generator_fragment";
+
+ /**
+ * @see #TAG_FRAGMENT_QR_CODE_SCANNER
+ */
+ public static final String TAG_FRAGMENT_CHOOSE_SAVED_WIFI_NETWORK =
+ "choose_saved_wifi_network_fragment";
+
+ /**
+ * @see #TAG_FRAGMENT_QR_CODE_SCANNER
+ */
+ public static final String TAG_FRAGMENT_ADD_DEVICE = "add_device_fragment";
+
/** The data is from {@code com.android.settingslib.wifi.AccessPoint.securityToString} */
public static final String EXTRA_WIFI_SECURITY = "security";
@@ -54,4 +78,46 @@
* H true Optional. True if the network SSID is hidden.
*/
public static final String EXTRA_QR_CODE = "qrCode";
+
+ /**
+ * Returns whether the user can share the network represented by this preference with QR code.
+ */
+ public static boolean isSharingNetworkEnabled(Context context) {
+ return FeatureFlagUtils.isEnabled(context,
+ com.android.settings.core.FeatureFlags.WIFI_SHARING);
+ }
+
+ /**
+ * Returns an intent to launch QR code scanner.
+ *
+ * @param ssid The data corresponding to {@code WifiConfiguration} SSID
+ * @return Intent for launching QR code scanner
+ */
+ public static Intent getConfiguratorQRCodeScannerIntent(String ssid) {
+ final Intent intent = new Intent(
+ WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_SCANNER);
+ if (!TextUtils.isEmpty(ssid)) {
+ intent.putExtra(EXTRA_WIFI_SSID, ssid);
+ }
+ return intent;
+ }
+
+ /**
+ * Returns an intent to launch QR code generator.
+ *
+ * @param ssid The data corresponding to {@code WifiConfiguration} SSID
+ * @param Security The data is from {@code AccessPoint.securityToString}
+ * @return Intent for launching QR code generator
+ */
+ public static Intent getConfiguratorQRCodeGeneratorIntent(String ssid, String Security) {
+ final Intent intent = new Intent(
+ WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_GENERATOR);
+ if (!TextUtils.isEmpty(ssid)) {
+ intent.putExtra(EXTRA_WIFI_SSID, ssid);
+ }
+ if (!TextUtils.isEmpty(Security)) {
+ intent.putExtra(EXTRA_WIFI_SECURITY, Security);
+ }
+ return intent;
+ }
}
diff --git a/tests/robotests/res/layout-mcc999/fingerprint_enroll_find_sensor.xml b/tests/robotests/res/layout-mcc999/fingerprint_enroll_find_sensor.xml
index cedf5b9..50e2a37 100644
--- a/tests/robotests/res/layout-mcc999/fingerprint_enroll_find_sensor.xml
+++ b/tests/robotests/res/layout-mcc999/fingerprint_enroll_find_sensor.xml
@@ -15,14 +15,14 @@
limitations under the License.
-->
-<com.android.setupwizardlib.GlifLayout
+<com.google.android.setupdesign.GlifLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/setup_wizard_layout"
style="?attr/fingerprint_layout_theme"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:suwFooter="@layout/fingerprint_enroll_find_sensor_base_footer">
+ app:sucFooter="@layout/fingerprint_enroll_find_sensor_base_footer">
<FrameLayout
android:layout_width="match_parent"
@@ -77,4 +77,4 @@
</LinearLayout>
</FrameLayout>
-</com.android.setupwizardlib.GlifLayout>
+</com.google.android.setupdesign.GlifLayout>
diff --git a/tests/robotests/src/com/android/settings/SetupWizardUtilsTest.java b/tests/robotests/src/com/android/settings/SetupWizardUtilsTest.java
index beabd15..6220ac1 100644
--- a/tests/robotests/src/com/android/settings/SetupWizardUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/SetupWizardUtilsTest.java
@@ -22,7 +22,9 @@
import android.os.SystemProperties;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.setupwizardlib.util.WizardManagerHelper;
+
+import com.google.android.setupcompat.util.WizardManagerHelper;
+import com.google.android.setupdesign.util.ThemeHelper;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -47,9 +49,9 @@
@Test
public void testGetTheme_withIntentExtra_shouldReturnExtraTheme() {
SystemProperties.set(SetupWizardUtils.SYSTEM_PROP_SETUPWIZARD_THEME,
- WizardManagerHelper.THEME_GLIF);
+ ThemeHelper.THEME_GLIF);
Intent intent = new Intent();
- intent.putExtra(WizardManagerHelper.EXTRA_THEME, WizardManagerHelper.THEME_GLIF_V2);
+ intent.putExtra(WizardManagerHelper.EXTRA_THEME, ThemeHelper.THEME_GLIF_V2);
assertThat(SetupWizardUtils.getTheme(intent)).isEqualTo(R.style.GlifV2Theme);
}
@@ -57,7 +59,7 @@
@Test
public void testGetTheme_withEmptyIntent_shouldReturnSystemProperty() {
SystemProperties.set(SetupWizardUtils.SYSTEM_PROP_SETUPWIZARD_THEME,
- WizardManagerHelper.THEME_GLIF_V2_LIGHT);
+ ThemeHelper.THEME_GLIF_V2_LIGHT);
Intent intent = new Intent();
assertThat(SetupWizardUtils.getTheme(intent)).isEqualTo(R.style.GlifV2Theme_Light);
@@ -66,7 +68,7 @@
@Test
public void testGetTheme_glifV3Light_shouldReturnThemeResource() {
SystemProperties.set(SetupWizardUtils.SYSTEM_PROP_SETUPWIZARD_THEME,
- WizardManagerHelper.THEME_GLIF_V3_LIGHT);
+ ThemeHelper.THEME_GLIF_V3_LIGHT);
Intent intent = new Intent();
assertThat(SetupWizardUtils.getTheme(intent)).isEqualTo(R.style.GlifV3Theme_Light);
diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/RolesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/RolesPreferenceControllerTest.java
new file mode 100644
index 0000000..0946f37
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/applications/defaultapps/RolesPreferenceControllerTest.java
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+package com.android.settings.applications.defaultapps;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.provider.Settings;
+
+import androidx.preference.Preference;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class RolesPreferenceControllerTest {
+
+ private static final String PREFERENCE_KEY = "roles";
+ private static final String DIFFERENT_PREFERENCE_KEY = "different";
+ private static final String PERMISSION_CONTROLLER_PACKAGE_NAME =
+ "com.android.permissioncontroller";
+
+ @Mock
+ private Context mContext;
+ @Mock
+ private PackageManager mPackageManager;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ when(mContext.getPackageManager()).thenReturn(mPackageManager);
+ }
+
+ @Test
+ public void getAvailabilityStatus_noPermissionController_shouldReturnUnsupportedOnDevice() {
+ when(mPackageManager.getPermissionControllerPackageName()).thenReturn(null);
+ RolesPreferenceController controller = new RolesPreferenceController(mContext,
+ PREFERENCE_KEY);
+
+ assertThat(controller.getAvailabilityStatus())
+ .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_hasPermissionController_shouldReturnAvailableUnsearchable() {
+ when(mPackageManager.getPermissionControllerPackageName())
+ .thenReturn(PERMISSION_CONTROLLER_PACKAGE_NAME);
+ RolesPreferenceController controller = new RolesPreferenceController(mContext,
+ PREFERENCE_KEY);
+
+ assertThat(controller.getAvailabilityStatus())
+ .isEqualTo(BasePreferenceController.AVAILABLE_UNSEARCHABLE);
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_differentKey_shouldReturnFalse() {
+ when(mPackageManager.getPermissionControllerPackageName())
+ .thenReturn(PERMISSION_CONTROLLER_PACKAGE_NAME);
+ RolesPreferenceController controller = new RolesPreferenceController(mContext,
+ PREFERENCE_KEY);
+ Preference preference = mock(Preference.class);
+ when(preference.getKey()).thenReturn(DIFFERENT_PREFERENCE_KEY);
+
+ assertThat(controller.handlePreferenceTreeClick(preference)).isFalse();
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_sameKey_shouldReturnTrue() {
+ when(mPackageManager.getPermissionControllerPackageName())
+ .thenReturn(PERMISSION_CONTROLLER_PACKAGE_NAME);
+ RolesPreferenceController controller = new RolesPreferenceController(mContext,
+ PREFERENCE_KEY);
+ Preference preference = mock(Preference.class);
+ when(preference.getKey()).thenReturn(PREFERENCE_KEY);
+
+ assertThat(controller.handlePreferenceTreeClick(preference)).isTrue();
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_noPermissionController_shouldNotStartActivity() {
+ when(mPackageManager.getPermissionControllerPackageName()).thenReturn(null);
+ RolesPreferenceController controller = new RolesPreferenceController(mContext,
+ PREFERENCE_KEY);
+ Preference preference = mock(Preference.class);
+ when(preference.getKey()).thenReturn(PREFERENCE_KEY);
+ controller.handlePreferenceTreeClick(preference);
+
+ verify(mContext, never()).startActivity(any(Intent.class));
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_hasPermissionController_shouldStartActivityWithIntent() {
+ when(mPackageManager.getPermissionControllerPackageName())
+ .thenReturn(PERMISSION_CONTROLLER_PACKAGE_NAME);
+ RolesPreferenceController controller = new RolesPreferenceController(mContext,
+ PREFERENCE_KEY);
+ Preference preference = mock(Preference.class);
+ when(preference.getKey()).thenReturn(PREFERENCE_KEY);
+ controller.handlePreferenceTreeClick(preference);
+ ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
+
+ verify(mContext).startActivity(intent.capture());
+ assertThat(intent.getValue().getAction())
+ .isEqualTo(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS);
+ assertThat(intent.getValue().getPackage()).isEqualTo(PERMISSION_CONTROLLER_PACKAGE_NAME);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/AutoBatterySeekBarPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/AutoBatterySeekBarPreferenceControllerTest.java
index 5a92ce7..5d2ac62 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/AutoBatterySeekBarPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/AutoBatterySeekBarPreferenceControllerTest.java
@@ -86,7 +86,7 @@
mController.updateState(mPreference);
assertThat(mPreference.isVisible()).isTrue();
- assertThat(mPreference.getTitle()).isEqualTo("At 20%");
+ assertThat(mPreference.getTitle()).isEqualTo("20%");
assertThat(mPreference.getProgress()).isEqualTo(TRIGGER_LEVEL / INTERVAL);
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSchedulePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSchedulePreferenceControllerTest.java
new file mode 100644
index 0000000..c4d4c87
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSchedulePreferenceControllerTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ *
+ */
+package com.android.settings.fuelgauge.batterysaver;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.os.PowerManager;
+import android.provider.Settings;
+import android.provider.Settings.Global;
+import androidx.preference.Preference;
+import com.android.settings.R;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.SettingsShadowResources;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = SettingsShadowResources.class)
+public class BatterySaverSchedulePreferenceControllerTest {
+
+ private static final int TRIGGER_LEVEL = 20;
+ private static final int DEFAULT_LEVEL = 15;
+
+ private BatterySaverSchedulePreferenceController mController;
+ private Context mContext;
+ private Preference mPreference;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ SettingsShadowResources.overrideResource(
+ com.android.internal.R.integer.config_lowBatteryWarningLevel, DEFAULT_LEVEL);
+ mContext = RuntimeEnvironment.application;
+ mController = new BatterySaverSchedulePreferenceController(mContext);
+ mPreference = new Preference(mContext);
+ mController.mBatterySaverSchedulePreference = mPreference;
+ }
+
+ @Test
+ public void testPreference_lowPowerLevelZero_percentageMode_summaryNoSchedule() {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Global.AUTOMATIC_POWER_SAVER_MODE, PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.getSummary()).isEqualTo("No schedule");
+ }
+
+ @Test
+ public void testPreference_lowPowerLevelNonZero_percentageMode_summaryPercentage() {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, TRIGGER_LEVEL);
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Global.AUTOMATIC_POWER_SAVER_MODE, PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.getSummary()).isEqualTo("Will turn on at 20%");
+ }
+
+ @Test
+ public void testPreference_percentageRoutine_summaryRoutine() {
+ // It doesn't matter what this is set to for routine mode
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, TRIGGER_LEVEL);
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Global.AUTOMATIC_POWER_SAVER_MODE, PowerManager.POWER_SAVER_MODE_DYNAMIC);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.getSummary()).isEqualTo("Based on your routine");
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java
index fd44e4f..6e3e429 100644
--- a/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java
+++ b/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java
@@ -32,7 +32,8 @@
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.testutils.shadow.SettingsShadowResourcesImpl;
import com.android.settings.testutils.shadow.ShadowUtils;
-import com.android.setupwizardlib.GlifLayout;
+
+import com.google.android.setupdesign.GlifLayout;
import org.junit.After;
import org.junit.Before;
diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java
index ab7f795..352e2c4 100644
--- a/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java
+++ b/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java
@@ -32,7 +32,8 @@
import com.android.settings.testutils.shadow.SettingsShadowResourcesImpl;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settingslib.testutils.DrawableTestHelper;
-import com.android.setupwizardlib.GlifLayout;
+
+import com.google.android.setupdesign.GlifLayout;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockSettingsHelperTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockSettingsHelperTest.java
index e3f3833..12b0ebf 100644
--- a/tests/robotests/src/com/android/settings/password/ChooseLockSettingsHelperTest.java
+++ b/tests/robotests/src/com/android/settings/password/ChooseLockSettingsHelperTest.java
@@ -19,7 +19,9 @@
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settings.testutils.shadow.ShadowUtils;
-import com.android.setupwizardlib.util.WizardManagerHelper;
+
+import com.google.android.setupcompat.util.WizardManagerHelper;
+import com.google.android.setupdesign.util.ThemeHelper;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -109,7 +111,7 @@
@Test
public void testLaunchConfirmationActivity_internal_shouldPropagateTheme() {
Intent intent = new Intent()
- .putExtra(WizardManagerHelper.EXTRA_THEME, WizardManagerHelper.THEME_GLIF_V2);
+ .putExtra(WizardManagerHelper.EXTRA_THEME, ThemeHelper.THEME_GLIF_V2);
Activity activity = Robolectric.buildActivity(Activity.class, intent).get();
ChooseLockSettingsHelper helper = getChooseLockSettingsHelper(activity);
helper.launchConfirmationActivity(123, "test title", true, 0 /* userId */);
@@ -118,7 +120,7 @@
IntentForResult startedActivity = shadowActivity.getNextStartedActivityForResult();
assertThat(startedActivity.requestCode).isEqualTo(123);
assertThat(startedActivity.intent.getStringExtra(WizardManagerHelper.EXTRA_THEME))
- .isEqualTo(WizardManagerHelper.THEME_GLIF_V2);
+ .isEqualTo(ThemeHelper.THEME_GLIF_V2);
}
private ChooseLockSettingsHelper getChooseLockSettingsHelper(Activity activity) {
diff --git a/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java b/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java
index b3b3a8c..68db390 100644
--- a/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java
+++ b/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java
@@ -72,9 +72,9 @@
public static void addIncludedResourcePaths(List<ResourcePath> paths) {
try {
paths.add(new ResourcePath(null,
- Fs.fromURL(new URL("file:packages/apps/Settings/res")), null));
+ Fs.fromURL(new URL("file:packages/apps/Settings/res")), null));
paths.add(new ResourcePath(null,
- Fs.fromURL(new URL("file:frameworks/base/packages/SettingsLib/res")), null));
+ Fs.fromURL(new URL("file:frameworks/base/packages/SettingsLib/res")), null));
paths.add(new ResourcePath(null,
Fs.fromURL(new URL("file:frameworks/base/packages/SettingsLib/AppPreference/res/")), null));
paths.add(new ResourcePath(null,
@@ -88,21 +88,19 @@
paths.add(new ResourcePath(null,
Fs.fromURL(new URL("file:frameworks/base/packages/SettingsLib/LayoutPreference/res")), null));
paths.add(new ResourcePath(null,
- Fs.fromURL(new URL("file:frameworks/base/core/res/res")), null));
+ Fs.fromURL(new URL("file:frameworks/base/core/res/res")), null));
paths.add(new ResourcePath(null,
- Fs.fromURL(new URL("file:frameworks/opt/setupwizard/library/main/res")), null));
+ Fs.fromURL(new URL("file:external/setupcompat/main/res")), null));
+ paths.add(new ResourcePath(null,
+ Fs.fromURL(new URL("file:external/setupdesign/main/res")), null));
paths.add(new ResourcePath(null,
Fs.fromURL(new URL("file:out/target/common/obj/JAVA_LIBRARIES/robolectric_android-all-stub_intermediates/classes/raw-res/res")), null));
paths.add(new ResourcePath(null,
- Fs.fromURL(new URL("file:frameworks/opt/setupwizard/library/gingerbread/res")), null));
+ Fs.fromURL(new URL("file:out/soong/.intermediates/prebuilts/sdk/current/androidx/androidx.appcompat_appcompat-nodeps/android_common/aar/res/")), null));
paths.add(new ResourcePath(null,
- Fs.fromURL(new URL("file:frameworks/opt/setupwizard/library/recyclerview/res")), null));
+ Fs.fromURL(new URL("file:out/soong/.intermediates/prebuilts/sdk/current/extras/material-design-x/com.google.android.material_material-nodeps/android_common/aar/res/")), null));
paths.add(new ResourcePath(null,
- Fs.fromURL(new URL("file:out/soong/.intermediates/prebuilts/sdk/current/androidx/androidx.appcompat_appcompat-nodeps/android_common/aar/res/")), null));
- paths.add(new ResourcePath(null,
- Fs.fromURL(new URL("file:out/soong/.intermediates/prebuilts/sdk/current/extras/material-design-x/com.google.android.material_material-nodeps/android_common/aar/res/")), null));
- paths.add(new ResourcePath(null,
- Fs.fromURL(new URL("file:out/soong/.intermediates/prebuilts/sdk/current/androidx/androidx.cardview_cardview-nodeps/android_common/aar/res")), null));
+ Fs.fromURL(new URL("file:out/soong/.intermediates/prebuilts/sdk/current/androidx/androidx.cardview_cardview-nodeps/android_common/aar/res")), null));
paths.add(new ResourcePath(null,
Fs.fromURL(new URL("file:out/soong/.intermediates/prebuilts/sdk/current/androidx/androidx.slice_slice-view-nodeps/android_common/aar/res")), null));
paths.add(new ResourcePath(null,
diff --git a/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceTest.java b/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceTest.java
index 5d914a2..8a6aabf 100644
--- a/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/widget/RadioButtonPreferenceTest.java
@@ -24,6 +24,7 @@
import static org.mockito.Mockito.when;
import android.app.Application;
+import android.view.LayoutInflater;
import android.view.View;
import androidx.preference.PreferenceViewHolder;
@@ -93,4 +94,13 @@
mPreference.onBindViewHolder(preferenceViewHolder);
assertEquals(View.GONE, summaryContainer.getVisibility());
}
+
+ @Test
+ public void hideAppendix_shouldBeGone() {
+ mPreference.setAppendixVisibility(View.GONE);
+ View view = LayoutInflater.from(mContext).inflate(R.layout.preference_radio, null);
+ PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(view);
+ mPreference.onBindViewHolder(holder);
+ assertThat(holder.findViewById(R.id.appendix).getVisibility()).isEqualTo(View.GONE);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/wifi/ButtonPreferenceTest.java b/tests/robotests/src/com/android/settings/wifi/ButtonPreferenceTest.java
new file mode 100644
index 0000000..3dc109f
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/wifi/ButtonPreferenceTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+package com.android.settings.wifi;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.ImageButton;
+
+import com.android.settings.R;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import androidx.preference.PreferenceViewHolder;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class ButtonPreferenceTest {
+
+ private Context mContext;
+ private View mRootView;
+ private ButtonPreference mPref;
+ private PreferenceViewHolder mHolder;
+ private boolean mClicked;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mContext = RuntimeEnvironment.application;
+ mPref = new ButtonPreference(mContext);
+ mRootView = View.inflate(mContext, R.layout.wifi_button_preference_widget, /* parent */
+ null);
+ mHolder = PreferenceViewHolder.createInstanceForTests(mRootView);
+ }
+
+ @Test
+ public void initButton_noIcon_shouldInvisible() {
+ mPref.initButton(mHolder);
+ assertThat(mRootView.findViewById(R.id.button_icon).getVisibility()).isEqualTo(View.GONE);
+ }
+
+ @Test
+ public void initButton_withIcon_shouldVisible() {
+ mPref.setButtonIcon(R.drawable.ic_qrcode_24dp);
+ mPref.initButton(mHolder);
+ assertThat(mRootView.findViewById(R.id.button_icon).getVisibility()).isEqualTo(
+ View.VISIBLE);
+ }
+
+ @Test
+ public void initButton_whenClick_shouldCallback() {
+ mClicked = false;
+ mPref.setButtonIcon(R.drawable.ic_qrcode_24dp);
+ mPref.setButtonOnClickListener((View v) -> {
+ mClicked = true;
+ });
+ mPref.initButton(mHolder);
+ ImageButton button = (ImageButton) mRootView.findViewById(R.id.button_icon);
+ button.performClick();
+ assertThat(mClicked).isTrue();
+ }
+}
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
index 70e9587..2f95fa5 100644
--- a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
+++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
@@ -73,4 +73,12 @@
assertThat(activity instanceof WifiNetworkConfig.Retriever).isEqualTo(true);
}
+
+ @Test
+ public void testActivity_shouldImplementsQrCodeGeneratorFragmentCallback() {
+ WifiDppConfiguratorActivity activity = mActivityRule.getActivity();
+
+ assertThat(activity instanceof WifiDppQrCodeGeneratorFragment
+ .OnQrCodeGeneratorFragmentAddButtonClickedListener).isEqualTo(true);
+ }
}
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragmentTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragmentTest.java
new file mode 100644
index 0000000..d3f667f
--- /dev/null
+++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragmentTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+package com.android.settings.wifi.dpp;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.settings.R;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class WifiDppQrCodeGeneratorFragmentTest {
+ @Rule
+ public final ActivityTestRule<WifiDppConfiguratorActivity> mActivityRule =
+ new ActivityTestRule<>(WifiDppConfiguratorActivity.class, true);
+
+ @Before
+ public void setUp() {
+ Intent intent =
+ new Intent(WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_GENERATOR);
+ intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WEP");
+ intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest");
+ mActivityRule.launchActivity(intent);
+ }
+
+ @Test
+ public void rotateScreen_shouldNotCrash() {
+ mActivityRule.getActivity().setRequestedOrientation(
+ ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+ mActivityRule.getActivity().setRequestedOrientation(
+ ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+ }
+}
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java
index 98742ed..70cfc2d 100644
--- a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java
+++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java
@@ -16,12 +16,6 @@
package com.android.settings.wifi.dpp;
-import static android.support.test.espresso.action.ViewActions.click;
-import static android.support.test.espresso.matcher.ViewMatchers.withText;
-import static android.support.test.espresso.Espresso.onView;
-
-import static com.google.common.truth.Truth.assertThat;
-
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;